Hy. I have a problem with selenium IDE. I have a button in a table that I must click on.
Command: click
Target: xpath=//table[#id='mainForm:dataTable']//tr[contains(., 'test1')]/td[9]/div/table/tbody/tr/td[contains(., 'Edit')]/a
When I click the button 'Find' of selenium it show's me the button 'Edit' for the person 'test1' in my table. So selenium finds the button, that means what I write in target must be correctly.
The problem is, if I wanna run the test, selenium says :
[error] Element //table[#id='mainForm:dataTable']//tr[contains(., 'test1')]/td[9]/div/table/tbody/tr/td[contains(., 'Löschen')]/a not found
and I don#t know why.
Please help me with this problem :)
Maybe row where this text has to be present is another than 9 ? maybe try/td[contains(., 'Löschen')]/a if you don't have another td like this on page. Good practice will be sign in some way that element in your server script (for example add rel= or title= or just specific id=) and find that by this parameter.
Try to run test growing this xpath from none, thet you should catch a situation where exactly requested element not exists, like:
//table
//table[#id='mainForm:dataTable']
//table[#id='mainForm:dataTable']//tr
//table[#id='mainForm:dataTable']//tr[contains(., 'test1')]
//table[#id='mainForm:dataTable']//tr[contains(., 'test1')]/td
//table[#id='mainForm:dataTable']//tr[contains(., 'test1')]/td[9]
And so on, until error will appear
Maybe you have some javascripts on page that do modifications in DOM tree
Related
I'm using cefsharp and vb.net to put some code together to move to the next page of this site:
https://www.recommendedagencies.com/search#{}
The idea is to read the list of company names on each page and store to a csv file. This part I can do.
The problem I have is that I can't find the name of the 'Next' button - presumably if I had that I could execute some javascript on the browser to press the button.
I've inspected the page in Firefox, but can't see any name I can use - I'm not really familiar enough with html/page design to know why not or how it works.
Could anyone tell me a good method to get button names from a web page? - I've done some searching and even asked a similar question myself before, but I can't find anything which helps, given my patchy knowledge.
Thanks
Inspect the DOM for the 'Next' button.
Look for id's or classes that you can use to identify it.
use document.querySelector() to find the element by the css selector
call the element.click() function to programatically press next
const nextButton = document.querySelector('.sp-pages-nav_next')
nextButton.addEventListener('click', (event) => {
console.log('something clicked next')
})
nextButton.click()
<div class="sp-pages-nav sp-pages-nav_next" data-reactid=".1.3.4.1">Next</div>
In the above snippet on load you can see the code nextButton.click() invokes the console log. You can click the word Next manually to the same effect.
in cefsharp perhaps something like:
browser.ExecuteJavaScriptAsync("(function(){ document.querySelector('.sp-pages-nav_next').click(); })();");
A very similar example can be found here :
https://github.com/cefsharp/CefSharp/wiki/General-Usage#1-how-do-you-call-a-javascript-method-from-net
// When executing multiple statements, group them together in an IIFE
// https://developer.mozilla.org/en-US/docs/Glossary/IIFE
// For Google.com pre-populate the search text box and click the search button
browser.ExecuteJavaScriptAsync("(function(){ document.getElementsByName('q')[0].value = 'CefSharp Was Here!'; document.getElementsByName('btnK')[0].click(); })();");
Consider the following Selenium automation:
Its goal is to go to a financial chart from the website Barchart, click on the custom calendar icon (at the top right corner over the chart), input a custom range in the form that pops up over it, and validated it using the apply button.
driver = webdriver.Chrome()
url = 'https://www.barchart.com/stocks/quotes/AAPL/interactive-chart'
driver.get(url)
driver.find_element_by_css_selector('.calendar-icon').click()
driver.find_element_by_css_selector('option[label="Intraday"]').click()
driver.find_element_by_css_selector('[data-ng-model="selectedAggregation.range.from"]').send_keys('11/01/2019')
driver.find_element_by_css_selector('[data-ng model="selectedAggregation.range.to"]').send_keys('11/01/2019')
driver.find_element_by_css_selector('[data-ng-model="selectedAggregation.range.to"]').send_keys(Keys.ENTER)
driver.find_element_by_css_selector('[data-ng-click="modalConfirm()"]').click()
It works fine for the most part, until I try to validate, which never works. I then realised that sometime this last action would lead me to a promotional page whose link is located exactly beneath the Apply button. Which seems to indicate that selenium 'click through' the form onto the link below.
I have tried other selector for the apply button, which all give the same result.
I also try to use the submit() method from selenium, which returns an error. Lastly, I also try to implement the execute_script method from selenium, but I did not manage to understand what exactly is the javascript call being executed on clicking apply.
Note : this is because i need to get the cookie and xsrf token that is generated by that call, not because i need to collect the actual financial data ( I know that the financial data can be collected using 'https://www.barchart.com/proxies/timeseries/queryminutes.ashx?' + data), where data are the query string parameters.
Any help greatly appreciated.
I had a look for you, the below should accept the changes for you, I've checked this and it works for me.
javascript = 'document.querySelector("body > div.reveal-modal.fade.interactive-chart-modal-aggregation.in > div > div > div > button.bc-button.light-blue").click()'
driver.execute_script(javascript)
I am trying to fill forms on certain webpages. I am having success with most
pages however certain ones are giving me trouble.
Some pages have a format where the form is not initially visible on the page itself, instead you need to click a button which then opens a (what seems to be JavaScript) pop up within the page which then needs to be filled.
I have looked around and have seen examples which address how to fill forms which get created in a new pop up window and which get created in alert windows. However I can not seem to find any examples which can solve this particular case.
This is the code I have so far.
driver = webdriver.Chrome()
driver.implicitly_wait(10)
mouse = webdriver.ActionChains(driver)
driver.get(url)
driver.maximize_window()
value = 'fill form'
span_xpath = '//span[contains(text(), "' + value + '")]'
span_element = driver.find_element_by_xpath(span_xpath)
mouse.move_to_element(span_element).click().perform()
time.sleep(5)
Everything works till here, the fill form button gets clicked which opens the form in the browser page.
But when the following is execute an error always arises: "no such element: unable to locate element"
n =driver.find_element_by_id('name')
n.send_keys('john smith')
I have tried to locate the element by, name, id, xpath and so on but no matter what try, it can not locate any of the form elements.
I would greatly appreciate any help on this matter.
First switch using driver.switch_to_frame(0) (parent iFrame)
then switch using driver.switch_to_frame(1) (chiled iFrame)
and then find the element.
Note: instead of using index you can identify the frame using id, name, xpath etc. like any other Web Element and pass that element to switch_to_frame as an argument. This gives more consistency.
My apology as this question is quite long.
To be more specific, I am trying to click on the Pencil icon (Edit button) that is shown on the 4th row
Here's the code I tried to execute:
WebElement ele = driver.findElement(By.xpath("//a[contains(#title, 'Edit Row')]"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
Executor1.executeScript("arguments[0].click();", ele);
And here's the HTML code
After I ran the selenium code, the driver actually clicked on the Edit button of the 1st row (Administration | NA) instead of the 4th. I found out that not only the 1st but other rows also have the same HTML code, only difference was that the Pencil/Edit button is hidden because I wasn't the one that created the values of that row.
I did try with the following code as well:
driver.findElement(By.xpath("//a[contains(#title, 'Edit Row')]")).click();
I then received the error
element is not currently visible and so may not be interacted with
It seems the driver was still looking at the hidden Edit button in the first row, instead of the obvious visible one in 4th.
Is there anyway that I could click on the Edit button based on the value instead of the row number? The reason is that in the future, the value I enter for testing may not end up in 4th but 1st or 10th row.
Last but not least, my Safari can't seem to run the JS Executor code, everytime I gave it a go, the following error returned:
org.openqa.selenium.WebDriverException: 'undefined' is not a function (WARNING: The server did not provide any stacktrace information)
Can someone shed some light on this for me as well?
Cheers
Since there is only one edit icon displayed, the code below should work.
driver.findElement(By.cssSelector("a[title='Edit Row']")).click();
I think the reason you were running into the hidden element issue is that you were using JSE to click on it. Selenium is designed to only interact with elements that are visible... the way a user would. JSE allows you to interact with elements that are NOT visible. There are reasons to use JSE but I don't believe this is one of them. Using JSE you were finding an element that matched your XPath that was not visible and then trying to click on it... thus the error.
I suggest you to go once in firefox and then try same xpath in firebug with firepath add-on.
Try to inspect xpath of the pencil icon. Only one maching element with no dynamic values in that, then you can and use it. Else evaluate this xapth
//a[contains(#title, 'Edit Row')]
You can find one or more matching elements. Then try to find difference in one of attribute for required element. If you are able to create xpath by using that odd attribute then its on else go for List and in loop cross theck for that, then work on it.
Thanks murali and JeffC for the suggestions, I have managed to get the driver to click on the displayed Pencil with this:
List<WebElement> EditButtons = driver.findElements(By.cssSelector("a[title='Edit Row']"));
for(WebElement button : EditButtons) {
if(button.isDisplayed()) {
button.click();
}
}
Although it only solved half of the issue, I am trying to click on the displayed Edit button based on the value next to it. If I create another row with the value of 'Test234' and if the row is placed under the 4th row, the Edit button of 'Test234' won't be clicked. Any suggestion? I tried this but it doesn't seem to work, driver still clicked on the first visible edit button it saw:
List<WebElement> EditButtons = driver.findElements(By.cssSelector("a[title='Edit Row']"));
String textvalue = driver.findElement(By.xpath("//span[contains(text(),'test456')]")).getText();
for(WebElement button : EditButtons) {
if(button.isDisplayed() && textvalue.equalsIgnoreCase("test456")) {
button.click();
}
}
UPDATE: Alright, issue resolved, I switched back to use xpath instead of cssSelector, then modified Vagnesh's suggestion (Thanks Vagnesh !!) a bit and now the driver is clicking on the visible edit button next to the text I search for without going through the loop
driver.findElement(By.xpath("//span[contains(text(), 'Enter my desired Text here')]/following::div//a[contains(#title,'Edit Row')]")).click();
You should find the element based on the field text, so that it can find its corresponding edit link.
functional_area = "Business Development / Innovation"
WebElement ele = driver.findElement(By.xpath("//span[#class='xspTextComputedField'][contains(#text, '" + functional_area + "')]/following-sibling::div/a[contains(#title, 'Edit Row')]"));
You can make it more dynamic by parameterizing the text ex. Financial.
I am trying to write an applescript application that logs into a website upon launching. So far I can successfully open Chrome, load the web page into the active tab, select and input the password, but I cannot click the submit button.
Below is the element on the page:
<button type="submit" class="btn btn--ac" alt="Login"
title="Login" tabindex="6"><i aria-hidden="true"
class="lush lush-locked"></i> Login</button>
My skill level in javascript is little to none, yet I cannot find a way to successfully select this item and click it. I have tried already using the TagName and ClassName but it does not work, perhaps my syntax is incorrect. Is there a way to do this without a ID type?
I have tried:
execute front window's active tab javascript
"document.getElementByClassName('btn, btn--ac').click()"
execute front window's active tab javascript
"document.getElementByTagName('button').click()"
I should note this script runs in Google Chrome.
Thanks for any help in advance.
First of all you're using a wrong function. It should be
document.getElementsByClassName
Try using: (Assuming the Submit button is the only button with class btn)
document.getElementsByClassName('btn')[0].click();
Here's basic definition of the function from Mozilla:
document.getElementsByClassName():
Returns an array-like object of all child elements which have all of
the given class names.
Hence, you get a list of elements. Hence, you select the first element in it (using the 0 as index), and then click on it.
The correct syntax in plain js to select an element by his class is:
document.getElementsByClassName('btn--ac');
With this you'll get an array with all elements with the class 'btw--ac'. In your case try this:
document.getElementsByClassName('btn--ac')[0].click();