Unable to find a WebElement when invoking an ant job in Jenkins - java

I was trying to invoke an ant job in Jenkins, it failed since some web elements were not found (I find these elements by their ID). However, I can build the ant successfully in Eclipse without this issue. I was using Jenkins-1.651.3 in Window7.
public class SendEmail
WebDriver browser = new FirefoxDriver();
#Parameters("url")
#Test
public void openHomePage(String url) throws Exception
{
browser.get("https://exmail.qq.com/");
}
#Test(dependsOnMethods = "openHomePage" )
public void openLoginPage() throws Exception
{
WebElement loginButton = browser.findElement(By.linkText("登录"));
loginButton.click();
}
#Parameters({"username","password"})
#Test(dependsOnMethods = "openLoginPage" )
public void authentication(String username, String password) throws Exception
{
WebElement userNameField = browser.findElement(By.id("inputuin"));
WebElement passwordField = browser.findElement(By.id("pp"));
WebElement checkbox = browser.findElement(By.id("ss"));
WebElement buttonLogin = browser.findElement(By.id("btlogin"));
checkbox.click();
userNameField.sendKeys(username);
passwordField.sendKeys(password);
buttonLogin.submit();
}

Add some implicit wait after creating driver instance:
WebDriver browser = new FirefoxDriver();
browser.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
And also add some explicit wait before before finding username input field like
WebDriverWait wait = new WebDriverWait(browser, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("inputuin"))));

Related

Webdriver can't find element by locator set as variable in another class

I wrote automated tests with help of JUnit, Selenium Webdriver (v. 3.141.59) and Chromedriver (v. 2.45).
Firstly, I wrote a login test:
[...]
void loginTest() {
driver().findElement(By.id("login-button")).click();
driver().findElement(By.id("name")).sendKeys("mail#xx.com");
driver().findElement(By.id("password")).sendKeys("password");
driver().findElement(By.id("send")).click();
assertTrue(driver().findElement(By.id("logged-in-msg")).isDisplayed());
}
Everything worked fine, all good, test green.
Then I got some more and more complicated and long ids and xpaths I had to use, so I decided to keep tests short and nice and put all my locators in separate class, like this:
public class LocatorsList {
public static final String
SIGN_IN_BUTTON = "login-button",
LOG_IN_USERNAME = "name",
LOG_IN_PASSWORD = "password",
LOG_IN_BUTTON = "send",
SUCCESS_MSG = "logged-in-msg";
}
And my test:
[...]
void loginTest() {
driver().findElement(By.id(SIGN_IN_BUTTON)).click();
driver().findElement(By.id(LOG_IN_USERNAME)).sendKeys("mail#xx.com");
driver().findElement(By.id(LOG_IN_PASSWORD)).sendKeys("password");
driver().findElement(By.id(LOG_IN_BUTTON)).click();
assertTrue(driver().findElement(By.id(SUCCESS_MSG)).isDisplayed());
}
Then it stopped working. Webdriver sends errors:
org.openqa.selenium.NoSuchElementException: no such element:
Unable to locate element: {"method":"id","selector":"name"}
As I watched my test going, this element was right there on the page, webdriver even clicked at it as if it wanted to fill the field... but it didn't. Says 'unable to locate element'.
I tried to change chromedriver and selenium versions but it didn't help.
If that's honestly the only real change to the code, then could it be as simple as you missing the class name before the string? I.e:
driver().findElement(By.id(LocatorsList.SIGN_IN_BUTTON)).click()
This is most probably due to element not present, you need to wait for the element to be loaded. Use
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.presenceOfElementLocated((By.id(LOG_IN_USERNAME))));
After that you can perform the action on that particular element say sendKeys event.
public class Testing {
public static final String
SIGN_IN_BUTTON = "jsid-login-button",
LOG_IN_USERNAME = "login-email-name",
LOG_IN_PASSWORD = "login-email-password",
LOG_IN_BUTTON = "input[type='submit']";
WebDriver driver;
#BeforeMethod
public void setUp() {
System.setProperty("webdriver.chrome.driver", <driverLocation>);
driver = new ChromeDriver();
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
driver.get("https://9gag.com/");
}
#Test
public void demoTest() {
driver.findElement(By.id(SIGN_IN_BUTTON)).click();
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.presenceOfElementLocated((By.id(LOG_IN_USERNAME))));
driver.findElement(By.id(LOG_IN_USERNAME)).sendKeys(<YOUR_EMAIL>);
driver.findElement(By.id(LOG_IN_PASSWORD)).sendKeys(<YOUR_PASSWORD>);
driver.findElement(By.cssSelector(LOG_IN_BUTTON)).click();
}
#AfterMethod
public void tearDown() {
driver.quit();
}
}

