Kiểm tra xem phần tử có hiện diện bằng Selenium WebDriver không?


163

Có cách nào để kiểm tra nếu có một yếu tố không? Bất kỳ phương thức findEuity nào cũng sẽ kết thúc bằng một ngoại lệ, nhưng đó không phải là điều tôi muốn, bởi vì đó có thể là một yếu tố không có mặt và điều đó không sao, đó không phải là một thử nghiệm thất bại, vì vậy một ngoại lệ không thể là giải pháp.

Tôi đã tìm thấy bài đăng này: Selenium c # WebSearch: Chờ cho đến khi Element có mặt Nhưng đây là cho C # và tôi không giỏi lắm về nó. Bất cứ ai cũng có thể dịch mã sang Java? Tôi xin lỗi các bạn, tôi đã thử nó trong Eclipse nhưng tôi không hiểu đúng về mã Java.

Đây là mã:

public static class WebDriverExtensions{
    public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds){

        if (timeoutInSeconds > 0){
            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
            return wait.Until(drv => drv.FindElement(by));
        }

        return driver.FindElement(by);
    }
}

Tôi có một vài phương thức hoạt động rất hiệu quả trong việc kiểm tra một đối tượng nhưng nó phụ thuộc vào những gì bạn muốn làm với nó. ví dụ bạn có muốn tìm phần tử cho đến khi nó tồn tại không, bạn có muốn tìm phần tử đó cho đến khi nó không còn tồn tại hay bạn chỉ muốn thử tìm nó?
CBRRacer

1
Java rất giống với C # Tôi nghĩ rằng một trong những vấn đề chính mà bạn đang gặp phải ở đây là ở java đó là WebEuity thay vì IWebEuity
CBRRacer

Bạn có biết về phương pháp chờ đợi ngầm? Bằng cách thiết lập điều này khi bắt đầu thử nghiệm, bạn không bao giờ phải kiểm tra sự tồn tại của một yếu tố vì nó sử dụng giá trị chờ ẩn để thăm dò ý kiến, tuy nhiên nếu vượt quá giá trị đó, nó sẽ ném ngoại lệ
Bob Evans

Đây là bài viết của tôi về WebDriverWait trong Java: WebDriverWait

Nếu một trong hai trường hợp đều ổn, điều này có thể gây ra vấn đề đối với hiệu suất thử nghiệm, vì thời gian chờ liên quan để chờ đợi một yếu tố mà bạn không mong đợi tồn tại thực sự tăng lên. Tôi đã sử dụng một vài hack để có được thời gian chờ đợi, nhưng vẫn chưa tìm được giải pháp thực sự sạch cho việc này.
mrfreester

Câu trả lời:


277

Sử dụng findElementsthay vì findElement.

findElements sẽ trả về một danh sách trống nếu không tìm thấy phần tử phù hợp thay vì ngoại lệ.

Để kiểm tra xem một phần tử có mặt hay không, bạn có thể thử

Boolean isPresent = driver.findElements(By.yourLocator).size() > 0

Điều này sẽ trả về true nếu ít nhất một phần tử được tìm thấy và false nếu nó không tồn tại.

Các tài liệu chính thức khuyến nghị phương pháp này:

findEuity không nên được sử dụng để tìm kiếm các phần tử không có mặt, sử dụng findElements (By) và xác nhận đáp ứng độ dài bằng không thay thế.


32
Điều này sẽ thêm rất nhiều thời gian để chạy thử nghiệm của bạn. Bạn không thể sử dụng kỹ thuật này ở mọi nơi.
Dropogans

8
@Droogans - Tôi sẽ không thêm thời gian vào bài kiểm tra của bạn. Lý do nó không phải là vì chờ đợi mặc định vẫn là 0. Nếu bạn tăng chờ đợi ngầm định mặc định, thì tôi đồng ý rằng nó sẽ xảy ra, nhưng dường như không phải là trường hợp ở đây.
djangofan

1
Tốt gọi djangofan! Tôi đã sử dụng thành công chiến lược này bằng cách thay đổi thời gian chờ ngầm định của trình điều khiển về 0, sau đó thay đổi lại về giá trị trước đó.
emery

3
Điều này đã đưa ra một ngoại lệ NoSuchEuityFound, đó là một sự xấu hổ vì tôi đã hy vọng sử dụng điều này để tránh bắt ngoại lệ đó trong một trường hợp cụ thể.

