Guillaume
Guillaume

Reputation: 77

Passing a variable as argument to selenium find_element function instead of hardcoded argument results in a InvalidArgumentException

Context

I am using selenium with python and trying to separate my PageObjects from my code following the official selenium documentation and I get an error which I don't understand:

from selenium.webdriver.common.by import By

class MainPageLocators(object):
    """A class for main page locators. All main page locators should come here"""
    GO_BUTTON = (By.ID, 'submit') 

Doing it like above gives me an selenium.common.exceptions.InvalidArgumentException: Message: expected value at line 1 column 11 error.

Reproducing

I reproduced the error using the Google homepage:

from selenium import webdriver
from selenium.webdriver.common.by import By


def test():
    driver = webdriver.Firefox()
    driver.get('https://www.google.com')

    element = (By.NAME, "btnK")
    driver.find_element(element)


if __name__ == "__main__":
    test()

Full error:

Traceback (most recent call last):
  File "test.py", line 14, in <module>
    test()
  File "test.py", line 10, in test
    driver.find_element(element)
  File "C:\Users\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
    'value': value})['value']
  File "C:\Users\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidArgumentException: Message: expected value at line 1 column 11

Interestingly passing directly passing the argument in the find_element function as follow works fine.

def test():
    driver = webdriver.Firefox()
    driver.get('https://www.google.com')

    element = ()
    driver.find_element(By.NAME, "btnK")

Environment

OS: Windows 10 Browser: Firefox Browser version: 77.0.1 Browser Driver version: GeckoDriver 0.26 Language Bindings version: Python 3.6 , python-selenium 3.141.0 Selenium Grid version (if applicable):

GeckoDriver logs

1593341659616   mozrunner::runner   INFO    Running command: "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "-marionette" "-foreground" "-no-remote" "-profile" "C:\\Users\\xxx\\AppData\\Local\\Temp\\rust_mozprofileNZPCZw"
JavaScript error: resource://gre/modules/XULStore.jsm, line 66: Error: Can't find profile directory.
1593341663463   Marionette  INFO    Listening on port 62786
1593341663826   Marionette  WARN    TLS certificate errors will be ignored for this session
JavaScript error: resource://gre/modules/NetworkGeolocationProvider.jsm, line 555: TypeError: xhr.response.location is undefined

How can I solve this error?

Upvotes: 1

Views: 1356

Answers (1)

thebjorn
thebjorn

Reputation: 27321

The difference between

driver.find_element(By.NAME, "btnK")

and

args = (By.NAME, "btnK")
driver.find_element(args)

is that the first version sends two arguments, and the second version sends one argument (a tuple).

Use the * operator to "unpack" the arguments:

args = (By.NAME, "btnK")
driver.find_element(*args)

Upvotes: 3

Related Questions