Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to NOT wait for page load to complete in Selenium by using ChromeDriver? (mobile)

I am using ChromeDriver to write tests for Android Chrome browser. I use C#. My goal is to use few chrome tabs in parallel. When one page stuck by loading some data or by doing some calcaultion I want to switch to another tab and do another tests, and time to time do some checks: is previous page already loaded, and if yes do another work on it.

Issue: When you set driver.Url or Click on element which load another page your thread stuck until whole page get loaded. It is not ok for me. But I found workaround, I can execute script with timeout like this:

driver.ExecuteScript(string.Format("setTimeout(function() {{ location.href = \"{0}\" }}, 150);", url));

and now at least my C# thread is not stuck.

Now I need to have way to check is page loading complete or not. Theoretical solution: Before executing code above I can get HTML element from document and check some it property, and after new page get loaded and I ask for any property of old element (which do not exist any longer)- I will get StaleElementReferenceException. So my plan sounds good, but it doesnt work. When page is laoading and I ask property of element - my tread is just stuck until page get loaded. I used fiddler proxy to increase time of page loading to have enough time to investigate this issue (I freeze page loading and slow down my connection speed through fiddler). Also I tried to not access any DOM element, but just execute script like "return true;" - same issue it stucks until page get loaded.

Is there any way to not wait for page load? Maybe Is it possible to connect to different tabs with different chromedriver instance? I will appreciate any sugestion!

Version of ChromeDriver: 2.27.440174 System1: Windows 10 x64 System2: Samsung S6 Android 6.0.1

Update 1: I found https://github.com/bayandin/chromedriver/blob/e9a1f55b166ea62ef0f6e78da899d9abf117e88f/chrome/page_load_strategy.h where I can see three types of behaviour: Normal, None, Eager; Seems by default ChromeDriver use Normal. Which means wait until page get loaded. I need to use None - which means do not wait anything (exactly what I need) but I can't make it work. I have tried both:

chromeOptions.AddAdditionalCapability("webdriver.load.strategy", "none");
chromeOptions.AddAdditionalCapability("pageLoadStrategy", "none");

I got next error: "unknown error: cannot parse capability: chromeOptions\nfrom unknown error: unrecognized chrome option: pageLoadStrategy\n (Driver info: chromedriver=2.27.440174 (e97a722caafc2d3a8b807ee115bfb307f7d2cfd9),platform=Windows NT 10.0.14393 x86_64)"}

like image 783
GDocal Avatar asked Oct 29 '22 11:10

GDocal


2 Answers

In python, this seems possible by the following code. The scraping seems now faster and with fewer cases of stuck driver URL loading on some websites which happens quite a lot and randomly. Most dynamic websites need scrolling down to let the JS do its stuff and load some parts of the page. So it seems setting "pageLoadStrategy" to "none" will not affect completion of the page loading anyway, due to the scrolling and waiting in my code for the dynamic website loading.

I have explored this possibilities according to the other answers in other languages and from the module:

C:\Users\Haider\Anaconda3\envs\web-py37\Lib\site-packages\selenium\webdriver\common\desired_capabilities.py

Here is the code that worked for me:

options = webdriver.ChromeOptions()
options.add_argument("--disable-blink-features")
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument("ignore-certificate-errors")
options.add_argument("--no-sandbox")
options.add_argument("disable-notifications")
options.add_argument("--disable-infobars")
options.add_argument("--disable-extensions")

# Avoid some websites stuck selenium and the whole process stuck in loading the page
capabilities = webdriver.DesiredCapabilities.CHROME.copy()
capabilities['pageLoadStrategy'] = "none"  # default is "normal".

with webdriver.Chrome(options=options, desired_capabilities=capabilities) as driver:
    driver.get(link)
like image 57
Haider Avatar answered Nov 15 '22 06:11

Haider


Here is my solution:

private class ChromeOptionsEx: ChromeOptions
    {
        public override ICapabilities ToCapabilities()
        {
            var r =(DesiredCapabilities)base.ToCapabilities();
            r.SetCapability("pageLoadStrategy","none");

            return r;
        }
    }

Use ChromeOptionsEx instead of ChromeOptions. These code lines:

chromeOptions.AddAdditionalCapability("webdriver.load.strategy", "none");
chromeOptions.AddAdditionalCapability("pageLoadStrategy", "none");

doesn't work because it will be added to ChromeOptions but pageLoadStategy is not chrome optionts, it is capability. Chrome driver expected t find it in a root of capability. Explanation: ChromeOptions generate next map of capabilities:

  • {[browserName, chrome]}
  • {[version, ]}
  • {[platform, ANY]}
  • {[chromeOptions,Dictionary2[System.String,System.Object]]}
  • {[pageLoadStrategy,none]} <-------- we should add it here and my code do this

where chromeOptions is

  • {[args,ReadOnlyCollection1[System.String]]}
  • {[binary,]}
  • {[androidPackage, com.android.chrome]}
  • {[pageLoadStrategy,none]}<-------------------- AddAdditionalCapability add value there it is no ok
like image 44
GDocal Avatar answered Nov 15 '22 05:11

GDocal