How to identify individual controls within a search result using Selenium Webdriver? - selenium

I have a list of search results in the following link and would like to know on how can I identify the individual controls using dynamic xpath
http://www.bigbasket.com/cl/fruits-vegetables/?nc=nb
I'm able to get the list of product names displayed using the below line
List<WebElement> productResults = browser.findElements(By.xpath("//*[contains(#id,'product')]/div[2]/span[2]/a"));
I'm able to print the product names displayed in Page 1 using the below code, but however the list size is not matching with the list of results displayed in Page 1 so which I see blank lines in between when printing
System.out.println(productResults.size());
for(int i=0;i<productResults.size();i++){
System.out.println(productResults.get(i).getText());
}
Also I tried to locate the individual controls such as Qty text box, Add button in a similar like how I located the product names but the list count is not matching so which I cannot specify the quantity, add the required product to the cart.
Could you please help me with this one?

The first step is get only the visible itens (that is displayed), sou you can use this xpath:
"//*[contains(#id,'product')][not(contains(#style,'display:none'))]/div[2]/span[2]/a"
Now, you need to return the main iten div, that allows you to acess other functions. You can get the tag parents in this way:
"//*[contains(#id,'product')][not(contains(#style,'display:none'))]/div[2]/span[2]/a/../../.."
The elements that you recieve in this last XPath have all html itens that you want, as set quantity, select the dropdown etc. You can acess each using a findElement() in each IWebElement of the list. Example:
List<WebElement> productResults = browser.findElements(By.xpath("//*[contains(#id,'product')][not(contains(#style,'display:none'))]/div[2]/span[2]/a/../../.."));
for(WebElement element : productResults ){
IWebElement quantityInput = element.findElement(By.XPath("//input[contains(#id, '_qty')]"));
string quantityValue = quantityInput.getAttribute("value"); // if you want to know the current value. YOu can also parse it in an int
IWebElement addButton = element.findElement(By.XPath("//a[contains(#class, 'add-button')]"));
// etc to all elements inside element.
// Remember: Element is yout complete card of the item, that contains Value, name, image, buttons and all it.
}
Sorry for some Java syntax error. I am not a Java developer / tester. My piece of cake is C#.

Related

How can I check that a dropdown field is disabled using selenium?

