We have some UI tests written in selenium running with Browserstack on TeamCity.
These tests randomly fail because (in my opinion) the wait.Untils are not working correctly as the error always is 'could not click element ... because element would receive the click. As you can see in the code i apply multiple waits and still it randomly ignores them.
driver.FindElement(By.XPath("//input[#value='Login']")).Click();
//wait for the page to be loaded, check the title and open a booking
wait.Until(ExpectedConditions.ElementExists(By.LinkText("To be completed")));
wait.Until(ExpectedConditions.ElementToBeClickable(By.LinkText("To be completed")));
Assert.AreEqual("Booking Overview", driver.Title);
wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath("//button")));
wait.Until(ExpectedConditions.ElementToBeClickable(By.LinkText("To be completed")));
driver.FindElement(By.LinkText("To be completed")).Click();
//wait for step 2 to load
wait.Until(ExpectedConditions.ElementExists(By.XPath("//div[#id='WiredWizardsteps']/div[2]/div/form/div/div[2]/label/span")));
wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath("//div[#id='WiredWizardsteps']/div[2]/div/form/div/div[2]/label/span")));
//verify we are at step 2
var step2 = driver.FindElement(By.XPath("//ul[contains(#class, 'steps')]/li[contains(#class, 'active')]"));
Assert.AreEqual("2", step2.GetAttribute("data-target"));
//click the radiobutton with a movetoelement
var option = driver.FindElement(By.XPath("//div[#id='WiredWizardsteps']/div[2]/div/form/div/div[2]/label/span"));
new Actions(driver).MoveToElement(option).Click().Perform();
//retry programmatically
driver.FindElement(By.XPath("//div[#id='WiredWizardsteps']/div[2]/div/form/div/div[2]/label/span")).Click();
//wait for the textbox to appear
wait.Until(ExpectedConditions.ElementToBeClickable(By.Name("commodityNonOperative")));
anybody has a suggestion or had the same problems please let me know.
Related
I want to start my Selenium script on a login page, wait for 30 seconds so I can manually resolve a captcha, and once the login is successful, start the actual work automation work.
I'm using the code below, and it works ok up to the line where it enter the email.
I supposed that this code will wait in a sort of pooling until it sees the H4 element with certain text in it (login successful), but it throws an exception when the element is not found.
IWebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
driver.Navigate().GoToUrl("URL");
var loginEmail = driver.FindElement(By.Id("LOGINTextBTTN"));
loginEmail.SendKeys("myEmail"); //this line works
IWebElement firstResult = wait.Until(ExpectedConditions.ElementExists(By.XPath(#"//h4[text()='H4 Text']"))); //this lines fails with an exception
Console.WriteLine(firstResult.GetAttribute("textContent"));
Write the code
driver.manage().timeouts().implicitlyWait(60,TimeUnit.SECONDS) ; // Wait for 60 Sec.
WebElement firstResult = wait.Until(ExpectedConditions.ElementExists(By.XPath(#"//h4[text()='H4 Text']")));
Or
You can use Fluentwait
Wait wait = new FluentWait(driver).withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
I had to deal with this a while back. The way I solved was with sleep:
time.sleep(seconds need to solve) #for me it was around 60ish seconds
Probably something like:
import code
code.interact(local=dict(globals(), **locals()))
Then Ctrl+D out after you solve the captcha
I am doing an upload with Selenium, after the upload an elements gets invisible and I know its completed. The problem is this code throws a WebDriverException everytime after 1 minute and I don't know why since I set the timeout to 5 minutes.
It would be great if someone knows a solution for this. Thank you :)
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(300));
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.XPath(xpath)));
In my automation project.
Browser: Firefox
I would like add a wait function without any specific time
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(7));
IWebElement query1 = driver.FindElement(By.("continue"));
How can do that?
Also to verify that if another page did not load then repeat the previous function. The reason why I am doing this is because sometimes browser does not change the page. It actually stays on that same page.
Besides this is below thing possible in Selenium
Clear Cache and Cookie for last hour
Opening URL in new tab (In already opened browser rather then opening new window)
One thing that has worked consistently for me (regarding waits) is used in the conductor framework..
Here's some pseudo-code you can attempt to recreate in C#:
while (size == 0) {
size = driver.findElements(by).size();
if (attempts == MAX_ATTEMPTS) fail(String.format("Could not find %s after %d seconds",
by.toString(),
MAX_ATTEMPTS));
attempts++;
try {
Thread.sleep(1000); // sleep for 1 second.
} catch (Exception x) {
fail("Failed due to an exception during Thread.sleep!");
x.printStackTrace();
}
}
basically this loops through the size of the selector passed, and will poll each second. Another way you can do it, is just by conditions.
Some more pseudo-code:
function waitForElement(element) {
Wait.Until(ExpectedConditions.elementIsClickable(element), 10.Seconds)
}
And to your questions -
Can Selenium...
Clear Cache and Cookie for last hour
Opening URL in new tab (In already opened browser rather then opening new window)
Opening URL in new tab (In already opened browser rather then opening new window)
If you write your tests cases correctly by making them independent of one-another and not re-using the same browser over and over, this happens automatically. When Selenium opens a new window, it starts fresh with an entirely fresh profile - meaning it has "nothing" in the cache from the start.
Selenium does not (and will never) know the difference between a tab and a window. To Selenium, it's just a handle.
Source:
I have a problem that my phantomjs loads one site too slow, always at least 60 seconds though on other sites like google.com it takes less than 1 second.
PhantomJSDriverService service = PhantomJSDriverService.CreateDefaultService();
service.IgnoreSslErrors = true;
service.LoadImages = false;
service.ProxyType = "none";
service.HideCommandPromptWindow = true;
using (IWebDriver driver = new PhantomJSDriver(service ))
{
driver.Navigate().GoToUrl("http://abc.xyz"); //blocks too long
...
}
Is there any way to force it finish loading after reaching some point so the script will continue?
I see what you are asking now. You have a long loading page that you want to stop after the relevant stuff loads. I run into this same issue with some of the sites that we have at work but I have not tried a programmatic solution. Sorry, I don't know phantomjs but I found some links that I think would be helpful.
The way I would approach it is to wait for the DOMContentLoaded event to fire and then send an ESC to the page. At least that's what I do manually to stop the long loading files that I don't care about so that the execution can continue.
I found this question How can I wait for the page to be ready in PhantomJS? Here's the relevant part:
var page = require('webpage').create();
var system = require('system');
page.onInitialized = function() {
page.onCallback = function(data) {
console.log('Main page is loaded and ready');
//Do whatever here
};
page.evaluate(function() {
document.addEventListener('DOMContentLoaded', function() {
window.callPhantom();
}, false);
console.log("Added listener to wait for page ready");
});
};
page.open('https://www.google.com', function(status) {});
Once you detect DOMContentLoaded, use sendkeys() to send the ESC key. I honestly don't know if this will work but it's where I would start. Hopefully it will get you started.
I've just found out the reasons why the phantomjs load so slow because the target web has too many extensions, ads... so I switch to chrome and use adblock like Running Selenium WebDriver using Python with extensions (.crx files)
In Visual Studio, C#, I have this test:
BrowserWindow.CurrentBrowser = "chrome";
var browser = BrowserWindow.Launch(BaseURL + "/wizard");
var button = new HtmlButton(browser);
button.SearchProperties.Add(HtmlButton.PropertyNames.Id, "NewUser");
ClickButton(browser, "Login");
Playback.Wait(10000);
try {
bool exists = button.Exists;
} catch {}
ClickButton initiates a javascript function which:
1. Hides all of the buttons.
2. initiates an ajax promise.
3. On Success, redirects to a dashboard page
4. On failure, un-hides the buttons.
As you'd imagine, 10 seconds after clicking the Login button, the "NewUser" button is certainly gone/stale since I am logged in.
If I debug, I can see that I get a StaleElementReferenceException. If I run the tests, the browser explodes saying QTAgent32.exe has stopped working.
If I comment out the button.Exists line, I get no errors.
What I'm really attempting is a loop which checks for either the existence of the NewUser button, or the existence of a field on the Dashboard, so I know the result of the button click.
My problem is that the browser explodes when I run the tests.
Instead of using Exists use button.TryFind() which will give you a boolean value and wont cause an exception.
Note: this my slow the process - to solve this:
reduce the Playback.PlaybackSettings.SearchTimeout before the search and return it to default value after search has finished:
var def = Playback.PlaybackSettings.SearchTimeout;
Playback.PlaybackSettings.SearchTimeout = 1000;
{
Do workd
}
Playback.PlaybackSettings.SearchTimeout = def ;