我正在寻找有关如何选择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>
答案 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来帮助解决方案。