I am trying to write a function in selenium to check if a Reasons dropdown is showing as disabled, but can't quite get the xpath right. The code for the dropdown is in the pic, the function I'm working on is the second one (InputDisabled), having based it on the working first one (SearchDisabled):
` public By SearchDisabled(string searchId) => By.XPath($"//div[#id='{searchId}']//div[contains(#class, 'v-input--is-disabled')]");
public By InputDisabled(string inputId) => By.XPath($"//div[#id='{inputId}']//div[contains(#class, 'v-input--is-disabled')]");`
The inputId going into it is 'ai-confirm-allergy-modal-reason'. I've tried it as 'input[contains...' and 'contains(#disabled, 'disabled'...' among other things, but my xpath knowledge isn't great yet!
dropdown code
Use below code
String value = driver.findElement(By.XPath("//input[contains(#id, 'ai-confirm-allergy')]").getAttribute("disabled");
Assert.AssertEquals(value, "disabled");
I do not quite get your question.
well if you are trying to use xpath to locate an element, you can just use the id; assuming that it is unique.so:
driver.findElement(By.xpath("//input[contains(#id, 'ai-confirm-allergy')]")
should locate the webelement.
However, your xpath for the SearchDisabled is locating a div containing class 'v-input--is-disabled' with in another div with id of '{searchId}';
the same logic goes for the next one. your xpath is trying to locate a div containing class 'v-input--is-disabled' which is located with in another div located using input id. I don't think this combination can locate the element highlighted in the picture.

Unable to recognize Element with relative xpath or other locator

I am facing an issue where I am unable to locate Element on webpage with any type of locator expect Absolute xpath. Here are details:
URL : https://semantic-ui.com/modules/dropdown.html#selection
Required Element Screen shot:
Manually created Xpath Screen shot( Please note that I am able to recognize Element in web application with manually created xpath but Same xpath is not working in selenium code)
But Same xpath is not working in selenium script.
PLEASE NOTE THAT I AM ABLE TO IDENTIFY SAME OBJECT WITH Absolute xpath
Please help to me to understand reason for this.
Here is code:
public static WebDriver driver;
public static void main(String[] args) {
driver= new FirefoxDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://semantic-ui.com/modules/dropdown.html");
//Selection
driver.findElement(By.xpath("//div[#class='ui selection dropdown upward']")).click();
driver.findElement(By.xpath("//div[#class='menu transition visible']/div[text()='Female']")).click();
System.out.println("Done");
This may be issue with your first x-path. You may try the following code. It may work.
driver.findElement(By.xpath("//div[#class='ui selection dropdown']").click();
driver.findElement(By.xpath("//div[#class='menu transition visible']/div[text()='Male']").click();
You are missing a preceding wildcard in you driver.FindElement XPath.
Instead of driver.findElement(By.xpath("//div..."));, do driver.findElement(By.xpath("//*div..."));.
Currently, what your code is doing is telling the XPath locator to find a first level div (not easily possible, as the first item is almost always the document body), but the wildcard of "*" tells it that it can look for the div at any level.
As an aside, please edit your answer up top with actual code instead of pictures so others with the same problem can find their solution easier.
Longshot:
You are using Chrome to look at the source, but Selenium is using Firefox.
There is a chance that the source is rendered differently between the two browsers. Specifically, your xpath is relying on an exact match of class. I do know that FireFox is notorious for modifying source output.
I haven't done any testing but I would not be surprised if the class is in a different order and it's failing on an exact match.
There are two solutions if that is the case:
Don't do a single exact match (xpath = "") but instead do a mix of contains joined with && (contains ui && contains selection && dropdown)
Don't rely on the output from the console tab. Instead "View Page Source" and view what is actually being sent instead of what is being interpreted by the browser
Find the dropdown container element firstly, then use it to find self descendant, like option etc.
driver.get("https://semantic-ui.com/modules/dropdown.html");
// find dropdown container element
WebElement dropdownWrapper = driver.findElement(
By.xpath("//div[#class='html']/div[input[#name='gender']]"));
// expand drop down options by click on the container element
dropdownWrapper.click();
// or click the down arrow
dropdownWrapper.findElement(By.css('i')).click();
// select option
dropdownWrapper.findElement(By.xpath(".//div[text()='Female']")).click();
To locate the element with text as Gender and select the option Female you can use the following Locator Strategy :
Code Block :
System.setProperty("webdriver.chrome.driver", "C:\\path\\to\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://semantic-ui.com/modules/dropdown.html#selection");
driver.findElement(By.xpath("//div[#class='another dropdown example']//div[#class='ui dropdown selection']")).click();
driver.findElement(By.xpath("//div[#class='another dropdown example']//div[#class='ui dropdown selection active visible']//div[#class='menu transition visible']//div[#class='item' and contains(.,'Female')]")).click();
System.out.println("Gender Female selected.");
Console Output :
Gender Female selected.
This might be helpful to clearify how selectors are working in general:
.(dot): Dot at starting represents the current node. It tells us that the processing will start from the current node.
. .(double dot): It will select parent of current node. For example, //table/. . will return div element because div is the parent of table element.
‘*’: is used to select all the element nodes descending from the current node. For example:
/table/*: It will select all child elements of a table element.
//*: It will select all elements in the document.
//*[#id = ‘username’]: It will select any element in document which has an attribute named “id” with the specified value “username”.
#: It represents an attribute which selects id, name, className, etc. For example:
#id: It will select all elements that are defined with the id attribute in the document. No matter where it is defined in the document.
//img/#alt: It will select all the img elements that are defined with the #alt attribute.
//td[#*]: It will select all td elements with any attribute.
Here is a link to the article:
https://www.scientecheasy.com/2020/07/selenium-xpath-example.html/

Need to get all elements ending with specific text in selenium webdriver

I have some elements on my page which have xpath like //*[#id='protect']/a, //*[#id='deezer']/a ,//*[#id='international']/a..I want to get all the xpaths in an array list..all the xpaths are ending with '/a'..but the id is different for all the elements..please help
i want to get all the elements in an array list.so that i can click them by using some loops and conditions inside loop
There's a straighforward way to do it in selenium: using findElements. Ex:
List list = driver.findElements(By.xpath("//a"));
You'll get every single hyperlink on the page stored in a List. Then you'll be able to handle every webelement in it by using loops.

Locating images uniquely when img ids are dynamic and src same for multiple images

I have 3 custom dropdowns which open when clicked on "down arrow" image appended at the end, Code for the image is something like :
<img id="x-auto-2017" class="x-form-trigger x-form-trigger-arrow "
src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==">
Image id are dynamic and are in order of like 2017, 2018 etc. So I cannot use contains and identify them uniquely.
I want to get them clicked one by one and select value from the dropdown. Please help how to identify them uniquely.
Below code should work for you:
List<WebElement> elements = driver.findElements(By.xpath("//img[contains(#class,'x-form-trigger x-form-trigger-arrow']"));
System.out.println("Number of drop downs on the page: " + elements.size());
for (WebElement ele : elements) {
ele.click();
//Do what ever you want
}
Thanks for your response, I used the position qualifier [N] as suggested by #Marcus, though have to hit and trial a bit but writing manual xpath on Chrome console I got the following answer to my query.
driver.findElement(By.xpath("(//img[starts-with(#id,'x-auto-2')])[2]")).click();

How can I focus to a specific item which is in the bottom of the page in IDE

I am trying to select a specific item in a page which is at the bottom of the page. I want to verify that element is present and the same time I want to focus to that specific item.
How can I do this in the Selenium IDE?
I tried storeEval, but its specific co-ordinated which I don't want. I am looking for some dynamic command. I tried using css:.groupTile:contains("Concentrated") but the focus is not going to that particular item (Concentrated).
Can someone help me with Command, Target and value please?
CSS Selectors have many formats
i) Using id. Put this in Target: css=tag#id
tag = the HTML tag of the element being accessed,
id = the ID of the element being accessed
ii) Using class. Put this in Target: css=tag.class
tag = the HTML tag of the element being accessed,
class = the class of the element being accessed
In value you enter name of the item.