C# StaleElement单击网页中的表格行时发生异常

C# StaleElement单击网页中的表格行时发生异常,c#,angularjs,selenium-webdriver,protractor-net,C#,Angularjs,Selenium Webdriver,Protractor Net,第二种方式: IWebElement elem = driver.FindElement(By.XPath("//*[contains(text(),'" + nameCustomer + "')]//parent::div[contains(@id,'crm')]")); ExplicitWait.WaitAndClick(driver, elem); 我认为这个问题 对于StaleReferenceExceptions,以前创建的IWebElement不再附加到DOM,您可

第二种方式:

IWebElement elem = driver.FindElement(By.XPath("//*[contains(text(),'" + nameCustomer + "')]//parent::div[contains(@id,'crm')]"));
        ExplicitWait.WaitAndClick(driver, elem);
我认为这个问题 对于StaleReferenceExceptions,以前创建的IWebElement不再附加到DOM,您可能已经知道这一点。最可能发生的情况是: 1:点击搜索。 2:Selenium执行驱动程序。FindElement。。。并查找匹配的元素。 3:然后搜索功能完成,DOM更新。以前发现的旧IWebElement已经不见了。 4:然后Selenium尝试单击不再存在的元素,导致StaleElementException。有一种元素与之前的元素相匹配,但在Selenium的眼中它不是同一种元素

您关于大多数情况下都会发生这种情况的陈述让我更加怀疑这种情况,因为异常情况取决于事件的顺序,而事件的顺序取决于Selenium与网页的相对速度

如果这是您的问题,如何解决 您需要在页面上找到一些东西,向Selenium指示搜索操作已完成。这就是编写GUI自动化脚本的创造性所在。如果您知道页面上的某些内容会因加载而发生更改,请创建一个显式等待以确保完成。可能会出现一个加载栏,或者在搜索完成时出现一条消息。您可以在单击“搜索”之前获取与您的搜索不匹配的元素,然后进行显式等待以确保它消失,然后再继续查找您期望的结果

下面看起来像这样

在此之前执行的搜索操作。 WebDriverWait wait=新的WebDriverWait驱动程序,TimeSpan.FromSecondssecondsToWait; wait.UntilExpectedConditions.InvisibilityOfElementLocatedBy.XPath ExpressionForElements将消失; IWebElement elem=driver.FindElementBy.XPath/*[containstext,'+nameCustomer+']///parent::div[contains@id,‘客户关系管理’]; ExplicitWait.wait和clickdriver,elem;
我建议使用该方法来实现上面的显式等待。这些情况会经常出现。

1。此表出现之前是否发生过任何事件?i、 表隐藏在页面上,或者可能已预先填充了其他数据?2.您尝试过更精确的xpath吗?您的xpath只是尝试查找与页面1上的文本匹配的smthn。最初,表中填充了数据库中的前20个客户,搜索后,这些客户将被填充搜索条件的客户替换。2.文本即customername是唯一标识tablerow的属性。1。我猜Allard是前20位客户之一?2. //div[@id='crm']/div[text='Allard']-或者,如果您100%确定元素是唯一的,并且上面的大小写为true,则不需要它。1。你说得对,我要找的客户在第一页,在我开始搜索行动的那一刻就已经出现了,但与搜索行动后他的位置相比,它在另一个位置上。当同样的测试在寻找一个没有出现在第一页的客户时,它永远不会失败。我尝试了30多次。下面由@Tyler Nielsen给出的答案是对这种行为的完美解释。你是对的,你准确地描述了我问题的原因。我解决这个问题的方法是,在启动搜索功能之前先等待出现的消息不可见,然后再等待搜索结果可见。
IWebElement elem = driver.FindElement(By.XPath("//*[contains(text(),'" + nameCustomer + "')]//parent::div[contains(@id,'crm')]"));
        ExplicitWait.WaitAndClick(driver, elem);
var customers = driver.FindElements(NgBy.Repeater("customer in customerList"));
        foreach (var customer in customers)
        {
            if (elem.Text.Equals(nameCustomer))
            {
                elem.Click();
            }
        }