I'm new to testing and trying to automate an OBIEE Dashboard application using Selenium Webdriver with Java. But, the problem is, the object identifiers I'm using (class, xpath, etc.) are dynamically generated, which leads to failure of my test case. Is there any way to overcome this? The scope of my test case is limited to testing the UI only.
My advice? Consider if you really, really, need to be using Java/Selenium approach.
A lot of OBIEE testing is better done at the logical layer using nqcmd or ODBC calls into the BI Server. If you really need to test the front end then visual testing is a generally more successful approach. The new Baseline Validation Tool covers both of these.
You can read more detail here:
http://www.rittmanmead.com/2014/01/automated-regression-testing-for-obiee/
http://www.rittmanmead.com/2014/05/visual-regression-testing-of-obiee-with-phantomcss/
http://www.slideshare.net/themoff/smarter-regression-testing-for-obiee-ukoug-15
https://www.youtube.com/watch?v=gMrspsqW0qM
You have to adjust the Generated XPaths as they may be not accurate.
for Example: You want to select this Div
<div class='blueBtn'>Click Me</div>
the XPath generated will be //div[#class='blueBtn']
This may select the first one but if this div is repeatable under another.
You may need to adjust the XPath to select what exactly you want.
So we may be adjust it to be //div[#class='blueBtn' and position()='2']
It's recommended to use the IDs of the elements as they are granted to be unique.
I hope this could help.
Related
I am trying to find a unique locator of the "update profile picture button" in my Facebook account to use it for automation test (selenium webdriver with java).
I use driver.findElement(By.className("_156p")).click();, but it doesn't work.
What should I use?!
Being unable to see the rest of the html source, I can't say for sure, but my guess is that the class is actually defined earlier in the source. The problem with using just a class name is that class names do not have to be unique on a page. The unique version of a class name is id, and if you are testing code that you can edit, try to use lots of ids.
If that's not the case, a decent way to deal with code that you can'y edit yourself is to use a css selector. Really good information on doing them here.
Another good debugging option is to use javascript or python to run a webdriver from the terminal. Because these languages are not compiled, you can run them in real time, which can allow you to tweak a class name a lot quicker. If you don't have experience with python, check this out. By using python/javascript you can create the webdriver, and then keep typing in driver.find_element_by_whatever("value_to_find") while on the same page. This will be much quicker than running the java program from scratch for every different "value_to_find".
As the page source you have provided is pretty limited unable to come up with a stable locator. How about getting the div using the text through xpath.
"//div[.='Update Profile Picture']"
Try This:
WebElement element = driver.findElement(By.className("_156n"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
Worked for me.
I am working on a project for a client where they are going to upgrade to Siebel Open UI. With that upgrade, they also want to start implementing Selenium. The problem we are currently facing, or going to face once implementing, is that with each build the ID's/Names of HTML elements in Siebel change. Because we are talking about a lot of views and applets it's not a good solution to change the code manually each time.
What is a good solution for this problem? One solution that was offered is a correlation table where we keep track of changes in the ID's.
Xpath in this case is also not a good option because of the complicated structure of the views and applets.
I would suggest that you look into CSS Selectors. They are faster and less brittle than XPath. For ID/names that are dynamic, typically there is at least some portion of the ID that is static.
For instance,
<a id="somestatictext_12345">...
where "12345" is some dynamically generated number. In this case you can use a CSS selector like
driver.findElement(By.cssSelector("[id^='somestatictext']"));
Examples
"[id^='somestatictext']" - ID begins with "somestatictext"
"[id$='somestatictext']" - ID ends with "somestatictext"
"[id*='somestatictext']" - ID contains "somestatictext"
For more info, take a look at this CSS Selector reference.
The application which I'm testing is fast developing, and new features keep being adding, requiring changes to the testing XPaths. So the selenium scripts which were successful before now failed as the XPaths have changed. Is there any reliable way to locate element (which will never change)? FYI, I thought of using ID's but my application does not have ID's for each and every element as it is not recommended to give ID's in the code.
I feel the following is the hierarchy for choosing the element in selenium
1.id
2.class name
3.name
4.css
5.xpath
6.link text
7.Partial link text
8.tag name
In case of changing DOM structure you can try using functions like text() and contains(). The following link explains basic of the mentioned function.
http://www.guru99.com/using-contains-sbiling-ancestor-to-find-element-in-selenium.html
The following link can be referred for Writing reliable locators
https://blog.mozilla.org/webqa/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/
Hope this helps you.
If you cannot impose #id discipline on the interface that keeps changing, one alternative is to use CSS selectors.
Another alternative to write more robust XPath:
Be smart about using the descendent-or-self axis (//):
Rather than /some/long/and/brittle/path/uniquepart use //uniquepart or //uniquepart/further/path to bypass that which is likely to change.
Don't overspecify label matching.
Use case-insensitive contains(), and try to match critical parts of labels that are likely to remain invariant across interface changes.
One other way I can think if is that you can load your page elements in to DOM and use DOM element navigation. It is a good practice to have id on elements though. If you have to use the xpath way then it is a good practice to split the path to keep the common path separately and adding the leaf elements as needed. In a way change in xpath triggering the test to fail is a good indication of catching the changes.
I'm following page object design pattern for Selenium automation and I can guess that many people store locators in .properties file and access them in code. It seems great to keep locators at separate place.
Since, I haven't work on any big project for Selenium automation, I would like to know thoughts on following so that I can avoid problems that might raise in future:
Is storing locators in properties file helpful in big projects(where test cases are more than 1000 or so)?
a) If not helpful in big projects, what are the difficulties that make us not to store locators in properties file?
b) If it's helpful, what are the precautions if that are taken makes job easier?
Is storing locators in page class itself is best way in comparison with properties file?
I would argue storing the files in the page class itself. Loading from properties file would incur additional overhead or parsing a large file. Maintaining such a file would also be harder, even with a good tool support you would be forced to use CTRL + F more than you should.
Even on a more conceptual level it feels wrong. A good fit for storing in properties files are configurable parameters, and especially the ones that are good candidates to be tweaked in runtime.
Locators don't have this nature. If the benefit you're seeking is declaring in a central place you should instead use dedicated constant class, which will give you much better refactoring options.
I would definitely agree with #Master Slave. The main purpose of selenium is to make the UI testing easier. Storing locators in the property file is cumbersome and additional overhead plus a nightmare for refactoring. One of the main reasons why the PageObject is popular is because it's ability to map elements with a very intuitive way
#FindBy(name="q")
private WebElement searchField;
#FindBy(name="btnG")
private WebElement searchButton;
It's just not only more readable but also far easier in case of refactoring and debugging. And, when something goes wrong on the page or changes there is a KNOWN place you go to change and you know where it is!
There are two basic ways:
1) Using FindBy annotation
#FindBy(xpath = "//*[#class = 'stackoverflow']")
private WebElement question;
2) Using By / WebElement class in the method structure
By stackoverflow = By.xpath("//*[#class = 'stackoverflow']");
WebElement stackoverflowElement = getDriver().findElement(stackoverflow);
And I completely agree with #Saifur and #MasterSlave.
I agree for the small projects with one running environment. Lets assume we have the project runs on two environments like Test and Production. Assume that in Test the locators are changed, then if you want to change code that will work properly in the both cases you should go to the branch. In case if locators placed in the property file you just change the file belongs to the environment.
I am not against storing locators in any format - either properties,INI, XML or xls as long as each file is small and manageable.
I think, as we are talking about 1000 test cases or more, for global variables [like URL, port number, username, password, email ] which are used only once, shall be stored in a separate global_variables file. Locators for EACH page can be stored in SEPARATE files. If one files is maintained for each page then locators are manageable. Pages will import ONLY file which is needed.
Clearly this approach creates more number of properties files as number of pages. This can be bettered by creating single file for related module or feature pages. Anyways as user we need to balance between less but huge locator file or more but smaller manageable locator files.
I am working on a similar strategy, where I need to decide which locator strategy is the best. What would be the best place to store the locators.
For code / property files, I have the following cons:
Time consuming to change the value of a single locator
Having stale locators/elements in the code
Makes the code bulky
Running tests on pre-prod and prod environment with different locators, results in creation of branches and duplication of code.
However, I am more inclined towards storing locators in a separate database and enabling its usage through a dashboard. I also feel this is very subjective to how your automation framework is setup. For a large scale framework, having over 1000 tests, having them separate makes more sense.
I am using Selenium, java and Testng for automation. I am using ID to identify elements, but everybody say that IDs may change and its very brittle way to use Id for testing, so can any one tell me how to use part of id or any other way which will not effect my automation even if there is change in id after some time period.thanks in advance.
On the contrary...
A well built application will always have unique ID's on the page, and is the least projection-able thing to change.
Unfortunately, you will run into things that will be dynamic, or even duplicate.
Where I work, our ID's are generated by Apache Tapestry, and turn out to these types of ID's..
<input id="someID_124905830" />
<input id="submit_0" />
But these are easy to counter using parent-child hierarchy's, or a partial match like input[id^='submit_']
In short. The statement is invalid.
Everybody say that ID's may change and it's very brittle
My question for you is, who is "everybody"? Because "everybody" i talk to, and i'm sure the majority of the web development community would disagree.
There are many more ways to locate an element in Selenium.. other than ID, like xpath, css, dom, link, name etc. However working with xpath and relative xpath will give you confidence about it.
You can google it or can see link1 or link2 or link3