I want to test a Liferay portlet with Selenium, but the problem is that element ids generated by Liferay are dynamic and seems that they change each time I enter portlet. Does anyone has any suggestion how I test the portlet?
thanks for your help.
It would depend on how your elements are structured. There are various ways to identify elements and not just fixed ids.
If you have dynamic element ids, then try using some other attributes of the elements to uniquely identify elements for eg, text() or name etc... At times, it also happens that ids are generated with a common pattern, in which case you can try using that for eg, //div[contains(#id,'fixedpart')]
or //div[starts-with(#id,'fixedpart')]
I would recommend to use new HTML5 attribute like data-*, for example for a certain
<div data-selenium-test = "foo"></div>
Then grab this element with selenium:
//div[#data-selenium-test='foo']
Related
This isn't much of a coding question but one about what options should I take next. I've just started using selenium about a week ago and started to get the hang of most of its function.
I was working on a work project to login into various websites until I ran into a issue where I was getting this error when I tried to find the password field
Exception in thread "main" org.openqa.selenium.ElementNotVisibleException: element not visible
I went ahead and double checked the name & id but I couldn't find the field using locators like .id, name, and xpath. I inspected the xpath with Firebug and noticed that it returned two results instead of one.
Current Xpath looks like this
.//*[#id='password']
I was wondering if anyone could point me to the right direct when dealing with something like this.
Normally, id attribute suppose to be unique value, but there are some cases when front-end developer just hide part of DOM, create similar and forget to remove hidden one.
In such case you can (if it possible) ask developer to get rid of redundant code or use index as
"(.//*[#id='password'])[2]"
In cases like this you need to use another unique DOM element (parent, ancestor, sibling, child) with connection to the element you are looking for. For example In those html snippets
<div id='a'>
<div id='password'></div>
</div>
And
<div id='b'>
<div id='password'></div>
</div>
.//*[#id='password'] will have two results
However
.//*[#id='b']/[#id='password']
Will have only one result
Let me try to answer your queries one by one:
error when I tried to find the password field : This is because the property which you have mentioned id/name/css/xpath was incorrect.
ElementNotVisibleException : I doubt it was for the password_field at all. Reason behind that is, normally login field & password field stays on the same container. Either those resides on the HTML DOM (which gets loaded completely once the page loading is complete) or they may reside within a frame/iFrame (there are other measures to handle them which I am not covering here). But those 2 elements stays on the same container. So if you have found out the login_field element, password_field is just a step away.
inspected the xpath with Firebug and noticed that it returned two results : That's because the xpath which you are using doesnot identifies an unique element. There can be multiple elements on the HTML DOM with the same id attribute set to "password". But definitely the xpathof those elements will be different and unique.
What you should do?
I will suggest you the following:
a. Try to identify each element on a webpage following the attributes in sequence: id, name, visibleText, css, xpath.
b. Try to identify a unique logical xpath for elements using the other properties of the elements defined within the HTML tag. Cross check your xpath through Firebug/Firepath. There are some other handy xpath checker available too. Take help of those.
Let me know if this answers your question.
I have tried to locate button in my web app using xpath but it changes automatically each time I open selenium IDE. Is there any other way to locate it except using xpath or position? can I locate it using class name? If yes then how can I do it?
You can use xpath to find element by class name.
//*[#class='someClass']
where, someClass is the class name of your element.
Since it is your webapp, consider adding an id or a name to uniquely identify the element. It also makes the xpaths easier to write as you don't need to consider the possibility where you might be grabbing too many elements.
Answer - If by default recorded xpath are not working for your application, then you can define your own xpath for those components which should remain same throughout execution.
Please refer below URL which shows ways to develop userdefined xpath :-
http://docs.seleniumhq.org/docs/appendix_locating_techniques.jsp
Use a CSS selector. This site really helped me: http://saucelabs.com/resources/selenium/css-selectors
if it has an id on it you can just say "id=yourid"
for css it could be something like this: "css=button[class*='yourclass']" <-- that says it's a button, and that in class it contains yourclass.
All the elements in the application which i am testing have dynanic ID's . The test always passes when i replay it without refreshing the page but as soon as i refresh the page, The Test Fails because Id's of all the elements changes randomly and selenium cannot match the recorded id's with the new ones .
I tried to use Xpath-position, It works for some objects but in case of Dropdown list and Buttons, it dosent work!
Can anyone please tell me how to find the Xpath (Meathods in JAVA or S*elence*) of an object OR How to create a new Locator Finder for Dropdown list and Buttons
I can show the properties (Inspected by Firebug) of the dropdown which is teasing me.
properties of Dropdown :
<div id="ext-gen1345" class="x-trigger-index-0 x-form-trigger x-form-arrow-trigger x-form-trigger-last x-unselectable" role="button" style="-moz-user-select: none;"></div>
properties of Dropdown*Choice*:
<ul>
<li class="x-boundlist-item" role="option">Rescue</li>
</ul>
Please search before posting, I have been answering this over and over.
ExtJS pages are hard to test, especially on finding elements.
Here are some of the tips I consider useful:
Don't ever use dynamically generated IDs. like (:id, 'ext-gen1345')
Don't ever use absolute/meaningless XPath, like //*[#class='someclass']/li/ul/li[2]/ul/li[2]/table/tbody/tr/td[2]/div
Take advantage of meaningful auto-generated partial ids and class names. (So you need show more HTML in your example, as I can make suggestions.)
For example, this ExtJS grid example: (:css, '.x-grid-view .x-grid-table') would be handy. If there are multiple of grids, try index them or locate the identifiable ancestor, like (:css, '#something-meaningful .x-grid-view .x-grid-table'). In your case, (:css, '#something-meaningful .x-form-arrow-trigger')
Take advantage of button's text.
For example, this ExtJS example: you can use XPath .//li[contains(#class, 'x-boundlist-item') and text()='Rescue']. However, this method is not suitable for CSS Selector or multi-language applications.
The best way to test is to create meaningful class names in the source code. If you don't have the access to the source code, please talk to your manager, using Selenium against ExtJS application should really be a developer's job. ExtJS provides cls and tdCls for custom class names, so you can add cls:'testing-btn-foo' in your source code, and Selenium can get it by (:css, '.x-panel .testing-btn-foo').
Other answers I made on this topic:
How to find ExtJS elements with dynamic id
How to find unique selectors for elements on pages with ExtJS for use with Selenium?
How to click on elements in ExtJS using Selenium?
Using class names in Watir
how to click on checkboxes on a pop-up window which doesn't have name, label
I would suggest you build a xpath from any of the parent of your DIV. you may get messed if there is no immediate parent node has such one.
example,
//*[#id='parentof div']/div
//*[#class='grand parent of div']/div/div
i did even something like this,
//*[#class='someclass']/li/ul/li[2]/ul/li[2]/table/tbody/tr/td[2]/div
But still, its not encouraged to do so.
I am using selenium to test a page with multiple portlets made by liferay.
Every portlet is having a save button with the same id, it use the iframe id of the portlet to differentiate between the buttons.
How can I write a code in selenium that can understand which button I mean??
You need to use driver.switchTo().frame(IFrameElement). Any kind of IFrame you need to switch in/out of.
https://stackoverflow.com/a/9943605/1769273
You can use xpath or css selectors to find children dependent on parents.
paste your html and we can provide examples
Does this mean your portlets are all embedding iframes? Typically portlets just render HTML snippets into the same documents. In this case, your implementation would be considered flawed: Portlets must not use IDs that can conflict. E.g. you should not render
<input type="submit" id="save"/>
but
<input type="submit" id="<portlet:namespace/>save"/>
or similar - make sure the id is unique, as it ends up in the same HTML-DOM which - by specification - assumes ids are unique.
There are other methods to create unique ids, but keep in mind: If you come up with the prefix yourself, per portlet, someone might add the same portlet to the page twice and you can end up with the same id even though all different portlets have unique ids.
If you are indeed rendering many different iframes from your portlets, you can disregard this answer or take it as a suggestion to make better use of the portal environment by changing the implementation.
I spend hours already trying to find the way to find the Element using Selenium WebDriver. I assume I need to use driver.findElement(By.xpath("")), but I am not quite sure how.
I somehow need to find and click on "clickon" element. The problem is that part of that element is changing (see screenshot) I need to pick up from the file and putted into the xpath.
I would appreciate any help.
We have been rigorously searching for automated functional testing solutions recently, and we began with Selenium. The entire reason we decided to search for other solutions was that our application also has dynamic IDs with no other obvious XPath mechanism to identify them. Selenium is unable to identify these elements on the page without some additional knowledge, just as you would be unable to identify these elements on the page if you didn't already know what they are.
If you are controlling the DOM creation, consider adding a unique ID or class to this element.
We recently came across eggPlant from testPlant, and it is an interesting approach to functional testing. It's essentially image based. Other viable solutions are Ranorex or HP's QTP or SmartBear's TestComplete.
You can use xpath. If the div class is constant, you can use something like:
driver.findElement(By.xpath("list-row field-item")).click();
To view the xpath, you can install firefox plugin called 'xpath checker' found here and right click on the dom element and click 'View Xpath' option to get the xpath of the element and then you can use that xpath in your code.
Or you can even use regex in the xpath which is suitable for the similar problems. Xpath with regex is really powerful.
It seems that you want to click the div that has the on click attribute that contains certain text that doesn't change, ignoring the part that does. In that case, use an xpath like this:
//div[contains(#onclick, '/challenge/index/rfp_id/')]
This will select the first div with an onclick attribute with a value containing /challenge/index/rfp_id.