1
votes

I have been unable to find a good public image that runs Robot Framework using Python v3.x on Ubuntu v18.x. A colleague built an image and I'm using it as a base but My robot script is failing to connect to the site and I've been spinning my wheels for far too long. It's time to reach out to the community for assistance!

I have a simple robot framework script (see below) that connects to a site (chrome headless) and validates the title. It's working find on my Ubuntu workstation but when I run a docker container atop that workstation - it just fails to connect. Initially, I thought it was a plumbing issue but that isn't the case. Below are the steps that I've taken along with the robot code that works on my workstation but not the container:

  1. Confirm connection is working from container:
    curl -o /dev/null -s -w %{http_code} https://www.google.com (this returns a 200)

  2. Ensure the versions of python3, pip3 and ubuntu are the same on my workstation and container

  3. Ensure pip3 libraries are the same (except for a few that I know I don't need and yes, I know I have a couple more installed than what I need) - here is the list from a pip3 freeze command:

asn1crypto==0.24.0
certifi==2020.4.5.1
chardet==3.0.4
coverage==5.2
cryptography==2.1.4
decorator==4.4.2
idna==2.6
importlib-metadata==1.7.0
jsonpath-rw==1.4.0
jsonpath-rw-ext==1.2.2
keyring==10.6.0
keyrings.alt==3.0
pbr==5.4.5
pluggy==0.13.1
ply==3.11
py==1.9.0
pycrypto==2.6.1
pygobject==3.26.1
pyxdg==0.25
requests==2.23.0
robotframework==3.1.1
robotframework-jsonlibrary==0.3.1
robotframework-requests==0.7.0
robotframework-seleniumlibrary==4.1.0
SecretStorage==2.3.1
selenium==3.141.0
six==1.11.0
tox==3.0.0
urllib3==1.22
virtualenv==16.7.10
zipp==3.1.0

And now the robot script (again, works on my workstation, just not on the container)

*** Settings ***
Documentation
...    Basic Test for Google.com in headless mode

Library    Collections
Library    DateTime
Library    Dialogs
Library    OperatingSystem
Library    SeleniumLibrary
Library    String
Library    RequestsLibrary
Library    JSONLibrary

Suite Setup    Setup Environment and Open Browser
Suite Teardown    Close All Browsers

*** Variables ***
${BROWSER}      HeadlessChrome
${SITE_URL}     https://www.google.com

*** Test Cases ***

Title Test
    Title Should Be    Google

*** Keywords ***
Open Chrome Browser To URL
    [Documentation]    Open Chrome browser and navigate to URL with browser options set
    [Tags]  open_chrome_browser
    ${browserOptions}    Run Keyword If    'Headless' in '${BROWSER}'    Set Headless Chrome Options
    Create Webdriver    Chrome    chrome_options=${browserOptions}
    Go To    ${SITE_URL}
    Maximize Browser Window

Browser timeout and speed
    [Documentation]
    ...    Set browser timeout and speed
    Set Selenium Timeout   30s
    Set Selenium Speed   0s

Set Headless Chrome Options
    [Documentation]
    ...     Set the Chrome options for running in headless mode.  Restrictions do not apply to headless mode.
    [Tags]   headless_chrome_options
    ${chromeOptions}    Evaluate    sys.modules['selenium.webdriver'].ChromeOptions()    sys
    Call Method    ${chromeOptions}    add_argument    test-type
    Call Method    ${chromeOptions}    add_argument    --headless
    Call Method    ${chromeOptions}    add_argument    --disable-extensions
    Call Method    ${chromeOptions}    add_argument    --disable-gpu
    Call Method    ${chromeOptions}    add_argument    --disable-dev-shm-usage
    Call Method    ${chromeOptions}    add_argument    --no-sandbox
    [Return]  ${chromeOptions}

Setup Environment and Open Browser
    [Documentation]
    ...    This keyword will establish the environment variables and open a browser
    [Tags]    simple_test

    Open Chrome Browser To URL
    Browser timeout and speed
  1. After running robot -b debug.log testgoogle.robot the debug log shows this interesting bit:
20200820 11:40:53.410 - DEBUG - Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/SeleniumLibrary/__init__.py", line 467, in run_keyword
    return DynamicCore.run_keyword(self, name, args, kwargs)
  File "/usr/local/lib/python3.6/dist-packages/SeleniumLibrary/base/robotlibcore.py", line 102, in run_keyword
    return self.keywords[name](*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/SeleniumLibrary/keywords/element.py", line 569, in click_link
    self.find_element(locator, tag='link').click()
  File "/usr/local/lib/python3.6/dist-packages/SeleniumLibrary/base/context.py", line 74, in find_element
    return self.element_finder.find(locator, tag, True, required, parent)
  File "/usr/local/lib/python3.6/dist-packages/SeleniumLibrary/locators/elementfinder.py", line 76, in find
    % (element_type, locator))
20200820 11:40:53.410 - INFO - +--- END KW: SeleniumLibrary.Click Link (74)
20200820 11:40:53.410 - INFO - +-- END KW: LoginHandler.User Logout (75)

Any thoughts or suggestions on troubleshooting steps?

Thanks much!

2

2 Answers

0
votes

I still have not been able to get this to work with the ChromeDriver direct, however, I was able to get this to work using selenium grid:

https://selenium-release.storage.googleapis.com/3.141/selenium-server-standalone-3.141.59.jar

I started a Hub (in a container) and then a node directly on the container running the test and it worked. I'm still working on building the container that runs the node (it's not working as a separate container though...I must need to add some configurations). Below is the robot framework test suite using a remote chrome driver:

