เพื่อเพิ่มคำตอบของ @ jarib ฉันได้ทำวิธีการขยายหลายวิธีซึ่งช่วยกำจัดสภาพการแข่งขัน
นี่คือการตั้งค่าของฉัน:
ฉันมีคลาสที่เรียกว่า "Driver.cs" มันมีระดับคงที่เต็มรูปแบบของวิธีการขยายสำหรับไดรเวอร์และฟังก์ชั่นคงที่มีประโยชน์อื่น ๆ
สำหรับองค์ประกอบที่ฉันต้องการค้นคืนฉันสร้างวิธีการขยายแบบต่อไปนี้:
public static IWebElement SpecificElementToGet(this IWebDriver driver) {
return driver.FindElement(By.SomeSelector("SelectorText"));
}
สิ่งนี้ช่วยให้คุณสามารถดึงองค์ประกอบนั้นจากคลาสทดสอบใด ๆ ด้วยรหัส:
driver.SpecificElementToGet();
ตอนนี้ถ้าผลลัพธ์เป็น a StaleElementReferenceException
, ฉันมีวิธีคงที่ต่อไปนี้ในคลาสไดรเวอร์ของฉัน:
public static void WaitForDisplayed(Func<IWebElement> getWebElement, int timeOut)
{
for (int second = 0; ; second++)
{
if (second >= timeOut) Assert.Fail("timeout");
try
{
if (getWebElement().Displayed) break;
}
catch (Exception)
{ }
Thread.Sleep(1000);
}
}
พารามิเตอร์แรกของฟังก์ชันนี้คือฟังก์ชันใด ๆ ที่ส่งคืนออบเจ็กต์ IWebElement พารามิเตอร์ที่สองคือการหมดเวลาในหน่วยวินาที (รหัสสำหรับการหมดเวลาถูกคัดลอกจาก Selenium IDE สำหรับ FireFox) รหัสสามารถใช้เพื่อหลีกเลี่ยงข้อยกเว้นองค์ประกอบเก่าด้วยวิธีต่อไปนี้:
MyTestDriver.WaitForDisplayed(driver.SpecificElementToGet,5);
โค้ดด้านบนจะโทรออกdriver.SpecificElementToGet().Displayed
ไปจนกว่าจะdriver.SpecificElementToGet()
ไม่มีข้อยกเว้นและ.Displayed
ประเมินtrue
และ 5 วินาทีไม่ได้ผ่าน หลังจาก 5 วินาทีการทดสอบจะล้มเหลว
ที่ด้านพลิกเพื่อรอองค์ประกอบที่ไม่ได้อยู่คุณสามารถใช้ฟังก์ชั่นต่อไปนี้ในลักษณะเดียวกัน:
public static void WaitForNotPresent(Func<IWebElement> getWebElement, int timeOut) {
for (int second = 0;; second++) {
if (second >= timeOut) Assert.Fail("timeout");
try
{
if (!getWebElement().Displayed) break;
}
catch (ElementNotVisibleException) { break; }
catch (NoSuchElementException) { break; }
catch (StaleElementReferenceException) { break; }
catch (Exception)
{ }
Thread.Sleep(1000);
}
}