Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 30
×

Проблема з Selenium Webdriver

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

День добрий. Допоможіть будь ласка з проблемкою. Є такий от скромний тест, який заповнює форму невалідними наборами даних:

 @Test(dataProvider = "invalidAddressDataJson")
    public void addInvalidDeliveryAddress(Address provider){
        app.navigationHelper().goTo(By.cssSelector(".add-text"));
        app.addressHelper().fillAddressForm(provider);
        assertTrue(app.navigationHelper().isElementPresent(By.xpath(".//* 
                           [@class='errorMessage']")));
        app.navigationHelper().goTo(By.id("cancel-address"));
    }

І він, зараза, добре працює під час дебагінгу, покроково, але якщо запустити тест на виконання, то проходить тільки перший набір данних, а наступні падають з помилкою: org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with. Але ж під час дебагінгу всі локатори працюють, де може бути помилка? Очікування виставлене на 10 секунд: wd.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Дякую всім за підказки, допоміг банальний Thread.sleep(2000);

статичний вейтер — це одне з найгірших можливих рішень. Трошки гірший перфоманс і у вас знову буде це падати, ви піднімете таймаут, і буде просідати загальний час виконання тесту і якщо взяти собі такий патерн за правило, то скоро будете мати такі проблеми глобальними.

Треба робити лише smart waiter, щось на зразок


var finishWaiterTime = DateTime.Now + timeout;
do
{
//
}while (!successCondition && DateTime.Now < finishWaiterTime)

app.navigationHelper().goTo()

Кровь_из_глаз.жпг. Это что за дичь?
В дебаге скоре всего работает потому что ты выполнил действие с элементом, он изменился на странице и потом пока ты рассматривал детали снова стал доступен. Не в дебаге он тупо может не успевать вернуться к изначальному состоянию. Но всё это гадание на кофейной гуще.
Попробуй заюзать Selenide — он умный и умеет сам подождать когда нужно, и код красивей будет.

А на что за фреймворк использует сайт? (а то, возможно, вы зря силинием используете).

На якому саме рядку падає?
Плюс додайте взяття скріншоту під час падіння тесту.

Якщо не пофікситься, то як варіант спробуйте усі кліки, заповнення інпутів, і т.д. виконувати джаваскриптом на сторінці.

А вы на тот элемент повесили ожидание?

це треба дивитись конкретно сторінку, але у мене є теорія:
елемент присутній, селеніум його побачив, але між виконанням наступної команди джаваскріпт на сторінці змінив його, і тепер в селеніума в памяті старий елемент а на сторінці вже новий

тут бачу декілька підходів — я вгадую бо не знаю сторінки що тестується:
1. поставити банальний сліп на 1-2 секунди == Thread.sleep(1000)
2. виконати селеніумом кусок джаваскріпта на сторінці, якій вміє правельно дочекатись стану сторінки == більш конкретно ек скажу бо треба знати шо за сторінка, що там відбувається...
3. чекати виконання аякс запиту, і тільки тоді починаєте наствпну дію, приклад stackoverflow.com/...​o-load-universal-approach

знов такі це теж може не спрацювати бо ліби на сторінці можуть бути інші

Код на Джава. Переробив так:

 @Test(dataProvider = "invalidAddressDataJson")
    public void addInvalidDeliveryAddress(Address provider) throws InterruptedException {
        app.navigationHelper().goTo(By.xpath(".//*[@id=\"add-address\"]//*[.=\"Add new delivery address\"]"));
        boolean elementVisible = app.navigationHelper().isElementVisible(By.id("deliveryaddress-name-"));
        if(elementVisible) {
            app.addressHelper().fillAddressForm(provider);
        }
        assertTrue(app.navigationHelper().isElementPresent(By.xpath(".//*[@class='errorMessage']")));
        app.navigationHelper().goTo(By.id("cancel-address"));
    }
 public boolean isElementVisible(By locator){
            try{WebElement element = new WebDriverWait(wd, 10)
                    .until(ExpectedConditions.visibilityOfElementLocated(locator));
                return true;
            }catch (TimeoutException e){
                return false;
            }
    }

Нічого не змінилося — під час дебагінгу працює, а при виконанні падає. WTF?

new WebDriverWait(Driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible("your selector");

я допускаю що це сінг пейдж аплікуція, або просто нові дані підвантажуються джаваскріптом:

тре чекати покі конкретний елемент появиться і буде візібл,
іплісіт вейт чекає покі сторінка завантажиться — що є великою проблемою з сінг пейдж аплікуціями, де джабахатскріпт міняє дом, тобто для селеніума сторінка завантажилась і він думає шо все на місці — пробує доступитись до елемента, а на ділі джаваскріпт шось там міняє/колдує.

не впевнений на якій саме мові цей кусок, тому дам ссилку на джаву(для інших мов ідея та сама):
stackoverflow.com/...​it-for-element-using-java

То що працює в дебагу, означає, що щось або встигає ініціалізуватися, або навпаки не встигає =)

Загалом, з протрактором допомагало наступне

1) розвернути вікно на повну
browser.driver.manage().window().maximize();

2) Перевірити що селектор не вертає багато елементів. Перевірити, що селектор дійсно видимий

3) Чекати, доки елемент буде доступий до кліку
browser.wait(EC.elementToBeClickable(elm), 5000);

4) Проскролюватися до елементу
і т.п.

Підписатись на коментарі