Firefox WebDriver does not find the element of the page - firefox

I would like to use WebDriver (Firefox) to test my webpage, but I always get this message:
Unable to locate element: {"method":"xpath","selector":"//li[#id='something_spicy']"}
But, the really strange thing is that if I copy the element locator "//li[#id='something_spicy']" and paste it into Firefinder then it works. Basically, I ran out of thoughts about what could be the root cause.
I use C# and here is the code:
movedElement = driver.FindElement(By.XPath("//li[#id='" + originalOrderOfSportContainers[1] + "']"));
Did I do something wrong? Have I missed something?

provide a snippet of the html code of your page.
There is a chance that element is not there immediately after the page is loaded,
but appears a bit later as a result of some javascript function execution.
If this is the case, use explicit wait to wait for element to appear before using it.

Related

How does capybara/selenium grab current URL? Issue with single page site

I am using ruby and capybara(which leverages selenium) to automate walking through a website. After navigating to a new page I verify that the new page URL is what i'm expecting. My issue comes when I walk through an order funnel that is a single page but loads different views.
Some code...
I create my session instance then have additional code opening the browser and walking to a certain point in the website that I wont include
$session = Capybara::Session.new(:selenium)
My line for checking the browser URL without search params ie: everything after '?'
if url == $session.current_url.to_s.split("?")[0]
urlCorrect = true
end
This code works fine when my URL is
https://www.homepage.com
Then I click on a link that takes me to my order funnel ... https://www.homepage.com/order#/orderpage1?option1=something&option2=somethingelse
My function still matches the expected URL. But the issue comes when I move to the second page of the order funnel :
https://www.homepage.com/order#/orderpage2?option1=something&option2=somethingelse
My capybara code to get current url still returns the URL from orderpage1. Im guessing its because there is no postback when moving from orderpage1 to orderpage2 but i dont know how to force a postback or tell capybara to re-grab the url
Any advice will be appreciated.
Thanks
Quick Edit: I forgot to mention this behavior is only in IE. Chrome and Firefox both work correctly with the exact same code
Capybara grabs the current_url by querying the browser - it doesn't cache it. The issue you're probably running into is that clicking the link to move to the next page doesn't wait for the page change to happen, so if you call current_url before the page load has happened you'll still get the original url. There are two solutions for that - 1. use capybara to look for content that doesn't appear until the new page is loaded ( have_content ), 2. use the has_current_path? method which will wait/retry for a period of time until the current_path/url match
$session.has_current_path?('expected path')
There are options if you want to match against the full url, and you can use a regex to match as well - http://www.rubydoc.info/gems/capybara/Capybara/SessionMatchers#has_current_path%3F-instance_method
Thanks to Tom Walpole for finding the bug report for this issue. This link sums up the root of the issue and provides a few workarounds if anyone else is encountering this issue.
https://github.com/angular/protractor/issues/132

Selenium webdriver can't find button

