2017-06-20 60 views
0

我想在同一个测试类中编写有效和无效登录的测试,但我得到StaleElementReferenceException。以下是密码获取StaleElementReferenceException尝试一个有效的和一个无效的登录

public class LoginTest { 
    static{ 
     System.setProperty("webdriver.chrome.driver", "./driver/chromedriver.exe"); 
    } 
    public static void main(String[] args) throws InterruptedException { 
     WebDriver driver = new ChromeDriver(); 
     driver.get("http://app.meltwaterbuzz.com/"); 
     driver.manage().window().maximize(); 
     LoginPage login = new LoginPage(driver); 
     System.out.println(driver.getTitle()); 
     login.setUsername("username"); 
     login.setPassword("password"); 
     login.clickSignIn(); 
     login.setUsername("username"); 
     login.setPassword("password"); 
     login.clickSignIn(); 
     System.out.println(driver.getTitle()); 

     //driver.close(); 
    } 
} 

任何想法如何处理?

+0

你能告诉了哪一行代码你得到的例外。 – Alok

回答

0

这里是回答你的问题:

在你的代码块,你创建了一个对象LoginPagelogin,填补了usernamepassword和你点击SignIn按钮。一旦您点击SignIn按钮,您将以注册用户身份登录并重定向到新页面。这里页面/网址已经改变,HTML DOM也改变了。

接下来,您再次尝试再次通过login.setUsername("username")传递用户名,Selenium无法在此新页面上找到相同的定位器(id/name/css/xpath)。因此Selenium抱怨StaleElementReferenceException这基本上意味着您正在寻找的定位符不再出现在HTML DOM上或已成为stale

您的问题的解决方案将是Logout并再次返回到初始url http://app.meltwaterbuzz.com/

让我知道这个答案是否是您的问题。

2

一般来说,如果在启动webelement后元素属性或其他内容发生更改,我们将会得到Stale Exception。例如,在某些情况下,如果用户尝试单击同一页面上的同一元素,但在页面刷新后,则会得到staleelement异常。

为了克服这一点,我们可以创建新的webelement,以防万一网页被改变或刷新。下面的代码可以给你一些想法。

例子:

webElement element = driver.findElement(by.xpath("//*[@id='StackOverflow']")); 
element.click(); 
//page is refreshed 
element.click();//This will obviously throw stale exception 

为了克服这一点,我们可以存储在一些字符串的XPath和使用它,因为我们去创造一个清新webelement。

String xpath = "//*[@id='StackOverflow']"; 
driver.findElement(by.xpath(xpath)).click(); 
//page has been refreshed. Now create a new element and work on it 
driver.fineElement(by.xpath(xpath)).click(); //This works 

希望这可以帮助你。谢谢。

+0

是的,如果我们试图再次找到元素,那么肯定会起作用,但是相同的代码会重复多次。 –

+0

我没有找到你@ZahidAfaque –

+0

你不应该把这当成代码重复,@santhosh kumar是对的。这是最佳做法。在页面初始化时加载所有元素可能会减少与dom的交互,但出于很多原因,除非您搞乱了静态网页,否则效率不高。交互后动态内容自然会发生变化。 添加手动等待是最好的解决方案,如下面的答案。除非必须,否则不要这样做。 –

0

我找到了克服StaleElementReferenceException的方法,如果我们使用页面对象模型,那么我们可以克服它。这里是例子。

POM类

public class LoginPage { 
//declaration 
@FindBy(id="username") 
private WebElement usernameTxt; 

@FindBy(name = "pwd") 
private WebElement passwordTxt; 

@FindBy(css="#loginButton") 
private WebElement loginBTN; 
//Initialization 
public LoginPage(WebDriver driver) { 
    PageFactory.initElements(driver, this); 
} 
//Utilization 
public void setUserName(String un) { 
    usernameTxt.sendKeys(un); 
} 

public void setPassword(String pw) { 
    passwordTxt.sendKeys(pw); 
} 

public void clickLogin() { 
    loginBTN.click(); 
} 

}

测试类

public class LoginTest { 
public static void main(String[] args) throws InterruptedException { 
    System.setProperty("webdriver.chrome.driver", "./driver/chromedriver.exe"); 
    WebDriver driver = new ChromeDriver(); 
    driver.get("http://localhost/login.do"); 
    LoginPage login = new LoginPage(driver); 

    login.setUserName("zahid"); 
    login.setPassword("manager"); 
    login.clickLogin(); 
    Thread.sleep(2000); 
    login.setUserName("admin"); 
    login.setPassword("manager"); 
    login.clickLogin(); 
} 

}