How to confirm the page title using selenium?

#Test(priority = 0)
public void test() throws Exception {
driver.get(baseUrl + "/");
driver.findElement(By.name("email")).clear();
driver.findElement(By.name("email")).sendKeys("lanka#ensiz.com");
driver.findElement(By.name("password")).clear();
driver.findElement(By.name("password")).sendKeys("123456");
driver.findElement(By.xpath("//button[contains(text(),'Sign In')]")).click();
}
#Test(priority = 1)
public void verifyHomepageTitle(){
String expectedTitle = "Placer Admin - Home";
String actualTitle = driver.getTitle();
Assert.assertEquals(actualTitle, expectedTitle);
}
#AfterClass(alwaysRun = true)
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
}
}
I'm new to automation testing.I want to make sure the valid user logins.For that i'm trying to verify the title of the page.But my test fail all the time,because it is execute before valid user going to the dashboard.how can I test this?Can i know the proper modifications for this code?
Please help..thanks
What you can do is, on the dashboard page select an element which is always there but is not on the login page. For example, a menu item or maybe a header.
Then create a wait like this at the end of the login test, so the test only completes after the dashboard is loaded:
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("XPath here")));
This will wait for a max of 5 seconds for the dashboard to load. The syntax could be wrong somewhere as I do everything in C#.
Use this code it is working fine in my machine :
public class User3806999 {
WebDriver driver;
WebDriverWait wait;
#BeforeClass
public void setUpClass(){
System.setProperty("webdriver.chrome.driver", "F:\\Automation\\chromedriver.exe");
driver = new ChromeDriver();
wait = new WebDriverWait(driver,30);
driver.manage().window().maximize();
driver.get("https://test.admin.placer.life/login");
}
#Test()
public void testLogin() throws Exception {
driver.findElement(By.name("email")).clear();
driver.findElement(By.name("email")).sendKeys("lanka#ensiz.com");
driver.findElement(By.name("password")).clear();
driver.findElement(By.name("password")).sendKeys("123456");
driver.findElement(By.xpath("//button[contains(text(),'Sign In')]")).click();
wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.id("user_menu"))));
//Assert something here
}
#Test(dependsOnMethods ={"testLogin"})
public void verifyHomepageTitle(){
String expectedTitle = "Placer Admin - Home";
String actualTitle = driver.getTitle();
Assert.assertEquals(actualTitle, expectedTitle);
}
#AfterClass(alwaysRun = true)
public void tearDown() throws Exception {
//logout here
}
}
Use the explicit wait as below before assertion:
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.titleContains(expectedTitle);

Selenium Webdriver TestNG tests are "overwriting" each other