EDIT:
I have cleaned this up a bit.
I have a button that looks like this:
<input id="applyRuleButton" class="Button" name="filtersContainer:applyRuleButton"
value="Apply" onclick="wicketShow('applyRuleButton--ajax-indicator');var
wcall=wicketSubmitFormById('id256', '?wicket:interface=:23:form:filtersContainer:applyRuleButton:
:IActivePageBehaviorListener:0:&wicket:ignoreIfNotActive=true',
'filtersContainer:applyRuleButton' ,function() { ;wicketHide('applyRuleButton--
ajax-indicator');}.bind(this),function() { ;wicketHide('applyRuleButton--
ajax-indicator');}.bind(this), function() {return
Wicket.$$(this)&&Wicket.$$('id256')}.bind(this));;; return false;" type="submit">
Firebug:
<input id="applyRuleButton" class="Button" type="submit"
onclick="wicketShow('applyRuleButton--ajax-indicator');var
wcall=wicketSubmitFormById('id2ee',
'?wicket:interface=:29:form:filtersContainer:applyRuleButton::IActivePageBehaviorListener:0
:&wicket:ignoreIfNotActive=true', 'filtersContainer:applyRuleButton' ,function() {
;wicketHide('applyRuleButton--ajax-indicator');}.bind(this),function() {
;wicketHide('applyRuleButton--ajax-indicator');}.bind(this), function() {return
Wicket.$$(this)&&Wicket.$$('id2ee')}.bind(this));;; return false;" value="Apply"
name="filtersContainer:applyRuleButton">
I'm trying to click it and have tried pretty much everything for 2 days, webdriver does not find the element, IDE does find it:
//This was my first approach, it should work.
It works in IDE, but not Webdriver:
driver.findElement(By.id("applyRuleButton")).click();
//then perhaps this should do the trick, hint: It doesn't:
WebElement element3 = driver.findElement(By.id("applyRuleButton"));
JavascriptExecutor executor3 = (JavascriptExecutor)driver;
executor3.executeScript("arguments[0].click();", element3);
Ok, Id not working, I get it.
Then this should work at least:
driver.findElement(By.xpath("//table/tbody/tr/td/div/div/table/tbody/tr[6]/td/input[#id='applyRuleButton']")).click();
It feels like I am missing something obvious here, some help please?
Additional information:
I have added a 5 second wait, the page is completely loaded.
This button is located in a table:
The Xpath is
/html/body/div[4]/div[2]/form/div[3]/div/div/table/tbody/tr/td/div/div/table/tbody/tr[6]/td/input
Webdriver error, no matter what I throw at it, is: Unable to locate element
I have used both 'click' and 'submit', still no success.
I think in this case there are two possibilities :
Either there is another element having same id/xpath.
OR Element present in another iframe.
Is the button visible. Selenium click (latest firefox 26 and latest webdriver 2.39.0) does not sometimes implicitly scroll; Or it may not scroll it fully. So scroll it into view - Scroll Element into View with Selenium and then it should work.
Note Selenium Best Practise try to use By.Id,By.CSSSelector and if nothing gets use By.Xpath in the order of priority. ( Use the FireFinder, FireBug plugin to test XPath or CSS)
This might be a synchronization issue. Such issues can be solved using smart waits.
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementExists((By.Id("applyRuleButton"))));
WebElement element3 = driver.findElement(By.id("applyRuleButton"));
And that should work perfectly fine.
There is absolutely nothing wrong with your selector. I just don't think you're invoking the click correctly.
Try:
driver.findElement(By.id("applyRuleButton")).click();
If this doesn't work, then you might have to invoke a WebDriverWait since you have this question marked as [ajax]
Could you post the entire html?
As a simple experiment, I took the html snippet that you posted and wrote a short python script that invokes selenium:
from selenium import webdriver
br = webdriver.Firefox()
br.get("put your path to snippet here")
button = br.find_element_by_id("applyRuleButton")
print button.get_attribute("name")
button.click()
br.close()
I can find the button and extract the attribute "name" which prints "filtersContainer:applyRuleButton". This is admittedly a very limited experiment, but it suggests that the issue is related to not being where you think you are on the page.
Try this:
driver.findElement(By.Name("filtersContainer:applyRuleButton"));
If this doesn't help, check whether this button is located in any other frame. If so, you may have to find and move your focus to that frame and then locate this button.
First try to identify the button by writting correct xpath using firebug, if you are able to identify button by that xpath then use that xpath while writing your script.
driver.findElement(By.xpath("//input[# type='submit' and # id='applyRuleButton'")).click();
This is ajax application use proper explicit/ webdriver wait till the button gets downloaded
I see that this thread is old, but I was looking at it today (Sept/2021) as I was having the same problem: I could see the name / id/ type of the button, but it would never be found.
I discovered that when I had clicked in a prior link, it opened a new tab in my browser, but Selenium did not change the focus to the new tab, so it couldn't find the ID of the button I was looking for.
I solved it with :
driver.find_element_by_id("export").click() #driver
time.sleep(2)
driver.switch_to.window(driver.window_handles[1]) # Change focus to the new tab
driver.find_element_by_id("0001btn").click() #click
driver.close() #close new tab
switching to a specific frame helped me to resolve the same issue. (python + selenium)
I installed the Selenium Recorder extension on chrome and recorded my steps, and found out that the recorder had a step to select a frame = 0, so adding
self.home_page.driver.switch_to.frame(0)
self.home_page.click_on_element_by_id("clickSubmit")
solved the problem.

