I am using selwnium web driver. When I am using selenium and nunit to run my test cases I find that every time a test case starts it open a new page and when its done the mew page will be destoryed. Therefore I have to open new page and login in every test case.
I want to have my test cases share one single webpage so that they can be performed in sequence.
Is a selenium limitation, or is it a way to implement it?
Thank you!
Try to declare Webdriver instance variable as static inside your test class and initialize only once. Your behavior is because different webdriver instances does not share the same session, so therefore you have always to login into desired page.
You probably using #Before , #After annotation.
Try use #BeforeClass, #AfterClass instead. e.g:
....
static WebDriver driver;
#BeforeClass
public static void firefoxSetUp() throws MalformedURLException {
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
driver.manage().window().setSize(new Dimension(1920, 1080));
}
#Before
public void homePageRefresh() throws IOException {
driver.manage().deleteAllCookies();
driver.get(propertyKeysLoader("login.base.url"));
}
#AfterClass
public static void closeFirefox(){
driver.quit();
}
.....
Related
I am working on a selenium script where I am using explicit wait. I have a script where I have three methods to invoke IE,FireFox and Chrome browsers.
I will be executing script for one browser at a time. now the question is how should I declare the wait (explicitly). I can see two following options.
1. Create an object of WebDriverWait class Globally--- In this scenario web driver throws the exception as there is no object created for the browser class(in this case FireFoxDriver()).
2.Create an object of WebDriverWait class locally in any method-- In this scenario wait works perfectly but in case i have to use the wait again for any other element. it would ask you to create object of WebDriverWait class locally again(which is something i want to avoid)..
In Short. I just want to create object of WebDriverWait class onle once in the code. How can i do it for the below mentioned code???
following is the code..
public class para {
WebDriver driver;
#BeforeClass
void InvokeFF() {
System.setProperty("webdriver.gecko.driver",
"C:/Users/Vinay/workspace_n/EGuru/drivers/geckodriver.exe");
driver = new FirefoxDriver();
// driver.get("http://seleniumpractise.blogspot.in/2016/08/bootstrap-dropdown-example-for-selenium.html");
System.out.println("Firefox invoked");
System.out.println("Firefox thread:" + Thread.currentThread().getId());
}
#BeforeClass(enabled = false)
void InvokeIE() {
System.setProperty("webdriver.ie.driver",
"C:/Users/Vinay/workspace_n/EGuru/drivers/IEDriverServer.exe");
driver = new InternetExplorerDriver();
System.out.println("Internet Explorer invoked");
System.out.println("IE thread:" + Thread.currentThread().getId());
}
#BeforeClass(enabled = false)
void InvokeGC() {
System.setProperty("webdriver.chrome.driver",
"C:/Users/Vinay/workspace_n/EGuru/drivers/chromedriver.exe");
driver = new ChromeDriver();
// driver.get("http://www.seleniumeasy.com");
System.out.println("Chrome invoked");
System.out.println("Chrome thread:" + Thread.currentThread().getId());
}
#Test
void Auto() throws Exception {
WebDriverWait wait = new WebDriverWait(driver, 20);
driver.get("file:///C:/Users/Vinay/Desktop/Upload1.html");
wait.until(ExpectedConditions.visibilityOfElementLocated(By
.xpath(".//*[#id='1']")));
driver.findElement(By.xpath(".//*[#id='1']")).click();
Runtime.getRuntime().exec("C:\\Users\\Vinay\\Desktop\\AutoUpload.exe");
}
}
I think what you're looking for is an implicit wait, not an explicit wait. This can be accomplished by using the line of code below after your driver has been created (using whichever driver it needs)
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Obviously change the 10 seconds to whatever default timeout you want.
If you want to put explicitly wait please use the please code :
public static WebDriverWait wait = new WebDriverWait(driver, 10);
public static void wait(String waitElement)
{
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(waitElement)));
}
Worked for me !
I am using Selenium WebDriver with TestNG framework for running test suite on Windows and MAC platform on different browsers - Chrome, IE, firefox and Safari. I have around 300 test cases in my test suite.
The problem is that some of the test cases gets skipped in between where I believe driver becomes unresponsive. However the logs failed to capture any details why the test cases are getting skipped.
The reporter class extends TestListenerAdapter and hence the skipped test cases gets listed in the log file with the use of onConfigurationSkip method. It only prints that a particular test case has been skipped.
Below are some code snippets for reference
Code from Reporter Class
#Override
public void onConfigurationSkip(ITestResult testResult) {
LOGGER.info(String.format("Skipped Configuration for : %s", testResult.getMethod().getMethodName()));
}
Sample Test Class
public class TestClass {
private WebDriver driver;
#Parameters({ "platform", "browser"})
#BeforeClass
public void setUp(String platform, String browser) {
// Creates a new driver instance based on platform and browser details
driver = WebDriverFactory.getDriver(platform, browser);
// Login to web application
Utils.login(driver, username, password);
}
#Test
public void sampleTestMethod() {
// scripts for validating Web elements
}
#AfterClass
public void tearDown() {
driver.quit();;
}
}
Observations:
driver.quit() doesn't guarantee that driver instance has been closed because I can still see driver instance running in task manager. Again this is intermittent and happens sometimes only.
This issue is observed on all platform and browser
This is an intermittent issue and probability of its occurrence increases as the number of test cases increase in test suite
There is no definite pattern of skipped test cases. The test cases get randomly skipped on some browser and platform
The probability of occurance of skip test cases increases with subsequent run of test suite. I believe the reason is that more and more driver instances that were not properly closed keep running in the back ground
Normally a test Class has 5-15 test methods and new driver instance is created every time in #BeforeClass method and is closed in #AfterClass
Any Suggestions? Thanks in Advance
If you're fine with opening and closing the browsers around every test then you should use #BeforeMethod or #AfterMethod instead of #BeforeClass and #AfterClass
If you follow the following code and its output then you'll find that #BeforeMethod executes before every test annotated methods however, #BeforeClass does only once for all methods in the class.
Since I don't have your full code to analyze then I can just assume that your tests are trying to reuse the wrong driver instances. So the best bet would be to close it down after every test execution finishes.
Code:
package com.autmatika.testng;
import org.testng.annotations.*;
public class FindIt {
#BeforeClass
public void beforeClass(){
System.out.println("Before Class");
}
#AfterClass
public void afterClass(){
System.out.println("After Class");
}
#BeforeMethod
public void beforeTest(){
System.out.println("Before Test");
}
#AfterMethod
public void afterTest(){
System.out.println("After Test");
}
#Test
public void test1(){
System.out.println("test 1");
}
#Test
public void test2(){
System.out.println("test 2");
}
#Test
public void test3(){
System.out.println("test 3");
}
#Test
public void test4(){
System.out.println("test 4");
}
}
Output:
Before Class
Before Test
test 1
After Test
Before Test
test 2
After Test
Before Test
test 3
After Test
Before Test
test 4
After Test
After Class
===============================================
Default Suite
Total tests run: 4, Failures: 0, Skips: 0
===============================================
The most common reason for the test cases getting skipped with Selenium using TestNG is if your methods are dependent on other method and a method you depend on is failed.
To get information on why the test got skipped you can implement that in after test method as below :-
#AfterMethod
public void afterTest(ItestResult result) {
Throwable t = result.getThrowable();
// with the object of t you can get the stacktrace and log it into your reporter
}
and to avoid tests getting skipped you can have alwaysRun parameter to be true after the #Test annotation
#Test(alwaysRun=true)
to avoid the webdriver getting retarted do the driver cleanups in methods with #BeforeMethod and #AfterMethod annotations, so try changing the annotation of setUp and tearDown methods to #BeforeMethod and #AfterMethod respectively
In selenium Webdriver testng, i have hardcoded some elements in my program but the testng is not finding the element.so i gave thread.sleep but in case its working and in other case not working.i gave explicit function also.TO find Element , i written the method called findelement
public findElement(String Locator)
{
locator(Locator);
identifyBy (identifier);
}
public static void locator(String locator) {
}
This is what i done in my selenium framework.please help me to fetch the data.
public static void waitForElementToAppear(WebDriver driver, By selector, long timeOutInSeconds) {
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(selector));
}
I am new to Selenium, While practicing I come up with one issue, I am doing testing for my own application which has been deployed in tomcat server. So after opening my application I am testing validations in one method and page change in one method. Now My point is I am doing both testing for my both methods at same page.
Why do I need to write same code both methods,
driver.get("http://localhost:8070/");
driver.findElement(By.xpath("//div[#id='actions']/div[2]/a/span")).click();
driver.findElement(By.linkText("/ReportGenerator")).click();
How can I directly perform operations, If I remove above two lines in my second method It is getting failed. How to solve this?
#Test
public void analysisValidation()
{
driver.get("http://localhost:8070/");
driver.findElement(By.xpath("//div[#id='actions']/div[2]/a/span")).click();
driver.findElement(By.linkText("/ReportGenerator")).click();
driver.findElement(By.id("Analysis")).click();
WebElement webElement = driver.findElement(By.id("modelForm.errors"));
String alertMsg = webElement.getText();
System.out.println(alertMsg);
Assert.assertEquals("Please select a Survey Id to perform Aggregate Analysis", alertMsg);
}
#Test
public void testAnalysisPage()
{
driver.get("http://localhost:8070/");
driver.findElement(By.xpath("//div[#id='actions']/div[2]/a/span")).click();
driver.findElement(By.linkText("/ReportGenerator")).click();
new Select(driver.findElement(By.id("surveyId"))).selectByVisibleText("Apollo");
driver.findElement(By.id("Analysis")).click();
System.out.println(driver.getTitle());
String pageTitle = driver.getTitle();
Assert.assertEquals("My JSP 'analysis.jsp' starting page", pageTitle);
}
How can I directly perform operations, If I remove above two lines in
my second method It is getting failed. How to solve this
The tests fail because each #Test test is executed independently. The code you remove is needed to initialize the driver and load the page.
You can fix this as follows:
Create a function, setUp() with the #beforemethod annotation. Populate it with the driver initialization and loading-page calls.
Create a function, teardown() with the #AfterMethod annotation. Populate it with the driver cleanup calls.
For example, here is some pseudocode (modify this as per taste)
#BeforeMethod
public void setUp() throws Exception {
driver.get("http://localhost:8070/");
driver.findElement(By.xpath("//div[#id='actions']/div[2]/a/span")).click();
driver.findElement(By.linkText("/ReportGenerator")).click();
}
#AfterMethod
public void teardown() throws Exception {
driver.quit()
}
The advantage of the #BeforeMethod and #AfterMethod annotations is that the code will be run before / after each #Test method executes. You can therefore avoid having to duplicate your code.
I am using selenium2.0 with testNG. While on using XPATH or CSS for element to locate its shows error “unable to locate the element” .
I have programmed in Java as
below:
public class mytest {
public static WebDriver driver;
public Alert alert;
#BeforeClass
public static void setUpBeforeClass() throws Exception {
driver=new FirefoxDriver();
driver.get("http://localhost:4503/xyz.html");
}
public static void clickButton(WebDriver driver, String identifyBy, String locator){
if (identifyBy.equalsIgnoreCase("xpath")){
driver.findElement(By.xpath(locator)).click();
}else if (identifyBy.equalsIgnoreCase("id")){
driver.findElement(By.id(locator)).click();
}else if (identifyBy.equalsIgnoreCase("name")){
driver.findElement(By.name(locator)).click();
}
}
public static void typeinEditbox(WebDriver driver, String identifyBy, String locator, String valuetoType){
if (identifyBy.equalsIgnoreCase("xpath")){
driver.findElement(By.xpath(locator)).sendKeys(valuetoType);
}else if (identifyBy.equalsIgnoreCase("id")){
driver.findElement(By.id(locator)).sendKeys(valuetoType);
}else if (identifyBy.equalsIgnoreCase("name")){
driver.findElement(By.name(locator)).sendKeys(valuetoType);
}
}
public static void openApplication(WebDriver driver, String url) {
driver.get(url);
}
#Test
public void testAcrolinxApplication() throws InterruptedException {
openApplication(driver,"http://xyz.com");
typeinEditbox(driver,"name","p_user","xxx");
typeinEditbox(driver,"name","p_pas","yyy");
clickButton(driver,"id","input-submit");
/*Up to this its working fine …..
At below line this throws error could not locate the xpath element "//a[#id='cq-gen100']/em/span/span" BUT THIS IS WOKING FINE IN Selenium1.0 api that is with
selenium.click("//a[#id='cq-gen100']/em/span/span"); */
driver.findElement(By.xpath("//a[#id='cq-gen100']/em/span/span")).click();
}
}
Please help me on this.
Thanks in advance…
Make Sure XPath/CSS Query is Correct
Download something like Firefinder or anything else where you can test the XPath query directly on the page. Once you know for sure that your query is correct, then you can narrow down the problem in Selenium.
Narrow Down the Problem in Selenium
For example, if your query "//a[#id='cq-gen100']/em/span/span" is not working, try the base of the query and see if Selenium finds it (don't worry about click for now). Increment from there until the error appears again.
Example:
driver.findElement(By.xpath("//a[#id='cq-gen100']"); //works?
driver.findElement(By.xpath("//a[#id='cq-gen100']/em"); //works?
driver.findElement(By.xpath("//a[#id='cq-gen100']/em/span"); //works?
//etc
I have used
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
to wait for some time, Noew its working.