Integration testing with Selenium Webdrive on a project with Continous Integration - selenium

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

Related

Selenium getting stuck on data:, (MS Edge)

I want to use Selenium to navigate to a website. Selenium opens up the browser but does not navigate further to the specified website URL, but gets stuck on the "data:," url. After some time time I get the following exception:
"The HTTP request to the remote WebDriver server for URL http://localhost:58504/session timed out after 60 seconds"
Note: I did not specify the 58504 port anymore, so I guess it is the default port that Selenium use?
I am programming in C# and using the following Nuget Packages:
https://www.nuget.org/packages/Selenium.WebDriver/4.1.1
https://www.nuget.org/packages/WebDriverManager/2.13.0
Here is the code:
using OpenQA.Selenium;
using OpenQA.Selenium.Edge;
using WebDriverManager;
using WebDriverManager.DriverConfigs.Impl;
using WebDriverManager.Helpers;
public void VisitWebsite()
{
IWebDriver driver = null;
try
{
new DriverManager().SetUpDriver(new EdgeConfig(), VersionResolveStrategy.MatchingBrowser);
EdgeOptions options = new EdgeOptions();
options.AddArgument("--no-sandbox);
options.AddArgument("--disable-infobars");
options.AddArgument("--disable-dev-shm-usage");
options.AddArgument("--disable-browser-side-navigation");
options.AddArgument("--disable-extensions");
options.AddArgument("--dns-prefetch-disable");
options.AddArgument("--disable-gpu");
options.AddArgument("--disable-software-rastersizer");
driver = new EdgeDriver(options);
}
catch (Exception ex)
{
throw ex;
}
driver.Navigate().GoToUrl("https://www.google.com");
}
Where does it go wrong? Thanks!
I found the answer. It seems the DeveloperToolsAvailability policy for the MSEdge browser had a value that "blocks" Selenium from working. You can read more about it here: https://learn.microsoft.com/en-us/microsoft-edge/webdriver-chromium/?tabs=c-sharp#developer-tools-availability-policy

Winium remote automation?

I am using Winium to automate a desktop application. The process is I download a file from the web and execute it. which opens the remote application. Till here everything is working fine, but I am unable to access any control of that newly launched remote Citrix application. Any help would be appreciated.
public void SetupEnv() throws InterruptedException
{
DesktopOptions options = new DesktopOptions();
options.setApplicationPath("C:\\Users\\ajinkya\\Downloads\\launch.ica");
try
{
driver = new WiniumDriver(new URL("http://localhost:9999"), options);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
Thread.sleep(5000);
driver.findElementByClassName("Transparent Windows Client").click();
Thread.sleep(5000);
}
Maybe you should try something like this:
WebElement window = driver.findElementByName("abcd.exe");
WebElement menuItem = window.findElement(By.name ("Find Item"));
menuItem.click();

How to run selenium tests without the need to launch web app first

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.

Handling Browser Authentication using Selenium

Does anyone know about handling Browser Authentication using Selenium or any other tool during automation?
EDIT in 2015:
This answer is outdated. WebDriver nowadays supports authentication! See How to handle authentication popup with Selenium WebDriver using Java
Original answer:
This is not handled very well by Selenium.
You can try using http://username:password#example.com/yourpage
instead of just http://example.com/yourpage
However, as far as I know, Firefox will still pop up a browser dialog requesting a confirmation.
You can try Robot if you're using Java (or any similar tool like AutoIt).
You could use driver.manage().addCookie() if you're using WebDriver.
Or a custom FirefoxProfile that has already passed the authentication once.
I spent days on this - literally.
Trying to get past browser level authentication within my company network to hit an application.
The solution was to use the 'unsername:password#' component within the URL, BUT to add a forward slash at the end of the login URL.
So total login URL looks like this (note the '/' after yourpage):
http://username:password#example.com/yourpage/
Works with Watir, Capybara and Selenium Webdriver.
Everything I have read on the Web didn't help me. So before making a request, like this:
driver.get(url);
you have to run a new thread like this:
RunScript runScript = new RunScript();
runScript.start();
In this case you are free to input login and password on another thread of follwing class
public class RunScript extends Thread {
#Override
public void run() {
try {
File file = new File("D:\\jacob-1.18-x86.dll");
System.setProperty(LibraryLoader.JACOB_DLL_PATH, file.getAbsolutePath());
AutoItX autoIt = new AutoItX();
Thread.sleep(2000);
autoIt.winActivate("yourWindowName", "");
autoIt.winWaitActive("yourWindowName");
if (autoIt.winExists("yourWindowName")) {
autoIt.send("username{TAB}", false);
autoIt.send("password{Enter}", false);
}
}
} catch (InterruptedException ex) {
//
}
}
}
All the hacks via auto-it, sikuli, etc. just wasting your time when you'll run it in your CI solution, using several browser types / OS / Version / Resolutions etc.
The way to do it correctly is to identify the authentication actual method and perform a login using Rest protocol for instance.
I used it to get the JSESIONID cookie and insert it to the selenium driver.
hint on that: go to a non-exiting url of the domian first, then set the cookie, then go to the required url - you are logged-in.
use: rest client authentication to get the JSESSION ID
and With this information:
browser().navigate(foo.getUrl()+"non-exiting-url");
//the information got from the rest client login:
Cookie cookie = new Cookie(name, value, domain, path, expiry, isSecure, isHttpOnly);
try {
driver.manage().addCookie(cookie);
} catch (Exception e) {
System.out.println(e.toString());
}
browser().navigate(foo.getUrl());
you can use auto IT script to handle this problem
WinWaitActive("[CLASS:Chrome_WidgetWin_1]", "", time)
Send("user")
Send("{TAB}")
Send("pass")
Send("{ENTER}")
with Chrome 70 and other versions :
http://username:password#example.com/yourpage
You can use Java Robot class with Selenium 2 /Selenium WebDriver using Firefox
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:9990");
WebElement myDynamicElement = driver.findElement(By.id("app"));
Alert alert = driver.switchTo().alert();
try {
Robot robot = new Robot();
alert.sendKeys("username");
robot.keyPress(KeyEvent.VK_TAB);//go to password feild
robot.keyPress(KeyEvent.VK_P);
robot.keyPress(KeyEvent.VK_A);
robot.keyPress(KeyEvent.VK_S);
robot.keyPress(KeyEvent.VK_S);
robot.keyPress(KeyEvent.VK_ENTER);
} catch (AWTException e) {
e.printStackTrace();
}
}
Using Selenium with Robot
http://docs.oracle.com/javase/1.5.0/docs/api/java/awt/Robot.html

How to set up Selenium to work with Visual Studio .NET using C#?

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
}
}