robotframework / SeleniumLibrary

Web testing library for Robot Framework
Apache License 2.0
1.38k stars 761 forks source link

Create Webdriver - syntax for changing 'page_load_strategy' #1820

Closed akozyreva closed 1 year ago

akozyreva commented 1 year ago

Additional information

Hi everyone! Could you please tell me, how can I change pageLoadStrategy, when use keyword create Create Webdriver with chromedriver?

Expected behavior and actual behavior

I tried to change value of property pageLoadStrategy in the following way:

${chrome_options}=  Evaluate  sys.modules['selenium.webdriver'].ChromeOptions()  sys,selenium.webdriver
${options.page_load_strategy}=       Set Variable    eager
Call Method  ${chrome_options}  add_argument    ${options.page_load_strategy}
Create Webdriver  Chrome  chrome_options=${chrome_options}

But it doesn't work

Environment

Browser driver: ChromeDriver 111.0.5563.64 Operating System: MacOS Libraries

emanlove commented 1 year ago

@akozyreva I have a busy schedule for the next two hours but to try to get you immediate support, I think you may have the wrong options structure. Looking at the Selenium docs I am thinking you will want selenium.webdriver.chrome.options instead of webdriver.ChromeOptions()

.. ah looks like ChromeOptions is an instance of selenium.webdriver.chrome.options. (I'll admit i rarely use options in the testing I do so I am a bit ignorant in this area :) )

emanlove commented 1 year ago

I do prefer the adding options via the string format over the method above as seen in the "Open Browser" keyword doc. Using the example there I would guess this should look like

Open Browser    None    Chrome    options=add_argument("page_load_strategy='eager'")

with a question about quoting 'eager'. Not sure if that is need or not but am assuming it is expecting a string.

The other question I have is how do you know, the implementation above is not working?

emanlove commented 1 year ago

Tried out some simple test cases. For both Create WebDriver and Open Browser the library is putting those options under chromeOptions in the underlying open session request sent to the driver.

*** Settings ***
Library  SeleniumLibrary

*** Test Cases ***
Check Setting Page Load Strategy
    ${chrome_options}=  Evaluate  sys.modules['selenium.webdriver'].ChromeOptions()  sys,selenium.webdriver
    ${options.page_load_strategy}=       Set Variable    eager
    Call Method  ${chrome_options}  add_argument    ${options.page_load_strategy}
    Create Webdriver  Chrome  chrome_options=${chrome_options}
    Open Browser    ${None}    Chrome    options=add_argument("page_load_strategy='eager'")

with the log showing the request for just the Open Browser line being


09:27:51.412    TRACE   Arguments: [ None | 'Chrome' | options='add_argument("page_load_strategy=\'eager\'")' ] 
09:27:51.412    INFO    Opening browser 'Chrome' to base url 'None'.    
09:27:51.931    DEBUG   POST http://localhost:54944/session {"capabilities": {"firstMatch": [{}], "alwaysMatch": {"browserName": "chrome", "pageLoadStrategy": "normal", "goog:chromeOptions": {"extensions": [], "args": ["page_load_strategy='eager'"]}}}, "desiredCapabilities": {"browserName": "chrome", "pageLoadStrategy": "normal", "goog:chromeOptions": {"extensions": [], "args": ["page_load_strategy='eager'"]}}}  
09:27:51.933    DEBUG   Starting new HTTP connection (1): localhost:54944   
09:27:52.451    DEBUG   http://localhost:54944 "POST /session HTTP/1.1" 200 787 
09:27:52.451    DEBUG   Finished Request    
09:27:52.451    DEBUG   POST http://localhost:54944/session/6de2a783bd206cba7985fac39ed143c1/timeouts {"script": 5000}  
09:27:52.452    DEBUG   http://localhost:54944 "POST /session/6de2a783bd206cba7985fac39ed143c1/timeouts HTTP/1.1" 200 14    
09:27:52.452    DEBUG   Finished Request    
09:27:52.452    DEBUG   POST http://localhost:54944/session/6de2a783bd206cba7985fac39ed143c1/timeouts {"implicit": 0}   
09:27:52.453    DEBUG   http://localhost:54944 "POST /session/6de2a783bd206cba7985fac39ed143c1/timeouts HTTP/1.1" 200 14    
09:27:52.453    DEBUG   Finished Request    
09:27:52.453    DEBUG   Opened browser with session id 6de2a783bd206cba7985fac39ed143c1.    
09:27:52.453    TRACE   Return: 2

But if I make a small unit test case and add logging, as in

import logging
import sys

root = logging.getLogger()
root.setLevel(logging.DEBUG)

handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
root.addHandler(handler)

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.page_load_strategy = 'eager'
driver = webdriver.Chrome(options=options)
driver.get("http://www.google.com")
driver.quit()

then the request going out has the page load strategy under the capabilities and desired capabilities structure

$ python utest.py 
2023-05-05 09:18:41,063 - selenium.webdriver.remote.remote_connection - DEBUG - POST http://localhost:54467/session {"capabilities": {"firstMatch": [{}], "alwaysMatch": {"browserName": "chrome", "pageLoadStrategy": "eager", "goog:chromeOptions": {"extensions": [], "args": []}}}, "desiredCapabilities": {"browserName": "chrome", "pageLoadStrategy": "eager", "goog:chromeOptions": {"extensions": [], "args": []}}}
2023-05-05 09:18:41,066 - urllib3.connectionpool - DEBUG - Starting new HTTP connection (1): localhost:54467

DevTools listening on ws://127.0.0.1:54470/devtools/browser/ddc715ed-6a6d-4acd-91eb-b7310c977147
2023-05-05 09:18:41,591 - urllib3.connectionpool - DEBUG - http://localhost:54467 "POST /session HTTP/1.1" 200 785
2023-05-05 09:18:41,592 - selenium.webdriver.remote.remote_connection - DEBUG - Finished Request
2023-05-05 09:18:41,592 - selenium.webdriver.remote.remote_connection - DEBUG - POST http://localhost:54467/session/8351f3b8b19dca61f2df4b02c9acdcbe/url {"url": "http://www.google.com"}
2023-05-05 09:18:41,950 - urllib3.connectionpool - DEBUG - http://localhost:54467 "POST /session/8351f3b8b19dca61f2df4b02c9acdcbe/url HTTP/1.1" 200 14
2023-05-05 09:18:41,951 - selenium.webdriver.remote.remote_connection - DEBUG - Finished Request
2023-05-05 09:18:41,951 - selenium.webdriver.remote.remote_connection - DEBUG - DELETE http://localhost:54467/session/8351f3b8b19dca61f2df4b02c9acdcbe {}
2023-05-05 09:18:41,981 - urllib3.connectionpool - DEBUG - http://localhost:54467 "DELETE /session/8351f3b8b19dca61f2df4b02c9acdcbe HTTP/1.1" 200 14
2023-05-05 09:18:41,981 - selenium.webdriver.remote.remote_connection - DEBUG - Finished Request

I will look to see what the library is doing internally with options and capabilities.

emanlove commented 1 year ago

I stepped through the code and see why it was doing what I observed above and figured out how to set the argument properly. The folowing works,

*** Settings ***
Library  SeleniumLibrary

*** Test Cases ***
Check Setting Page Load Strategy
    Open Browser    ${None}    Chrome    options=page_load_strategy("eager")

Noting the difference of this with what I tried above page_load_strategy is a method on the selenium.webdriver.chrome.options and not one of the numerous "options" one can set with Chrome.

emanlove commented 1 year ago

Similarly to do this under Create WebDriver the following is the correct method for setting page_load_strategy

*** Settings ***
Library  SeleniumLibrary

*** Test Cases ***
Check Setting Page Load Strategy
    ${chrome_options}=  Evaluate  sys.modules['selenium.webdriver'].ChromeOptions()  sys,selenium.webdriver
    ${chrome_options.page_load_strategy}=       Set Variable    eager
    Create Webdriver  Chrome  chrome_options=${chrome_options}
emanlove commented 1 year ago

Closing this issue as the above should allow one to set the page_load_strategy for either the Create WebDriver or Open Browser keywords.

akozyreva commented 1 year ago

Hi @emanlove ! Many thanks for your help! It works like a charm.

P.S. Would be nice if it will be documented somewhere, e.g. in Manual.

emanlove commented 1 year ago

@akozyreva I went ahead an created an issue (#1842) to update the documentation hopefully making this more clear. Thanks for suggesting this!