Thucydides проблема: Page Object Pattern и чекбоксы, селекты

Всем привет, уже не первый раз наблюдаю подобную проблему, что используя Page Object Pattern (POP) вываливается ошибка при попытке нажать на чекбокс:

70439 [main] INFO net.thucydides.core.steps.StepInterceptor - STEP FAILED: accept_terms - org.openqa.selenium.WebDriverException: unknown error: Runtime.evaluate threw exception: TypeError: Cannot read property 'click' of null
  (Session info: chrome=35.0.1916.114)
  (Driver info: chromedriver=2.8.240825,platform=Linux 3.8.0-35-generic x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 295 milliseconds
Build info: version: '2.39.0', revision: '14fa800511cc5d66d426e08b0b2ab926c7ed7398', time: '2013-12-16 13:18:38'
System info: host: 'nxc003', ip: '127.0.1.1', os.name: 'Linux', os.arch: 'amd64', os.version: '3.8.0-35-generic', java.version: '1.8.0'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{applicationCacheEnabled=false, rotatable=false, chrome={userDataDir=/tmp/.org.chromium.Chromium.CLCF3Q}, takesHeapSnapshot=true, databaseEnabled=false, handlesAlerts=true, version=35.0.1916.114, platform=LINUX, browserConnectionEnabled=false, nativeEvents=true, acceptSslCerts=true, locationContextEnabled=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}]
Session ID: 54402e08961a5b03e7b489b683bcb823
70491 [main] INFO net.thucydides.core.steps.StepInterceptor - SKIPPED STEP: confirm
70493 [main] INFO net.thucydides.core.steps.StepInterceptor - SKIPPED STEP: assert_text

import net.thucydides.core.pages.PageObject;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

    public class Summary extends PageObject
    {
        public WebDriver driver;
    
        public Summary(WebDriver driver) {
            super(driver);
        }
    
       @FindBy(id= "accept-terms")
        private WebElement acceptTerms;
    
        public void AcceptTerms()
        {
            $(acceptTerms).click();
        }
    }

import net.thucydides.core.annotations.Step;
import net.thucydides.core.pages.Pages;
import net.thucydides.core.steps.ScenarioSteps;
import org.junit.Assert;

import static org.hamcrest.Matchers.is;


public class MySteps extends ScenarioSteps
{
 Summary summary;

    public MySteps(Pages pages)
    {
        super(pages);
    }

    @Step
    public void start_browser()
    {
        HomePage loginPage = getPages().get(HomePage.class);
        loginPage.open();
    }

    @Step
    public void accept_terms()
    {
        summary.AcceptTerms();
    }
}

@Story(Application.Test.Booking.class)
@RunWith(ThucydidesRunner.class)
@Concurrent(threads="8")
public class BlaBlaTest
{

...........................


@WithDriver("chrome")
    @WithTag("register_user")
    @Test
    public void RegisterUser() throws InterruptedException
    {
        user.start_browser();
        user.homepage_select_dates_and_submit();
        user.room_and_rate_page_select_room();
        user.skip_extras();
        user.fill_guest_info_page
                (
                        account.getProperty("fname"),
                        account.getProperty("lname"),
                        account.getProperty("phoneNumber"),
                        account.getProperty("email"),
                        account.getProperty("address"),
                        account.getProperty("zipCode"),
                        account.getProperty("city")
                );
        user.submit_summaty_page(card.getProperty("cardName"), card.getProperty("cardNumber"));
        user.accept_terms(); <----------------------------------------------------------------
        user.confirm();
        user.assert_text("Reservation Confirmed");
    }
}

НО!!

если в main-классе вызвать, то всё отлично:

@WithDriver("chrome")
    @WithTag("register_user")
    @Test
    public void RegisterUser() throws InterruptedException
    {
        user.start_browser();
        user.homepage_select_dates_and_submit();
        user.room_and_rate_page_select_room();
        user.skip_extras();
        user.fill_guest_info_page
                (
                        account.getProperty("fname"),
                        account.getProperty("lname"),
                        account.getProperty("phoneNumber"),
                        account.getProperty("email"),
                        account.getProperty("address"),
                        account.getProperty("zipCode"),
                        account.getProperty("city")
                );
        user.submit_summaty_page(card.getProperty("cardName"), card.getProperty("cardNumber"));    
        AcceptTerms(); <----------------------------------------------------------------
        user.confirm();
        user.assert_text("Reservation Confirmed");
    }

    public void AcceptTerms()
    {
        driver.findElement(By.id("accept-terms")).click();
    }

Кто-то может сталкивался? Аналогичная проблема с некоторыми селекторами(JQuery).

Можно ли всё-таки реализовать это через POP, а не захламлять main-класс?

Заранее спасибо!

Мне одному кажется, что проблема вовсе не в PageObject’ах? Подключать ожидания не пробовали? :wink:

Пробовал ) не помогает:)

А как пробовали?

Стандартным дедовским методом, так как не нужно ждать появления элемента:

Ну кто ж так ждет-то? Про имплисит / эксплисит вейты значит ничего не читали? А как же конструктор пейдж обджектов специально для аяксовских страниц? А как же встроенные во фреймворк методы вейта появления элемента? В общем, вот статья, изучайте, пробуйте.

1 лайк

имплисит - тоже не помогло :smile:

за статью спасиб, попробую сейчас, отпишу результат

по поводу чекбокса…он сразу подгружается и видим…
просто показывает, что нельзя на него нажать…

Caused by: org.openqa.selenium.NoSuchElementException: Timed out after 10 seconds. Unable to locate the element: Element is not usable [[ChromeDriver: chrome on LINUX (e88f74951265394851c48f2f8bf3f244)] -> id: accept-terms]

Так может ваш id указывает не на сам инпут, а на его обертку? Т.е. фактически вы пытаетесь кликнуть некликабельный элемент, который принимает фокус по заданному локатору. Покажите html участок, содержащий чекбокс, по которому вы хотите кликнуть.

<(так)input type=“checkbox” name=“” id=“accept-terms”>

http://awesomescreenshot.com/0f82z2ny36

тут же как-то кликает :smile:

Ну так разница ведь очевидна: у thucydides кастомная реализация фабрики инициализации элементов, исходя из этого бага (который очень похож на вашу проблему). В одном случае (где летит эксепшен) вы используете фабрику, в другом - By класс. Т.е. технически элемент ищется только в момент, когда дергаете findElement. Вы пробовали AjaxElementLocatorFactory?

Если вы про это:

 private static final Integer CATALOG_WAIT_FOR_TIMEOUT = 10000;
 
    @FindBy(id = "search")
    WebElement searchButton;
 
    public CatalogFilterPage(WebDriver driver) {
        super(driver, CATALOG_WAIT_FOR_TIMEOUT);
 
    }

то да:) не помогло
кстати, спасибо огромное, это внутреннее ожидание очень пригодится

Тогда нужно смотреть глубже в код. Возможно еще один баг thucydides, либо драйвера.