I am trying to run Selenium Webdriver tests in parallel on a single machine, using TestNG. I have 3 #Test methods, where 3 different users log in to the same application and reach the home page. I need #Test methods to run in parallel, and write to an ExtentReports report.
My problem is, despite 3 completely different methods in different classes, one of the users will be logged into 2 out of 3 of the browsers, leaving a user out.
The login method is located in a PageFactory page object class.
Here are my 3 test methods:
#Test(enabled = true, priority = 0)
public void JohnLogin() throws Exception {
ExtentTest t = ClientReportFactory.getTest();
try {
Login objLogin = new Login(getDriver());
String username = "John";
String password = "Password";
objLogin.SignIn(username, password);
HomePage objHomePage = new HomePage(getDriver());
assertTrue(objHomePage.clientName.getText().c‌​ontains("John"));
} catch (Exception e) {
}
}
#Test(enabled = true, priority = 1)
public void BobLogin() throws Exception {
ExtentTest t = ClientReportFactory.getTest();
try {
Login objLogin = new Login(getDriver());
String username = "Bob";
String password = "Password";
objLogin.SignIn(username, password);
HomePage objHomePage = new HomePage(getDriver());
assertTrue(objHomePage.clientName.getText().c‌​ontains("Bob"));
} catch (Exception e) {
}
}
#Test(enabled = true, priority = 2)
public void SamLogin() throws Exception {
ExtentTest t = ClientReportFactory.getTest();
try {
Login objLogin = new Login(getDriver());
String username = "Sam";
String password = "Password";
objLogin.SignIn(username, password);
HomePage objHomePage = new HomePage(getDriver());
assertTrue(objHomePage.clientName.getText().c‌​ontains("Sam"));
} catch (Exception e) {
}
}
So, if I pause the tests on the Homepage. I will have 2 browser windows opened as "John", one "Bob" and no "Sam"... Causing failures.
Here's the PageFactory Object's login method.
public void SignIn(String strUsername, String strPassword) throws InterruptedException {
WebDriverWait wait = new WebDriverWait(driver, 15);
username.clear();
username.sendKeys(strUsername);
password.clear();
password.sendKeys(strPassword);
submit.click();
wait.until(ExpectedConditions.visibilityOf(homePagePanel));
}
At first I was sure the problem was in the #BeforeMethod threading (As in, the tests were in a different thread than the #Before and #After). But I don't see how that could be the case. The Base Test method successfully opens and closes 3 browsers. It just seems like the #Test methods use each other's data! But just in case, here's my #Before and #After, with my Threading code.
public class BaseTest {
public String browser;
private ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>();
#BeforeMethod(alwaysRun = true)
#Parameters({ "browser"})
public void setup(String browser)throws MalformedURLException,
InterruptedException {
WebDriver driver = null;
if (browser.equalsIgnoreCase("Internet Explorer")) {
System.setProperty("webdriver.ie.driver", "C:\\Selenium\\IEDriverServer.exe");
driver = new InternetExplorerDriver();
} else if (browser.equalsIgnoreCase("Firefox")) {
System.setProperty("webdriver.gecko.driver", "C:\\Selenium\\geckodriver.exe");
driver = new FirefoxDriver();
} else if (browser.equalsIgnoreCase("chrome")) {
System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\chromedriver.exe");
driver = new ChromeDriver();
} else if (browser.equalsIgnoreCase("MicrosoftEdge")) {
System.setProperty("webdriver.edge.driver", "C:\\Selenium\\MicrosoftWebDriver.exe");
driver = new EdgeDriver();
}
setWebDriver(driver);
this.browser = browser;
ClientReportFactory.getTest(ExtentTestName, ExtentTestDescription);
baseURL = "testApp.com";
driver.get(baseURL);
driver.manage().window().maximize();
}
public WebDriver getDriver(){
return threadedDriver.get();
}
public void setWebDriver(WebDriver driver) {
threadedDriver.set(driver);
}
#AfterMethod
public void afterMethod() {
ClientReportFactory.closeTest(ExtentTestName, ExtentTestDescription);
getDriver().quit();
threadedDriver.set(null);
}
#AfterSuite
public void afterSuite() {
ClientReportFactory.closeReport();
if (getDriver() != null) {
getDriver().quit();
} else {
System.out.println("Drivers already closed");
}
}
Assuming that all of your #Test methods are in different classes, I am guessing that the problem is perhaps due to the fact that your ThreadLocal variable is NOT STATIC but is an instance variable. This causes the behaviour to be per thread per instance rather than the desired behaviour viz., per thread across all instances. You can refer to this StackOverFlow thread for a better explanation on this.
You would resort to using an instance variant of ThreadLocal if and only if all your #Test methods belong to the same test class (Because now you are only trying to ensure that the class level data member WebDriver is shared in a thread safe manner across all the test methods that belong to the same test class)
So if each of your #Test methods reside in its own Test class, then please try changing:
private ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>();
to
private static ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>();
You could try this.
public class DriverFactory(){
private static ThreadLocal<WebDriver> driverThread;
public WebDriver driver;
#Parameters("browser")
public WebDriver instantiateDriverObject(String browser) {
DriverFactory factory = new DriverFactory();
driver = factory.createInstance(browser); //Driver instantiation goes here
driverThread = new ThreadLocal<WebDriver>() {
#Override
protected WebDriver initialValue() {
webDriverPool.add(driver);
return driver;
}
};
return driver;
}
public WebDriver getDriver() {
return driverThread.get();
}
}

Element is not clickable(x,y) even there is no scroll in page have tried thread.sleep()

I am unable to click on the "Login" button provided in the header I am new to selenium, here is the code snippet
public class Muft_Mashwara_login {
public WebDriver driver= null;
#BeforeMethod
public void startBrowser () {
driver= new FirefoxDriver();
driver.get("http://sqa.muftmashwara.be.vteamslabs.com/home");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);
}
#Test
public void Click()throws InterruptedException {
//Thread.sleep(3000);
driver.findElement(By.xpath(".//*[#id='header2']/nav/div/ul/li/a")).click();
WebElement loginTxt = driver.findElement(By.xpath("html/body/main/div/section/article[2]/div/div/form[1]/div[1]/div/input"));
loginTxt.sendKeys("test#test.com");
}
#AfterMethod
public void Close() {
driver.close();
}
}
It only works if I uncomment "Thread.sleep". I don't know how to implement dynamic wait in this case.
Should work with something like this:
WebDriverWait webDriverWait = new WebDriverWait(driver, 5); // Wait up to five seconds.
wait.until(ExpectedConditions.visibilityOfElementLocated(
By.xpath(".//*[#id='header2']/nav/div/ul/li/a"))).click();
// Or perhaps:
//webDriverWait.until(ExpectedConditions.elementToBeClickable(
// By.xpath("//xpath"))).click();
You may also want to add this one before clicking, as the loading overlay interferes with clicking for some versions of webdriver.
wait.until(ExpectedConditions.invisibilityOfElementLocated(
By.xpath("//div[#id='cover']")));
I think the webdriverwait is not working correctly for this scenario so Thread.sleep will do.
Try this code, it ran sucessfully at my end.
And always Use Css before you think of XPath.
Css are faster than Xpath.
#Test
public void test() throws InterruptedException, AWTException{
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("http://sqa.muftmashwara.be.vteamslabs.com/home");
Thread.sleep(10000L);
driver.findElement(By.cssSelector(".fa.fa-lock")).click();
}
use the below code:
public class Muft_Mashwara_login {
public WebDriver driver= null;
#BeforeMethod
public void startBrowser () {
driver= new FirefoxDriver();
driver.get("http://sqa.muftmashwara.be.vteamslabs.com/home");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);
}
#Test
public void Click()throws InterruptedException {
//use javascript click here
WebElement elem = driver.findElement(By.cssSelector("li>a[href='/login']"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", elem);
WebElement loginTxt = driver.findElement(By.cssSelector("div.form-group.ng-invalid>input[name='username']"));
loginTxt.click();
loginTxt.sendKeys("test#test.com");
}
#AfterMethod
public void Close() {
driver.close();
}
}
but if u want to learn how to use dynamic wait,see the below example:
WebDriverWait webDriverWait = new WebDriverWait(driver, 20);
webDriverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("ue selector")));
//u can use by xpath or class or name here also
// this will until the element is visible to the page