1
Cách dễ dàng hơn nhiều là sử dụng: if (driver.getPageSource (). Chứa ("Một văn bản trong trang")) {} Nếu trang chứa văn bản này thì điều kiện sẽ là đúng, nếu không nó sẽ sai và bạn có thể viết mã phù hợp.
pradyot

56

Điều gì về một phương thức riêng chỉ đơn giản là tìm kiếm phần tử và xác định xem nó có hiện diện như thế này không:

private boolean existsElement(String id) {
    try {
        driver.findElement(By.id(id));
    } catch (NoSuchElementException e) {
        return false;
    }
    return true;
}

Điều này sẽ khá dễ dàng và thực hiện công việc.

Chỉnh sửa: bạn thậm chí có thể đi xa hơn và lấy By elementLocatortham số làm tham số, loại bỏ các sự cố nếu bạn muốn tìm phần tử bằng một thứ khác ngoài id.


3
Đúng, đây là con đường để đi. Không hiểu tại sao mọi người lại bỏ qua cách này và đếm các yếu tố phù hợp, xem kết quả có bằng 0.
Ralph Lavelle

45
Chà, tôi phải nói rằng sử dụng Ngoại lệ để điều chỉnh luồng chương trình không phải là cách tốt nhất để đi.
Dennis

2
Huh? Đó là đề nghị của bạn! Đó là một cách tốt để đi nếu bài kiểm tra của bạn hy vọng không tìm thấy phần tử. Như bạn hiển thị, chỉ cần trả về null và assert.isnull hoặc isnotnull, đó là một cách có ý nghĩa để kiểm tra nếu một thứ tồn tại.
Ralph Lavelle

2
Trong trường hợp tôi giải thích sai câu hỏi "có cách nào để kiểm tra xem có yếu tố nào không?" sai, tôi sẽ vui mừng tìm hiểu lý do tại sao ý kiến ​​của bạn khác nhau về việc liệu đây có phải là một câu trả lời hợp pháp hay không.
Dennis

có thể muốn giảm thời gian chờ đợi. Ngay bây giờ, nếu phần tử không tồn tại, bạn phải đợi "30 giây" trước khi hàm trả về sai
Jason Smiley

14

Tôi thấy rằng điều này hoạt động cho Java:

WebDriverWait waiter = new WebDriverWait(driver, 5000);
waiter.until( ExpectedConditions.presenceOfElementLocated(by) );
driver.FindElement(by);

18
presenceOfElementLocatedsẽ ném Ngoại lệ nếu không tìm thấy phần tử trên bất kỳ nỗ lực cụ thể nào. Để tránh điều này, hãy thêm một wait.ignoring(NoSuchElementException.class);tuyên bố giữa dòng đầu tiên và thứ hai.
Steve Chambers

8
public static WebElement FindElement(WebDriver driver, By by, int timeoutInSeconds)
{
    WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds);
    wait.until( ExpectedConditions.presenceOfElementLocated(by) ); //throws a timeout exception if element not present after waiting <timeoutInSeconds> seconds
    return driver.findElement(by);
}

5

Tôi gặp vấn đề tương tự. Đối với tôi, tùy thuộc vào cấp phép của người dùng, một số liên kết, nút và các yếu tố khác sẽ không hiển thị trên trang. Một phần của bộ phần mềm của tôi đã kiểm tra các phần tử NÊN bị thiếu, bị thiếu. Tôi đã dành hàng giờ cố gắng để tìm ra điều này. Cuối cùng tôi đã tìm thấy giải pháp hoàn hảo.

Những gì nó làm, là bảo trình duyệt tìm kiếm bất kỳ và tất cả các yếu tố dựa trên được chỉ định. Nếu kết quả là 0, điều đó có nghĩa là không có yếu tố nào dựa trên đặc điểm kỹ thuật được tìm thấy. Sau đó, tôi có mã thực thi một câu lệnh if để cho tôi biết nó không được tìm thấy.

Đây là trong C#, vì vậy bản dịch sẽ cần phải được thực hiện Java. Nhưng không nên quá khó.

public void verifyPermission(string link)
{
    IList<IWebElement> adminPermissions = driver.FindElements(By.CssSelector(link));
    if (adminPermissions.Count == 0)
    {
        Console.WriteLine("User's permission properly hidden");
    }
}

Ngoài ra còn có một con đường khác bạn có thể đi tùy thuộc vào những gì bạn cần cho bài kiểm tra của mình.

Đoạn mã sau đang kiểm tra xem liệu một yếu tố rất cụ thể có tồn tại trên trang không. Tùy thuộc vào sự tồn tại của phần tử, tôi có bài kiểm tra thực thi nếu khác.

