datadriven multi-browser Selenium Grid2 MbUnit/Gallio C# tests timeout - selenium

I am working in C# with Selenium Grid2 and MbUnit/Gallio. I read that a combination of datasets can be used to drive MbUnit UsingFactories alternative in MbUnit v3. So, I am trying to use MbUnit to have a single Test executed on multiple browsers with an additional dataset to make the cartesian product of browsers and data into tests. If I run the code without the extra data set things work fine, the test code is executed against the two browsers.
private IEnumerable<ICapabilities> ProvideCapabilities
{
get
{
yield return DesiredCapabilities.Firefox();
yield return DesiredCapabilities.Chrome();
}
}
[Test]
public void testBrowser([Factory("ProvideCapabilities")] ICapabilities browser)
{
IWebDriver driver = new RemoteWebDriver(new Uri("http://127.0.0.1:4444/wd/hub"),
browser);
driver.Navigate().GoToUrl("http://www.google.com/");
IWebElement query = driver.FindElement(By.Name("q"));
query.SendKeys("Bark");
query.Submit();
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until((d) => { return d.Title.ToLower().StartsWith("bark"); });
System.Console.WriteLine("Page title is: " + driver.Title);
driver.Quit();
System.Console.WriteLine("end of testBrowser");
}
If I add in the dataset to make the testcase data driven Selenium times out, but the actions have been run against browsers correctly. It seems like the grid just never receives the result from the node. In the MbUnit testrunner Icarus I see four tests have been ran but timeout. The code is creating a new WebDriver object with each execution but could there be some other shared resource in Selenium Grid2 that is preventing this from working.
private IEnumerable<ICapabilities> ProvideCapabilities
{
get
{
yield return DesiredCapabilities.Firefox();
yield return DesiredCapabilities.Chrome();
}
}
public IEnumerable<string> ProvideSearchString
{
get
{
yield return "Cheese";
yield return "Bark";
}
}
[Test]
public void testBrowser([Factory("ProvideCapabilities")] ICapabilities browser, [Factory("ProvideSearchString")] string searchString)
{
IWebDriver driver = new RemoteWebDriver(new Uri("http://127.0.0.1:4444/wd/hub"),
browser);
driver.Navigate().GoToUrl("http://www.google.com/");
IWebElement query = driver.FindElement(By.Name("q"));
query.SendKeys(searchString);
query.Submit();
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until((d) => { return d.Title.ToLower().StartsWith(searchString); });
System.Console.WriteLine("Page title is: " + driver.Title);
driver.Quit();
System.Console.WriteLine("end of testBrowser");
}

Related

driver.getCurrentUrl() returns data:, instead of actual URL

I'm writing a test with Serenity BDD-Cucumber.
I want to check if the URL is correct when it's navigated. But the result always shows data, and my test fails with driver.getCurrentUrl().
Please see my code below:
Feature steps:
public void homePageOpens() {
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.titleContains("STORE"));
String homepageUrl = navigationUser.getUrl();
System.out.println(homepageUrl);
Assert.assertTrue(homepageUrl.contains("https://www.example.com/index.html"));
driver.close();
}
Navigation steps:
#Step("Get the URL")
public String getUrl() { return basePage.getUrl();
}
BasePage:
public String getUrl() {
System.out.println("just testing");
WebDriver driver = new ChromeDriver();
return driver.getCurrentUrl();
}
This also opens a page with URL: "data:," which doesn't close after the test
Use driver.get in order to navigate somewhere.
String someUrl = "https://www.example.com/index.html";
driver.get(someUrl);
This code:
public String getUrl() {
System.out.println("just testing");
WebDriver driver = new ChromeDriver();
return driver.getCurrentUrl();
}
just launch the browser, and the initial url is data:,.
Also it's unclear why BasePage getUrl() method launches the new webdriver and uses it as a local variable. But in homePageOpens() method in feature steps looks like some another driver used..

WinAppDriver could not find element sometimes

