Mengapa Selenium berkedip antara menemukan dan tidak menemukan elemen HTML tertentu?

Saya menggunakan Specflow/Selenium untuk mengotomatiskan pengujian aplikasi web yang saya kerjakan di lingkungan ASP.Net. Sebagian besar 'klik tombol' menyebabkan pemuatan halaman selesai. Saya menjalankan baris kode berikut untuk dieksekusi ketika mengklik tombol seperti itu, tetapi itu adalah potongan kode yang berkedip-kedip - terkadang ia menemukan elemen dan di lain waktu gagal. Mengapa demikian?

public class CreateQuestionPOM : BasePOM
{
    //Flickering find!
    [FindsBy(How = How.XPath, Using = "//label[text()[contains(.,'True/False')]]")] 
    private IWebElement trueFalseOption;

    [FindsBy(How = How.XPath, Using = "//a[@ct='Button' and @title='Next']")]
    private IWebElement nextButton; 

    public CreateQuestionPOM(IWebDriver driver) : base(driver) { }

    public void CreateTrueFalseQuestion()
    {            
        trueFalseOption.Click();
        nextButton.Click();

        WebDriverWait wait = new WebDriverWait(GetDriver(), TimeSpan.FromSeconds(20));
        wait.Until(driver1 => ((IJavaScriptExecutor)GetDriver()).ExecuteScript("return document.readyState").Equals("complete"));
    }

}

Tanda tangan metode di atas serupa dengan semua klik tombol yang terjadi pada halaman. Potongan kode di atas dipanggil setelah tombol sebelumnya diklik. Caranya sangat mirip dengan di atas - tunggu document.readystate menjadi complete. Tapi kenapa ini sering sekali berkedip dan apa solusi yang disarankan?


person PhD    schedule 01.10.2015    source sumber
comment
Mungkin terkadang halaman tidak dimuat sepenuhnya saat halaman di-scrap?   -  person JeffC    schedule 02.10.2015
comment
Saya tidak berpikir demikian mengingat pernyataan wait.Until.   -  person PhD    schedule 02.10.2015
comment
Klik terjadi sebelum penantian.   -  person JeffC    schedule 03.10.2015
comment
Err...ya. Pemuatan halaman terjadi setelah klik. Jadi klik terjadi sebelum menunggu. Tidak yakin saya mengerti...   -  person PhD    schedule 03.10.2015
comment
Satu-satunya elemen yang Anda temukan dalam cuplikan kode ini adalah sebelum menunggu. Jadi... jika elemennya tidak ditemukan, menunggu tidak akan membantu.   -  person JeffC    schedule 04.10.2015
comment
Begini alurnya: klik dan tunggu halaman baru. Setiap metode memanggil 'tunggu' setelah klik sehingga metode selanjutnya dapat menemukan elemen pada halaman baru yang diambil. Metode di atas dipanggil setelah metode serupa lainnya dijalankan. Seolah-olah penantian kembali ke halaman saat ini, bukannya benar-benar menunggu sebelum mencoba.   -  person PhD    schedule 04.10.2015


Jawaban (1)


Tidak perlu menunggu dalam kode Anda, ada wait.until(). Ketika kode tersebut dieksekusi, kode tersebut segera dieksekusi dan kondisi until dicentang. Jika kondisi until benar, eksekusi dilanjutkan. Hanya jika kondisi until salah maka harus menunggu. Jika kode dieksekusi cukup cepat, browser mungkin tidak akan bertransisi ke halaman berikutnya sebelum kondisi until dicentang. Kondisi until akan lolos karena halaman saat ini (halaman tempat Anda mengklik elemen) sudah dimuat. Satu hal yang dapat Anda coba adalah memilih elemen dari halaman yang diklik dan menunggu hingga elemen tersebut menjadi basi. Sebuah elemen menjadi basi jika tidak lagi ada di DOM. Saat halaman berikutnya dimuat, elemen pada halaman sebelumnya sudah basi. Coba kode di bawah ini dan lihat apakah itu membantu.

public void CreateTrueFalseQuestion()
{            
    trueFalseOption.Click();
    nextButton.Click();

    WebDriverWait wait = new WebDriverWait(GetDriver(), TimeSpan.FromSeconds(20));
    // when nextButton is stale you know the browser is transitioning...
    wait.until(ExpectedConditions.stalenessOf(nextButton));
    // ... then you wait for the new page to load
    wait.Until(driver1 => ((IJavaScriptExecutor)GetDriver()).ExecuteScript("return document.readyState").Equals("complete"));
}
person JeffC    schedule 04.10.2015