*** Settings ***
Documentation
...    This is a simple robot test to open a browser and check the title of a given website.

Library    Collections
Library    DateTime
Library    Dialogs
Library    OperatingSystem
Library    SeleniumLibrary
Library    String
Library    RequestsLibrary

Suite Setup    Setup Environment and Open Browser
Suite Teardown    Close All Browsers

*** Variables ***
${BROWSER}      HeadlessChrome
${SITE_URL}     https://www.google.com

*** Test Cases ***

Title Test
    Title Should Be    Google

*** Keywords ***
Open Chrome Browser To URL
    [Documentation]    Open Chrome browser and navigate to URL with browser options set
    [Tags]  open_chrome_browser

    ${chromeOptions}    Evaluate    sys.modules['selenium.webdriver'].ChromeOptions()    sys, selenium.webdriver

    Call Method    ${chromeOptions}    add_argument    --headless

    ${ws}=    Set Variable    window-size=1920, 1080
    Call Method    ${chromeOptions}    add_argument    ${ws}
    Call Method    ${chromeOptions}    add_argument    --disable-extensions
    Call Method    ${chromeOptions}    add_argument    --disable-gpu
    Call Method    ${chromeOptions}    add_argument    --disable-dev-shm-usage
    Call Method    ${chromeOptions}    add_argument    --ignore-certificate-errors

    ${remoteOptions}=    Call Method    ${chromeOptions}    to_capabilities
    Create Webdriver    Remote   command_executor=http://<IP ADDR OF HUB>:4444/wd/hub    desired_capabilities=${remoteOptions}

    Go To    ${SITE_URL}
    Maximize Browser Window

Browser timeout and speed
    [Documentation]
    ...    Set browser timeout and speed
    Set Selenium Timeout   30s
    Set Selenium Speed   0s

Setup Environment and Open Browser
    [Documentation]
    ...    This keyword will establish the environment variables and open a browser
    [Tags]    simple_test

    Open Chrome Browser To URL
    Browser timeout and speed

Now to figure out how to run the node in a container...

0
votes

After a bit more research, I just used the public Selenium Grid 3 hub and nodes to solve my issue.

https://github.com/SeleniumHQ/docker-selenium/tree/selenium-3/Hub