seleniumbase / SeleniumBase

📊 Python's all-in-one framework for web crawling, scraping, testing, and reporting. Supports pytest. UC Mode provides stealth. Includes many tools.
https://seleniumbase.io
MIT License
5k stars 944 forks source link

How to change response body with uc_cdp_events #2050

Closed FranciscoPalomares closed 1 year ago

FranciscoPalomares commented 1 year ago

Hi, I need to change response data with option uc_cdp_events, and I don't see response field Thanks

mdmintz commented 1 year ago

In order to change the response from uc_cdp_events, you'll need to use driver.execute_cdp_cmd(). Here's an example where the Geo Location is changed in a test:

from seleniumbase import BaseCase
BaseCase.main(__name__, __file__)

class TestGeolocation(BaseCase):
    def tearDown(self):
        self.save_teardown_screenshot()  # If test fails, or if "--screenshot"
        if self.is_chromium() and not self._multithreaded:
            # Reset Permissions and GeolocationOverride
            self.execute_cdp_cmd("Browser.resetPermissions", {})
            self.execute_cdp_cmd("Emulation.setGeolocationOverride", {})
        super().tearDown()

    def test_geolocation(self):
        self.open("about:blank")
        if self._multithreaded:
            self.skip("Skipping test in multi-threaded mode.")
        if not self.is_chromium():
            print("\n* execute_cdp_cmd() is only for Chromium browsers")
            self.skip("execute_cdp_cmd() is only for Chromium browsers")
        self.execute_cdp_cmd(
            "Browser.grantPermissions",
            {
                "origin": "https://www.openstreetmap.org/",
                "permissions": ["geolocation"],
            },
        )
        self.execute_cdp_cmd(
            "Emulation.setGeolocationOverride",
            {
                "latitude": 48.87645,
                "longitude": 2.26340,
                "accuracy": 100,
            },
        )
        self.open("https://www.openstreetmap.org/")
        self.click("span.geolocate")
        self.assert_url_contains("48.87645/2.26340")
        self.save_screenshot_to_logs()
        if self.headed:
            self.sleep(2.5)

I'm not the expert on using driver.execute_cdp_cmd(), so for that you'll need to search the web.


For the uc_cdp example, see:

from pprint import pformat
from seleniumbase import BaseCase

if __name__ == "__main__":
    from pytest import main
    main([__file__, "--uc", "--uc-cdp", "-s"])

class CDPTests(BaseCase):
    def add_cdp_listener(self):
        # (To print everything, use "*". Otherwise select specific headers.)
        # self.driver.add_cdp_listener("*", lambda data: print(pformat(data)))
        self.driver.add_cdp_listener(
            "Network.requestWillBeSentExtraInfo",
            lambda data: print(pformat(data))
        )

    def verify_success(self):
        self.assert_text("OH YEAH, you passed!", "h1", timeout=6.25)
        self.sleep(1)

    def fail_me(self):
        self.fail('Selenium was detected! Try using: "pytest --uc"')

    def test_display_cdp_events(self):
        if not (self.undetectable and self.uc_cdp_events):
            self.get_new_driver(undetectable=True, uc_cdp_events=True)
        self.open("https://nowsecure.nl/#relax")
        try:
            self.verify_success()
        except Exception:
            self.clear_all_cookies()
            self.get_new_driver(undetectable=True, uc_cdp_events=True)
            self.open("https://nowsecure.nl/#relax")
            self.verify_success()
        self.add_cdp_listener()
        self.refresh()
        self.sleep(1)
FranciscoPalomares commented 1 year ago

Hi, There is no example to change the response of an http call ? for example from an api ? with selenium wire is easy, but it detected

jdholtz commented 1 year ago

Hey @FranciscoPalomares. I just figured this out myself. To get the response body of a request, first get the requestId. Then, you'll want to execute the following: driver.execute_cdp_cmd("Network.getResponseBody", { "requestId": "<request id>" })