Skip to content

Instantly share code, notes, and snippets.

@ksummerlin
Created May 4, 2012 02:43
Show Gist options
  • Save ksummerlin/2591548 to your computer and use it in GitHub Desktop.
Save ksummerlin/2591548 to your computer and use it in GitHub Desktop.
SlowLoadableComponent implementation
// <copyright file="SlowLoadableComponent.cs" company="WebDriver Committers">
// Copyright 2007-2011 WebDriver committers
// Copyright 2007-2011 Google Inc.
// Portions copyright 2011 Software Freedom Conservancy
//
// Licensed 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 System;
using System.Linq;
using System.Threading;
using System.Globalization;
namespace OpenQA.Selenium.Support.UI
{
///<summary>
/// A <see cref="LoadableComponent<T>"/> which might not have finished loading when Load() returns. After a
/// call to Load(), the IsLoaded() method should continue to fail until the component has fully
/// loaded. Use the IsError() methd to check for error conditions which caused the Load() to fail.
///
/// <pre class="code">
/// new SlowHypotheticalComponent().Load();
/// </pre>
///</summary>
///<typeparam name="T">The type to be returned (normally the subclass' type)</typeparam>
///
public abstract class SlowLoadableComponent<T> : LoadableComponent<T> where T : SlowLoadableComponent<T>
{
private readonly IClock clock;
private readonly TimeSpan timeOut;
public SlowLoadableComponent(int timeoutInSeconds) : this(new SystemClock(), timeoutInSeconds) { }
public SlowLoadableComponent(TimeSpan timeout) : this(new SystemClock(), timeout) { }
public SlowLoadableComponent(IClock clock, int timeOutInSeconds) : this(clock, TimeSpan.FromSeconds(timeOutInSeconds)) { }
public SlowLoadableComponent(IClock clock, TimeSpan timeout)
{
this.clock = clock;
this.timeOut = timeout;
}
public override T Load()
{
if (this.IsLoaded)
{
return (T)this;
}
else
{
this.TryLoad();
}
DateTime end = clock.LaterBy(timeOut);
while (clock.IsNowBefore(end))
{
if (this.IsLoaded)
{
return (T)this;
}
IsError();
WaitFor();
}
if (this.IsLoaded)
{
return (T)this;
}
else
{
string timeoutMessage = string.Format(CultureInfo.InvariantCulture, "Timed out after {0} seconds.", timeOut.TotalSeconds);
throw new TimeoutException(timeoutMessage);
}
}
///<summary>
/// Check for well known error cases, which would mean that loading has finished, but an error
/// condition was seen. If an error has occured throw any exception other than LoadableComponentException
/// </summary>
protected virtual void IsError()
{
// no-op by default
}
protected virtual int SleepFor
{
get
{
return 200;
}
}
private void WaitFor()
{
Thread.Sleep(SleepFor);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment