I have an integration test. It uses Selenium, from Java. I would like to click on a specific link, which has no ID. All I know about it is that it is in a specific cell in a specific table. The table has an ID.
How can I click on that element using DefaultSelenium?
I tried
defaultselenium.click("th.tblHeader:nth-child(14) > a:nth-child(1)");
because Firefox said that it's the XPath of the element, and I also tried
defaultselenium.click("#tableId > thead:nth-child(1) > tr > th.tblHeader:nth-child(14) > a:nth-child(1)");
because I don't use XPath very often and I had no idea what I was doing, but I thought that having a unique ID in the equation may help.
Both of them give me "ERROR: Element ... not found" messages.
That's not XPath, it's CSS. Vanilla Firefox isn't helpful for extracting XPath from a page, but there are plugins available. Alternatively, Chrome will give you the XPath.
Related
I am trying to capture a drop-menu field using test automation in SELENIUM with chrome driver.
Why does the element "id" changes in some web pages when inspecting elements time to time, with Chrome browser? How to keep the "id"s static, without changing?
Steps I followed:
When I inspect elements in the web page, the particular drop-menu shows its "id" as: id="combo-1782-inputEl"
HTML:
<input id="combo-1782-inputEl**" type="text" class="x-form-field x-form-required-field x-form-text x-trigger-noedit x-form-focus x-field-form-focus x-field-default-form-focus" autocomplete="off" name="type" readonly="readonly" aria-invalid="false" data-errorqtip="" style="width: 135px;">
id observed by inspecting the web page in normal chrome browser:
Then I used the above id in my java code(automation script) as below:
driver.findElement(By.id("combo-1782-inputEl")).click();
When I run the test > The google chrome browser opens automatically > The test gets successful till it meets the above line of code.
But, when it meets the above code line, the test failed Throwing the following exception:
class org.openqa.selenium.NoSuchElementException *
Then I inspected the same drop menu item in chrome web page opened (controlled) by automated test software, and found out that the "id" is different than the previous id mentioned in step 1.
The "id" in this case is: "combo-1781-inputEl"
id observed by inspecting the web page in chrome browser controlled by automated software:
As you can see, the number in the middle of the id has reduced from 1.
(1782-1 = 1781)
Same issue was found in the other drop menu items on the same web page.
What is the issue cause for this? How can I overcome this situation? Please help. :)
P.S. When I used "combo-1781-inputEl" ("id" from step 5) in my code, the test passed successfully.
driver.findElement(By.id("combo-1782-inputEl")).click(); //Test: failed
driver.findElement(By.id("combo-1781-inputEl")).click(); //Test: passed
I expected the test to be passed when I used the "id" I got in step 1 by inspecting the web page in normal chrome browser which is not controlled by automated software.
In order to provide you with the best answer, I'd need to see a section of HTML code for the web page, enough that I can see other attributes. When you have dynamic ID's you have two options:
Option 1: use an xpath that uses part of the ID that is constant, i.e.:
//*[starts-with(#id, 'combo-')]
might do the trick, but only if there are no other similar ID's.
Or perhaps:
//*[starts-with(#id, 'combo-') and ends-with(#id, '-inputEl')]
but that might still not be specific-enough. This is why seeing a section of your HTML would help.
Option 2: use other attributes instead of ID, i.e. class, text, or some other attribute.
//*[#name='FirstName']
for example. You can craft rather elaborate xpaths using combinations of attributes, and it will be fairly stable if you do it right. Sharpening your xpath creation skills will come in handy for things like this.
Use Xpath and WebDriverWait to handle dynamic element.Hope this will work.
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//input[starts-with(#id, 'combo-')][#type='text']")));
As it is evident that the id attribute of the <input> tag changes dynamically e.g. "combo-1782-inputEl", "combo-1781-inputEl" and so on so you need to create a Dynamic Locator inducing WebDriverWait and you can use either of the following Locator Strategies:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("input.x-form-field.x-form-required-field.x-form-text.x-trigger-noedit.x-form-focus.x-field-form-focus.x-field-default-form-focus[id$='-inputEl'][name='type']"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[starts-with(#id, 'combo-') and #class='x-form-field x-form-required-field x-form-text x-trigger-noedit x-form-focus x-field-form-focus x-field-default-form-focus'][#name='type']"))).click();
I am trying to click a button from a list but this button has the same class than others in the list because they have the same name (btn ban-red) so how can I click it if in the inspect I have this information:
<a class=“btn ban-red” data-track-event=“navigate” data-track=name=“Jobylon” - Quality Engineer” href=“https://emp.jobylon.com/jobs/16654-f/” target=“_blank”>View job/a>
The inspect is copying this xpath:
/html/body/div[1]/div[4]/div/div/div/div[3]/div/div/div/div[1]/section/div/div[2]/div[1]/div[1]/article[14]/a
But it is not working
I also created my own xpath this way:
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[#data-track-name=‘Jobylon - Quality Engineer’]"))).click();
But is not working either
I am using Selenium with java and I am in a Macbook, thank you for your help.
Absolute xpath not recommended. You can try using relative xpath.
Locate based on element text
driver.findElement(By.xpath("//a[contains(.,'View job')]")).click()
Locate using combination of element attribute if classes are not unique
driver.findElement(By.xpath("//a[#class='btn ban-red'][#data-track-event='navigate']")).click()
OR
driver.findElement(By.xpath("//a[#class="btn ban-red"][#href='https://emp.jobylon.com/jobs/16654-f/']")).click()
Better to use CSS selector as its faster then xpath. So you try like
driver.findElement(By.cssSelector("a[class='btn ban-red'][data-track-event='navigate']")).click()
OR
driver.findElement(By.cssSelector("a[class="btn ban-red"][href='https://emp.jobylon.com/jobs/16654-f/']")).click()
Still facing some issue like element not visible or no such element then try with explicit wait conditions until your element gets visible or clickable.
I found a few answers about this but they did not answer my question an so I am writing a new question.
I have HTML code having below kind of checkbox elements (in browser's inspect element)
<input role="checkbox" type="checkbox" id="jqg_TransactionFormModel501EditCollection2_147354_grid_-1274" class="cbox" name="jqg_TransactionFormModel501EditCollection2_147354_grid_-1274" value="true">
In my test case I want to click on checkbox using its ID using Selenium Webdriver.
here Id= "jqg_TransactionFormModel501EditCollection2_147354grid-1274" is dynamic.
in above id, Bold & Italic marked letters (dynamic) will change with different check boxes in same page as well as page refresh.
Bold marked letters (dynamic) will change on page refresh only (remain same through all the check boxes in same page.)
How shoud I format/write XPATH so that I can click on desired check boxes using below statement.
WebElement checkbox = webDriver.findElement(By.id("idOfTheElement"));
if (!checkbox.isSelected()) {
checkbox.click();
}
Thanks for your help in advance.. !
Here are a few examples of xpaths which you can use to find your checkbox
//input[contains(#id,'jqg_TransactionFormModel')]
OR, if you want more checks, try something like
//*[starts-with(#id,'jqg_TransactionFormModel') and contains(#id,'EditCollection2_')]
Additionally, you can try regex as well using matches
//*[matches(#id,'<regex matching your id>')]
You can use partial ID using cssSelector or xpath
webDriver.findElement(By.cssSelector("[id*='TransactionFormModel']"));
webDriver.findElement(By.xpath("//input[contains(#id, 'TransactionFormModel')]"));
You can replace TransactionFormModel with any other fixed part of the ID.
As a side note, no need to locate the element twice. You can do
WebElement checkbox = webDriver.findElement(By.id("idOfTheElement"));
if (!checkbox.isSelected()) {
checkbox.click();
}
You can write xpath like this :
//input[starts-with(#id,'jqg_TransactionFormModel')]
//input[contains(#id,'jqg_TransactionFormModel')]
I recommend not using ID's or xpath and adding a data attribute to your elements. This way, you can avoid the annoyance of xpath and have a strong selector that you feel confident will always be selectable.
For example, you could call the attribute: data-selector. You can assign a value of "transactionFormModelCheckbox". Then, when creating a new element, you create by css selector with the value referenced above.
No matter what type of formatting, you'll always be able to select that checkbox - as long as the element exists in the DOM. If you need to investigate other attributes, you can use the selector to do things like hasClass() or anything else you need.
Hope that helps !
How to deal with Dynamically changing "class names" or "ids" in HTML source code while automating using Selenium WebDriver
Example Application : GMAIL
if you know the cell index then using XPath or cssSelector will solve the issue. Here in the above screenshot it is clear that the text "Wordpress" is in 5th cell of each table row/so you can use below XPath to get the particular cell.
List<WebElement> cellValue = driver.findElements(By.xpath(".//table/descendant::tr/following-sibling::td[5]"));
The Selenium mechanism for locating elements (org.openqa.selenium.By) offers other methods of locating elements.
Example: name, partialLinkText, css selector, xpath selector, tagname, linkText.
This tutorial from Selenium Easy contains some easy to understand examples.
If you want to locate <span name="WordPress">WordPress</span> element, You can locate this element using By.name() as below :-
driver.findElement(By.name("WordPress"));
I have a login button and want to identify it using xpath and id. But both the xpath and id are dynamically changing. Please advise on how to do it.
The Xpath and ID keep changing as below for login button and i am not able to find any common element to find it:
Xpath : .//*[#id='uO4Qo']
ID : uO4Qo
Xpath : .//*[#id='tP5Qo']
ID : tP5Qo
Xpath : .//*[#id='vVBPn']
ID : vVBPn
If you're using Selenium IDE to create your script, the target field is a dropdown, displaying all the possible options to identify your specified button. If the options CSS, name or anything else are not available, it means that these things are not present on your page. Perhaps is xpath:position an option in your specific case.
Use below code, use login button text in place of LoginButtonText:
driver.findElement(By.LinkText("LoginButtonText")).click();