Uji apakah elemen hadir menggunakan Selenium WebDriver?

163

Apakah ada cara bagaimana menguji apakah suatu elemen ada? Setiap metode findElement akan diakhiri dengan pengecualian, tetapi bukan itu yang saya inginkan, karena bisa jadi elemen tidak ada dan tidak apa-apa, itu bukan kegagalan tes, jadi pengecualian tidak bisa menjadi solusi.

Saya telah menemukan posting ini: Selenium c # Webdriver: Tunggu Sampai Elemen Hadir Tapi ini untuk C # dan saya tidak pandai itu. Adakah yang bisa menerjemahkan kode ke Jawa? Saya minta maaf teman-teman, saya mencobanya di Eclipse tapi saya tidak bisa melakukannya dengan benar ke kode Java.

Ini kodenya:

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);
    }
}
penguji
sumber
Saya memiliki beberapa metode yang bekerja sangat efektif untuk memeriksa suatu objek tetapi tergantung pada apa yang ingin Anda lakukan dengannya. misalnya apakah Anda ingin mencari elemen sampai ada, apakah Anda ingin mencarinya sampai tidak ada lagi atau Anda hanya ingin mencoba menemukannya?
CBRRacer
1
Java sangat mirip dengan C # Saya pikir salah satu masalah utama yang Anda temui di sini adalah di Jawa itu WebElement, bukan IWebElement
CBRRacer
Apakah Anda tahu tentang metode menunggu implisit? Dengan mengatur ini pada awal tes Anda tidak perlu memeriksa keberadaan elemen karena menggunakan nilai tunggu implisit untuk polling, namun jika melebihi nilai itu akan membuang pengecualian
Bob Evans
Berikut ini adalah posting saya tentang WebDriverWait di Jawa: WebDriverWait
Jika salah satu kasus ok, ini bisa menjadi masalah untuk kinerja tes, karena waktu tunggu yang terkait untuk menunggu elemen yang tidak Anda harapkan ada benar-benar bertambah. Saya telah menggunakan beberapa peretasan untuk berkeliling menunggu waktu, tetapi belum menemukan solusi yang benar-benar bersih untuk ini.
mrfreester

Jawaban:

277

Gunakan findElementssebagai ganti findElement.

findElements akan mengembalikan daftar kosong jika tidak ada elemen yang cocok yang ditemukan selain pengecualian.

Untuk memeriksa apakah ada elemen, Anda dapat mencoba ini

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

Ini akan mengembalikan true jika setidaknya satu elemen ditemukan dan false jika tidak ada.

Dokumentasi resmi merekomendasikan metode ini:

findElement tidak boleh digunakan untuk mencari elemen yang tidak ada, gunakan findElements (oleh) dan sebagai gantinya berikan respons panjang nol.

el roso
sumber
32
Ini akan menambah banyak waktu yang diperlukan untuk menjalankan tes Anda. Anda tidak dapat menggunakan teknik ini di mana-mana.
Droogan
8
@Dogogan - Saya tidak akan menambah waktu untuk tes Anda. Alasan mengapa hal itu tidak terjadi adalah karena default implisit wait masih 0. Jika Anda meningkatkan default implisit wait, maka saya setuju bahwa itu akan terjadi, tetapi tampaknya tidak terjadi di sini.
Djangofan
1
Panggilan bagus djangofan! Saya berhasil menggunakan strategi ini dengan mengubah waktu tunggu implisit driver menjadi nol, kemudian mengubahnya kembali ke nilai sebelumnya.
Amril
3
Ini memberikan pengecualian NoSuchElementFound, yang memalukan karena saya berharap untuk menggunakan ini untuk menghindari menangkap pengecualian itu dalam contoh yang diberikan.
1
Cara yang lebih mudah adalah dengan menggunakan: if (driver.getPageSource (). Berisi ("Teks dalam halaman")) {} Jika halaman berisi teks ini maka kondisinya akan benar, atau jika tidak maka akan salah dan Anda dapat memberi kode demikian.
pradyot
56

Bagaimana dengan metode pribadi yang hanya mencari elemen dan menentukan apakah ada seperti ini:

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

Ini akan sangat mudah dan melakukan pekerjaan.

Sunting: Anda bahkan dapat melangkah lebih jauh dan mengambil By elementLocatorsebagai parameter, menghilangkan masalah jika Anda ingin menemukan elemen dengan sesuatu selain id.

Dennis
sumber
3
Yap, ini jalannya. Tidak mengerti mengapa orang mengabaikan cara ini, dan menghitung elemen yang cocok, melihat apakah hasilnya 0.
Ralph Lavelle
45
Yah, saya harus mengatakan menggunakan Pengecualian untuk mengatur aliran program bukan cara terbaik untuk pergi.
Dennis
2
Hah? Itu saran Anda! Ini adalah cara yang baik untuk pergi jika tes Anda berharap tidak menemukan elemen. Seperti yang Anda tunjukkan, kembalikan null dan assert.isnull atau isnotnull, yang merupakan cara yang berarti untuk menguji apakah ada sesuatu.
Ralph Lavelle
2
Jika saya salah menafsirkan pertanyaan, "adakah cara untuk menguji apakah ada elemen?" salah, saya akan senang mengetahui mengapa pendapat Anda berbeda pada apakah ini merupakan jawaban yang sah atau tidak.
Dennis
mungkin ingin mengurangi waktu tunggu. Saat ini, jika elemen tidak ada, Anda harus menunggu "30 detik" sebelum fungsi kembali salah
Jason Smiley
14

Saya menemukan bahwa ini berfungsi untuk Java:

WebDriverWait waiter = new WebDriverWait(driver, 5000);
waiter.until( ExpectedConditions.presenceOfElementLocated(by) );
driver.FindElement(by);
Tango Ben
sumber
18
presenceOfElementLocatedakan mengeluarkan Pengecualian jika elemen tidak ditemukan pada upaya tertentu. Untuk menghindari ini, tambahkan wait.ignoring(NoSuchElementException.class);pernyataan antara baris pertama dan kedua.
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);
}
RedDeckWins
sumber
5

Saya memiliki masalah yang sama. Bagi saya, tergantung pada tingkat izin pengguna, beberapa tautan, tombol, dan elemen lainnya tidak akan ditampilkan di halaman. Bagian dari suite saya sedang menguji bahwa elemen-elemen yang HARUS hilang, hilang. Saya menghabiskan berjam-jam mencoba untuk mencari tahu ini. Saya akhirnya menemukan solusi yang tepat.

Apa yang dilakukan, adalah memberitahu browser untuk mencari elemen apa saja dan semua elemen yang ditentukan. Jika hasilnya 0, itu berarti tidak ada elemen berdasarkan spesifikasi yang ditemukan. Lalu saya minta kode mengeksekusi pernyataan if untuk memberi tahu saya bahwa itu tidak ditemukan.

Ini sudah dalam C#, jadi terjemahan perlu dilakukan Java. Tapi seharusnya tidak terlalu sulit.

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

Ada juga jalur lain yang dapat Anda ambil tergantung pada apa yang Anda butuhkan untuk ujian Anda.

Cuplikan berikut ini memeriksa untuk melihat apakah ada elemen yang sangat spesifik pada halaman. Bergantung pada keberadaan elemen, saya memiliki tes yang menjalankan if if.

Jika elemen ada dan ditampilkan pada halaman, saya telah console.writememberi tahu saya dan melanjutkan. Jika elemen yang dimaksud ada, saya tidak dapat menjalankan tes yang saya butuhkan, yang merupakan alasan utama di balik perlu mengatur ini.

Jika elemen Tidak Ada, dan tidak ditampilkan pada halaman. Saya memiliki yang lain di if else melaksanakan tes.

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.
}

Saya tahu saya sedikit terlambat dalam menanggapi OP. Semoga ini bisa membantu seseorang!

Tasha
sumber
5

Coba ini: Panggil metode ini dan berikan 3 argumen:

  1. Variabel WebDriver. // mengasumsikan driver_variable sebagai driver.
  2. Elemen yang akan Anda periksa. Harus menyediakan dari dengan metode. // ex: By.id ("id")
  3. Batas waktu dalam detik.

Contoh: waitForElementPresent (driver, 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; 
    }
Prabu Ananthakrishnan
sumber
3

