3

I am remote controlling a Firefox browser using Python and Selenium. I have switched to using Marionette, as directed on the mozilla developer site. That all works fine.

There is one page, where when I want to select an element. I get an exception. I think it is a Javascript warning that is causing the driver to bork. Does anyone know how I can make the driver less picky about Javascript errors? Additionally does anyone know where there is comprehensive documentation of the Python Marionette client?

Sorry I can't make the code completely reproducible because it is a client's private site that I am attempting to select an element from.

from selenium import webdriver

# see https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver

from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

caps = DesiredCapabilities.FIREFOX

# Tell the Python bindings to use Marionette.
# This will not be necessary in the future,
# when Selenium will auto-detect what remote end
# it is talking to.
caps["marionette"] = True
caps["binary"] = "/Applications/Firefox.app/Contents/MacOS/firefox-bin"

from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
browser = webdriver.Firefox(capabilities=caps)
webdriver.Firefox.get_capabilities()
browser.implicitly_wait(3)

browser.get("https://www.example.com/examplepage")

saved_exports_field = browser.find_element_by_id('exportlist')
saved_exports_field_select = Select(saved_exports_field)

That is where it goes wrong. The trace is as follows

---------------------------------------------------------------------------
WebDriverException                        Traceback (most recent call last)
<ipython-input-35-6e712759af43> in <module>()
      1 saved_exports_field = browser.find_element_by_id('exportlist')
----> 2 saved_exports_field_select = Select(saved_exports_field)
      3 #saved_exports_field_select.select_by_visible_text('test score export dan')

/Users/dan/anaconda/envs/lt/lib/python3.5/site-packages/selenium/webdriver/support/select.py in __init__(self, webelement)
     39                 webelement.tag_name)
     40         self._el = webelement
---> 41         multi = self._el.get_attribute("multiple")
     42         self.is_multiple = multi and multi != "false"
     43 

/Users/dan/anaconda/envs/lt/lib/python3.5/site-packages/selenium/webdriver/remote/webelement.py in get_attribute(self, name)
    134             attributeValue = self.parent.execute_script(
    135                 "return (%s).apply(null, arguments);" % raw,
--> 136                 self, name)
    137         else:
    138             resp = self._execute(Command.GET_ELEMENT_ATTRIBUTE, {'name': name})

/Users/dan/anaconda/envs/lt/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py in execute_script(self, script, *args)
    463         return self.execute(Command.EXECUTE_SCRIPT, {
    464             'script': script,
--> 465             'args': converted_args})['value']
    466 
    467     def execute_async_script(self, script, *args):

/Users/dan/anaconda/envs/lt/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py in execute(self, driver_command, params)
    234         response = self.command_executor.execute(driver_command, params)
    235         if response:
--> 236             self.error_handler.check_response(response)
    237             response['value'] = self._unwrap_value(
    238                 response.get('value', None))

/Users/dan/anaconda/envs/lt/lib/python3.5/site-packages/selenium/webdriver/remote/errorhandler.py in check_response(self, response)
    190         elif exception_class == UnexpectedAlertPresentException and 'alert' in value:
    191             raise exception_class(message, screen, stacktrace, value['alert'].get('text'))
--> 192         raise exception_class(message, screen, stacktrace)
    193 
    194     def _value_or_default(self, obj, key, default):

WebDriverException: Message: SyntaxError: missing ) in parenthetical

Thanks

Dan
  • 1,536
  • 1
  • 10
  • 20

2 Answers2

1

There's a bug in release 3.0.0-beta-3 which prevents the use of get_attribute. So you can either revert to 3.0.0-beta-2 or you can fix the bug by editing the file yourself:

In file /Users/dan/anaconda/envs/lt/lib/python3.5/site-packages/selenium/webdriver/remote/webelement.py, replace the line 133:

raw = pkgutil.get_data(__package__, 'getAttribute.js')

by:

raw = pkgutil.get_data(__package__, 'getAttribute.js').decode('utf8')
Florent B.
  • 41,537
  • 7
  • 86
  • 101
  • Thanks, that fixed the code failing through an exception. I still have a weird problem in that "select_by_visible_text" won't actually select an option. If I change the text then it fails, but it seems the driver's attempts to tell Firefox to select the element are not getting through. I will have to try more debugging. – Dan Sep 19 '16 at 13:35
  • @Dan, I also faced some issues with the native drop-down list. I had to select the – Florent B. Sep 19 '16 at 14:58
  • Thanks Florent, I may try that. For the moment I just switched to using Chrome – Dan Sep 20 '16 at 08:25
0

To answer your second question first, this documentation seems fairly comprehensive; does this meet your needs?

As for the question of how to disable WebDriverException, the only thing I know of would be to use try: except: blocks, but I don't think this would be a good idea. WebDriverException is the base exception that the webdriver uses, and it would catch all errors including NoSuchElementException, which you are using.

I don't know of any way to specifically catch JavaScript errors, since these appear to bubble up as WebDriverExceptions. I assume that because you are asking this question, fixing the JavaScript itself is not an option?

One thing you might try is using the webdriver's get_log() method. From what I have read, JS errors should be visible in the results returned by this method. You could try calling browser.get_log(log_type) (where log_type is one of 'browser', 'client', 'driver', or 'server' depending on where the error originates) before your Select() call, parsing that data, and than acting accordingly.

elethan
  • 16,408
  • 8
  • 64
  • 87
  • Thanks Elethan, Florent's answer fixed the exception, although it still isn't selecting the option. I will try using get_log to see if it provides any insight in to why the option is not being selected. – Dan Sep 19 '16 at 14:11