I have 2 methods in my testcase.
method 1 :
[TestMethod]
public void AddUser()
{
firefox = new OpenQA.Selenium.Firefox.FirefoxDriver();
firefox.Navigate().GoToUrl("http://<code><code>domain</code></code>:44220/learn-language-online/");
firefox.FindElement(By.LinkText("Sign In")).Click();
firefox.FindElement(By.CssSelector("span.watermarkify-watermark-inner")).Click();
firefox.FindElement(By.Id("Username")).Clear();
firefox.FindElement(By.Id("Username")).SendKeys("rachana#prakashinfotech.com");
firefox.FindElement(By.Id("Password")).Clear();
firefox.FindElement(By.Id("Password")).SendKeys("123456");
firefox.FindElement(By.XPath("(//a[contains(text(),'Sign In')])[2]")).Click();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(90));
OpenQA.Selenium.Interactions.Actions builder = new OpenQA.Selenium.Interactions.Actions(firefox);
IWebElement elem = firefox.FindElement(By.ClassName("icon"));
builder.MoveToElement(elem).Build().Perform();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(40));
firefox.FindElement(By.LinkText("Manage Users")).Click();
firefox.FindElement(By.Id("FirstName")).Clear();
firefox.FindElement(By.Id("FirstName")).SendKeys("Kashyap");
firefox.FindElement(By.Id("LastName")).Clear();
firefox.FindElement(By.Id("LastName")).SendKeys("Khanna");
firefox.FindElement(By.Id("Password")).Clear();
firefox.FindElement(By.Id("Password")).SendKeys("123");
firefox.FindElement(By.Id("ConfirmPassword")).Clear();
firefox.FindElement(By.Id("ConfirmPassword")).SendKeys("123");
firefox.FindElement(By.Id("Email")).Clear();
firefox.FindElement(By.Id("Email")).SendKeys("kashyap#gmail.com");
new SelectElement(firefox.FindElement(By.Id("Languages"))).SelectByText("India");
new SelectElement(firefox.FindElement(By.Id("DifficultyLevels"))).SelectByText("Level 1");
new SelectElement(firefox.FindElement(By.Id("MaturityLevels"))).SelectByText("Everyone");
firefox.FindElement(By.XPath("//a[2]/span")).Click();
}
method 2 :
[TestMethod]
public void AssignCourse()
{
firefox = new OpenQA.Selenium.Firefox.FirefoxDriver();
firefox.Navigate().GoToUrl("http://<code>domain</code>:44220/Home/Index");
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(90));
OpenQA.Selenium.Interactions.Actions builder = new OpenQA.Selenium.Interactions.Actions(firefox);
IWebElement elem = firefox.FindElement(By.ClassName("icon"));
builder.MoveToElement(elem).Build().Perform();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(90));
firefox.FindElement(By.LinkText("Manage Users")).Click();
firefox.FindElement(By.XPath("//div[#id='divUser_84700']/div[2]/div/div/a[2]")).Click();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(120));
firefox.FindElement(By.XPath("(//img[#alt='Delete'])[5]")).Click();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(80));
firefox.FindElement(By.XPath("//a[#id='addCourses']/span")).Click();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(80));
firefox.FindElement(By.CssSelector("li.class_73.courseItem > a > span.detail")).Click();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(40));
firefox.FindElement(By.CssSelector("li.class_87.courseItem > a > span.detail")).Click();
firefox.FindElement(By.Id("btnAddCourse")).Click();
}
now when my 1st method get tested and it moves to 2nd method session of uesrid and password not get maintained and because of that i am not able to navigate my url to http://domain:44220/Home/Index. so how to solve the issue of authentication.
Specify firefox = new OpenQA.Selenium.Firefox.FirefoxDriver();
in a setup method may be in #BeforeTest, it makesures that there is only one instance of firefoxdriver is running for the entire set of tests.
You have at least two options.
You can use cookie:
Cookie ck = new Cookie("name", "value");
driver.manage().addCookie(ck);
(code in java)
Operation on cookie - http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/Cookie.html
You can use Page Object Pattern it is best practice to create test code. You can then call method to log in from #Before or #BeforeTest annotation etc. I encourage you to reaad about Page Object Pattern because it helps writing maintanable, and cleaner test code
WebDriver creates a new Firefox profile every time you launch the browser so any cookies or whatever session parameters are lost. Meaning, you have to log in again. That would be:
private WebDriver firefox;
private void LogIn()
{
firefox = new OpenQA.Selenium.Firefox.FirefoxDriver();
firefox.Navigate().GoToUrl("http://<code><code>domain</code></code>:44220/learn-language-online/");
firefox.FindElement(By.LinkText("Sign In")).Click();
firefox.FindElement(By.CssSelector("span.watermarkify-watermark-inner")).Click();
firefox.FindElement(By.Id("Username")).Clear();
firefox.FindElement(By.Id("Username")).SendKeys("rachana#prakashinfotech.com");
firefox.FindElement(By.Id("Password")).Clear();
firefox.FindElement(By.Id("Password")).SendKeys("123456");
firefox.FindElement(By.XPath("(//a[contains(text(),'Sign In')])[2]")).Click();
}
[TestMethod]
public void AddUser()
{
LogIn();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(90));
OpenQA.Selenium.Interactions.Actions builder = new OpenQA.Selenium.Interactions.Actions(firefox);
IWebElement elem = firefox.FindElement(By.ClassName("icon"));
builder.MoveToElement(elem).Build().Perform();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(40));
firefox.FindElement(By.LinkText("Manage Users")).Click();
firefox.FindElement(By.Id("FirstName")).Clear();
firefox.FindElement(By.Id("FirstName")).SendKeys("Kashyap");
firefox.FindElement(By.Id("LastName")).Clear();
firefox.FindElement(By.Id("LastName")).SendKeys("Khanna");
firefox.FindElement(By.Id("Password")).Clear();
firefox.FindElement(By.Id("Password")).SendKeys("123");
firefox.FindElement(By.Id("ConfirmPassword")).Clear();
firefox.FindElement(By.Id("ConfirmPassword")).SendKeys("123");
firefox.FindElement(By.Id("Email")).Clear();
firefox.FindElement(By.Id("Email")).SendKeys("kashyap#gmail.com");
new SelectElement(firefox.FindElement(By.Id("Languages"))).SelectByText("India");
new SelectElement(firefox.FindElement(By.Id("DifficultyLevels"))).SelectByText("Level 1");
new SelectElement(firefox.FindElement(By.Id("MaturityLevels"))).SelectByText("Everyone");
firefox.FindElement(By.XPath("//a[2]/span")).Click();
}
[TestMethod]
public void AssignCourse()
{
LogIn();
firefox.Navigate().GoToUrl("http://<code>domain</code>:44220/Home/Index");
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(90));
OpenQA.Selenium.Interactions.Actions builder = new OpenQA.Selenium.Interactions.Actions(firefox);
IWebElement elem = firefox.FindElement(By.ClassName("icon"));
builder.MoveToElement(elem).Build().Perform();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(90));
firefox.FindElement(By.LinkText("Manage Users")).Click();
firefox.FindElement(By.XPath("//div[#id='divUser_84700']/div[2]/div/div/a[2]")).Click();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(120));
firefox.FindElement(By.XPath("(//img[#alt='Delete'])[5]")).Click();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(80));
firefox.FindElement(By.XPath("//a[#id='addCourses']/span")).Click();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(80));
firefox.FindElement(By.CssSelector("li.class_73.courseItem > a > span.detail")).Click();
firefox.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(40));
firefox.FindElement(By.CssSelector("li.class_87.courseItem > a > span.detail")).Click();
firefox.FindElement(By.Id("btnAddCourse")).Click();
}
Related
I've been trying to implement headless browser to my tests and I'm getting an error message that shows me this: "Unable to locate element: {"method":"id","selector":"my_id"}". This is the code that I'm working with:
[TestFixture]
class ClientesSystemTest
{
private ChromeOptions options;
private NewClientesPage page;
private IWebDriver driver;
public ClientesSystemTest()
{
options = new ChromeOptions();
options.AddArgument("--headless");
driver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), options);
page = new NewClientesPage(driver);
}
[Test]
public void CadastraCliente()
{
page.Visita();
page.Cadastra("Paulo", "Guedes", "00870021087", "Rua abcdwxyz, 14", 15);
driver.Close();
}
}
and this is the Cadastra method.:
public void Cadastra(string nome, string sobrenome, string cpf, string endereco, int idade)
{
IWebElement nomeCliente = driver.FindElement(By.Id("Nome"));
IWebElement sobrenomeCliente = driver.FindElement(By.Id("Sobrenome"));
IWebElement cpfCliente = driver.FindElement(By.Id("CPF"));
IWebElement enderecoCliente = driver.FindElement(By.Id("Endereco"));
IWebElement idadeCliente = driver.FindElement(By.Id("Idade"));
IWebElement estadoCivilCliente = driver.FindElement(By.Name("EstadoCivil"));
driver.FindElement(By.CssSelector("[value=Divorciado]")).Click();
nomeCliente.SendKeys(nome);
sobrenomeCliente.SendKeys(sobrenome);
cpfCliente.SendKeys(cpf);
enderecoCliente.SendKeys(endereco);
idadeCliente.SendKeys(idade.ToString());
nomeCliente.Submit();
}
I've tried everything by this point. The test runs normally without the headless feature. Does anyone have a solution for this error? Thanks.
My guess would be that your site shows different elements depending on the browser resolution. Typically the headless browser is a smaller setting so I'd make sure it's set to the same size you use when you test non-headless.
I'm new to Selenium, TestNG and Stackoverflow.
After sendkeys, I want to do some validation. If the validation is true, then the assert is true. I know this is not the right way to write the Assert method.
WebDriver driver;
#DataProvider(name= "testdata")
public static Object[][] loginData(){
return new Object[][]{{"username1", "123"}, {"username2", "4211"}};
}
#BeforeTest
public void configure(){
....
}
#Test(dataProvider = "testdata")
public void testmethod(String uname, String password){
WebElement usernameTextbox = driver.findElement(By.id("username"));
usernameTextbox.sendKeys(uname);
WebElement passwordTextbox = driver.findElement(By.id("username"));
passwordTextbox.sendKeys(uname);
driver.manage().timeouts().implicitlyWait(2, TimeUnit.MICROSECONDS);
Assert.assertTrue(if(usernameTextbox.contains("[a-zA-Z0-9]+") && passwordTextbox.contains("[0-9]+") == true));
PS: Any inputs will be appreciated.
Try implementing explicit wait in Your code. What that mean, is that You wait for some condition to be set, here is example how to manage this:
But my suggestion is that You assert if there are some error messages (labels, span, or whatever that appears saying something is wrong with email or pass)
So here is how I would do it:
WebDriver driver;
#DataProvider(name= "testdata")
public static Object[][] loginData(){
return new Object[][]{{"username1", "123"}, {"username2", "4211"}};
}
#BeforeTest
public void configure(){
driver = new WebDriver();
driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS); //this is wait which will wait until driver throws exception (that is not found eg."NoSuchElementException")
}
#Test(dataProvider = "testdata")
public void testmethod(String uname, String password){
WebElement usernameTextbox = driver.findElement(By.id("usernameID"));
usernameTextbox.sendKeys(uname);
WebElement passwordTextbox = driver.findElement(By.id("passwordID"));
passwordTextbox.sendKeys(password); //here is where You've sent wrong param
// if You know You will get error label or something use this
WebDriverWait wait = new WebDriverWait(driver, 10); //wait for max 10 sec, and wait for error element defined bellow
WebElement errorElement = wait.until(ExpectedConditions. presenceOfElementLocated(By.id("someErrorElementId"))); //(or ExpectedConditions.textToBePresentInElement(..)), see what better suites You
// If You're expecting error than use this assert
Assert.assertTrue(errorElement.isDisplayed(),"There should be error message!")
// but If You're expecting that there should not be any error than use this assert
Assert.assertFalse(errorElement.isDisplayed(),"There shouldn't be no error messages!")
}
tweak this code, but basicaly this is the logic.
So to try to answer the original question your code could look like below:
1. Using the getAttribute("value")
2. Building the assertion - you don't need to wrap the condition in an if as the contains() function will return true or false for you:
WebDriver driver;
#DataProvider(name= "testdata")
public static Object[][] loginData(){
return new Object[][]{{"username1", "123"}, {"username2", "4211"}};
}
#BeforeTest
public void configure(){
....
}
#Test(dataProvider = "testdata")
public void testmethod(String uname, String password){
WebElement usernameTextbox = driver.findElement(By.id("username"));
usernameTextbox.sendKeys(uname);
WebElement passwordTextbox = driver.findElement(By.id("username"));
passwordTextbox.sendKeys(uname);
driver.manage().timeouts().implicitlyWait(2, TimeUnit.MICROSECONDS);
Assert.assertTrue(usernameTextbox.getAttribute("value").contains("[a-zA-Z0-9]+") && passwordTextbox.getAttribute("value").contains("[0-9]+"));
HTH
As per your question just after invoking sendKeys() you want to do some assertions.
At this point it is worth to mention that when you invoke sendKeys() on a <input> node/tag/field the HTML DOM is not immediately updated with the value / characters which you have just entered in majority of the cases (of-coarse there are exceptional cases). Moving forward when you invoke click() or submit()on a <button> or similar <input> element, the associated onclick event of this <input> element updates the HTML DOM and the value / characters previously sent through sendKeys() are adjusted within the HTML DOM.
Unless the value / characters are not accommodated within the DOM Tree Selenium won't be able to interact with them.
As per your code block, you have populated the passwordTextbox field with the String value of uname as follows :
passwordTextbox.sendKeys(uname);
This value / characterset is still volatile and editable (can be overwritten/cleared/deleted) as follows :
passwordTextbox.clear();
passwordTextbox.sendKeys("Emma E");
Essentially, Assert methods can be invoked on text those are part of the HTML DOM. As an example you can use the following Assert for a Page Heading, Table Heading, etc :
Assert.assertTrue(if(pageHeaderElement.contains("[a-zA-Z0-9]+") && tableHeaderElement.contains("[0-9]+") == true));
Our team uses TestNG to run some tests in Selenium. We need to be able to run a given test on 3 different browsers (Chrome, Firefox, and [sadly] IE). We have a browser parameter on our base test class and really we could just declare three tests, one each for each browser; however, we'd really like to just be able to specify the browser value as "Standard 3" and have that run the test on each browser automatically.
So, I've built a class that implements ISuiteListener and attempts to create the new tests on the fly. However, any way I try to add tests fails. That is, no new tests I try to add will be executed by the suite. It's like nothing I did actually changed anything.
Here's my code:
public class Standard3BrowserSuiteListener implements ISuiteListener {
#Override
public void onStart(final ISuite suite) {
final XmlSuite xmlSuite = suite.getXmlSuite();
final Map<String, String> suiteParameters = xmlSuite.getParameters();
final List<XmlTest> currentTests = new ArrayList<XmlTest>(xmlSuite.getTests());
final ArrayList<XmlTest> testsToRun = new ArrayList<XmlTest>(currentTests.size());
for (final XmlTest test : currentTests) {
final Browser browser;
final Map<String, String> testParameters = test.getAllParameters();
{
String browserParameter = testParameters.get("browser");
if (browserParameter == null) {
browserParameter = suiteParameters.get("browser");
}
browser = Util.Enums.getEnumValueByName(browserParameter, Browser.class);
}
if (browser == Browser.STANDARD_3) {
XmlTest nextTest = cloneTestAndSetNameAndBrowser(xmlSuite, test, testParameters, "Chrome");
xmlSuite.addTest(nextTest);
testsToRun.add(nextTest); // alternate I've tried to no avail
nextTest = cloneTestAndSetNameAndBrowser(xmlSuite, test, testParameters, "Firefox");
xmlSuite.addTest(nextTest);
testsToRun.add(nextTest); // alternate I've tried to no avail
nextTest = cloneTestAndSetNameAndBrowser(xmlSuite, test, testParameters, "IE");
xmlSuite.addTest(nextTest);
testsToRun.add(nextTest); // alternate I've tried to no avail
} else {
testsToRun.add(test);
}
}
// alternate to xmlSuite.addTest I've tried to no avail
testsToRun.trimToSize();
currentTests = xmlSuite.getTests();
currentTests.clear();
currentTests.addAll(testsToRun);
}
private XmlTest cloneTestAndSetNameAndBrowser(final XmlSuite xmlSuite, final XmlTest test,
final Map<String, String> testParameters, final String browserName) {
final XmlTest nextTest = (XmlTest) test.clone();
final Map<String, String> nextParameters = new TreeMap<String, String>(testParameters);
nextParameters.put("browser", browserName.toUpperCase());
nextTest.setName(browserName);
final List<XmlClass> testClasses = new ArrayList<XmlClass>(test.getClasses());
nextTest.setClasses(testClasses);
return nextTest;
}
#Override
public void onFinish(final ISuite suite) {}
}
How can I replace the test with the browser value "Standard 3" with 3 tests and have it run properly? Thanks!
Here's what you need to do :
Upgrade to the latest released version of TestNG.
Build an implementation of org.testng.IAlterSuiteListener
Move your implementation that you created in ISuiteListener into this listener implementation.
Wire in this listener via the <listeners> tag in your suite XML File (or) via ServiceLoaders (As described in the javadocs of this interface)
To test some of the legacy pages I need to execute few test cases against IE8. These same testcases run efficiently against IE10/11, FF, Chrome without any issue.
public void TypePassword(string password)
{
var element = new WebDriverWait(Driver, TimeSpan.FromSeconds(10)).Until(
ExpectedConditions.ElementIsVisible(By.XPath("//input[#id='txtPassword']")));
//I also tried with just id and cssselector
element.Clear();
element.SendKeys(password);
}
I also tried
public void TypePassword(string password)
{
Password.Clear();
Password.SendKeys(password);
}
Interestingly,
public void TypeUsername(string username)
{
Username.Clear();
Username.SendKeys(username);
}
always work without any issue.
The IE driver configuration
var options = new InternetExplorerOptions { EnableNativeEvents = false};
options.AddAdditionalCapability("EnsureCleanSession", true);
Driver = new InternetExplorerDriver(options);
Seems like I am missing some configuration which is specific to IE8.
Also, confirmed zoom level and protected mode set up
Have you tried JavascriptExecutor ?
var element = new WebDriverWait(Driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(By.XPath("//input[#id='txtPassword']")));
((JavascriptExecutor)Driver).executeScript("arguments[0].value='"+password+"'", element);
It is difficult to find the element exists,
so u can go for the element count >1 using do while loop,
do
{
Thread.Sleep(500);
}while(driver.FindElements(By.Id("IDNAME")).Count>0);
Unless until, the count of the element gets, this do loop will execute and wait for the element to visible also
I am researching how to set an individual profile using RemoteWebDriver. I have been reading about it on the following thread.
http://stackoverflow.com/questions/12961037/parallel-execution-of-firefoxdriver-tests-with-profile-share-same-profile-copy
I am trying to tackle it as following:
public static RemoteWebDriver getDriver(String methodName) throws MalformedURLException {
String SELENIUM_HUB_URL = "http://localhost:4444/wd/hub";
ThreadLocal<RemoteWebDriver> remoteWebDriver = null;
File currentProfileFile = new File(methodName);
//This is where it gives the error
FirefoxProfile currentFireFoxProfile = new FirefoxProfile(currentProfileFile);
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
capabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
capabilities.setCapability(FirefoxDriver.PROFILE, currentFireFoxProfile);
String proxy = System.getProperty("proxy");
try {
remoteWebDriver = new ThreadLocal<RemoteWebDriver>();
remoteWebDriver.set(new RemoteWebDriver(new URL(SELENIUM_HUB_URL),
capabilities));
} catch (MalformedURLException e) {
System.out.println("Please fix the RemoteDriverSetup.class");
}
remoteWebDriver.get().manage().window()
.setSize(new Dimension(2880, 1524));
remoteWebDriver.get().manage().timeouts()
.pageLoadTimeout(10, TimeUnit.SECONDS);
remoteWebDriver.get().manage().timeouts()
.implicitlyWait(10, TimeUnit.SECONDS);
return remoteWebDriver.get(); // Will return a thread-safe instance of the WebDriver
}
I am getting the following error :
Time elapsed: 1.044 sec <<< FAILURE!
org.openqa.selenium.firefox.UnableToCreateProfileException: Given model profile directory does
not exist: TEST001
Update : I am injecting method name in the BaseTest class below
#BeforeMethod
public void startTest(Method testMethod) {
LOG.info("Starting test: " + testMethod.getName());
this.driver = WebDriverSetup.getDriver(testMethod.getName());
}
If you don't want to customize anything on your Firefox profile, better to create Firefox webdriver instance by NOT providing any profile details (as mentioned by Nguyen).
If you really want to create separate profiles (may be required to install some plug-ins like Firebug), in that case, you can do that by without passing any file name as below:
FirefoxProfile currentFireFoxProfile = new FirefoxProfile();
//Do some customization - add extension
currentFireFoxProfile.addExtension(pathOfextensionToInstall);
//or Setup some Firefox config. switch values
currentFireFoxProfile.setPreference("browser.download.manager.showWhenStarting", false);