Created
November 20, 2019 11:53
-
-
Save zeburek/1a4eec9c4e7f3ad516f9ea59e1525878 to your computer and use it in GitHub Desktop.
Wait for browser requests using pure JS and Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from selenium.common.exceptions import ( | |
WebDriverException, | |
) | |
class number_of_all_elements_located(object): | |
""" An expectation for checking that there is at least given number of | |
elements present on a web page. | |
locator is used to find the element | |
returns the list of WebElements once they are located | |
""" | |
def __init__(self, locator, number): | |
self.locator = locator | |
self.number = number | |
def __call__(self, driver): | |
elements = _find_elements(driver, self.locator) | |
if len(elements) >= self.number: | |
return elements | |
def _find_elements(driver, by): | |
try: | |
return driver.find_elements(*by) | |
except WebDriverException as e: | |
raise e |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import typing | |
from selenium.webdriver.common.by import By | |
from selenium.webdriver.support.abstract_event_listener import \ | |
AbstractEventListener | |
class SeleniumRequests: | |
_responses: typing.Dict[str, typing.List[int]] = {} | |
def add_base_script(self): | |
self._responses = {} | |
self.d.execute_script(""" | |
window.addXMLRequestCallback = (callback) => { | |
var oldSend, i; | |
if( XMLHttpRequest.callbacks ) { | |
XMLHttpRequest.callbacks.push( callback ); | |
} else { | |
XMLHttpRequest.callbacks = [callback]; | |
oldSend = XMLHttpRequest.prototype.send; | |
XMLHttpRequest.prototype.send = function(){ | |
this.addEventListener('load', function() { | |
for(i = 0; i < XMLHttpRequest.callbacks.length; i++) { | |
XMLHttpRequest.callbacks[i](this); | |
} | |
}); | |
oldSend.apply(this, arguments); | |
} | |
XMLHttpRequest.prototype.open = (function(original) { | |
// in case this code is called twice | |
if (original.name === 'newOpen') { | |
return original; | |
} | |
return function newOpen( | |
method, url, asyncflag, user, password | |
) { | |
this.xopen = { | |
method: method, | |
url: url, | |
asyncflag: asyncflag, | |
user: user, | |
password: password | |
}; | |
return original.apply(this, arguments); | |
} | |
})(XMLHttpRequest.prototype.open); | |
} | |
} | |
""") | |
def add_new_response_callback(self, regexp: str, name: str): | |
self.d.execute_script(f""" | |
window.addXMLRequestCallback( function( xhr ) {{ | |
if (/{regexp}/.test(xhr.responseURL)) {{ | |
let elem = document.createElement("response") | |
elem.setAttribute("data-url", xhr.responseURL) | |
//elem.setAttribute("data-content", xhr.responseText) | |
elem.setAttribute("data-name", "{name}") | |
elem.setAttribute("data-status", xhr.status) | |
elem.setAttribute("data-method", xhr.xopen.method) | |
document.body.appendChild(elem) | |
}} | |
}}); | |
""") | |
def wait_response(self, name, wait_time=5): | |
if self._responses.get(name): | |
self._responses.get(name).append(1) | |
else: | |
self._responses[name] = [1] | |
self.wait_number_of_all_elements( | |
(By.XPATH, f"//response[@data-name='{name}']"), | |
len(self._responses.get(name)), | |
wait_time=wait_time | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment