Thread Rating:
  • 1 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Open web page in web browser, and wait until loaded. Chrome, Edge, Firefox.
#1
Code:
Copy      Help
// class "WebBrowserApp.cs"
/// <summary>
///
Opens a web page in current tab in web browser, and waits until loaded.
/// Works with Chrome, Edge, Firefox. Tested 2023-06-17.
/// </summary>
///
<remarks>
///
To open a URL in current tab, uses the address bar's UI element. May need to edit its name in this script or set the <b>AddressBarName</b> property.
/// To detect the loading state, uses the Reload button. May need to edit its name and/or description in this script or set the properties.
///
/// Even when the page is loaded, some UI elements may still be unavailable. Let the script wait for an element, or insert code like `500.ms();`.
/// </remarks>
///
<example>
///
<code><![CDATA[
/// var w = wnd.find(0, "* - Google Chrome", "Chrome_WidgetWin_1");
/// //var w = wnd.find(0, "*- Microsoft​ Edge", "Chrome_WidgetWin_1");
/// //var w = wnd.find(0, "*Mozilla Firefox", "MozillaWindowClass");
/// var p = new WebBrowserApp(w);
/// p.OpenAndWait("https://www.libreautomate.com/forum");
/// ]]></code>
///
</example>
public class WebBrowserApp {
    wnd _w;
    elm _eTB, _eAddress, _eReload;
    bool _firefox;
    
    //May need to change these strings. They may depend on the computer's language and browser app version.
    //    Discover them with the "Find UI element" tool.
    //    Then either change here, or set these properties in scripts that use this class, before the `new WebBrowserApp` line, like `WebBrowserApp.AddressBarName = "name";`.

    
    ///
    public static string AddressBarName = "**m Address and search bar||Search *or enter address"; //Chrome,Edge||Firefox
    
    ///
    public static string ReloadButtonName = "**m Reload||Refresh"; //Chrome,Firefox||Edge
    
    ///
    public static string ReloadButtonDescription = "**m Reload *||Refresh *"; //Chrome||Edge. Not used for Firefox.
    
    //TODO: test with other languages.
    //CONSIDER: get desc in ctor.

    
    /// <summary>
    ///
Finds UI elements for later opening a URL and waiting.
    /// </summary>
    ///
<param name="w">Web browser window.</param>
    ///
<exception cref="NotFoundException">Web browser UI elements not found. Either <i>w</i> isn't a web browser window, or need to change strings.</exception>
    ///
<exception cref="AuWndException"><i>w</i> 0 or invalid.</exception>
    public WebBrowserApp(wnd w) {
        _w = w;
        _firefox = _w.ClassNameIs("Mozilla*");
        
        //May need to edit this code. Probably only "Navigation".
        _eTB = _w.Elm["TOOLBAR", _firefox ? "Navigation" : null].Find(1);
        _eAddress = _eTB.Elm["TEXT", AddressBarName].Find(1);
        _eReload = _eTB.Elm["BUTTON", ReloadButtonName].Find(1);
    }

    
    /// <summary>
    ///
Opens a web page in current tab, and waits until loaded or stopped.
    /// Also activates the browser window and makes the address bar focused.
    /// </summary>
    ///
<param name="url">Web page URL.</param>
    ///
<param name="secondsTimeout">How long to wait until loaded. The same as with most other "wait for" functions of the automation library (0 infinite, negative no exception).</param>
    ///
<returns>false if timeout (when <i>secondsTimeout</i> negative).</returns>
    ///
<exception cref="TimeoutException"></exception>
    ///
<exception cref="Exception">Exceptions of used functions.</exception>
    public bool OpenAndWait(string url, double secondsTimeout = 60) {
        OpenDontWait(url);
        return WaitWhileLoading(secondsTimeout);
    }

    
    /// <summary>
    ///
Opens a web page in current tab. Does not wait.
    /// Also activates the browser window and makes the address bar focused.
    /// </summary>
    ///
<param name="url">Web page URL.</param>
    ///
<exception cref="Exception">Exceptions of used functions.</exception>
    public void OpenDontWait(string url) {
        _w.Activate();
        _eAddress.Focus(); //must be before setting Value
        _eAddress.Value = url;
        _w.Send(0x100, (int)KKey.Enter); //WM_KEYDOWN
        _w.Send(0x101, (int)KKey.Enter); //WM_KEYUP
    }
    
    /// <summary>
    ///
Waits while the web browser is loading a web page, until loaded or stopped.
    /// </summary>
    ///
<param name="secondsTimeout">How long to wait until loaded. The same as with most other "wait for" functions of the automation library (0 infinite, negative no exception).</param>
    ///
<returns>false if timeout (when <i>secondsTimeout</i> negative).</returns>
    ///
<exception cref="TimeoutException"></exception>
    public bool WaitWhileLoading(double secondsTimeout = 60) {
        if (_firefox) {
            if (!wait.forCondition(-3, () => !_eTB.Elm["BUTTON", ReloadButtonName, "state=!DISABLED"].Exists())) return true; //usually need ~180 ms, but sometimes 500 ms
            return null != _eTB.Elm["BUTTON", ReloadButtonName, "state=!DISABLED"].Wait(secondsTimeout);
            
            //Firefox changes and restores the button image and UI element name with a 150-500 ms delay.
            //    That is why need the first wait.
            //    And it makes this func ~50% slower than with the fastest Chrome code. But not much slower that with current Chrome code.
            //    Can't use IA2_DOCUMENT_LOAD_COMPLETE. It is received without a delay, but sometimes in the middle.
            //    Never mind.

        } else {
            wildex desc = ReloadButtonDescription;
            
            //return wait.forCondition(secondsTimeout, () => desc.Match(_eReload.Description)); //fastest, but less reliable
            
            int n = 0;
            return wait.forCondition(secondsTimeout, () => { if (!desc.Match(_eReload.Description)) n = 0; else if (n++ == 5) return true; return false; });
            
            //The n code adds ~200 ms. Without it may return before all UI elements are available. Eg https://www.libreautomate.com/forum/forumdisplay.php?fid=19.
            //    To make faster can be used IA2_DOCUMENT_LOAD_COMPLETE, but it is unreliable etc. Worked well when tested with that 1 page, but maybe a coincidence.

        }
    }
}

Note: may need editing to make it work on your computer. Read comments in the code.


Forum Jump:


Users browsing this thread: 2 Guest(s)