动态创建值时使用的最佳方法?

时间:2014-01-07 12:53:12

标签: selenium selenium-webdriver junit4

我正在寻找有关如何选择WebElement的一些建议。 当我单击创建新“页面”的按钮时,给定值是动态的,因为它是完全随机的而不是顺序的。我希望它遵循以下内容:第1页= 0,第2页= 1,第3页= 2等。

默认情况下,我从一个页面开始,其值为c3。虽然当我触发按钮来创建新页面时,值显示如下:

<select class="j-currentPage f-feature-A" name="currentPage">  <option value="c3">New Page</option>  <option value="c277">New Page 2</option>  <option value="c383">New Page 3</option>  <option selected="" value="c461">New Page 4</option>  </select>

所以当我尝试使用以下内容时:

 List<WebElement> option = chrome.findElements(By.tagName("option"));

    option.get(0).click();
    option.get(1).click();
    option.get(0).click();

它显然是失败的,因为值是c277,c346等等,并且无法知道新会话中的值将是什么,因为它们将始终不同。

stacktrace抛出一个StaleElementReferenceException,因为它不在DOM中。

当值完全随机时,如何选择每个页面?

我正在使用Webdriver和JUnit4。

修改

测试方法:创建一些新页面。

@Test
public void createANewPage(){
    WebDriverWait wait = new WebDriverWait(chrome, 60);

    wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("select.j-currentPage.f-feature-A[name=\"currentPage\"]")));

    WebElement newPage = chrome.findElement(By.cssSelector("span.j-addViewBtn.ss-layers"));
    newPage.click();

    List<WebElement> option = chrome.findElements(By.tagName("option"));

    option.get(1).click();

    option.get(0).click();
}

然后进行一些测试我想回调创建的页面

@Test
public void goToPage(){

    new WebDriverWait(chrome, 60).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("select.j-currentPage.f-feature-A[name=\"currentPage\"]")));
    List<WebElement> option = chrome.findElements(By.tagName("option"));

    option.get(0).click();
    option.get(1).click();
    option.get(0).click();
}

我在第三个org.openqa.selenium.StaleElementReferenceException

点收到option.get(0).click();

但是我感觉好像我正在以错误的方式接近这个,因为值是动态创建的<option value="c3">New Page</option>
<option value="c207">New Page 2</option>
<option value="c288">New Page 3</option>
<option selected="" value="c366">New Page 4</option>

3 个答案:

答案 0 :(得分:0)

StaleElementReferenceException并不意味着它不在DOM中。这意味着自从找到该对象后DOM已更改,因此可能会被删除或更改。更改可能是由于页面重新加载或通过javascript刷新HTML。无论哪种方式,Webdriver都会抛出错误,因为它认为在页面发生变化时重新绑定对象可能是个好主意。

如果您重新构造元素,那么它将起作用。你是通过标签名称找到的,所以ids已经改变的事实应该没有影响。

以下方法可行,但确实存在性能问题;

chrome.findElements(By.tagName("option")).get(0).click
chrome.findElements(By.tagName("option")).get(1).click
chrome.findElements(By.tagName("option")).get(2).click

有一种更好的方法来解决您的特定应用程序的问题,但希望了解实际指示的陈旧元素,将帮助您解决问题。

答案 1 :(得分:0)

FindElement()策略都不支持使用正则表达式来查找元素。

虽然还有另一种使用正则表达式的方式,但可能对你有帮助

List<WebElement> option = chrome.findElements(By.tagName("option"));

现在循环选项和getText。然后通过程序进行正则表达式检查 下面是一个不会运行的演示代码。请将它转移到jave

foreach(WebElement link in links)
{
    string text = link.Text;
    if (Regex.Match("your Regex here", text))
    {
        matchingLinks.Add(text);
    }
}

foreach(string linkText in matchingLinks) // now you have the texts even if they are dynamics
{
    WebElement element = driver.findElement(By.LinkText(linkText));
    element.Click();
    // do stuff on the page navigated to
    driver.Navigate().Back();
}

答案 2 :(得分:0)

好的,我刚刚在这个问题的贡献者的帮助下设法解决了这个问题。

好像我只需要使用xpath而不是List<WebElement>,所以下面的代码现在选择我想要的页面。

@Test
public void jGoToPage(){

    new WebDriverWait(chrome, 60).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("select.j-currentPage.f-feature-A[name=\"currentPage\"]")));

    WebElement page1 = chrome.findElementByXPath("//option[contains(.,'New Page')]");
    page1.click();

    WebElement page2 = chrome.findElementByXPath("//option[contains(.,'New Page 2')]");
    page2.click();

    WebElement selectPage1Again = chrome.findElementByXPath("//option[contains(.,'New Page')]");

    selectPage1Again.click();

也许不是最好的代码,但如果有人想建议更好的方法来改进它,请发表评论,以便其他人可以学习。

我两次宣布New Page的原因是因为我再次收到staleElementReferenceException。因此,只需在page1.click();之后立即尝试执行page2.click();即发生这种情况,这就是为什么我将其声明为selectPage1Again

我还使用此question来帮助解决方案。