You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Protractor时遭遇Stale Element Reference错误的技术求助

Hey there, let's break down why you're hitting that stale element reference error and how to fix it!

The Root Cause

When you first grab the full list of links with element.all(by.xpath('linkname')).then(function(ann){...}), you're storing references to those specific DOM elements. But when you click the "back" button, the modal's content gets re-rendered—meaning those original link elements are no longer attached to the page document. When your loop tries to access ann[i] the second time, it's pointing to an element that doesn't exist anymore, hence the error.

Solution: Re-locate Elements on Each Loop Iteration

Instead of caching the entire list of links upfront, you should re-fetch the link you need every time before clicking it. This ensures you're always interacting with the current, active DOM elements.

Here's a revised version of your code, using async/await for cleaner readability (Protractor supports this in newer versions):

this.new = async function () {
  // Open the modal and switch context
  await element(by.xpath('')).click();
  await browser.sleep(5000);
  await browser.switchTo().defaultContent();
  
  // Get total number of links once
  const linkCount = await element.all(by.xpath('linkname')).count();
  
  for (let i = 0; i < linkCount; i++) {
    // Re-fetch the i-th link each iteration to avoid stale references
    const currentLink = element.all(by.xpath('linkname')).get(i);
    await currentLink.click();
    
    // Wait for detail content, then navigate back
    await browser.sleep(2000);
    await element(by.id("back")).click();
    await browser.sleep(2000);
  }
};

Bonus: Replace Fixed Sleeps with Explicit Waits

browser.sleep() is flaky because it waits a fixed time regardless of when elements are actually ready. For more reliable tests, use Protractor's ExpectedConditions to wait for elements to be interactable:

const EC = protractor.ExpectedConditions;

this.new = async function () {
  await element(by.xpath('')).click();
  // Wait for links to become visible instead of fixed sleep
  await browser.wait(EC.visibilityOf(element(by.xpath('linkname'))), 5000);
  await browser.switchTo().defaultContent();
  
  const linkCount = await element.all(by.xpath('linkname')).count();
  
  for (let i = 0; i < linkCount; i++) {
    const currentLink = element.all(by.xpath('linkname')).get(i);
    await browser.wait(EC.elementToBeClickable(currentLink), 5000);
    await currentLink.click();
    
    const backButton = element(by.id("back"));
    await browser.wait(EC.elementToBeClickable(backButton), 5000);
    await backButton.click();
  }
};

This way, your test waits exactly as long as needed for elements to be ready, making it more stable across different environments.

内容的提问来源于stack exchange,提问作者Sneh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:45:50