2

I am using webdriver to fill out a form in Django. The first field, name, is found and filled out. But the second field is somehow not being found. Here's the script I'm using...

name = browser.find_element_by_id("name")
value = browser.find_element_by_id("value")
submit = browser.find_element_by_id("offer-submit")
name.send_keys(address)
name.send_keys(Keys.TAB)
# I tried having the browser press tab to see if it becomes visible. no luck.
value.send_keys(random.randrange(1, 100, 2))

Here's the error traceback:

Traceback (most recent call last):
  File "populate_map.py", line 71, in <module>
    value.send_keys(random.randrange(1, 100, 2))
  File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webelement.py", line 320, in send_keys
    self._execute(Command.SEND_KEYS_TO_ELEMENT, {'value': keys_to_typing(value)})
  File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webelement.py", line 461, in _execute
    return self._parent.execute(command, params)
  File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 236, in execute
    self.error_handler.check_response(response)
  File "C:\Python27\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 192, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with
Stacktrace:
    at fxdriver.preconditions.visible (file:///c:/users/owner/appdata/local/temp/tmprd4j_t/extensions/fxdriver@googlecode.com/components/command-processor.js:10092)
    at DelayedCommand.prototype.checkPreconditions_ (file:///c:/users/owner/appdata/local/temp/tmprd4j_t/extensions/fxdriver@googlecode.com/components/command-processor.js:12644)
    at DelayedCommand.prototype.executeInternal_/h (file:///c:/users/owner/appdata/local/temp/tmprd4j_t/extensions/fxdriver@googlecode.com/components/command-processor.js:12661)
    at fxdriver.Timer.prototype.setTimeout/<.notify (file:///c:/users/owner/appdata/local/temp/tmprd4j_t/extensions/fxdriver@googlecode.com/components/command-processor.js:625)

The fields are being created with this form:

class OfferForm(forms.ModelForm):        
    service = forms.BooleanField()

    class Meta:
        model = Offer
        fields = [
            "name", 
            "value",
            "description",
            "tags",
            "location",
            "code",
            "service",
       #     "duration"
            "icon",
        ]
        widgets = {
            'name': forms.TextInput(
                attrs={'id': 'name', 'class': 'data', 'style': 'font-family: VT323; font-size: 60%', 'required': True, 'placeholder': 'name'}
            ),
            'value': forms.TextInput(
                attrs={'id': 'value', 'class': 'data', 'style': 'font-family: VT323; font-size: 60%', 'required': True, 'placeholder': 'value'}
            ),

}

Reading this question, I see that there should be a good reason that the value isn't visible -- i.e. it is being made invisible with a style attribute. But when I bring up firebug, I can't see anything to indicate that it's invisible.

Here's my template code: (I should mention that #offer is clicked earlier in the script, which activates the display -- it's not none by the time the webdriver is looking for it.)

      <script>
      $("#offer").click(function(){
    $("#find-offer").css("display", "none");
    $("#make-offer").css("display", "block");
    $("#popular-offers").css("display", "block")
    $(".welcome").css("display", "none");
});
</script>

      <div id="make-offer" style="display: none">

      <p>Make an offer</p>
      <form name="offer-form" action="" method="post" enctype="multipart/form-data">
      {% csrf_token %}
      {{ form.as_p }}
      <input type="submit" id="offer-submit" class="data" style="font-family: Fira Mono; font-size: 70%; padding: 10px; position: absolute"  value="Submit" />
      </form>

Any other ideas?

Community
  • 1
  • 1
David J.
  • 1,753
  • 13
  • 47
  • 96

1 Answers1

1

In my experience, ActionChains are often the answer when I have an issue like this in selenium. It is worth a try in this case:

from selenium.webdriver.common.action_chains import ActionChains

ActionChains(browser).move_to_element(value).click().send_keys(random.randrange(1, 100, 2)).perform()

This will first move to the element, click to focus the input, and then send the keys. If the element is not being seen as visible this might raise the same exception, but it is worth a shot.

elethan
  • 16,408
  • 8
  • 64
  • 87
  • I tried your suggestion, got the following error message: raise exception_class(message, screen, stacktrace) selenium.common.exceptions.MoveTargetOutOfBoundsException: Message: Offset within element cannot be scrolled into view: (0, 0): [object HTMLInputElement] Stacktrace: – David J. Sep 17 '16 at 05:13
  • @DavidJ. If you put the line `import time; time.sleep(5)` right before the line that causes the error, do you see the input there as being visible? – elethan Sep 17 '16 at 14:49
  • Yes, the input appears visible with or without the sleep. – David J. Sep 17 '16 at 20:33