WinAppDriver sometimes find element, sometimes no... I try to log my elements List size, and when I run my test sometimes it return 1, sometimes 0. My code:
public class Test {
public WindowsDriver<RemoteWebElement > driver;
#Before
public void setup() {
try {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("app", "C:\\Program Files\\App\\Bin\\MainFrame.exe");
capabilities.setCapability("platformName", "Windows");
capabilities.setCapability("deviceName", "WindowsPC");
driver = new WindowsDriver<RemoteWebElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
}catch(Exception e){
e.printStackTrace();
} finally {
}
}
#Test
public void listLength() {
System.out.println(driver.findElementsByClassName("MaskEdit").size());
}
}
In log I see NoSuchElementException:
org.openqa.selenium.NoSuchElementException: An element could not be located on the page using the given search parameters. (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 2.04 seconds
The application MainFrame.exe always runs correctly but test always returns different result.
Why is this happening?
this may happen if the application may not be properly loaded at time , try adding explicit wait.

How to interact with webelement on popup while browser loader running?

I have an authentication popup before loading the website and while popup display on the webpage and a loader display running on the browser it means webpage not loaded completely.
And as per selenium if complete webpage not loaded initially, selenium not interact with elements
Need help on this.
Use following method with Java + Selenium :
public boolean isPageReady(WebDriver driver){
boolean readyStateComplete = false;
while (!readyStateComplete){
JavascriptExecutor executor = (JavascriptExecutor) driver;
readyStateComplete = executor.executeScript("return document.readyState") == "complete";
}
return readyStateComplete;
}
For C# + Selenium :
private void WaitUntilDocumentIsReady(TimeSpan timeout){
var javaScriptExecutor = WebDriver as IJavaScriptExecutor;
var wait = new WebDriverWait(WebDriver, timeout);
// Check if document is ready
Func<IWebDriver, bool> readyCondition = webDriver => javaScriptExecutor
.ExecuteScript("return (document.readyState == 'complete' && jQuery.active == 0)");
wait.Until(readyCondition);
}
You can wait until the page is completely loaded via JavaScript.
private void WaitUntilLoaded()
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
wait.Until((x) =>
{
return ((IJavaScriptExecutor)this.driver)
.ExecuteScript("return document.readyState").Equals("complete");
});
}
Another option is to wait for a specific element(s) to be visible on the page
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(
By.XPath("some Xpath")));
Source here: https://www.automatetheplanet.com/advanced-webdriver-tips-tricks-part-1/

Wait for page loading using PageFactory C#

