blob: 81673737e061aa9b88a50c7d59f32958ac0a8bc5 [file] [log] [blame]
using System;
using NMock2;
using NUnit.Framework;
namespace OpenQA.Selenium.Support.UI
{
[TestFixture]
public class WebDriverWaitTest
{
private const string SOME_STRING = "str";
private static readonly TimeSpan ZERO_SECONDS = TimeSpan.FromSeconds(0);
private static readonly TimeSpan ONE_SECONDS = TimeSpan.FromSeconds(1);
private static readonly TimeSpan FIVE_SECONDS = TimeSpan.FromSeconds(5);
private Mockery mocks;
private bool executed;
[SetUp]
public void SetUp()
{
mocks = new Mockery();
executed = false;
}
[Test]
public void CanGetListOfOptions()
{
var mockDriver = mocks.NewMock<IWebDriver>();
var condition = GetCondition(() => null, () => SOME_STRING);
var wait = new WebDriverWait(new TickingClock(), mockDriver, FIVE_SECONDS, ZERO_SECONDS);
Assert.AreEqual(SOME_STRING, wait.Until(condition));
mocks.VerifyAllExpectationsHaveBeenMet();
}
[Test]
public void WaitsForBaseObjectType()
{
var mockDriver = mocks.NewMock<IWebDriver>();
var condition = GetCondition(() => null, () => new object());
var wait = new WebDriverWait(new TickingClock(), mockDriver, FIVE_SECONDS, ZERO_SECONDS);
Assert.IsNotNull(wait.Until(condition));
mocks.VerifyAllExpectationsHaveBeenMet();
}
[Test]
public void WaitsUntilABooleanResultIsTrue()
{
var mockDriver = mocks.NewMock<IWebDriver>();
var condition = GetCondition(() => false, () => true);
var wait = new WebDriverWait(new TickingClock(), mockDriver, FIVE_SECONDS, ZERO_SECONDS);
Assert.True(wait.Until(condition));
}
[Test]
public void ThrowsForInvalidTypes()
{
var mockDriver = mocks.NewMock<IWebDriver>();
var nullableBooleanCondition = GetCondition<bool?>(() => null, () => true);
var intCondition = GetCondition(() => 1, () => 2);
var wait = new WebDriverWait(new TickingClock(), mockDriver, FIVE_SECONDS, ZERO_SECONDS);
Assert.Throws(typeof(ArgumentException), () => wait.Until(nullableBooleanCondition));
Assert.Throws(typeof(ArgumentException), () => wait.Until(intCondition));
}
[Test]
public void ThrowsAnExceptionIfTheTimerRunsOut()
{
var mockDriver = mocks.NewMock<IWebDriver>();
var wait = new WebDriverWait(GetClock(), mockDriver, ONE_SECONDS, ZERO_SECONDS);
Assert.Throws(typeof(WebDriverTimeoutException), () => wait.Until(driver => false));
}
[Test]
public void SilentlyCapturesNoSuchElementExceptions()
{
var mockDriver = mocks.NewMock<IWebDriver>();
var element = mocks.NewMock<IWebElement>();
var condition = GetCondition(() => { throw new NoSuchElementException(); }, () => element);
var wait = new WebDriverWait(new TickingClock(), mockDriver, FIVE_SECONDS, ZERO_SECONDS);
Assert.AreEqual(element, wait.Until(condition));
}
[Test]
public void PassesWebDriverFromConstructorToExpectation()
{
var mockDriver = mocks.NewMock<IWebDriver>();
Expect.Once.On(mockDriver).GetProperty("CurrentWindowHandle").Will(Return.Value(SOME_STRING));
Func<IWebDriver, string> condition = driver => driver.CurrentWindowHandle;
var wait = new WebDriverWait(new TickingClock(), mockDriver, FIVE_SECONDS, ZERO_SECONDS);
Assert.AreEqual(SOME_STRING, wait.Until(condition));
mocks.VerifyAllExpectationsHaveBeenMet();
}
[Test]
public void ChainsNoSuchElementExceptionWhenTimingOut()
{
var mockDriver = mocks.NewMock<IWebDriver>();
var condition = GetCondition<string>(() => { throw new NoSuchElementException(); }, () => { throw new NoSuchElementException(); });
var wait = new WebDriverWait(GetClock(), mockDriver, ONE_SECONDS, ZERO_SECONDS);
try
{
wait.Until(condition);
Assert.Fail("Expected WebDriverTimeoutException to be thrown");
}
catch (WebDriverTimeoutException e)
{
Assert.IsInstanceOf(typeof (NoSuchElementException), e.InnerException);
}
}
private Func<IWebDriver, T> GetCondition<T>(Func<T> first, Func<T> second)
{
return driver =>
{
if (executed)
{
return second();
}
executed = true;
return first();
};
}
private static IClock GetClock()
{
return new TickingClock(TimeSpan.FromMilliseconds(500));
}
}
class TickingClock : IClock
{
private readonly TimeSpan increment;
public TickingClock() : this(TimeSpan.FromSeconds(0))
{
}
public TickingClock(TimeSpan increment)
{
this.increment = increment;
Now = new DateTime(0);
}
public DateTime Now { get; private set; }
public DateTime LaterBy(TimeSpan delay)
{
return Now + delay;
}
public bool IsNowBefore(DateTime then)
{
Now = Now + increment;
return Now < then;
}
}
}