I wrote code in C# use Selenium which tests functional. The goal is to put some text in a field, press a button and wait until the site after few times show additional forms. But my code works very strangely. If time very short: it works perfectly. But if the time is more than 30 sec, it throws exception. Here is part of my code, which wait when page loaded by Ajax data and show in the page:
while (true)
{
try
{
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5));
IWebElement myDynamicElement = driver.FindElement(By.Id("smapxml"));
Console.WriteLine("Done");
if (myDynamicElement != null)
{
Console.WriteLine("Ok. Element not null. Follow next step.");
break;
}
}
catch (Exception error)
{
Console.WriteLine("error."+error.ToString());
return;
}
}
Exception:
OpenQA.Selenium.NoSuchElementException: Unable to locate element: {"method":"id","selector":"smapxml"}
in OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse) in c:\Projects\webdriver\dotnet\src\webdriver\Remote\RemoteWebDriver.cs:line 1092
So how do I fix this?
Related
I'm writing a bot with c # selenium. (The working logic of the bot is simply that there are 20 companies on each page, they go back to the detail page and get the data back. They go through all the companies in order. After getting the data of the last company, they continue to the next page.) After visiting 200-250 companies, the page in the picture opens. Bot's stopping progress. If I press the F5 menu manually, the bot continues to progress, but it doesn't work when we try with the code.
How do I resolve this error?
Error Page
I noticed it was on the way back from the detail page of this page. To go back;
driver.navigate().Back();
driver.navigate().GoToUrl("");
//I tried to go back with the codes but the solution was not.
I get this Error because the error page does not pass.
Bot needs to visit all companies without encountering an error page.
A correct approach for this is to wait for some amount of time for some element you expect on the page using WebDriverWait.
In this example, I wait for 10 seconds and look for element id 'some-id'.
You can change the criteria by replacing By.Id("some-id") with some other condition.
More about By class.
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
driver.Navigate().GoToUrl("https://www.somedomain.com");
var validPage = false;
try
{
validPage = wait.Until(c =>
{
try
{
return driver.FindElement(By.Id("some-id")) != null;
}
catch
{
return false;
}
});
}
catch
{
// not exist
}
if (validPage == true)
{
// ok.
}
else
{
}
I have been trying to find ways to catch this error in my selenium webdriver c#.Is any method which will catch this error in my test case ? There is system error or Server Error but I am unable to retrieve my error and fail my test cases. All my test cases which have these error (System/Server) end with the result = "Test Passed" instead of showing of the Error.
Eg: Click to View ServerError
Eg: Click to View System Error
[Test]
public void TestYamaha()
{
driver = new ChromeDriver();
driver.Navigate().GoToUrl("http://192.161.0.1/iels-admin-dev/Login/Login.aspx");
driver.Manage().Window.Maximize();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
driver.FindElement(By.Id("ctl00_MainContent_ucLogin_txtUserID")).Click();
driver.FindElement(By.Id("ctl00_MainContent_ucLogin_txtUserID")).Click();
driver.FindElement(By.Id("ctl00_MainContent_ucLogin_txtUserID")).SendKeys("manteng");
driver.FindElement(By.Id("ctl00_MainContent_ucLogin_txtPassword")).SendKeys("Nic15742368");
driver.FindElement(By.Id("ctl00_MainContent_ucLogin_cmdLogin")).Click();
Thread.Sleep(2000);
driver.Navigate().GoToUrl("http://192.161.0.1/iels-admin-dev/Announcement_News/Announcement_News_Search.aspx");
Thread.Sleep(2000);
driver.FindElement(By.CssSelector(".ui-datepicker-trigger:nth-child(2)")).Click();
Thread.Sleep(2000);
driver.FindElement(By.CssSelector(".ui-icon-circle-triangle-w")).Click();
Thread.Sleep(2000);
driver.FindElement(By.LinkText("1")).Click();
Thread.Sleep(2000);
driver.FindElement(By.Id("ctl00_MainContent_cmdSubmit")).Click();
Thread.Sleep(2000);
driver.FindElement(By.CssSelector(".clsDataGridAltData a:nth-child(2) > img")).Click();
Thread.Sleep(2000);
driver.FindElement(By.Id("ctl00_MainContent_cmdSubmit")).Click();
Thread.Sleep(2000);
}
This code shows System Error (As shown in the picture) but how I show in my test case.
Use try-catch block to handle any exception and if required then you can log it in catch block. You should use any assertion library for making it pass/fail.
Note: Don't write everything into Test class.
I can only think of if the URL contain "Error", it will screenshot and fail the test case .
if (url.Contains("error") || url.Contains("Error") == true)
{
Base.ErrorMessage(driver, element); // screenshot the page
throw new SystemException("Webpage throw error");
//Console.WriteLine("Got");
}
else
{
Console.WriteLine("Passed");
}
}
I am new to Selenium, and I am trying to verify that if user has successfully landed on the Home page or not. Here is the snippet:
LoginPage.GoTo();//Goes Well
LoginPage.LoginAs("UserName").WithPassword("Password").Login();//goes Well
Assert.IsTrue(HomePage.IsAt, "Failed to login");//Below is the implementation of HomePAge.IsAt
public static bool IsAt
{
get
{
var wait = new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(5));
wait.Until(x => x.SwitchTo().ActiveElement().GetAttribute("id") == "IDHere");//Here the exception is occuring.
}
var homePage = Driver().Instance.FindElement(By.Id("IDHere"));
// return true or False;
Can someone please help?
When an alert is present on your browser, it prevents you from actually doing ANYTHING else.
FYI, when I try to run my application, a window authentication pop up
comes and after that Page loads.
Well, yeah. That's the alert part from "Unhandled Alert Exception". The unhandled part, is because you didn't use any line of code to show your program how to handle the alert. Selenium goes to login page. Then tries to run this line x.SwitchTo().ActiveElement().GetAttribute("id") == "IDHere", but there is an alert on your page that prevents you from doing anything.
You have to actually try to handle it (close it or accept the message) and THEN do anything else.
It might be considered a good practice to wait for your alert to appear (since it might not appear instantly), and then, after (e.g.) 5 seconds, if there is no alert, run your code.
Try the code below to see if it resolves your problem:
public static boid WaitForAlert(bool accept)
{
//Initialize your wait.
WebDriverWait wait = new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(5));
//Wait for alert
try
{
wait.Until(ExpectedConditions.AlertIsPresent());
if (accept)
{
Driver().Instance.SwitchTo().Alert().Accept();
}
else
{
Driver().Instance.SwitchTo().Alert().Dismiss();
}
}
catch (WebDriverTimeoutException) { /*Alert did not appear, do nothing*/ }
}
And then do:
LoginPage.GoTo();
LoginPage.LoginAs("UserName").WithPassword("Password").Login();
LoginPage.WaitForAlert(true); //True to accept the alert
Assert.IsTrue(HomePage.IsAt, "Failed to login");
C#
.Net 4.5
VS 2013
NUnit 3.2.1
Webdriver and Webdriver.Support 2.53
So my issue is I am trying navigating to ebay's sandbox login page and login. This seems simple enough but I am struggling to get the page to fully load before giving me a System.Net.WebException timeout error.
Here is the link I am trying to go to
https://signin.sandbox.ebay.com/
And Here is what my code looks like that is doing this.
var EbaySandboxPage = new EbaySandboxLoginPageModel(Driver);
Driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(200));
Driver.Navigate().GoToUrl(EbaySandboxLoginPageModel.sandboxUrl);
And here is the exception that is getting thrown every time I try this in Firefox.
Test Name: VerifyItemsSold
Test FullName: POMAuctivaTest.TestSuite.PostSaleTestSuite<FirefoxDriver>.VerifyItemsSold
Test Source: c:\git\POMAuctivaTest\POMAuctivaTest.TestSuite\PostSaleTestSuite.cs : line 204
Test Outcome: Failed
Test Duration: 0:00:00.0000001
Result Message:
OneTimeSetUp: OpenQA.Selenium.WebDriverException : The HTTP request to the remote WebDriver server for URL http://localhost:7055/hub/session/80efbcbe-841d-4a53-a422-5e7498a0438b/element timed out after 60 seconds.
----> System.Net.WebException : The operation has timed out
So my question is how to I change the System.Net.WebRequest.Timeout property? I am not using an instance of webrequest. I guess webdriver is but I would imagine there is a way for me to change this value. As you can see I have already upped the SetPageLoadTimeout() value to exceed 2 min. Which in my manual testing has been more than enough.
Here was my attempt at #Buaban's solution although mine was still throwing the exception.
Driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(120));
try
{
Driver.Navigate().GoToUrl(EbaySandboxLoginPageModel.sandboxUrl);
}
catch (WebDriverException)
{
}
EbaySandboxPage.WaitForElementVisible(Driver, EbaySandboxLoginPageModel.usernameFieldSelector);
Here is what the WaitForElementVisible() method looks like.
public void WaitForElementVisible(IWebDriver driver, By element)
{
try
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(90));
wait.Until(ExpectedConditions.ElementIsVisible(element));
}
catch (WebDriverTimeoutException)
{
TakeScreenshot(Driver);
Console.Write("Test failed trying to wait for this element " + element.ToString() + " to be visible ");
}
}
Here is the definition of the usernameFieldSelector
public static By usernameFieldSelector = By.CssSelector("#userid");
So thank your #Florent and #Buaban, with your help I was able to figure out a solution to this. Ill post it here but award the answer to your Buaban as I am not sure I would have been able to get to this as quickly without your help.
Driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(30));
try
{
Driver.Navigate().GoToUrl(#"https://signin.sandbox.ebay.com/");
}
catch (Exception)
{
System.Diagnostics.Debug.WriteLine("Some resources are dead!");
}
var attempts = 0;
while (attempts < 2)
{
try
{
IWait<IWebDriver> wait = new DefaultWait<IWebDriver>(Driver);
wait.Timeout = TimeSpan.FromSeconds(20);
wait.PollingInterval = TimeSpan.FromMilliseconds(300);
wait.Until(d => d.FindElements(By.XPath("//span[text()='SIGN IN']")).Count > 0);
break;
}
catch (WebDriverException)
{
attempts++;
}
}
As Florent B. mentioned in comment, some page resources are dead. You have to ignore the exception then wait for an element on the page. See example below:
Driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(30));
try
{
Driver.Navigate().GoToUrl(#"https://signin.sandbox.ebay.com/");
}
catch (Exception)
{
System.Diagnostics.Debug.WriteLine("Some resources are dead!");
}
IWait<IWebDriver> wait = new DefaultWait<IWebDriver>(Driver);
wait.Timeout = TimeSpan.FromSeconds(10);
wait.PollingInterval = TimeSpan.FromMilliseconds(300);
wait.Until(d => d.FindElements(By.XPath("//span[text()='SIGN IN']")).Count > 0);
System.Diagnostics.Debug.WriteLine("SIGN IN textbox is loaded");
We are using Selenium with C#. We have a driver script where we instantiate the driver and then we call a testscript (automated functional testcase flow). Everything works well when the object is present on the page. We are facing issue of driver getting killed when we try and verify that certain object is not present, below is the code
Driver Script Code
//driver = new RemoteWebDriver(new Uri(uri), capabilites,TimeSpan.FromSeconds(120));
Test Script Code
public class GraphNew
{
public Boolean testGraphNew(IWebDriver driver, Logger OneLogger)
{
try
{ //Navigate to a page
try
{
driver.FindElement(By.XPath("//a[contains(text(),'Add New Claim')]")).Click();
}
catch
{
OneLogger.Log("Element is not prsent")
}
}
}
catch(Exception e)
{
OneLogger.LogException(e);
return false;
}
}
The problem is when the object is not identified (as it is not present) in the inner try, rather than going to the inner catch block, the execution proceeds to outer catch and shows exception as -
{"The HTTP request to the remote WebDriver server for URL
http://localhost:4449/wd/hub/session/35c483a6-6871-425a-a936-aeebb0742fd2/element
timed out after 120 seconds."}
and driver gets killed.
Can anyone please suggest, if we are missing something or what should be the idle way to code so that once the object is not identified, driver does not get killed and execution continues for the remaining code.
You can do something like below ...
The code is in java but it is very similar/near to C#
You can check first whether your element is present or not in your HTML DOM to prevent from error/failer of script. like below:-
(I am replacing size to lenght in below code as lenght is using in C# to determine the size of array)
if (driver.findElements("YOUR LOCATOR").Length() != 0) {
driver.findElement(YOUR LOCATOR).click();
System.out.println("element exists");
}
else{
System.out.println("element is not exists");
}
You can also use isDisplayed() method of selenium, it will return boolean value. true if element exist on DOM.
Boolean result = driver.findElement(By.xpath("//a[contains(text(),'Add New Claim')]")).isDisplayed();
if(result==true)
{
System.out.println("element exists");
}else{
System.out.println("element is not exists");
}
Refer below link if you want to know more about isDisplayed() method
http://www.softwaretestinghelp.com/webdriver-commands-selenium-tutorial-14/
Hope it will help you :)