| // <copyright file="WebDriverWaitTest.cs" company="Selenium Committers"> |
| // Licensed to the Software Freedom Conservancy (SFC) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The SFC licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // </copyright> |
| |
| using Moq; |
| using NUnit.Framework; |
| using System; |
| |
| 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 bool executed; |
| |
| [SetUp] |
| public void SetUp() |
| { |
| executed = false; |
| } |
| |
| [Test] |
| public void CanGetListOfOptions() |
| { |
| var mockDriver = new Mock<IWebDriver>(); |
| var condition = GetCondition(() => null, () => SOME_STRING); |
| |
| var wait = new WebDriverWait(new TickingClock(), mockDriver.Object, FIVE_SECONDS, ZERO_SECONDS); |
| Assert.That(wait.Until(condition), Is.EqualTo(SOME_STRING)); |
| } |
| |
| [Test] |
| public void WaitsForBaseObjectType() |
| { |
| var mockDriver = new Mock<IWebDriver>(); |
| var condition = GetCondition(() => null, () => new object()); |
| |
| var wait = new WebDriverWait(new TickingClock(), mockDriver.Object, FIVE_SECONDS, ZERO_SECONDS); |
| Assert.That(wait.Until(condition), Is.Not.Null); |
| } |
| |
| [Test] |
| public void WaitsUntilABooleanResultIsTrue() |
| { |
| var mockDriver = new Mock<IWebDriver>(); |
| var condition = GetCondition(() => false, () => true); |
| |
| var wait = new WebDriverWait(new TickingClock(), mockDriver.Object, FIVE_SECONDS, ZERO_SECONDS); |
| Assert.That(wait.Until(condition), Is.True); |
| } |
| |
| [Test] |
| public void ThrowsForInvalidTypes() |
| { |
| var mockDriver = new Mock<IWebDriver>(); |
| var nullableBooleanCondition = GetCondition<bool?>(() => null, () => true); |
| var intCondition = GetCondition(() => 1, () => 2); |
| |
| var wait = new WebDriverWait(new TickingClock(), mockDriver.Object, FIVE_SECONDS, ZERO_SECONDS); |
| |
| Assert.That(() => wait.Until(nullableBooleanCondition), Throws.ArgumentException); |
| Assert.That(() => wait.Until(intCondition), Throws.ArgumentException); |
| } |
| |
| [Test] |
| public void ThrowsAnExceptionIfTheTimerRunsOut() |
| { |
| var mockDriver = new Mock<IWebDriver>(); |
| var wait = new WebDriverWait(GetClock(), mockDriver.Object, ONE_SECONDS, ZERO_SECONDS); |
| |
| Assert.That( |
| () => wait.Until(driver => false), |
| Throws.TypeOf<WebDriverTimeoutException>()); |
| } |
| |
| [Test] |
| public void SilentlyCapturesNoSuchElementExceptions() |
| { |
| var mockDriver = new Mock<IWebDriver>(); |
| var element = new Mock<IWebElement>(); |
| var condition = GetCondition(() => { throw new NoSuchElementException(); }, () => element.Object); |
| |
| var wait = new WebDriverWait(new TickingClock(), mockDriver.Object, FIVE_SECONDS, ZERO_SECONDS); |
| |
| Assert.That(wait.Until(condition), Is.EqualTo(element.Object)); |
| } |
| |
| [Test] |
| public void PassesWebDriverFromConstructorToExpectation() |
| { |
| var mockDriver = new Mock<IWebDriver>(); |
| mockDriver.SetupGet<string>(_ => _.CurrentWindowHandle).Returns(SOME_STRING); |
| |
| Func<IWebDriver, string> condition = driver => driver.CurrentWindowHandle; |
| |
| var wait = new WebDriverWait(new TickingClock(), mockDriver.Object, FIVE_SECONDS, ZERO_SECONDS); |
| |
| Assert.That(wait.Until(condition), Is.EqualTo(SOME_STRING)); |
| |
| mockDriver.Verify(_ => _.CurrentWindowHandle, Times.Once); |
| } |
| |
| [Test] |
| public void ChainsNoSuchElementExceptionWhenTimingOut() |
| { |
| var mockDriver = new Mock<IWebDriver>(); |
| var condition = GetCondition<string>(() => { throw new NoSuchElementException(); }, () => { throw new NoSuchElementException(); }); |
| |
| var wait = new WebDriverWait(GetClock(), mockDriver.Object, ONE_SECONDS, ZERO_SECONDS); |
| |
| Assert.That( |
| () => wait.Until(condition), |
| Throws.InstanceOf<WebDriverTimeoutException>().With.InnerException.InstanceOf<NoSuchElementException>()); |
| } |
| |
| 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; |
| } |
| } |