Force Selenium is waiting for AngularJS

How can I make python Selenium wait a second until AngularJS finishes parsing the pages and loading some things it needs.

Or how can I make Selenium wait 1 second after clicking a button, which causes an ajax request to the server processed by AngularJS. I need to perform server side actions before moving to another page.

+4
source share
3 answers

Access to the AngularJS area through Selenium - most likely, this state is already held in Scope / IsolatedScope.

I created several extensions to help with this, which can be translated into python.

webDriver.NgWaitFor(productDiv, "scope.Data.Id != 0");
webDriver.NgWaitFor(partialElement, "scope.IsBusyLoadingTemplate == false");

https://github.com/leblancmeneses/RobustHaven.IntegrationTests/blob/master/NgExtensions/NgWebDriverExtensions.cs

ajax, $http jquery, :

webDriver.WaitFor("window.isBrowserBusy() == false");

, angularjs, jquery, xhr.

, : ( )

https://github.com/leblancmeneses/RobustHaven.IntegrationTests

+3

,

from datetime import datetime, timedelta
from time import sleep

from selenium import webdriver
from selenium.common.exceptions import WebDriverException


class MyDriver(webdriver.Chrome):
def __init__(self, executable_path="chromedriver", port=0,
             chrome_options=None, service_args=None,
             desired_capabilities=None, service_log_path=None):
    super().__init__(executable_path, port, chrome_options, service_args,
                     desired_capabilities, service_log_path)

def wait_until_angular(self, seconds: int = 10) -> None:
    java_script_to_load_angular = "var injector = window.angular.element('body').injector(); " \
                                  "var $http = injector.get('$http');" \
                                  "return ($http.pendingRequests.length === 0);"
    end_time = datetime.utcnow() + timedelta(seconds=seconds)
    print("wait for Angular Elements....")
    while datetime.utcnow() < end_time:
        try:
            if self.execute_script(java_script_to_load_angular):
                return
        except WebDriverException:
            continue
        sleep(0.1)
    raise TimeoutError("waiting for angular elements for too long")

, .

+1

- , , . , script .

, , API , , , , , , , . " script , , .

, , . , , , AngularJS API React API ..

1.

Selenium includes WebDriverWaitand expected_conditionsto help you wait until the special conditions are met:

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

TIMEOUT = 5

# ...

WebDriverWait(driver, TIMEOUT).until(
    EC.text_to_be_present_in_element(
        [By.CLASS_NAME, "alert"],
        "Record created successfully"))

2. Using Capybara (which uses Selenium)

As you can see above, bare selenium is complex and subtle. capybara-py tears most of it off:

from capybara.dsl import page

# ...

page.assert_text("Record created successfully")
0
source

All Articles