I'm running into an issue where Selenium Chrome Driver will hang the unit test process if the driver fails to initialize. See the below code. In this case the driver fails to initialize because the chrome version was updated. However this hangs the unit test process as the conhost and chrome instance are still running in the background. Anyone know how to get around this programmatically. This really becomes an issue on Azure Devops CI where DotNetCoreCLI#2 will not terminate if there are running processed spawned by dotnet test still running.
using System;
using System.Diagnostics;
using OpenQA.Selenium.Chrome;
namespace Tests.Fixtures
{
/// <summary>
/// Test fixture which provides Chrome web driver instance.
/// </summary>
public sealed class ChromeDriverFixture : IDisposable
{
public ChromeDriverFixture()
{
var chromeOptions = new ChromeOptions();
if (!Debugger.IsAttached)
{
chromeOptions.AddArguments("headless");
}
chromeOptions.AcceptInsecureCertificates = true;
Browser = new ChromeDriver(chromeOptions); //failure here hangs dotnet test
}
/// <summary>
/// Chrome web browser instance
/// </summary>
public ChromeDriver Browser { get; }
public void Dispose()
{
Browser?.Dispose();
}
}
}
Related
I have created a java/selenium/cucumber automation framework with 4 feature files each testing different functional area's.
I can run each of these within Eclipse as feature files and they all run fine.
However I am trying to figure out how I can run them all as a JUnit test so that I can generate the extent reports.
I run the mainRunner class as a Junit test like ..
The first feature runs fine but then the next three do not. A chrome browser is opened for each of these but
the site is not navigated to. The error
'org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()?'
is shown in the console logs.
So is this issue to do with how I have set my feature files up to use the startBrowser, initBrowser and closeBrowser methods. Which are
defined in a seperate class 'BrowserInitTearDownStepDefinitions'?
All my feature files look like ..
Feature: Update a Computer in Database
-- left out details
#StartBrowser
Scenario: Start browser session
When I initialize driver
Then open browser
#MyTest4
Scenario Outline: Update a computer
-- left our details
Examples:
-- left out details
#CloseBrowser
Scenario: Close the browser
Then close browser
I have had a look at the other posts related to this message that reference the same error, but can't see a clear cut solution.
As the error would indicate I seem to be quitting the driver but then not reinitialising it for the next test. Although Im not sure why this
would be the case given that each feature file has the #StartBrowser and #CloseBrowser tags which should execute these methods. Below is my BrowserInitTearDownStepDefinitions class.
public class BrowserInitTearDownStepDefinitions {
//Initialises Chrome browser
#When("^I initialize driver$")
public void initializeDriver() {
System.out.println("initializeDriver runs");
System.setProperty("webdriver.chrome.driver","C:\\xxxx\\CucumberAutomationFramework\\src\\test\\java\\cucumberAutomationFramework\\resources\\chromedriver.exe");
WebDriverUtils.setDriver(new ChromeDriver());
}
//Opens Chrome browser and clicks in search input box
#Then("^open browser$")
public void openBrowser() {
System.out.println("Open Browser runs");
WebDriver driver = WebDriverUtils.getDriver();
driver.manage().window().maximize();
driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(60, TimeUnit.SECONDS);
driver.get("https://computer-database.gatling.io/computers");
}
//Closes browser after all scenarios run and deletes cookies
#Then("^close browser$")
public void closeBrowser() {
System.out.println("Close Browser runs");
WebDriver driver = WebDriverUtils.getDriver();
driver.manage().deleteAllCookies();
driver.quit();
driver =null;
}
}
I create a new instance of the webdriver within my stepDefs file with ..
WebDriver driver = WebDriverUtils.getDriver()
The webdriver utils class code is ..
package cucumberAutomationFramework.utilityClasses;
import org.openqa.selenium.WebDriver;
public class WebDriverUtils {
private static WebDriver driver;
public static void setDriver(WebDriver webDdriver) {
if (driver == null) {
driver = webDdriver;
}
}
public static WebDriver getDriver() {
if (driver == null) {
throw new AssertionError("Driver is null. Initialize driver before calling this method.");
}
return driver;
}
}
Any advice would be much appreciated. Thanks.
I have an MVC web application in development.
Currently to run my Selenium browser tests I have to right click on one of the views and choose "View In Browser". This initiates the web application and then I can run my browser tests.
Is there a way I can effectively "launch" the website as part of the setup() and teardown() of the test?
e.g.
[TestFixture]
public class MainNavigationTests
{
// here I have to predetermine the localhost port that Visual Studio uses
const string host = "http://localhost:57237/";
IWebDriver driver = new FirefoxDriver();
[Test]
public void canBrowseToHomePage()
{
driver.Url = host;
Assert.AreEqual("Index - My web app", driver.Title);
var homePageLink = driver.FindElement(By.ClassName("navbar-brand"));
homePageLink.Click();
Assert.IsTrue(driver.PageSource.Contains("The home page of the web app"));
}
}
Thanks.
selenium grid connection with auto it not working ?
#daluudaluu/PartialSeleniumGridIntegrationWithAutoItExample.java
Last active a year ago
Embed
Download ZIP
Code Revisions 2 Forks 1
Partial Selenium Grid integration support with tools like AutoIt, Sikuli, etc.
Raw
PartialSeleniumGridIntegrationWithAutoItExample.java
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.*;
import java.net.URL;
public class DemoTest {
public WebDriver driver;
public DesiredCapabilities capabilities;
#Before
public void setUp() throws Exception {
capabilities = DesiredCapabilities.firefox();
driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub" ), capabilities);
}
#After
public void tearDown() throws Exception {
driver.quit();
}
#Test
public void test() throws Exception {
// Use RemoteWebDriver, grab actual node host info
driver.get("http://www.google.com");
String sessionId = ((RemoteWebDriver) driver).getSessionId().toString();
//grid info extractor from: https://gist.github.com/krmahadevan/1766772
String nodeHost = GridInfoExtracter.getHostNameAndPort("localhost", 4444, sessionId)[0];
System.out.println("Extracted hostname: "+nodeHost);
// Now use node host info to handle running AutoIt on that specific node, assuming all needed files deployed to all nodes
// Case 1 - PSExec.exe from Windows host (that is executing this Selenium code) to Selenium node that is Windows host
//String psexecCmd = "C:\\LocalMachinePathTo\\psexec.exe \\\\%s -u %s -p %s -i C:\\GridNodeMachinePathTo\\autoitCompiledScript.exe";
//Process p = Runtime.getRuntime().exec(String.format(psexecCmd,nodeHost,"jdoe","hisPassword"));
//p.waitFor();
// Case 2 - winexe from *nix host (that is executing this Selenium code) to Selenium node that is Windows host
// Example reference: http://secpod.org/blog/?p=661
//String winexeCmd = "/LocalMachinePathTo/winexe -U domainName/jdoe%hisPassword //"+nodeHost+" C:\\GridNodeMachinePathTo\\autoitCompiledScript.exe";
//Process p = Runtime.getRuntime().exec(winexeCmd);
//p.waitFor();
// Case 3 - have SSH installed on Windows-based Selenium nodes, now just connect to node host via SSH to run a command, i.e. execute AutoIt script binary
// no sample code given for Java, but maybe this gives you ideas on Java SSH connection:
// http://stackoverflow.com/questions/995944/ssh-library-for-java
// Case 4 - if you have implemented a custom web service (XML-RPC/SOAP/REST) for AutoIt that listens for requests/commands
// just connect to it via (Java) HTTP library to "http://"+nodeHost+"/someWebServicePath/someCommand" (via GET or POST)
// details not covered, this is just an example. Most people won't be taking this route due to customization & complexity in
// building the web service first
// Case 5 - using AutoItDriverServer that is also running on Selenium nodes
//DesiredCapabilities autoitCapabilities = new DesiredCapabilities();
//autoitCapabilities.setCapability("browserName", "AutoIt");
//WebDriver autoitDriver = new RemoteWebDriver(new URL("http://"+nodeHost+":4723/wd/hub"), autoitCapabilities);
//autoitDriver.findElement(By.id("133")).click();
//and whatever other AutoItX commands to call that you normally have in the AutoIt script that you compile into binary
//for more ideas on AutoIt commands issued as WebDriver commands with respect to Selenium integration, see:
//https://github.com/daluu/AutoItDriverServer/blob/master/sample-code/SeleniumIntegrationWithAutoItDriver.py
//or if you are old school, and want to do that same approach even with AutoItDriverServer,
// assuming you have first set AutoItScriptExecuteScriptAsCompiledBinary to True in autoit_options.cfg file before starting AutoItDriverServer:
//((JavascriptExecutor) autoitDriver).executeScript("C:\\GridNodeMachinePathTo\\autoitCompiledScript.exe");
// Case for Sikuli integration, using https://github.com/enix12enix/sikuli-remote-control
//RemoteScreen rs = new RemoteScreen(nodeHost);
//rs.setMinSimilarity(0.9);
//rs.click("D://test.png");
}
}
I have a question. When I run a selenium webdrive integration test on my webb app, the web app must be running, because selenium browses to a debug version of my app (which is launched in IIS Express from Visual Studios). The problem is that if I want to achive this using CI development practice, on a dedicated CI machine, that machine have to be running a version of my webb app that's based on the current mainline code from subversion directory.
The code base constantly changes, and so theoretically you could run and restart the web app on the CI machine with code from the subversion dir, so that the tests always cover the latests commit.
Each individual developer on the project doesn't have any problems running the integration tests on the pre-commit build/test. And the unit tests can be handled with Cruise Control, MsBuild, subversion and NUnit working together. But running the integration tests (selenium webdrive test) on the integration server automatically with dynamic codebase is what I'm wondering about. Does anyone have experience of this, perhaps examples?
EDIT:
Arran has suggested that you can utilize a dedicated test enviroment to solve this problem. I don't quite practically understand how dedicated test enviroments works, and how practically it would works to solve this problem. The answers received doesn't seems to be automatable to the point where it can be implemented with the concurrent integration flow of Continous Integration. Does anyone else have any experience or thoughts on the matter?
This is the Selenium Webdrive code for reference:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.Support;
using OpenQA.Selenium.Support.UI;
using NUnit.Framework;
using OpenQA.Selenium.Firefox;
using System.Threading.Tasks;
using System.Threading;
namespace ChatProj.Tests
{
[TestFixture]
class WebDriverTestClass
{
private IWebDriver _driver;
private StringBuilder verificationErrors;
private string baseURL;
private bool acceptNextAlert = true;
[SetUp]
public void SetUp()
{
_driver = new FirefoxDriver();
baseURL = "http://localhost:59932/";
verificationErrors = new StringBuilder();
}
[TearDown]
public void TeardownTest()
{
try
{
_driver.Quit();
}
catch (Exception)
{
// Ignore errors if unable to close the browser
}
Assert.AreEqual("", verificationErrors.ToString());
}
[Repeat(2)]
[Test]
public void TestFirefox()
{
_driver.Navigate().GoToUrl(baseURL + "");
IWebElement userNameInput = _driver.FindElement(By.Name("UserName"));
userNameInput.SendKeys("Svenneglenne");
IWebElement passwordInput = _driver.FindElement(By.Name("Password"));
passwordInput.SendKeys("password");
_driver.FindElement(By.CssSelector("input[type=\"submit\"]")).Click();
WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(10));
IWebElement messageBox = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.Id("message"));
});
IWebElement adminMessageWaiter = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.XPath("//ul[#id='discussion']/li[1]"));
});
System.Console.Out.WriteLine("STUFF");
//IWebElement query = driver.FindElement(By.Id("message"));
String textSnippet = "This is a selenium test";
adminMessageWaiter.SendKeys("");
messageBox.SendKeys("This is a selenium test");
IWebElement waitForJava = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.XPath("//ul[#id='discussion']/li[1]"));
});
//Thread.Sleep(2000);
WaitForPageLoad(10);
_driver.FindElement(By.Id("sendmessage")).Click();
//Thread.Sleep(2000);
_driver.FindElement(By.LinkText("Logg")).Click();
IWebElement loggWaiter = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.XPath("//div[#id='body']/section/table/tbody/tr/td[2]"));
});
Assert.AreEqual(textSnippet, loggWaiter.Text);
_driver.FindElement(By.LinkText("MPM Graph")).Click();
Thread.Sleep(2000);
}
public void WaitForPageLoad(int maxWaitTimeInSeconds)
{
string state = string.Empty;
try
{
WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(maxWaitTimeInSeconds));
//Checks every 500 ms whether predicate returns true if returns exit otherwise keep trying till it returns ture
wait.Until(d =>
{
try
{
state = ((IJavaScriptExecutor)_driver).ExecuteScript(#"return document.readyState").ToString();
}
catch (InvalidOperationException)
{
//Ignore
}
catch (NoSuchWindowException)
{
//when popup is closed, switch to last windows
_driver.SwitchTo().Window(_driver.WindowHandles.Last());
}
//In IE7 there are chances we may get state as loaded instead of complete
return (state.Equals("complete", StringComparison.InvariantCultureIgnoreCase) || state.Equals("loaded", StringComparison.InvariantCultureIgnoreCase));
});
}
catch (TimeoutException)
{
//sometimes Page remains in Interactive mode and never becomes Complete, then we can still try to access the controls
if (!state.Equals("interactive", StringComparison.InvariantCultureIgnoreCase))
throw;
}
catch (NullReferenceException)
{
//sometimes Page remains in Interactive mode and never becomes Complete, then we can still try to access the controls
if (!state.Equals("interactive", StringComparison.InvariantCultureIgnoreCase))
throw;
}
catch (WebDriverException)
{
if (_driver.WindowHandles.Count == 1)
{
_driver.SwitchTo().Window(_driver.WindowHandles[0]);
}
state = ((IJavaScriptExecutor)_driver).ExecuteScript(#"return document.readyState").ToString();
if (!(state.Equals("complete", StringComparison.InvariantCultureIgnoreCase) || state.Equals("loaded", StringComparison.InvariantCultureIgnoreCase)))
throw;
}
}
}
}
the basic answer for your test automation automation is to run it in your gitlab CI
i dont undrestand what do you mean by running on "to be running a version of my webb app"
is this version of your webb app has a spicific url or domaine ?
if not then the test automation project is continous integration every version of your app the test project gonna run on it , if it has upgrade , then you need to upgrade your test automation to follow the flow
i hope thats help
I tried to google, but there are many different ways to work with Selenium. I'm using:
- Windows 2003 Server
- Visual Studio 2008
- Selenium IDE installed through Firefox
- NUnit 2.5 is copied into C:\
- Selenium RC is copied into C:\
First I created a Library Project using C#.
And this my class :
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NUnit.Framework;
using Selenium;
namespace SeleniumTest
{
[TestFixture]
public class NewTest
{
private ISelenium selenium;
private StringBuilder verificationErrors;
[SetUp]
public void SetupTest()
{
selenium = new DefaultSelenium( "localhost", 4444, "*iexplore", "http://localhost:4444" );
selenium.Start();
verificationErrors = new StringBuilder();
}
[TearDown]
public void TeardownTest()
{
try
{
selenium.Stop();
}
catch( Exception )
{
// Ignore errors if unable to close the browser
}
Assert.AreEqual( "", "" );
}
[Test]
public void TheNewTest()
{
selenium.Open( "/google.com" );
}
}
}
Next add all references from the C:\Selenium RC\selenium-dotnet-client-driver-1.0.1
Compiled the Library Project, succeeded. No errors.
Run NUnit.exe, now errors :(
SeleniumTest.NewTest.TheNewTest:
Selenium.SeleniumException : XHR
ERROR: URL =
http://localhost:4444/google.com
Response_Code = 403 Error_Message =
Forbidden+for+Proxy
You are getting the Forbidden error because you are setting the baseURL to that of Selenium RC. You need to set it to http://www.google.com and then in your test would look like
[Test]
public void TheNewTest()
{
selenium.Open( "/" );
}
or you need to change your test to
[Test]
public void TheNewTest()
{
selenium.Open( "http://www.google.com" );
}
to setup ide for selenium in conjunction with c# is to use visual studio express. And you can nUnit as the testing framework. Below links provide you more details
How to setup C#,nUnit and selenium client drivers on VSExpress for Automated tests
Creating Basic Selenium web driver test case using Nunit and C#
Create Unit testing project
Add library project to your solution.
right click on library project select NuGet package option.
search selenium install first two options selenium and selenium support class.
Also download chrome driver, IEDriver, gecko driver if you want to perform cross-browser testing.
create the test class and test method in the unit testing project.
[TestClass]
// ReSharper disable once InconsistentNaming
public class Test class
{
[TestMethod]
public void LoginTest()
{
// code
}
}