@@ -515,6 +515,50 @@ impl BrowserWindow {
515515 }
516516 }
517517
518+ async fn scroll_selector (
519+ & self ,
520+ selector : & str ,
521+ timeout_secs : u64 ,
522+ ) -> Result < ( ) , ToolproofStepError > {
523+ match self {
524+ BrowserWindow :: Chrome ( page) => {
525+ loop {
526+ let element = browser_specific:: wait_for_chrome_element_selector (
527+ page,
528+ selector,
529+ timeout_secs,
530+ )
531+ . await ?;
532+
533+ if let Err ( e) = element. scroll_into_view ( ) . await {
534+ match e {
535+ // If the element was detached from the DOM after the time we selected it,
536+ // we want to restart this section and select a new element.
537+ CdpError :: ScrollingFailed ( msg) if msg. contains ( "detached" ) => continue ,
538+ _ => {
539+ return Err ( ToolproofStepError :: Assertion (
540+ ToolproofTestFailure :: Custom {
541+ msg : format ! (
542+ "Element {selector} could not be scrolled into view: {e}"
543+ ) ,
544+ } ,
545+ ) )
546+ }
547+ }
548+ }
549+ break ;
550+ }
551+
552+ Ok ( ( ) )
553+ }
554+ BrowserWindow :: Pagebrowse ( _) => Err ( ToolproofStepError :: Internal (
555+ ToolproofInternalError :: Custom {
556+ msg : "Scrolls not yet implemented for Pagebrowse" . to_string ( ) ,
557+ } ,
558+ ) ) ,
559+ }
560+ }
561+
518562 async fn press_key ( & self , key : & str , timeout_secs : u64 ) -> Result < ( ) , ToolproofStepError > {
519563 match self {
520564 BrowserWindow :: Chrome ( page) => {
@@ -929,6 +973,39 @@ mod interactions {
929973 }
930974 }
931975
976+ pub struct ScrollSelector ;
977+
978+ inventory:: submit! {
979+ & ScrollSelector as & dyn ToolproofInstruction
980+ }
981+
982+ #[ async_trait]
983+ impl ToolproofInstruction for ScrollSelector {
984+ fn segments ( & self ) -> & ' static str {
985+ "In my browser, I scroll to the selector {selector}"
986+ }
987+
988+ async fn run (
989+ & self ,
990+ args : & SegmentArgs < ' _ > ,
991+ civ : & mut Civilization ,
992+ ) -> Result < ( ) , ToolproofStepError > {
993+ let selector = args. get_string ( "selector" ) ?;
994+
995+ let Some ( window) = civ. window . as_ref ( ) else {
996+ return Err ( ToolproofStepError :: External (
997+ ToolproofInputError :: StepRequirementsNotMet {
998+ reason : "no page has been loaded into the browser for this test" . into ( ) ,
999+ } ,
1000+ ) ) ;
1001+ } ;
1002+
1003+ window
1004+ . scroll_selector ( & selector, auto_selector_timeout ( civ) )
1005+ . await
1006+ }
1007+ }
1008+
9321009 pub struct PressKey ;
9331010
9341011 inventory:: submit! {
0 commit comments