TestStack / TestStack.Seleno

Seleno helps you write automated UI tests in the right way by implementing Page Objects and Page Components and by reading from and writing to web pages using strongly typed view models.
http://teststack.github.com/TestStack.Seleno/
MIT License
180 stars 60 forks source link

How use a wait element method #204

Closed sirj77 closed 9 years ago

sirj77 commented 9 years ago

Hi guys!

I need some little help. Description: I have my page object. I want to use inside this page object method that clicks on some button on the page, wait max 10 seconds, and if the results on the page have been shown in this interval of time - that is ok, proceed to the next step, but if the time has been passed - it should be failed.

How ti use it in ma class? I'm using Seleno for the interactions between pages, but if I use, for example, this method:

public static IWebElement ElementWithWait(this IWebDriver driver, Func<IWebDriver, IWebElement> elementIsFound, TimeSpan maxWait)
        {
            try
            {
                if (maxWait == default(TimeSpan))
                    maxWait = TimeSpan.FromSeconds(5);
                var wait = new WebDriverWait(driver, maxWait);
                return wait.Until(elementIsFound);
            }
            catch (WebDriverTimeoutException e)
            {
                throw e.InnerException;
            }
        }

The word "this" is not allowed to use in my class. And how to use this method ElementWithWait exactly: what I should put inside this method, concrete example would be great!

Thanks!

robdmoore commented 9 years ago

That is an extension method, which is why you have an error trying to use it in your class.

If you use Find.Element(By.Something...) in your page object then it will automatically do a wait for you. You can override the timeout to pass in 10s if you want a different timeout than the default.

Does that help?

sirj77 commented 9 years ago

Is it something like this?

my class: ...

 public SomePage AddResult()
        {
            Find.Element(By.XPath(XpathItem), TimeSpan.FromSeconds(10)).Click();
            return this;
        }

...

So what I need: in my tests I'm using AddResult() method, after I click button I should wait no more than 10 sec, if more - I should get an exception and test has to be failed.

Sorry for asking not so smart question, I'm beginner with it.

robdmoore commented 9 years ago

Assuming that XpathItem targets the button then this will wait up to 10s for the button to become available and then will click it.

(By the way, in general I'd recommend against using xpath to find elements - it's generally more fragile than using By.Id or By.CssSelector)

If you want to wait for something to appear after the button is clicked then you'd need something more like:

    public SomePage AddResult()
    {
        Find.Element(By.XPath(XpathItem)).Click();
        Find.Element(By.XPath(XpathItem2), TimeSpan.FromSeconds(10));
        return this;
    }

Or, if you want to wait for the second item to be visible then you need something more like:

    public SomePage AddResult()
    {
        Find.Element(By.XPath(XpathItem)).Click();
        var wait = new WebDriverWait(Browser, TimeSpan.FromSeconds(10));
        wait.Until(d => {
            var elem = d.FindElement(By.XPath(XpathItem2);
            if (!elem.Displayed)
                return null;

            return elem;
        })
        return this;
    }
sirj77 commented 9 years ago

robdmoore, thank yo, it was good for me. This peace of code is working as I expected:

        public SomePage AddResult()
        {
            Find.Element(By.XPath(XpathItem)).Click();

            var wait = new WebDriverWait(Browser, TimeSpan.FromSeconds(10));
            wait.Until(d =>
            {
                if (!SomeExpectingResults)
                    return false;

                return SomeExpectingResults;
            });
            return this;
        }
robdmoore commented 9 years ago

No worries. Glad it's working :)