Create a Reusable method to Verify list elements by Selenium WebDriver - selenium

I am new to this site and don't know how things show up here. I was reading the post from below where String array is being used to ListwebElements.
Verify list elements by Selenium WebDriver
String[] expected = {"GRAM", "OUNCE", "POUND", "MILLIMETER", "TSP", "TBSP", "FLUID_OUNCE"};
I am trying to do something similar using String Array trying to get different buttons on a UI page. I want to make this method reusable by changing the "expected" list per test. Does anyone know how you would make this method Reusable?
In my case, "expected" list is different each time depending on a page.

I would suggest to use the custom annotation for reusing purpose. Please see the example here.
If you are using JUnit you can also use parameterized test

Related

Selenium Page Factory - finding element with nested selectors

I'm trying to use Page Factory and #FindBy to initialize my WebElements. However, I'm running into trouble when I have an element that cannot be found with just the ID.
The following selector is a little more complex to find, so I'm using Selenium's ByChained:
val endreBoligModal: MutableList<WebElement> = driver.findElements(ByChained(By.className("hb-card"), By.className("hb-card-header"), By.className("hb-card-tittel"), By.tagName("span")))
The reason is that, for some reason, finding the element with a unique ID doesn't work. Selenium just cannot find it.
So, with regards to the Page Factory and the #FindBy way of creating elements - how do I do it?
The way I've used it so far is like this:
#FindBy(id = "login")
private WebElemement login
Or
#FindBy(css = "[id=login]")
By for the chained selector element, I cannot figure out how to do it with Page Factory.
I think there's something called #FindBys (with an s at the end). At least, there seems to be. But for the life of it I cannot find ANY documentation about it on the net, so I don't even know if it's relevant.
All help is appreciated.
You can just look at the sources of org.openqa.selenium.support.FindBys. There is a short but informative description saying:
Used to mark a field on a Page Object to indicate that lookup should use a series of #FindBy tags in a chain as described in ByChained It can be used on a types as well, but will not be processed by default.
Eg:
#FindBys({#FindBy(id = "foo"),
#FindBy(className = "bar")})
So the example seems pretty straightforward. Give it a try.

Automation of test case independent of ui changes

We are automating test cases for hardware devices like tv, raspberrypi etc which require to perform certain number of steps and check expected result at the end of each step. To automate these test cases we are using dom element attributes such as id, class,data-component-id etc to fetch the objects and perform actions.
The problem with this way of automation is every time UI changes we need to change the dom elements id, class etc and hence it is rework of the scripts.
I want to know if there is automation framework or any other way using which we can automate test cases independent of ui changes.
Instead of using the exact path, try to identify the element in a more generic way. Using "contains" will help you to identify the elements with the text attributes with out going into the way it is defined. So even the DOM structure changes but with the text being same, your tests will not fail.
Contains
It is very handy XPath Selenium locator and sometimes it saves the life of a test automation engineer. When an attribute of an element is dynamic, then you can use contains() for the constant part of the web element but also you can use contains() in any condition when you need.
Syntax: //tag[contains(#attribute, ‘value‘)]
Example: //input[contains(#id, ‘er-messa’)]
Examples:
Java
1
2
3
4
5
6
7
8
//*[contains(#name,'btnClk')]
--> It searches "btnClk" for all name attributes in the DOM.
//*[contains(text(),'here')]
--> It searches the text "here" in the DOM.
//*[contains(#href,'swtestacademy.com')]
--> It searches "swtestacademy.com" link in the DOM.
That's why you should use id selectors if possible. They are supposed to be unique and hence immune to UI changes. The name selector should work the same way.
If you are using Selenium, use the following list of object locators in (loosely) this order of preference:
id
name
tag name
class
CSS or Xpath
linktext or partial linktext
And if you really want the elements to be consistently identifiable, you might talk to the developers and ask them nicely to add the ids.

Selenium Webdriver selecting wrong input in jquery dialog

I am testing a site that has a dialog box with multiple text fields, some with datepickers, some without.
For some reason, when I attempt to locate the inputs by their XPath selenium finds the element, but when it comes time to input data, it send the keys to the top field. Here is an example of my selenium code:
DriverHelper.SendKeysByXpath("//input[#name='registrationStartDate']",CurrentDate);
DriverHelper.SendKeysByXpath("//input[#name='firstStartDate']",CurrentDate);
DriverHelper.SendKeysByXpath("//input[contains(#name,'lastStartDate')]","01/01/2018");
FYI, the DriverHelper is a class I call to save myself from typing the same selenium calls over and over again.
The XPath names are all unique and as far as I know there shouldn't be any confusion as to which input I'd like to send the keys to.
Has anyone run into similar situations before?
I'm trying to get an example up in jsfiddle but so far I'm unable to replicate the issue there.
It is sending keys to the top element probably because that is the one that he is selecting.
Try to use this:
List<WebElement> result = webDriver.findElements( by );
Debug your code and check how many elements your selector is retrieving.
Try to narrow and improve your search in such a way that you narrow the group os selected elements as possible.
Very personal opinion:
The code is easier to fix and to read if you avoid using xPaths as selectors. I prefer id's and classes whenever its possible.
Selenium best pratices source