Nếu phần tử tồn tại và được hiển thị trên trang, tôi đã console.writecho tôi biết và tiếp tục. Nếu yếu tố trong câu hỏi tồn tại, tôi không thể thực hiện kiểm tra tôi cần, đó là lý do chính đằng sau cần phải thiết lập điều này.

Nếu phần tử Không tồn tại và không được hiển thị trên trang. Tôi có cái khác trong nếu khác thực hiện kiểm tra.

IList<IWebElement> deviceNotFound = driver.FindElements(By.CssSelector("CSS LINK GOES HERE"));
//if the element specified above results in more than 0 elements and is displayed on page execute the following, otherwise execute whats in the else statement
if (deviceNotFound.Count > 0 && deviceNotFound[0].Displayed){
    //script to execute if element is found
} else {
    //Test script goes here.
}

Tôi biết tôi hơi muộn khi trả lời OP. Hy vọng điều này sẽ giúp được ai đó!


5

Hãy thử điều này: Gọi phương thức này và truyền 3 đối số:

  1. Biến WebDriver. // giả sử driver_variable làm trình điều khiển.
  2. Các yếu tố mà bạn sẽ kiểm tra. Nên cung cấp từ phương pháp. // ví dụ: By.id ("id")
  3. Giới hạn thời gian tính bằng giây.

Ví dụ: WaitForEuityPftime (trình điều khiển, By.id ("id"), 10);

public static WebElement waitForElementPresent(WebDriver driver, final By by, int timeOutInSeconds) {

        WebElement element; 

        try{
            driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait() 

            WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds); 
            element = wait.until(ExpectedConditions.presenceOfElementLocated(by));

            driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); //reset implicitlyWait
            return element; //return the element
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return null; 
    }

3

Bạn có thể làm cho mã chạy nhanh hơn bằng cách rút ngắn thời gian chờ selenium trước câu lệnh thử bắt của bạn.

Tôi sử dụng đoạn mã sau để kiểm tra xem có yếu tố nào không.

protected boolean isElementPresent(By selector) {
    selenium.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
    logger.debug("Is element present"+selector);
    boolean returnVal = true;
    try{
        selenium.findElement(selector);
    } catch (NoSuchElementException e){
        returnVal = false;
    } finally {
        selenium.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
    }
    return returnVal;
}

Đây là những gì tôi sử dụng trong mã của tôi. Tôi để thời gian chờ Selenium theo mặc định và sau đó sử dụng cái này.
Nicholas DiP Square

2
Kể từ khi viết câu trả lời này, tôi đã học được rằng sử dụng ExpectedConditions được coi là hình thức tốt hơn nhưng sử dụng câu lệnh try Catch vẫn hữu ích khi cố gắng xác định xem có thành phần nào không.
EsotericNonsense

Tôi bị mắc kẹt trên một phiên bản cũ của selenium vì tôi phải kiểm tra IE8. nhưng tôi sẽ thử khi tôi có thể nâng cấp
Nicholas DiP quảng cáo

Mỗi lần phương thức của bạn sẽ đặt thời gian chờ ẩn ngầm, nhưng về mặt logic, chúng ta chỉ nên đặt chờ đợi ngầm định một lần sau khi khởi tạo đối tượng trình điều khiển và thời gian chờ được đặt thành phiên trình điều khiển.
Shekhar Swami

3

Viết hàm / methos sau bằng Java:

protected boolean isElementPresent(By by){
        try{
            driver.findElement(by);
            return true;
        }
        catch(NoSuchElementException e){
            return false;
        }
    }

Gọi phương thức với tham số thích hợp trong quá trình khẳng định.


2

nếu bạn đang sử dụng rspec-Webdo trong ruby, bạn có thể sử dụng tập lệnh này với giả định rằng một phần tử thực sự không nên có mặt và đó là một bài kiểm tra đã qua.

Đầu tiên, viết phương thức này trước từ tệp RB lớp của bạn

