Path: blob/trunk/dotnet/src/support/UI/LoadableComponent{T}.cs
2885 views
// <copyright file="LoadableComponent{T}.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> namespace OpenQA.Selenium.Support.UI; /// <summary> /// <para>Represents any abstraction of something that can be loaded.</para> /// <para>This may be an entire web page, or simply a component within that page (such as a login box or menu) or even a service.</para> /// <para> /// <code> /// // Example usage: /// new MyComponent().Load(); /// </code> /// </para> /// </summary> /// <typeparam name="T">The type to be returned (normally the subclass' type)</typeparam> /// <remarks> /// <para>After the <see cref="Load()"/> method is called, the component will be loaded and ready for use.</para> /// <para>Overload the protected Load and IsLoaded members to both load a component and determine if the component is already loaded.</para> /// </remarks> public abstract class LoadableComponent<T> : ILoadableComponent where T : LoadableComponent<T> { /// <summary> /// Gets or sets the message for the exception thrown when a component cannot be loaded /// </summary> public virtual string? UnableToLoadMessage { get; set; } /// <summary> /// Gets a value indicating whether the component is fully loaded. /// </summary> /// <remarks> /// When the component is loaded, this property will return true or false depending on /// the execution of <see cref="EvaluateLoadedStatus"/> to indicate the not loaded state. /// </remarks> protected bool IsLoaded { get { try { return this.EvaluateLoadedStatus(); } catch (WebDriverException) { return false; } } } /// <summary> /// Ensure that the component is currently loaded. /// </summary> /// <returns>The loaded component.</returns> /// <remarks>This is equivalent to the Get() method in Java version.</remarks> public virtual T Load() { if (this.IsLoaded) { return (T)this; } else { this.TryLoad(); } if (!this.IsLoaded) { throw new LoadableComponentException(this.UnableToLoadMessage); } return (T)this; } /// <summary> /// Ensure that the component is currently loaded. /// </summary> /// <returns>The loaded <see cref="ILoadableComponent"/> instance.</returns> ILoadableComponent ILoadableComponent.Load() { return (ILoadableComponent)this.Load(); } /// <summary> /// HandleLoadError gives a subclass the opportunity to handle a <see cref="WebDriverException"/> that occurred /// during the execution of <see cref="ExecuteLoad"/>. /// </summary> /// <param name="ex">The exception which occurs on load.</param> protected virtual void HandleLoadError(WebDriverException ex) { } /// <summary> /// When this method returns, the component modeled by the subclass should be fully loaded. This /// subclass is expected to navigate to an appropriate page or trigger loading the correct HTML /// should this be necessary. /// </summary> protected abstract void ExecuteLoad(); /// <summary> /// Determine whether or not the component is loaded. Subclasses are expected to provide the details /// to determine if the page or component is loaded. /// </summary> /// <returns>A boolean value indicating if the component is loaded.</returns> protected abstract bool EvaluateLoadedStatus(); /// <summary> /// Attempts to load this component, providing an opportunity for the user to handle any errors encountered /// during the load process. /// </summary> /// <returns>A self-reference to this <see cref="LoadableComponent{T}"/></returns> protected T TryLoad() { try { this.ExecuteLoad(); } catch (WebDriverException e) { this.HandleLoadError(e); } return (T)this; } }