@@ -60,7 +60,7 @@ def test_logs_console_errors(driver, pages):
6060 log_entries = []
6161
6262 def log_error (entry ):
63- if entry .level == "error" :
63+ if entry .level == LogLevel . ERROR :
6464 log_entries .append (entry )
6565
6666 driver .script .add_console_message_handler (log_error )
@@ -561,3 +561,219 @@ def test_disown_handles(driver, pages):
561561 target = {"context" : driver .current_window_handle },
562562 arguments = [{"handle" : handle }],
563563 )
564+
565+
566+ # Tests for high-level SCRIPT API commands
567+
568+
569+ def test_pin_script (driver , pages ):
570+ """Test pinning a script."""
571+ function_declaration = "() => { window.pinnedScriptExecuted = 'yes'; }"
572+
573+ script_id = driver .script .pin (function_declaration )
574+ assert script_id is not None
575+ assert isinstance (script_id , str )
576+
577+ pages .load ("blank.html" )
578+
579+ result = driver .script .execute ("() => window.pinnedScriptExecuted" )
580+ assert result ["value" ] == "yes"
581+
582+
583+ def test_unpin_script (driver , pages ):
584+ """Test unpinning a script."""
585+ function_declaration = "() => { window.unpinnableScript = 'executed'; }"
586+
587+ script_id = driver .script .pin (function_declaration )
588+ driver .script .unpin (script_id )
589+
590+ pages .load ("blank.html" )
591+
592+ result = driver .script .execute ("() => typeof window.unpinnableScript" )
593+ assert result ["value" ] == "undefined"
594+
595+
596+ def test_execute_script_with_undefined_argument (driver , pages ):
597+ """Test executing script with undefined argument."""
598+ pages .load ("blank.html" )
599+
600+ result = driver .script .execute (
601+ """(arg) => {
602+ if(arg!==undefined)
603+ throw Error("Argument should be undefined, but was "+arg);
604+ return arg;
605+ }""" ,
606+ None ,
607+ )
608+
609+ assert result ["type" ] == "undefined"
610+
611+
612+ def test_execute_script_with_number_argument (driver , pages ):
613+ """Test executing script with number argument."""
614+ pages .load ("blank.html" )
615+
616+ result = driver .script .execute (
617+ """(arg) => {
618+ if(arg!==1.4)
619+ throw Error("Argument should be 1.4, but was "+arg);
620+ return arg;
621+ }""" ,
622+ 1.4 ,
623+ )
624+
625+ assert result ["type" ] == "number"
626+ assert result ["value" ] == 1.4
627+
628+
629+ def test_execute_script_with_boolean_argument (driver , pages ):
630+ """Test executing script with boolean argument."""
631+ pages .load ("blank.html" )
632+
633+ result = driver .script .execute (
634+ """(arg) => {
635+ if(arg!==true)
636+ throw Error("Argument should be true, but was "+arg);
637+ return arg;
638+ }""" ,
639+ True ,
640+ )
641+
642+ assert result ["type" ] == "boolean"
643+ assert result ["value" ] is True
644+
645+
646+ def test_execute_script_with_string_argument (driver , pages ):
647+ """Test executing script with string argument."""
648+ pages .load ("blank.html" )
649+
650+ result = driver .script .execute (
651+ """(arg) => {
652+ if(arg!=="hello world")
653+ throw Error("Argument should be 'hello world', but was "+arg);
654+ return arg;
655+ }""" ,
656+ "hello world" ,
657+ )
658+
659+ assert result ["type" ] == "string"
660+ assert result ["value" ] == "hello world"
661+
662+
663+ def test_execute_script_with_array_argument (driver , pages ):
664+ """Test executing script with array argument."""
665+ pages .load ("blank.html" )
666+
667+ test_list = [1 , 2 , 3 ]
668+
669+ result = driver .script .execute (
670+ """(arg) => {
671+ if(!(arg instanceof Array))
672+ throw Error("Argument type should be Array, but was "+
673+ Object.prototype.toString.call(arg));
674+ if(arg.length !== 3)
675+ throw Error("Array should have 3 elements, but had "+arg.length);
676+ return arg;
677+ }""" ,
678+ test_list ,
679+ )
680+
681+ assert result ["type" ] == "array"
682+ values = result ["value" ]
683+ assert len (values ) == 3
684+
685+
686+ def test_execute_script_with_multiple_arguments (driver , pages ):
687+ """Test executing script with multiple arguments."""
688+ pages .load ("blank.html" )
689+
690+ result = driver .script .execute (
691+ """(a, b, c) => {
692+ if(a !== 1) throw Error("First arg should be 1");
693+ if(b !== "test") throw Error("Second arg should be 'test'");
694+ if(c !== true) throw Error("Third arg should be true");
695+ return a + b.length + (c ? 1 : 0);
696+ }""" ,
697+ 1 ,
698+ "test" ,
699+ True ,
700+ )
701+
702+ assert result ["type" ] == "number"
703+ assert result ["value" ] == 6 # 1 + 4 + 1
704+
705+
706+ def test_execute_script_returns_promise (driver , pages ):
707+ """Test executing script that returns a promise."""
708+ pages .load ("blank.html" )
709+
710+ result = driver .script .execute (
711+ """() => {
712+ return Promise.resolve("async result");
713+ }""" ,
714+ )
715+
716+ assert result ["type" ] == "string"
717+ assert result ["value" ] == "async result"
718+
719+
720+ def test_execute_script_with_exception (driver , pages ):
721+ """Test executing script that throws an exception."""
722+ pages .load ("blank.html" )
723+
724+ from selenium .common .exceptions import WebDriverException
725+
726+ with pytest .raises (WebDriverException ) as exc_info :
727+ driver .script .execute (
728+ """() => {
729+ throw new Error("Test error message");
730+ }""" ,
731+ )
732+
733+ assert "Test error message" in str (exc_info .value )
734+
735+
736+ def test_execute_script_accessing_dom (driver , pages ):
737+ """Test executing script that accesses DOM elements."""
738+ pages .load ("formPage.html" )
739+
740+ result = driver .script .execute (
741+ """() => {
742+ return document.title;
743+ }""" ,
744+ )
745+
746+ assert result ["type" ] == "string"
747+ assert result ["value" ] == "We Leave From Here"
748+
749+
750+ def test_execute_script_with_nested_objects (driver , pages ):
751+ """Test executing script with nested object arguments."""
752+ pages .load ("blank.html" )
753+
754+ nested_data = {
755+ "user" : {
756+ "name" : "John" ,
757+ "age" : 30 ,
758+ "hobbies" : ["reading" , "coding" ],
759+ },
760+ "settings" : {"theme" : "dark" , "notifications" : True },
761+ }
762+
763+ result = driver .script .execute (
764+ """(data) => {
765+ return {
766+ userName: data.user.name,
767+ userAge: data.user.age,
768+ hobbyCount: data.user.hobbies.length,
769+ theme: data.settings.theme
770+ };
771+ }""" ,
772+ nested_data ,
773+ )
774+
775+ assert result ["type" ] == "object"
776+ value_dict = {k : v ["value" ] for k , v in result ["value" ]}
777+ assert value_dict ["userName" ] == "John"
778+ assert value_dict ["userAge" ] == 30
779+ assert value_dict ["hobbyCount" ] == 2
0 commit comments