3

I use htmlelements pattern, similar on pagefactory. Search for elements going through the @FindBy. With some elements can not perform the action (click, sendkeys...), because form on the page is not fully to load and does not appear to perform an action on it, and the driver is already trying to do actions for it. Helps only method Thread.sleep(). But I would like to use Explicit Waits. Timeouts(), a member of the htmlelements not help. For example:

public class ButtonForm extends HtmlElement {

    @FindBy(xpath = "//span[text()='Select']")
    public Button selectButton;

    public void selectButton() {
        selectButton.click();
    }

In the current test the behavior of a long running and there is no click operation. I would like to implement something like this ligament: "WebElement + WebDriverWait + ExpectedConditions"

BCR
  • 61
  • 6
  • Related? http://stackoverflow.com/questions/16182173/using-pageobjects-page-factory-and-webdriverwait-in-selenium-webdriver-using-ja and http://stackoverflow.com/questions/9478592/how-to-implement-user-types-for-findby-annotation. – alecxe Sep 24 '15 at 14:19
  • Your tips're good, but I want use ready-made solution as 'htmlelements', but if this framework it isn't impossible to change somehow to solve this problem, it is necessary to resort to the without pagefactory – BCR Sep 24 '15 at 14:41
  • Use a WebDriverWait + Expected conditions on page load to make sure the page is loaded. Once that is done, then you can load all the individual elements and shouldn't have to have waits on each of them. – JeffC Sep 24 '15 at 22:55
  • @JeffC Well I can't get driver instance within page class or form class, ie can't initiliaze WebDriverWait – BCR Sep 25 '15 at 08:01

1 Answers1

1

The problem probably is here @FindBy(xpath = "//span[text()='Select']"). When you start xpath expression with a // selenium ignores element context and looking up from document root. So maybe your action (click, sendkeys) works, but on wrong elements. To fix this issue, start your xpath with a ./ or use css locators.

artkoshelev
  • 872
  • 7
  • 22
  • So Element button located in the block. And when I refer to this block from class page, I override it, pointing xpath block. xpath this block: //div[@class = 'some name']//table[@id = 'some name']. – BCR Sep 26 '15 at 07:14
  • When you start xpath expression with a `//` selenium ignores element context and looking up from document root. It doesn't care of block xpath at all. – artkoshelev Sep 28 '15 at 08:05
  • I tried, and with the ".//". The result is the same. The problem's not that element is not, and that before pressing this button to perform some action in another form (pop-up). After it closed, it begins searching for the item button. But the search begins immediately, without waiting for the closure of the window. My question was next: whether it is possible to wait for the appearance of an element for example "wait. Intil"? – BCR Sep 28 '15 at 08:11
  • I realized what was happening. In this case I am dealing with AJAX page. When I use something WebDriverWait wait = new WebDriverWait (driver, 5);         wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath(".//*[@id='personEditPanelContentDiv']"))); then everything is fine - ie wait until the dialog box disappears, and only then click on the button. But can if work htmlelements with AJAX pages? – BCR Sep 28 '15 at 14:59
  • Or how get driver instance inside ClassPage if i want refer to class WebDriverWait wait = new WebDriverWait(driver, 5)? By default used public UsersPage(WebDriver driver) { HtmlElementLoader.populatePageObject(this, driver); } – BCR Sep 28 '15 at 14:59
  • You can check element visibility before trying to click, e.g. `assertThat(element, withWaitFor(isDisplayed()));` – artkoshelev Sep 28 '15 at 15:37
  • I think it's not such a graceful way, but I'll try. However, I did not get to use matcher withWaitFor (can not resolve method). I use: 'import ru.yandex.qatools.htmlelements.matchers. *; import org.hamcrest.Matcher; import static org.hamcrest.MatcherAssert.assertThat;' – BCR Sep 28 '15 at 16:07
  • 1
    Oh, in your case it should be `assertThat(element, should(isDisplayed()).whileWaitingUntil(timeoutHasExpired(timeout)))`, we've just implemented `withWaitFor` matcher to shorten this. And do not forget to `import static ru.yandex.qatools.htmlelements.matchers.MatcherDecorators.timeoutHasExpired; import static ru.yandex.qatools.htmlelements.matchers.decorators.MatcherDecoratorsBuilder.should;` – artkoshelev Sep 29 '15 at 10:21
  • Hmm...'isDisplayed()' underlined in red: http://funkyimg.com/i/233bk.png I know that I bothered you, but I want to deal with it and make sure that your framework is applicable in my project :) – BCR Sep 29 '15 at 10:43
  • `import static ru.yandex.qatools.htmlelements.matchers.WebElementMatchers.isDisplayed;` =) no problem, mate – artkoshelev Sep 29 '15 at 10:48
  • Strangely, though, this method can not be taken from ru.yandex.qatools.htmlelements.matchers.WebElementMatchers. http://funkyimg.com/i/233cC.png Method 'isDisplayed' refers to a class HtmlElements.class – BCR Sep 29 '15 at 11:13
  • I applied this assert inside Page class and it worked! Thank you for help! – BCR Sep 29 '15 at 16:15
  • Hello! Please tell me, how do I use this the assert on the forms? Unfortunately, I can only use the pages. And when I try to use on the form, swearing http://funkyimg.com/i/24wFv.png – BCR Nov 16 '15 at 13:50
  • i can't see any problems with this code, i made same example in my project and everything is fine there – artkoshelev Nov 17 '15 at 15:40
  • So what would be a problem? Can I use is not the import of class? At current moment, I have to use on forms Thread.Sleep that does not suit me :( – BCR Nov 18 '15 at 15:40