Anda dapat membuat kode berjalan lebih cepat dengan mempersingkat waktu selenium sebelum pernyataan coba-coba.

Saya menggunakan kode berikut untuk memeriksa apakah ada elemen.

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;
}
Omong kosong Esoterik
sumber
Inilah yang saya gunakan dalam kode saya. Saya meninggalkan batas waktu Selenium di default dan kemudian menggunakan ini.
Nicholas DiPiazza
2
Sejak menulis jawaban ini saya belajar bahwa menggunakan ExpectedConditions dianggap sebagai bentuk yang lebih baik tetapi menggunakan pernyataan try catch masih berguna ketika mencoba untuk menentukan apakah suatu elemen tidak ada.
EsotericNonsense
Saya terjebak pada versi selenium lama karena saya harus menguji IE8. tetapi saya akan mencobanya ketika saya bisa memutakhirkan
Nicholas DiPiazza
Setiap kali metode Anda akan menetapkan batas waktu tunggu implisit, tetapi secara logis kita harus menetapkan waktu tunggu implisit hanya setelah menginisialisasi objek driver dan batas waktu diatur ke sesi driver.
Shekhar Swami
3

Tulis fungsi / meto berikut menggunakan Java:

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

Panggil metode dengan parameter yang sesuai selama pernyataan.

Ripon Al Wasim
sumber
2

jika Anda menggunakan rspec-Webdriver di ruby, Anda dapat menggunakan skrip ini dengan asumsi bahwa suatu elemen seharusnya benar-benar tidak ada dan itu adalah tes yang lulus.

Pertama, tulis metode ini terlebih dahulu dari file RB kelas Anda

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

Kemudian, pada file spec Anda, panggil metode itu.

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

 @Test.element_present?.should == nil

Jika elemen Anda TIDAK ada, spec Anda akan lulus, tetapi jika elemen tersebut ada, itu akan menimbulkan kesalahan, pengujian gagal.

abu-abu
sumber
2

Ini bekerja untuk saya:

 if(!driver.findElements(By.xpath("//*[@id='submit']")).isEmpty()){
    //THEN CLICK ON THE SUBMIT BUTTON
}else{
    //DO SOMETHING ELSE AS SUBMIT BUTTON IS NOT THERE
}
Amstel Bytes
sumber
masalah yang sama ada di sini: bagaimana jika elemen "// * [@ id = 'submit']" tidak ada? maka pengecualian akan dilempar, sehingga syarat jika tidak pernah mengevaluasi
MrBCut
1
public boolean isElementDisplayed() {
        return !driver.findElements(By.xpath("...")).isEmpty();
    }
Bogdan Shulga
sumber
1

Secara pribadi, saya selalu mencari campuran jawaban di atas dan membuat metode Utilitas statis yang dapat digunakan kembali yang menggunakan size() > 0saran:

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

Ini rapi, dapat digunakan kembali, dipelihara ... semua itu bagus ;-)

Charlie Seligman
sumber
0

Untuk menemukan Elemen tertentu ada atau tidak, kita harus menggunakan metode findElements () alih-alih findElement () ..

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

ini bekerja untuk saya .. sarankan saya jika saya salah ..

Subbarao Gaddam
sumber
0

Ini harus dilakukan:

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

Memberikan potongan kode saya. Jadi, metode di bawah ini memeriksa apakah elemen web acak tombol ' Buat Aplikasi Baru ' ada di halaman atau tidak. Perhatikan bahwa saya telah menggunakan periode tunggu sebagai 0 detik.

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;
    }
}
Rambo7
sumber
0

Saya akan menggunakan sesuatu seperti (dengan Scala [kode dalam Java 8 "baik" yang lama mungkin mirip dengan ini]):

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
  }
  ...
}

sehingga kemudian,

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

Cara paling sederhana yang saya temukan di Jawa adalah:

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

Anda dapat mencoba menunggu tersirat:

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"));

Atau Anda dapat mencoba menunggu secara eksplisit:

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"));
    });

Eksplisit akan memeriksa apakah elemen ada sebelum beberapa tindakan. Penantian implisit dapat dilakukan di setiap tempat dalam kode. Misalnya setelah beberapa tindakan AJAX.

Lebih banyak dapat Anda temukan di halaman SeleniumHQ

streser
sumber