Selenium's Webdriver.execute_script() returns an empty list while Chrome dev tools return a populated list

I'm trying to use Selenium's Webdriver.execute_script() to get a list of elements from Reddit's homepage. (Before you recommend PRAW: Reddit is not actually what I want to get elements from, I'm just using it as an example.)
Even though my executed script works fine when I run it in Chrome's dev tools console, Selenium's method only returns an empty list, which should be populated with the title elements of Reddit posts.
import urllib
from selenium import webdriver
from BeautifulSoup import BeautifulSoup
#Path to the chromedriver is definitely working fine.
path_to_chromedriver = 'C:\Path\goes\here\chromedriver.exe'
browser = webdriver.Chrome(executable_path = path_to_chromedriver)
url = 'http://www.reddit.com/'
browser.implicitly_wait(10)
browser.get(url)
code = 'document.getElementsByClassName("title may-blank loggedin")'
content = browser.execute_script("return "+code)
if len(content) == 0:
print content
else:
print len(content)
browser.quit()
I've also tried using the webdriver.set_script_timeout() and webdriver.set_page_load_timeout() methods.
Example of the target element:
<a class="title may-blank loggedin" href="/r/IAmA/comments/2necex/i_am_joel_hodgson_creator_of_mystery_science/" tabindex="1">I am Joel Hodgson, creator of Mystery Science Theater 3000, why don't you come at me?</a>
The JavaScript you use with execute_script should work.
However, as the class loggedin suggests, no element will match the loggedin class unless you are actually logged into the site. When you start a new Selenium instance, it is not logged in, so you won't find any element with the loggedin class. Edit your code to remove loggedin from your getElementsByClassName call and you'll get a list of matched elements.
It does not matter whether you use execute_script or find_element.... No elements will match the class loggedin until you are logged in. This being said, although sometimes there are excellent reasons to use execute_script to find elements, I don't see a good reason to use execute_script in this case so I'd suggest something like
browser.find_elements_by_css_selector('.title.may-blank')
without the loggedin class. This will return all elements that have the title and the may-blank classes.
A few problems.
Don't use JS to find the elements, that's the entire opposite to the point of Selenium.
Secondly, you have some misunderstanding behind what CSS selectors & Class name selectors are.
Thirdly, coupled with the above, your JS script is not a CSS selector. getElementsByClassName is very different, it will just return you what matches all of those classes.
Fourthly, in your comment you've bunched up the class name together. I assume this is because having spaces in there would have thrown a Compound Class error. This is correct and should have pointed you to the first three problems above. Now you've mushed them all into one string, it now no longer even relates to the original code you had - it would only return elements who had titlemay-blankloggedin as their class (obviously, none!).
Solution? I'd suggest using Selenium for what it's meant for and the locator strategies it has built in.
browser.find_element_by_css_selector('a.title.may-blank.loggedin')
(The selector can be made a little less brittle, but I've done it on purpose so you can see the effect).
The . in CSS selector will work as an and operator (an anchor element that has a class of title and a class of may-blank and a class of logged-in.)

Test case automation

I am new to test automation and I need help of experts who can help me in proceeding with the current difficulties.
Currently there is a web browser application which is tested manually based on the test cases in an excel.
There is also an automation framework also which uses Selenium and uses WebDriver and runs on Google Chrome.
The test cases(in excel) used for manual are taken up and another set of test cases(in excel) are written which is nothing but the div elements and the action which the framework should do like click or find which the framework will understand.
1.First I need to manually find out each div id for all the elements and put it in excel which the framework understands.How can I avoid this?
2.Also a new version of the application has come in which all the div id for the elements differ.Hence its pain to note the div id again and put them in excel.
How can I write the test cases only once for each case even if the div changes?
Please help.
Follow a design pattern, e.g. Page Objects
If ids will be changed try to use css and xpath selectors that do not stick to ids. The main idea is to specify such selectors that allow tests to find elements on the page using knowledge by their parents, tag names, other attributes that won't change (class and so on).