Using Angular JS(Protractor) with Selenium in Python

11,677

Solution 1

You can also use regular selenium bindings to test AngularJS applications. You would need to use Explicit Waits to wait for elements to appear, disappear, title/url to change etc - for any actions that would let you continue with testing the page.

Example (waiting for textarea element to appear):

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10)
wait.until(EC.visibility_of_element_located((By.TAG_NAME, "myaccount")))

There is one important thing that pytractor (as protractor itself) provides - it knows when AngularJS is settled and ready - models are updated, there are no outstanding async requests etc. It doesn't mean you have to use it to test AngularJS applications, but it gives you an advantage.

Additionally, pytractor provides you with new locators, e.g. you can find an element by model or binding. It also doesn't mean you cannot find the same element using other location techniques which regular selenium python provides out-of-the-box.

Note that pytractor is not actively developed and maintained at the moment.

Solution 2

You may just mine protractor for useful code snippets. I personally use this function that blocks until Angular is done rendering the page.

def wait_for_angular(self, selenium_driver):
    selenium_driver.set_script_timeout(10)
    selenium_driver.execute_async_script("""
        callback = arguments[arguments.length - 1];
        angular.element('html').injector().get('$browser').notifyWhenNoOutstandingRequests(callback);""")

Replace 'html' for whatever element is your 'ng-app'.

Solution for Angular 1 comes from protractor/lib/clientsidescripts.js#L51. It could also be possible to adapt the solution to Angular 2 using this updated code

Share:
11,677

Related videos on Youtube

Qu3ntin0
Author by

Qu3ntin0

Updated on June 04, 2022

Comments

  • Qu3ntin0
    Qu3ntin0 almost 2 years

    I'm trying to select a textarea wrapped in angular 1 using selenium, but it can't be seen in DOM. There's a module called Pytractor. I've been trying to solve this but I'm unable to use it correctly.

    Can anyone help me with this?

  • shakaran
    shakaran over 6 years
    I have to use document.getElementsByTagName('html') for avoid the error "Looking up elements via selectors is not supported by jqLite!"
  • GabLeRoux
    GabLeRoux over 6 years
    This worked for me and I like the idea of using what protractor uses too. Nice catch 👍