Selenium webdriver explicit wait

I'm writing some automated tests for using the selenium chrome driver. I trying to write a reusable method that will explicitly wait for elements to appear and then call this method in other classes. Seems pretty straight forward but its not doing what I want it do. Here is the method that I have.
public String waitForElement(String item) {
WebDriverWait wait = new WebDriverWait(driver,30);
WebElement element = wait.until(
ExpectedConditions.elementToBeClickable(By.id(item)));
return item;
}
Then I call the method and pass it a parameter like this:
waitForElement("new-message-button");
That doesn't seem to become working, can someone give some insight?
You can use Explicit wait or Fluent Wait
Example of Explicit Wait -
WebDriverWait wait = new WebDriverWait(WebDriverRefrence,20);
WebElement aboutMe;
aboutMe= wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("about_me")));
Example of Fluent Wait -
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(20, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement aboutMe= wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id("about_me"));
}
});
Check this TUTORIAL for more details.
public static void clickOn(WebDriver driver, WebElement locator, int timeout)
{
new WebDriverWait(driver,timeout).ignoring(StaleElementReferenceException.class).until(ExpectedConditions.elementToBeClickable(locator));
locator.click();
}
Call the above method in the main method then we will get explicitly wait functionality.
Your problem is that you passed String to method parameter:
public String waitForElement(String item) {
You have to pass your WebElement, something like:
public boolean visibilityOfElementWait(WebElement webElement) {
if (webElement != null) {
try {
WebDriverWait wait = new WebDriverWait(Driver.getCurrentDriver(), 20);
wait.until(ExpectedConditions.visibilityOf(wrappedElement));
highlightElement(webElement);
return true;
} catch (Exception e) {
return false;
}
} else
Logger.logError("PageElement " + webElement.getText() + " not exist");
return false;
}
public void highlightElement(WebElement element) {
if (!Config.getProperty(Config.BROWSER).equalsIgnoreCase("ANDROIDHYBRID")) {
String bg = element.getCssValue("backgroundColor");
for (int i = 0; i < 4; i++) {
Driver.getDefault()
.executeScript("arguments[0].style.backgroundColor = 'red'", element);
Driver.getDefault()
.executeScript("arguments[0].style.backgroundColor = '" + bg + "'", element);
}
// String highlightElementScript = "arguments[0].style.backgroundColor = 'red';";
// Driver.getDefault().executeScript(highlightElementScript, element);
}
}
We can develop implicit wait on our own.
Use this code; it should also work the same as implicit wait.
//=== Start of Implicit Wait Statement ===
public void implicit_Wait_ID(String str) throws Exception{
for(int i=0;i<60;i++){
try{
driver.findElement(By.id(str)).isDisplayed();
break;
}catch(Exception e){Thread.sleep(2000);
}
}
}
//=== End of Implicit Wait Statement ===
Use this method by passing the ID value:
public void loginGmail() throws Exception
{
driver.findElement(By.id("Email")).sendKeys("Mail ID");
driver.findElement(By.id("next")).click();
implicit_Wait_ID("Passwd");
driver.findElement(By.id("Passwd")).sendKeys("Pwd value");
driver.findElement(By.id("signIn")).click();
}
If it is Xpath, LinkText, just create one of the above methods for all locator types and reuse it n number of times in your script.
Just use this method.I hope it will work perfectly.
public void waitForElement(String item) {
WebDriverWait wait = new WebDriverWait(driver,30);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("item")));
}
Then call the method :
waitForElement("new-message-button");
I wrote an explicit wait for my selenium test in the following manner:
I declared my WebElement to be found with an #FindBy annotation added referencing the Id as follows:
#FindBy(how = How.ID, using = "home")
private WebElement home;
Then my method that waits for an element to load was written as follows:
public WebElement isElementLoaded(WebElement elementToBeLoaded) {
WebDriverWait wait = new WebDriverWait(driver, 15);
WebElement element = wait.until(ExpectedConditions.visibilityOf(elementToBeLoaded));
return element;
}
This allowed me to reference any element I was waiting for by name that I had annotated with a find by, regardless of the #FindBy method used.
I built a package using Selenium and waiting was one of the biggest issues I had. In the end, the methods as you described above wouldn't work. I had to resort to doing a simple implicit wait for any dynamic elements, as described below
An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.
Code:
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));
src
Hope that helps.

Categories

Resources