class Test
 def element_present?
    begin
        browser.find_element(:name, "this_element_id".displayed?
        rescue Selenium::WebDriver::Error::NoSuchElementError
            puts "this element should not be present"
        end
 end

Sau đó, trên tệp spec của bạn, gọi phương thức đó.

  before(:all) do    
    @Test= Test.new(@browser)
  end

 @Test.element_present?.should == nil

Nếu phần tử của bạn KHÔNG có mặt, thông số kỹ thuật của bạn sẽ vượt qua, nhưng nếu phần tử có mặt, nó sẽ đưa ra lỗi, kiểm tra thất bại.


2

Điều này làm việc cho tôi:

 if(!driver.findElements(By.xpath("//*[@id='submit']")).isEmpty()){
    //THEN CLICK ON THE SUBMIT BUTTON
}else{
    //DO SOMETHING ELSE AS SUBMIT BUTTON IS NOT THERE
}

vấn đề tương tự tồn tại ở đây: nếu phần tử "// * [@ id = 'submit']" không tồn tại thì sao? sau đó một ngoại lệ sẽ được đưa ra, do đó, nếu điều kiện không bao giờ đánh giá
MrBCut

1
public boolean isElementDisplayed() {
        return !driver.findElements(By.xpath("...")).isEmpty();
    }

1

Cá nhân, tôi luôn tìm kiếm một hỗn hợp các câu trả lời ở trên và tạo ra một phương thức Tiện ích tĩnh có thể sử dụng lại sử dụng size() > 0đề xuất:

public Class Utility {
   ...
   public static boolean isElementExist(WebDriver driver, By by) {
      return driver.findElements(by).size() > 0;
   ...
}

Đây là gọn gàng, có thể tái sử dụng, có thể bảo trì ... tất cả những thứ tốt đó ;-)


0

Để tìm một phần tử cụ thể có hay không, chúng ta phải sử dụng phương thức findElements () thay vì findEuity () ..

int i=driver.findElements(By.xpath(".......")).size();
if(i=0)
System.out.println("Element is not present");
else
System.out.println("Element is present");

cái này hiệu quả với tôi .. gợi ý cho tôi nếu tôi sai ..


0

Điều này nên làm điều đó:

try {
    driver.findElement(By.id(id));
} catch (NoSuchElementException e) {
    //do what you need here if you were expecting
    //the element wouldn't exist
}

0

Đưa đoạn mã của tôi. Vì vậy, phương pháp bên dưới sẽ kiểm tra xem nút ' Tạo ứng dụng mới ' có tồn tại trên một trang hay không. Lưu ý rằng tôi đã sử dụng khoảng thời gian chờ là 0 giây.

public boolean isCreateNewApplicationButtonVisible(){
    WebDriverWait zeroWait = new WebDriverWait(driver, 0);
    ExpectedCondition<WebElement> c = ExpectedConditions.presenceOfElementLocated(By.xpath("//input[@value='Create New Application']"));
    try {
        zeroWait.until(c);
        logger.debug("Create New Application button is visible");
        return true;
    } catch (TimeoutException e) {
        logger.debug("Create New Application button is not visible");
        return false;
    }
}

0

Tôi sẽ sử dụng một cái gì đó như (với Scala [mã trong Java 8 "tốt" cũ có thể tương tự như thế này]):

object SeleniumFacade {

  def getElement(bySelector: By, maybeParent: Option[WebElement] = None, withIndex: Int = 0)(implicit driver: RemoteWebDriver): Option[WebElement] = {
    val elements = maybeParent match {
      case Some(parent) => parent.findElements(bySelector).asScala
      case None => driver.findElements(bySelector).asScala
    }
    if (elements.nonEmpty) {
      Try { Some(elements(withIndex)) } getOrElse None
    } else None
  }
  ...
}

vậy thì

val maybeHeaderLink = SeleniumFacade getElement(By.xpath(".//a"), Some(someParentElement))

0

Cách đơn giản nhất tôi tìm thấy trong Java là:

List<WebElement> linkSearch=  driver.findElements(By.id("linkTag"));
int checkLink=linkSearch.size();
if(checkLink!=0){  //do something you want}

0

Bạn có thể thử chờ đợi ngầm:

WebDriver driver = new FirefoxDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
driver.Url = "http://somedomain/url_that_delays_loading";
IWebElement myDynamicElement = driver.FindElement(By.Id("someDynamicElement"));

Hoặc bạn có thể thử chờ một cách rõ ràng:

IWebDriver driver = new FirefoxDriver();
driver.Url = "http://somedomain/url_that_delays_loading";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
    {
        return d.FindElement(By.Id("someDynamicElement"));
    });

Rõ ràng sẽ kiểm tra nếu phần tử có mặt trước một số hành động. Chờ đợi ngầm có thể được gọi ở mọi nơi trong mã. Ví dụ sau một số hành động AJAX.

Nhiều hơn bạn có thể tìm thấy tại trang SeleniumHQ

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.