@@ -2843,8 +2843,8 @@ <h3>🔠 SeleniumBase supports multiple ways of structuring tests:</h3>
28432843< li > < a href ="#sb_sf_21 "> < strong > 21. SeleniumBase SB (Python context manager)</ strong > </ a > </ li >
28442844< li > < a href ="#sb_sf_22 "> < strong > 22. The driver manager (via context manager)</ strong > </ a > </ li >
28452845< li > < a href ="#sb_sf_23 "> < strong > 23. The driver manager (via direct import)</ strong > </ a > </ li >
2846- < li > < a href ="#sb_sf_24 "> < strong > 24. CDP driver (async/await API. No Selenium)</ strong > </ a > </ li >
2847- < li > < a href ="#sb_sf_25 "> < strong > 25. CDP driver (SB CDP Sync API. No Selenium)</ strong > </ a > </ li >
2846+ < li > < a href ="#sb_sf_24 "> < strong > 24. Pure CDP Mode (Async API. No Selenium)</ strong > </ a > </ li >
2847+ < li > < a href ="#sb_sf_25 "> < strong > 25. Pure CDP Mode ( Sync API. No Selenium)</ strong > </ a > </ li >
28482848</ ul >
28492849</ blockquote >
28502850
@@ -3690,58 +3690,77 @@ <h2><img src="https://seleniumbase.github.io/img/logo3b.png" title="SeleniumBase
36903690< p > The < code > Driver()</ code > manager format can be used as a drop-in replacement for virtually every Python/selenium framework, as it uses the raw < code > driver</ code > instance for handling commands. The < code > Driver()</ code > method simplifies the work of managing drivers with optimal settings, and it can be configured with multiple args. The < code > Driver()</ code > also accepts command-line options (such as < code > python --headless</ code > ) so that you don't need to modify your tests directly to use different settings. These command-line options only take effect if the associated method args remain unset (or set to < code > None</ code > ) for the specified options.</ p >
36913691< p > When using the < code > Driver()</ code > format, you may need to activate a Virtual Display on your own if you want to run headed tests in a headless Linux environment. (See https://github.com/mdmintz/sbVirtualDisplay for details.) One such example of this is using an authenticated proxy, which is configured via a Chrome extension that is generated at runtime. (Note that regular headless mode in Chrome doesn't support extensions.)</ p >
36923692< p > < a id ="sb_sf_24 "> </ a > </ p >
3693- < h2 > < img src ="https://seleniumbase.github.io/img/logo3b.png " title ="SeleniumBase " width ="32 " /> 24. CDP driver (async/await API. No Selenium)</ h2 >
3693+ < h2 > < img src ="https://seleniumbase.github.io/img/logo3b.png " title ="SeleniumBase " width ="32 " /> 24. Pure CDP Mode (Async API. No Selenium)</ h2 >
36943694
3695- < p > This format provides a pure CDP way of using SeleniumBase (without Selenium or a test runner). The async/ await API is used. Here's an example:</ p >
3695+ < p > This format provides a pure CDP way of using SeleniumBase (without Selenium/WebDriver or a test runner). The < code > async</ code > / < code > await</ code > API is used. Here's an example:</ p >
36963696< div class ="highlight "> < pre > < span > </ span > < code > < span class ="kn "> import</ span > < span class ="w "> </ span > < span class ="nn "> asyncio</ span >
3697- < span class ="kn "> import</ span > < span class ="w "> </ span > < span class ="nn "> time</ span >
36983697< span class ="kn "> from</ span > < span class ="w "> </ span > < span class ="nn "> seleniumbase</ span > < span class ="w "> </ span > < span class ="kn "> import</ span > < span class ="n "> cdp_driver</ span >
36993698
37003699< span class ="k "> async</ span > < span class ="k "> def</ span > < span class ="w "> </ span > < span class ="nf "> main</ span > < span class ="p "> ():</ span >
3701- < span class ="n "> url</ span > < span class ="o "> =</ span > < span class ="s2 "> "seleniumbase.io/simple/login"</ span >
3702- < span class ="n "> driver</ span > < span class ="o "> =</ span > < span class ="k "> await</ span > < span class ="n "> cdp_driver</ span > < span class ="o "> .</ span > < span class ="n "> start_async</ span > < span class ="p "> (</ span > < span class ="n "> incognito</ span > < span class ="o "> =</ span > < span class ="kc "> True</ span > < span class ="p "> )</ span >
3703- < span class ="n "> page</ span > < span class ="o "> =</ span > < span class ="k "> await</ span > < span class ="n "> driver</ span > < span class ="o "> .</ span > < span class ="n "> get</ span > < span class ="p "> (</ span > < span class ="n "> url</ span > < span class ="p "> )</ span >
3704- < span class ="nb "> print</ span > < span class ="p "> (</ span > < span class ="k "> await</ span > < span class ="n "> page</ span > < span class ="o "> .</ span > < span class ="n "> evaluate</ span > < span class ="p "> (</ span > < span class ="s2 "> "document.title"</ span > < span class ="p "> ))</ span >
3705- < span class ="n "> element</ span > < span class ="o "> =</ span > < span class ="k "> await</ span > < span class ="n "> page</ span > < span class ="o "> .</ span > < span class ="n "> select</ span > < span class ="p "> (</ span > < span class ="s2 "> "#username"</ span > < span class ="p "> )</ span >
3706- < span class ="k "> await</ span > < span class ="n "> element</ span > < span class ="o "> .</ span > < span class ="n "> send_keys_async</ span > < span class ="p "> (</ span > < span class ="s2 "> "demo_user"</ span > < span class ="p "> )</ span >
3707- < span class ="n "> element</ span > < span class ="o "> =</ span > < span class ="k "> await</ span > < span class ="n "> page</ span > < span class ="o "> .</ span > < span class ="n "> select</ span > < span class ="p "> (</ span > < span class ="s2 "> "#password"</ span > < span class ="p "> )</ span >
3708- < span class ="k "> await</ span > < span class ="n "> element</ span > < span class ="o "> .</ span > < span class ="n "> send_keys_async</ span > < span class ="p "> (</ span > < span class ="s2 "> "secret_pass"</ span > < span class ="p "> )</ span >
3709- < span class ="n "> element</ span > < span class ="o "> =</ span > < span class ="k "> await</ span > < span class ="n "> page</ span > < span class ="o "> .</ span > < span class ="n "> select</ span > < span class ="p "> (</ span > < span class ="s2 "> "#log-in"</ span > < span class ="p "> )</ span >
3710- < span class ="k "> await</ span > < span class ="n "> element</ span > < span class ="o "> .</ span > < span class ="n "> click_async</ span > < span class ="p "> ()</ span >
3711- < span class ="n "> time</ span > < span class ="o "> .</ span > < span class ="n "> sleep</ span > < span class ="p "> (</ span > < span class ="mi "> 1</ span > < span class ="p "> )</ span >
3700+ < span class ="n "> url</ span > < span class ="o "> =</ span > < span class ="s2 "> "https://seleniumbase.io/simple/login"</ span >
3701+ < span class ="n "> driver</ span > < span class ="o "> =</ span > < span class ="k "> await</ span > < span class ="n "> cdp_driver</ span > < span class ="o "> .</ span > < span class ="n "> start_async</ span > < span class ="p "> ()</ span >
3702+ < span class ="n "> page</ span > < span class ="o "> =</ span > < span class ="k "> await</ span > < span class ="n "> driver</ span > < span class ="o "> .</ span > < span class ="n "> get</ span > < span class ="p "> (</ span > < span class ="n "> url</ span > < span class ="p "> ,</ span > < span class ="n "> lang</ span > < span class ="o "> =</ span > < span class ="s2 "> "en"</ span > < span class ="p "> )</ span >
3703+ < span class ="nb "> print</ span > < span class ="p "> (</ span > < span class ="k "> await</ span > < span class ="n "> page</ span > < span class ="o "> .</ span > < span class ="n "> get_title</ span > < span class ="p "> ())</ span >
3704+ < span class ="k "> await</ span > < span class ="n "> page</ span > < span class ="o "> .</ span > < span class ="n "> type</ span > < span class ="p "> (</ span > < span class ="s2 "> "#username"</ span > < span class ="p "> ,</ span > < span class ="s2 "> "demo_user"</ span > < span class ="p "> )</ span >
3705+ < span class ="k "> await</ span > < span class ="n "> page</ span > < span class ="o "> .</ span > < span class ="n "> type</ span > < span class ="p "> (</ span > < span class ="s2 "> "#password"</ span > < span class ="p "> ,</ span > < span class ="s2 "> "secret_pass"</ span > < span class ="p "> )</ span >
3706+ < span class ="k "> await</ span > < span class ="n "> page</ span > < span class ="o "> .</ span > < span class ="n "> click</ span > < span class ="p "> (</ span > < span class ="s2 "> "#log-in"</ span > < span class ="p "> )</ span >
3707+ < span class ="nb "> print</ span > < span class ="p "> (</ span > < span class ="k "> await</ span > < span class ="n "> page</ span > < span class ="o "> .</ span > < span class ="n "> get_title</ span > < span class ="p "> ())</ span >
37123708 < span class ="n "> element</ span > < span class ="o "> =</ span > < span class ="k "> await</ span > < span class ="n "> page</ span > < span class ="o "> .</ span > < span class ="n "> select</ span > < span class ="p "> (</ span > < span class ="s2 "> "h1"</ span > < span class ="p "> )</ span >
37133709 < span class ="k "> assert</ span > < span class ="n "> element</ span > < span class ="o "> .</ span > < span class ="n "> text</ span > < span class ="o "> ==</ span > < span class ="s2 "> "Welcome!"</ span >
3710+ < span class ="n "> top_nav</ span > < span class ="o "> =</ span > < span class ="k "> await</ span > < span class ="n "> page</ span > < span class ="o "> .</ span > < span class ="n "> select</ span > < span class ="p "> (</ span > < span class ="s2 "> "div.topnav"</ span > < span class ="p "> )</ span >
3711+ < span class ="n "> links</ span > < span class ="o "> =</ span > < span class ="k "> await</ span > < span class ="n "> top_nav</ span > < span class ="o "> .</ span > < span class ="n "> query_selector_all_async</ span > < span class ="p "> (</ span > < span class ="s2 "> "a"</ span > < span class ="p "> )</ span >
3712+ < span class ="k "> for</ span > < span class ="n "> nav_item</ span > < span class ="ow "> in</ span > < span class ="n "> links</ span > < span class ="p "> :</ span >
3713+ < span class ="nb "> print</ span > < span class ="p "> (</ span > < span class ="n "> nav_item</ span > < span class ="o "> .</ span > < span class ="n "> text</ span > < span class ="p "> )</ span >
37143714 < span class ="n "> driver</ span > < span class ="o "> .</ span > < span class ="n "> stop</ span > < span class ="p "> ()</ span >
37153715
37163716< span class ="k "> if</ span > < span class ="vm "> __name__</ span > < span class ="o "> ==</ span > < span class ="s2 "> "__main__"</ span > < span class ="p "> :</ span >
37173717 < span class ="n "> loop</ span > < span class ="o "> =</ span > < span class ="n "> asyncio</ span > < span class ="o "> .</ span > < span class ="n "> new_event_loop</ span > < span class ="p "> ()</ span >
37183718 < span class ="n "> loop</ span > < span class ="o "> .</ span > < span class ="n "> run_until_complete</ span > < span class ="p "> (</ span > < span class ="n "> main</ span > < span class ="p "> ())</ span >
37193719</ code > </ pre > </ div >
3720- < p > (See < a href ="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_async .py "> examples/cdp_mode/raw_async .py</ a > for the test.)</ p >
3720+ < p > (See < a href ="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_basic_async .py "> examples/cdp_mode/raw_basic_async .py</ a > for the test.)</ p >
37213721< p > < a id ="sb_sf_25 "> </ a > </ p >
3722- < h2 > < img src ="https://seleniumbase.github.io/img/logo3b.png " title ="SeleniumBase " width ="32 " /> 25. CDP driver (SB CDP Sync API. No Selenium)</ h2 >
3722+ < h2 > < img src ="https://seleniumbase.github.io/img/logo3b.png " title ="SeleniumBase " width ="32 " /> 25. Pure CDP Mode ( Sync API. No Selenium)</ h2 >
37233723
3724- < p > This format provides a pure CDP way of using SeleniumBase (without Selenium or a test runner). The expanded SB CDP Sync API is used. Here's an example:</ p >
3724+ < p > This format provides a pure CDP way of using SeleniumBase (without Selenium/WebDriver or a test runner). The expanded < code > sb_cdp</ code > Sync API is used. Here's an example:</ p >
3725+ < div class ="highlight "> < pre > < span > </ span > < code > < span class ="kn "> from</ span > < span class ="w "> </ span > < span class ="nn "> seleniumbase</ span > < span class ="w "> </ span > < span class ="kn "> import</ span > < span class ="n "> sb_cdp</ span >
3726+
3727+ < span class ="n "> url</ span > < span class ="o "> =</ span > < span class ="s2 "> "https://seleniumbase.io/simple/login"</ span >
3728+ < span class ="n "> sb</ span > < span class ="o "> =</ span > < span class ="n "> sb_cdp</ span > < span class ="o "> .</ span > < span class ="n "> Chrome</ span > < span class ="p "> (</ span > < span class ="n "> url</ span > < span class ="p "> )</ span >
3729+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> type</ span > < span class ="p "> (</ span > < span class ="s2 "> "#username"</ span > < span class ="p "> ,</ span > < span class ="s2 "> "demo_user"</ span > < span class ="p "> )</ span >
3730+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> type</ span > < span class ="p "> (</ span > < span class ="s2 "> "#password"</ span > < span class ="p "> ,</ span > < span class ="s2 "> "secret_pass"</ span > < span class ="p "> )</ span >
3731+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> click</ span > < span class ="p "> (</ span > < span class ="s1 "> 'a:contains("Sign in")'</ span > < span class ="p "> )</ span >
3732+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> assert_exact_text</ span > < span class ="p "> (</ span > < span class ="s2 "> "Welcome!"</ span > < span class ="p "> ,</ span > < span class ="s2 "> "h1"</ span > < span class ="p "> )</ span >
3733+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> assert_element</ span > < span class ="p "> (</ span > < span class ="s2 "> "img#image1"</ span > < span class ="p "> )</ span >
3734+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> highlight</ span > < span class ="p "> (</ span > < span class ="s2 "> "#image1"</ span > < span class ="p "> )</ span >
3735+ < span class ="n "> top_nav</ span > < span class ="o "> =</ span > < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> find_element</ span > < span class ="p "> (</ span > < span class ="s2 "> "div.topnav"</ span > < span class ="p "> )</ span >
3736+ < span class ="n "> links</ span > < span class ="o "> =</ span > < span class ="n "> top_nav</ span > < span class ="o "> .</ span > < span class ="n "> query_selector_all</ span > < span class ="p "> (</ span > < span class ="s2 "> "a"</ span > < span class ="p "> )</ span >
3737+ < span class ="k "> for</ span > < span class ="n "> nav_item</ span > < span class ="ow "> in</ span > < span class ="n "> links</ span > < span class ="p "> :</ span >
3738+ < span class ="nb "> print</ span > < span class ="p "> (</ span > < span class ="n "> nav_item</ span > < span class ="o "> .</ span > < span class ="n "> text</ span > < span class ="p "> )</ span >
3739+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> click_link</ span > < span class ="p "> (</ span > < span class ="s2 "> "Sign out"</ span > < span class ="p "> )</ span >
3740+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> assert_text</ span > < span class ="p "> (</ span > < span class ="s2 "> "signed out"</ span > < span class ="p "> ,</ span > < span class ="s2 "> "#top_message"</ span > < span class ="p "> )</ span >
3741+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> driver</ span > < span class ="o "> .</ span > < span class ="n "> stop</ span > < span class ="p "> ()</ span >
3742+ </ code > </ pre > </ div >
3743+ < p > (See < a href ="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_basic_cdp.py "> examples/cdp_mode/raw_basic_cdp.py</ a > for the test.)</ p >
3744+ < p > Here's a Pure CDP Mode example that bypasses bot-detection to scrape data from a website:</ p >
37253745< div class ="highlight "> < pre > < span > </ span > < code > < span class ="kn "> from</ span > < span class ="w "> </ span > < span class ="nn "> seleniumbase</ span > < span class ="w "> </ span > < span class ="kn "> import</ span > < span class ="n "> sb_cdp</ span >
37263746
3727- < span class ="nd "> @decorators</ span > < span class ="o "> .</ span > < span class ="n "> print_runtime</ span > < span class ="p "> (</ span > < span class ="s2 "> "CDP Priceline Example"</ span > < span class ="p "> )</ span >
37283747< span class ="k "> def</ span > < span class ="w "> </ span > < span class ="nf "> main</ span > < span class ="p "> ():</ span >
37293748 < span class ="n "> url</ span > < span class ="o "> =</ span > < span class ="s2 "> "https://www.priceline.com/"</ span >
37303749 < span class ="n "> sb</ span > < span class ="o "> =</ span > < span class ="n "> sb_cdp</ span > < span class ="o "> .</ span > < span class ="n "> Chrome</ span > < span class ="p "> (</ span > < span class ="n "> url</ span > < span class ="p "> ,</ span > < span class ="n "> lang</ span > < span class ="o "> =</ span > < span class ="s2 "> "en"</ span > < span class ="p "> )</ span >
3731- < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> sleep</ span > < span class ="p "> (</ span > < span class ="mf "> 2.5 </ span > < span class ="p "> )</ span >
3750+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> sleep</ span > < span class ="p "> (</ span > < span class ="mi "> 2</ span > < span class ="p "> )</ span >
37323751 < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> internalize_links</ span > < span class ="p "> ()</ span > < span class ="c1 "> # Don't open links in a new tab</ span >
37333752 < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> click</ span > < span class ="p "> (</ span > < span class ="s2 "> "#link_header_nav_experiences"</ span > < span class ="p "> )</ span >
3734- < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> sleep</ span > < span class ="p "> (</ span > < span class ="mf "> 3.5 </ span > < span class ="p "> )</ span >
3753+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> sleep</ span > < span class ="p "> (</ span > < span class ="mi "> 3</ span > < span class ="p "> )</ span >
37353754 < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> remove_elements</ span > < span class ="p "> (</ span > < span class ="s2 "> "msm-cookie-banner"</ span > < span class ="p "> )</ span >
3736- < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> sleep</ span > < span class ="p "> (</ span > < span class ="mf "> 1.5 </ span > < span class ="p "> )</ span >
3755+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> sleep</ span > < span class ="p "> (</ span > < span class ="mi "> 1</ span > < span class ="p "> )</ span >
37373756 < span class ="n "> location</ span > < span class ="o "> =</ span > < span class ="s2 "> "Amsterdam"</ span >
37383757 < span class ="n "> where_to</ span > < span class ="o "> =</ span > < span class ="s1 "> 'div[data-automation*="experiences"] input'</ span >
37393758 < span class ="n "> button</ span > < span class ="o "> =</ span > < span class ="s1 "> 'button[data-automation*="experiences-search"]'</ span >
37403759 < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> wait_for_text</ span > < span class ="p "> (</ span > < span class ="s2 "> "Where to?"</ span > < span class ="p "> )</ span >
3741- < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> gui_click_element </ span > < span class ="p "> (</ span > < span class ="n "> where_to</ span > < span class ="p "> )</ span >
3760+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> click </ span > < span class ="p "> (</ span > < span class ="n "> where_to</ span > < span class ="p "> )</ span >
37423761 < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> press_keys</ span > < span class ="p "> (</ span > < span class ="n "> where_to</ span > < span class ="p "> ,</ span > < span class ="n "> location</ span > < span class ="p "> )</ span >
37433762 < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> sleep</ span > < span class ="p "> (</ span > < span class ="mi "> 1</ span > < span class ="p "> )</ span >
3744- < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> gui_click_element </ span > < span class ="p "> (</ span > < span class ="n "> button</ span > < span class ="p "> )</ span >
3763+ < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> click </ span > < span class ="p "> (</ span > < span class ="n "> button</ span > < span class ="p "> )</ span >
37453764 < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> sleep</ span > < span class ="p "> (</ span > < span class ="mi "> 2</ span > < span class ="p "> )</ span >
37463765 < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> click_if_visible</ span > < span class ="p "> (</ span > < span class ="s1 "> 'button[aria-label="Close"]'</ span > < span class ="p "> )</ span >
37473766 < span class ="n "> sb</ span > < span class ="o "> .</ span > < span class ="n "> sleep</ span > < span class ="p "> (</ span > < span class ="mi "> 1</ span > < span class ="p "> )</ span >
0 commit comments