When testing an ext-js application with Selenium (WebDriver), I have a button that brings up a dialog. The test then fills out some form fields, clicks buttons, etc. The problem is that selenium starts performing these actions before the dialog is fully done building.
I know that I can tell selenium to wait for a specific element to appear, but if I want to generalize the case to "wait for the dialog to finish loading", is there a way to do that?
The short answer is, "No, theres no simple way to do that." to understand why this is so, consider this: How do you define "the whole DOM is loaded?" Is it when the last closing </html> tag is downloaded? When it's parsed and added to the DOM? Is it when the document readyState property is "interactive," "contentReady," or some other value? What about DOM elements added via JavaScript? What if that JavaScript is fired via setTimeout()? What about processing XmlHttpRequests? There is no one-size-fits-all answer to that question that is correct 100% of the time for all use cases.
Waiting for an element is the right approach. Identifying the right element can be challenging when using extJs, because of the generated IDs. I've often found it more effective to use class attributes with that particular JavaScript framework.
Related
I am doing UI automation in Selenium-Java where I am recognising object/element based on XPATH or CSS selector. Due to many unwanted reason - tests are getting failed due to change in XPATH at different environment.
I thought to write a utility script which will identify and auto-generate robust and simple XPaths.
Is there a way - I can make this happen at run time to self heal my existing Selenium-Java automation scripts.
It's not possible to recognize the elements that should get their xpath regenerated without specifying somehow what those elements are.
It's easy for humans to know which one is the "sign up" button, for example, even if its label, style or position changes, since people can use other context clues to guess which button is meant by "the sign up button". Implementing these context clues for a computer would require quite a lot of effort, especially for more obscure type of elements.
I would stick to spending some time and human thought to figure out the most robust locator for each element. (For a sign up button I'd say it's often the value of the href attribute.)
Maybe you could even specify multiple different locators per element. Then implement the search so that the locator that first matches a single element is used and fail only if all specified locators fail. That could decrease the frequency with which a person has to be fixing the tests. Or it could have the opposite effect :)
One more idea: if you can use version control to get the last version that some specific selector still worked, maybe you could try finding the most similar element in the new version and regenerating the xpath for that.
I'm currently writing cucumber tests for widgets that will be (and are) implemented in different technologies (different web frameworks, Java Swing [not really, but it should technically be possible], etc). The tests are intended to describe the functionality of the widget under test, by directly emulating the input of a user. For example, a test could be phrased as something like "the user opens webpage X, then clicks there, then there, then there, and now I expect this textfield to contain the value Y".
The technology I'm currently implementing the tests in is the web, using Selenium.
Now, assuming a user wants to type something into a textfield, what the user would do in reality is click into the textfield and then start typing. On its own, typing on your keyboard doesn't have anything to do with the textfield - only because the click switched the focus to the textfield does the textfield receive the keyboard input.
Now, Selenium has a sendKeys method. What does this method do, precisely? The javadoc states "Use this method to simulate typing into an element, which may set its value".
Does the sendKeys method emulate a click (as if .click was called first) and then keyboard input, as a real user would? Or does it set the focus and then starts typing? Or does it circumvent focus altogether and simply sends "keyboard input" to the input element?
As certain widgets might exhibit special behavior if clicked, I need to know if Selenium performs a click under the hood, or if I manually have to call it in order to realistically emulate the user's behaviour.
Note: I have not added cucumber to the tags as it is, although relevant for context, only tangential to the actual question
Remember that elements can get keyboard focus in ways other than being clicked on. A user could use the tab key to navigate through the elements of a form, for example.
For Selenium and WebDriver, the steps taken by drivers for the sendKeys method are defined by the W3C WebDriver Specification. For setting the focus to an element before simulating the key input, that spec links, in turn, to the WHATWG HTML Specification.
The focusing occurs independent of a specific “click” action. In practice, a given spec implementation (chromedriver, geckodriver, etc) might “run the focusing steps” for the element by clicking on it. I don’t believe any implementations actually behave that way, but you’d need to validate that for the individual implementations.
Tl;dr, no, sendKeys does not necessarily imply a click.
Im testing on a site that sometimes doenst really have a good connection.
Everything works great until it decides to not work properly.
I am seperating every element with a wait.until, everything works normally until the connection gets slow and it believes the element is present and decides to use it.
public static WebElement login_btn(WebDriver driver, WebDriverWait wait) {
wait.until(ExpectedConditions.refreshed(ExpectedConditions.presenceOfElementLocated(By.id("btnEntrar"))));
wait.until(ExpectedConditions.refreshed(ExpectedConditions.elementToBeClickable(By.id("btnEntrar"))));
element = driver.findElement(By.id("btnEntrar"));
return element;
}
I cannot find a way to simulate this until the website becomes terribly slow and I get to see if it works or not. After months of trying I am unable to find out a way to completely wait for the element to be present and not receive a staleElementReferenceException or the site actually going into an error page due to me using an element. Using the site manually without these tests cannot simulate what is happening with the webdriver. Are there any hints or suggests on what I could do?
There are a few good answers you can try in this question and this question. One is to use Chrome dev tools to throttle adjust the download speed, https://stackoverflow.com/a/34728002/2386774. Another is Charles Web Debugging Proxy.
To solve this issue more simply, my suggestion is to specifically wait for the page to load completely then scrape the page. This will allow you to wait once and then you won't have to add waits everywhere. You would need to add additional waits if your page is dynamic, e.g. you click a button and it updates part of the page. In that case, add a wait when the button is clicked and you're good again. No need to add waits everywhere.
I'm building a page that has a search box that will populate a grid on the same page. There is also a button the user can select to bring up a "window" (JQuery UI "pop-up" in the same page) that lets the user configure said grid.
These are two separate forms but I don't want what was submitted as part of one to undo the other (so when the user submits to change the grid layout the search needs to re-run as well.
I'd rather not store things in session for this since that brings with it its own issues (search results may be large, shouldn't be saved when the page is re-entered later, etc.).
I've considered doing "one large form" (i.e. surrounding all the inputs) for the entire page that is backed by a form backing bean. I would then use which button is clicked to determine the action to take. There will eventually be other buttons on the page as well to add more functionality. This would be similar to how .NET (non-MVC) handles things.
I'm interested in how others may have solved similar challenges. Are there potential issues with my approach that I'm not seeing? Better ways that work with the framework?
What do you mean with:
but I don't want what was submitted as part of one to undo the other
. Are you referring to posting the form and loading the whole page, which in turn will "reset" the other form?
If that is the case I would still keep one page with two forms and make the posts using Ajax (as you may know jQuery makes this a breeze). Upon receiving a response for either call you will need to update the other form accordingly.
Note that you may still have your forms in two separate views if it helps keeping the code clean and then pull their html with Ajax calls into another view. But my point is that at the end I would still keep both in one page since it sounds like they depend on each other so updating one when the other changes may be easier this way,
Let me know if I misunderstood your question.
I'm attempting to use the Java Selenium client with JBehave to interact with a simple web page as a demonstration of BDD techniques.
When running the test, i'm trying to do a simple
selenium.click("joinButton");
but i'm getting a
(com.thoughtworks.selenium.SeleniumException: joinButton is not defined)
exception thrown.
I've tried qualifying the ID as a dom ID using id=joinButton, as a css selector and even as xpath but to no avail.
The element is definitely rendered in the page. I'm clearly doing something daft here.
Any pointers?
Thanks
Did you call waitForPageToLoad() after navigating to the page in Selenium? I'm betting your DOM hasn't loaded yet when your click is called.
Please confirm that while verifying with xpath and css you used selenium.click("//[#id=joinButton]") and selenium.click("css=#joinButton") respectively.
You can also keep selenium.isElementPresent("joinButton") in a loop until some timeout (30/60 sec) and the moment selenium finds this element, it would come out of this loop and execute click command.
I realised what the issue was here. The Selenium class was being extended, and the click method overridden to only accept CSS selectors. With this cruft now removed, the operation works as expected.
Thanks for your help folks.