I'm using PageFactory in my selenium tests. And I've faced a problem in waiting for loading page. I'm not talking about an element on a page I'm talking about timeout of page loading.
So, I have a method like the following:
public MyProjectsPage ClickSaveAndCloseButton()
{
//Do something and click a button
SaveAndCloseButton.Click();
return new MyProjectsPage(Driver); //return new page
}
And when I'm waiting for returning new PageObject (in my case it is "MyProjectsPage") I got a timeout exception. So, where can I set a page loading timeout?
Actual mistake looks like this:
AutomatedTests.FrontEnd.SouvenirProduct.SouvenirTestExecution.OrderSouvenirWithAuthorization(ByCash,Pickup,True,Cup):
OpenQA.Selenium.WebDriverException : The HTTP request to the remote WebDriver server for URL http://localhost:7585/session/b68c04d1ead1fc78fe083e06cbece38f/element/0.46564483968541026-14/click timed out after 60 seconds.
----> System.Net.WebException : The operation has timed out
I have:
The latest version of WebDriver
And the latest version of ChromeDriver and the latest version of Chrome Browser
The mistake that is above apears int the next line:
return new MyProjectsPage(Driver); //return new page
I create my ChromeDriver the next way:
public DriverCover(IWebDriver driver)
{
_driver = driver;
_driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
}
private readonly IWebDriver _driver;
1 note considering wait mechanisms on the page:
Take a couple of webElements and apply for them fluentWait() . That'll be explicit wait webdriver approach.
Another approach is to try out implicit wait like:
int timeToWait=10;
driver.manage().timeouts().implicitlyWait(timeToWait, TimeUnit.SECONDS);
Considering you pageObject code:
I would recommed you the following:
MyPage myPageInstance= PageFactory.initElements(driver, MyPage.class);
then you write the following method :
public MyPage clickSaveAndOtherActions(MyPage testPageToClick)
{
testPageToClick.clickFirstButton();
testPageToClick.clickSecondButton();
testPageToClick.closePoPup();
return testPageToClick; //return page in a new state
}
and if you wanna continue working (I mean update your page state) you do the following:
myPageInstance = clickSaveAndOtherActions(myPageInstance );
Hope this helps you. Thanks.
UPD : as I see from the log something looks wrong with remoteWebdriver server:
OpenQA.Selenium.WebDriverException : The HTTP request to the remote
WebDriver server for URL
http://localhost:7585/session/b68c04d1ead1fc78fe083e06cbece38f/element/0.46564483968541026-14/click
timed out after 60 seconds. ----> System.Net.WebException : The
operation has timed out
Also, I'd recommend you to double check you driver method init. I'm using the following piece of java code for driver init (UI , chrome instance, selenium grid+ hub nodes test architecture):
public static WebDriver driverSetUp(WebDriver driver) throws MalformedURLException {
DesiredCapabilities capability = DesiredCapabilities.chrome();
log.info("Google chrome is selected");
//System.setProperty("webdriver.chrome.driver", System.getProperty("user.home")+"/Documents/Tanjarine/chromedriver");
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
capability.setBrowserName("chrome");
capability.setPlatform(org.openqa.selenium.Platform.WINDOWS);
String webDriverURL = "http://" + environmentData.getHubIP() + ":" + environmentData.getHubPort() + "/wd/hub";
driver = new RemoteWebDriver(new URL(webDriverURL), capability);
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
driver.manage().window().setSize(new Dimension(1920, 1080));
return driver;
}
What you should really be doing when using the PageFactory pattern is when initialising your Page you should be using a constructor to initialise the elements.
public MyProjectsPage ClickSaveAndCloseButton()
{
//Do something and click a button
//I am guessing this is taking you to the MyProjectsPage
SaveAndCloseButton.Click();
return new MyProjectsPage(Driver); //return new page
}
public class MyProjectsPage
{
[FindsBy(How = How.Id, Using = "yourId")]
public IWebElement AWebElement { get; set; }
private IWebDriver WebDriver;
public MyProjectsPage (IWebDriver webDriver)
{
WebDriver = webDriver;
PageFactory.InitElements(WebDriver, this);
}
}
When you return the page, all elements using the FindsBy attribute will be initialised.
Update:
set this property on the driver when you initialise it:
WebDriver.Manage().Timeouts().SetPageLoadTimeout(timespan)
// Wait Until Object is Clickable
public static void WaitUntilClickable(IWebElement elementLocator, int timeout)
{
try
{
WebDriverWait waitForElement = new WebDriverWait(DriverUtil.driver, TimeSpan.FromSeconds(10));
waitForElement.Until(ExpectedConditions.ElementToBeClickable(elementLocator));
}
catch (NoSuchElementException)
{
Console.WriteLine("Element with locator: '" + elementLocator + "' was not found in current context page.");
throw;
}
}
// Wait For Page To Load
public static void WaitForPage()
{
new WebDriverWait(DriverUtil.driver, MyDefaultTimeout).Until(
d => ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState").Equals("complete"));
}

Selenium Browser keeps dying on me

I see other people have been having this issue, by mine seems a bit different than anyone elses as it only is occuring when I run a full suite (fails on like test 20).
if I run a single test or only a few test, the code works just fine.
Otherwise, I get the following stack trace:
org.openqa.selenium.remote.UnreachableBrowserException: Error communicating with the remote browser. It may have died.
I am running my code locally and I don't know why it doesn't try to create a new browser. Instead, it just skips all the remaining cucumber steps.
Does anyone know why this would happen?
Here is my setup and teardown steps:
public class Setup_Teardown_steps extends BaseStepClass {
#Before("#selenium")
public void selenium_before_step(Scenario scenario) { //Function responsible for setting the scenario start and global end condition
//Selenium setup
//initialize_selenium_elements();
driver = WebDriver_Singleton.getNewDriver(); //Creates a new Webdriver instance.
driver.manage().window().setSize(new Dimension(1280, 800));
startTime = System.currentTimeMillis();
testData.ClearTestData(); //Clears saved test data
testData.current_scenario = scenario;
}
/**
* After each scenario Hook (except report scenarios) - public cause it has to be.
*/
#After("#selenium")
public void selenium_after_step(Scenario scenario) throws IOException {
endTime = System.currentTimeMillis();
scenario.write("Run time = " + (endTime - startTime)/1000 + " seconds");
if (scenario.isFailed()){
String html_link = driver.getCurrentUrl();
scenario.write("\n");
scenario.write("URL = " + html_link);
try {
byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
} catch (WebDriverException wde) {
System.err.println(wde.getMessage());
} catch (ClassCastException cce) {
cce.printStackTrace();
}
}
driver.close(); //Clears cache and cookies
testData.ClearTestData(); //Clears saved test data
}
}
//WebDriver_Singleton Function below
private static WebDriver create_driver(){
if (driver != null){
driver.close();
}
assign_base_urls();
String browser = System.getProperty("browser") == null ? "ff" : System.getProperty("browser");
switch(browser.toLowerCase()){
case "ff":
case "firefox":
case "mozilla":
driver = new FirefoxDriver();
break;
case "ie":
case "internet explorer":
case "internet_explorer":
driver = new InternetExplorerDriver();
break;
case "chrome":
case "google":
driver = new ChromeDriver();
break;
default:
System.out.println("Defaulting to Firefox browser");
driver = new FirefoxDriver();
}
driver.manage().timeouts().implicitlyWait(implicit_wait_timeouts, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(page_load_timeouts, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(script_timeouts, TimeUnit.SECONDS);
return driver;
}
I looked at the stack trace, was hard to find but the jenkins server was running out of memory.