How a verify a page in transition using selenium

I clicked on a button on some page which redirects me to some other page.but between these pages there is one page which comes only for 1 or 2 seconds. I have to verify that page.I am using selenium.
Any suggestions?
What you could do here, is do a simple waitForElement subroutine.
Ideally, when your test framework cannot find an element to operate with, it will fail.
So we can assume, that when your test gets past waitForElement(theInterimElement) then your interim element has appeared, and we can continue.
Check the url of the page is the url of the desired page and wait while this is not true.
while (!webDriver.Url.Contains(desiredUrl.ToString()))
Thread.Sleep(50);

chrome-app won't recognize id's that work fine when run by the chrome browser

I'm converting a standard browser based app that's working fine to a chrome-app.
Once the page loads up, it has already hit an error - Uncaught TypeError: Cannot call method 'appendChild' of null. This occurs after several hundred lines of JS have done their job but its the first time the code makes a reference to the document object, specifically document.getElementById('mainDiv').appendChild(...).
I can clearly see the div with the id="mainDiv" in the debuggers elements tab. Yet, document.getElementById('mainDiv') must be returning a null. Any attempt at putting in breakpoints fails as they are ignored. I've added them to the line that fails as well as to lines that lead up to it and breakpoints are never triggered. I've read some of the threads on SO and I'm certain the breakpoints issue is just a bug in the debugger, but not recognizing an id when I can clearly see it and the code when run in the browser works fine leaves me wondering what's going on. Is document in the browser different from document in the app version?
Any ideas?
If I choose "inspect background page", the breakpoints work but it still fails but in a different way. The elements tab does NOT show my html page, but the pseudo generated background one and I can't get the debugger to show my page at all.
Any enlightenment would be appreciated. I've searched and read what I could find, but much of the docs are clearly out of date.
You seem to be accessing the document object of the background page, instead of that of your POS.html file.
Try this:
chrome.app.window.create('POS.html',{
'bounds': {
'width': screen.availWidth,
'height': screen.availHeight
}
}, function(appWin) {
var pageWindow = appWin.contentWindow;
var pageDocument = pageWindow.document;
pageWindow.addEventListener('load',function() {
// now use
pageDocument.getElementById('yourid');
// instead of
document.getElementById('yourid');
},false);
});
Also to inspect elements in your page right-click anywhere in the app window and select Inspect Element (this works only when the app was loaded as an 'unpacked extension')
Alternatively you can navigate to chrome://extensions and click the page link next to your app entry.
As lostsource mentioned, you're probably accessing the wrong DOM's document. You should think about the javascript in your app running in different global contexts, one for each page. There is (at a minimum) a page for the background page, and a page for each window.
Each of these pages runs in its own global context. This means global variables like document and window are different.
In the background page will be scripts which you load via the background manifest tag. When you open a window, it can also load its own script via script tags (make sure you do not use inline or block script tags, but use script src="foo.js". See http://developer.chrome.com/apps/contentSecurityPolicy.html).
The code that runs in the callback to chrome.app.window.create runs in the background page's context, so its document variable is for the background page's DOM, which is usually empty. Instead you can make it refer to the window's DOM using win.contentWindow as lostsource suggested, or add a page.js file with the script in it, and include it from the page via a script src='page.js' tag.
Is your call occurring after the load event, e.g. the JS called in a function set on window.onload?

HTMLUnit click() on HtmlElement does not work

I'm trying to get HTMLUnit to perform a click action on a span, which doesn't work for some reason. Please take a peek at the code below.
HtmlElement clickable = (HtmlElement) page.getByXPath("//div[10]/div/div/span").get(0);
clickable.click();
By doing this I get a really long error message. The interesting bit seems to be the following:
TypeError: Cannot find function setCapture in object [object].(script in [some long url here])
The same thing happens when i try to call on mouseDown() or dblClick() or any other mousey method. This is really frustrating since the code snippet is something that worked fine some time ago. I simply uncommented it today and now it won't co-operate.
HtmlUnit doesn't currently support .setCapture()/.releaseCapture(), please open a bug report in its tracker

Resources