@@ -994,3 +994,178 @@ async fn test_client_core(
994994
995995 Ok ( ( ) )
996996}
997+
998+ mod test3 {
999+ use super :: * ;
1000+ use pretty_assertions:: assert_eq;
1001+ harness ! ( test_client_updates_core) ;
1002+ }
1003+
1004+ #[ tokio:: test]
1005+ async fn test_client_updates ( ) -> Result < ( ) , Box < dyn Error + Send + Sync > > {
1006+ // If both thirtyfour tests start at the same time, both fail; perhaps
1007+ // there's some confusion when two requests care made to the same webserver
1008+ // from two clients within the same process? In order to avoid then, insert
1009+ // a delay to hopefully start this test at a different time than
1010+ // `test_server_core`.
1011+ sleep ( Duration :: from_millis ( 100 ) ) . await ;
1012+ test3:: harness ( test_client_updates_core, prep_test_dir ! ( ) ) . await
1013+ }
1014+
1015+ // Some of the thirtyfour calls are marked as deprecated, though they aren't
1016+ // marked that way in the Selenium docs.
1017+ #[ allow( deprecated) ]
1018+ async fn test_client_updates_core (
1019+ codechat_server : CodeChatEditorServer ,
1020+ driver_ref : & WebDriver ,
1021+ test_dir : PathBuf ,
1022+ ) -> Result < ( ) , WebDriverError > {
1023+ let mut expected_messages = ExpectedMessages :: new ( ) ;
1024+ let path = canonicalize ( test_dir. join ( "test.py" ) ) . unwrap ( ) ;
1025+ let path_str = path. to_str ( ) . unwrap ( ) . to_string ( ) ;
1026+ let current_file_id = codechat_server
1027+ . send_message_current_file ( path_str. clone ( ) )
1028+ . await
1029+ . unwrap ( ) ;
1030+ // The ordering of these messages isn't fixed -- one can come first, or the
1031+ // other.
1032+ expected_messages. insert ( EditorMessage {
1033+ id : current_file_id,
1034+ message : EditorMessageContents :: Result ( Ok ( ResultOkTypes :: Void ) ) ,
1035+ } ) ;
1036+ let mut server_id = 6.0 ;
1037+ expected_messages. insert ( EditorMessage {
1038+ id : server_id,
1039+ message : EditorMessageContents :: LoadFile ( path. clone ( ) ) ,
1040+ } ) ;
1041+ expected_messages
1042+ . assert_all_messages ( & codechat_server, TIMEOUT )
1043+ . await ;
1044+
1045+ // Respond to the load request.
1046+ codechat_server
1047+ . send_result_loadfile ( server_id, None )
1048+ . await
1049+ . unwrap ( ) ;
1050+
1051+ // Respond to the load request for the TOC.
1052+ let toc_path = canonicalize ( test_dir. join ( "toc.md" ) ) . unwrap ( ) ;
1053+ server_id += MESSAGE_ID_INCREMENT * 2.0 ;
1054+ assert_eq ! (
1055+ codechat_server. get_message_timeout( TIMEOUT ) . await . unwrap( ) ,
1056+ EditorMessage {
1057+ id: server_id,
1058+ message: EditorMessageContents :: LoadFile ( toc_path. clone( ) ) ,
1059+ }
1060+ ) ;
1061+ codechat_server
1062+ . send_result_loadfile ( server_id, None )
1063+ . await
1064+ . unwrap ( ) ;
1065+
1066+ // The loadfile produces a message to the client, which comes back here. We
1067+ // don't need to acknowledge it.
1068+ server_id -= MESSAGE_ID_INCREMENT ;
1069+ assert_eq ! (
1070+ codechat_server. get_message_timeout( TIMEOUT ) . await . unwrap( ) ,
1071+ EditorMessage {
1072+ id: server_id,
1073+ message: EditorMessageContents :: Result ( Ok ( ResultOkTypes :: Void ) )
1074+ }
1075+ ) ;
1076+
1077+ // Target the iframe containing the Client.
1078+ let codechat_iframe = driver_ref. find ( By :: Css ( "#CodeChat-iframe" ) ) . await . unwrap ( ) ;
1079+ driver_ref
1080+ . switch_to ( )
1081+ . frame_element ( & codechat_iframe)
1082+ . await
1083+ . unwrap ( ) ;
1084+
1085+ // Select the doc block and add to the line, causing a word wrap.
1086+ let contents_css = ".CodeChat-CodeMirror .CodeChat-doc-contents" ;
1087+ let doc_block_contents = driver_ref. find ( By :: Css ( contents_css) ) . await . unwrap ( ) ;
1088+ doc_block_contents
1089+ . send_keys ( "" + Key :: End + " testing" )
1090+ . await
1091+ . unwrap ( ) ;
1092+
1093+ // Verify the updated text.
1094+ let mut client_id = INITIAL_CLIENT_MESSAGE_ID ;
1095+ assert_eq ! (
1096+ codechat_server. get_message_timeout( TIMEOUT ) . await . unwrap( ) ,
1097+ EditorMessage {
1098+ id: client_id,
1099+ message: EditorMessageContents :: Update ( UpdateMessageContents {
1100+ file_path: path_str. clone( ) ,
1101+ contents: Some ( CodeChatForWeb {
1102+ metadata: SourceFileMetadata {
1103+ mode: "python" . to_string( ) ,
1104+ } ,
1105+ source: CodeMirrorDiffable :: Diff ( CodeMirrorDiff {
1106+ doc: vec![ StringDiff {
1107+ from: 79 ,
1108+ to: None ,
1109+ insert: "# testing\n " . to_string( )
1110+ } ] ,
1111+ doc_blocks: vec![ ]
1112+ } )
1113+ } ) ,
1114+ cursor_position: Some ( 1 ) ,
1115+ scroll_position: Some ( 0.0 )
1116+ } )
1117+ }
1118+ ) ;
1119+ codechat_server. send_result ( client_id, None ) . await . unwrap ( ) ;
1120+
1121+ // Move the cursor to code, then check that the position is correct. TODO:
1122+ // need access to codemirror in test mode.
1123+
1124+ // Insert a character to check the insertion point.
1125+ let code_line_css = ".CodeChat-CodeMirror .cm-line" ;
1126+ let code_line = driver_ref. find ( By :: Css ( code_line_css) ) . await . unwrap ( ) ;
1127+ code_line
1128+ . send_keys ( Key :: Alt + Key :: Control + "g" )
1129+ . await
1130+ . unwrap ( ) ;
1131+ // Enter a line in the dialog that pops up.
1132+ driver_ref
1133+ . find ( By :: Css ( "input.cm-textfield" ) )
1134+ . await
1135+ . unwrap ( )
1136+ . send_keys ( "4" + Key :: Enter )
1137+ . await
1138+ . unwrap ( ) ;
1139+ // Add an indented comment.
1140+ code_line. send_keys ( Key :: Home + "# " ) . await . unwrap ( ) ;
1141+ // This should edit the (new) third line of the file after word wrap: `def
1142+ // foo():`.
1143+ client_id += MESSAGE_ID_INCREMENT ;
1144+ assert_eq ! (
1145+ codechat_server. get_message_timeout( TIMEOUT ) . await . unwrap( ) ,
1146+ EditorMessage {
1147+ id: client_id,
1148+ message: EditorMessageContents :: Update ( UpdateMessageContents {
1149+ file_path: path_str. clone( ) ,
1150+ contents: Some ( CodeChatForWeb {
1151+ metadata: SourceFileMetadata {
1152+ mode: "python" . to_string( ) ,
1153+ } ,
1154+ source: CodeMirrorDiffable :: Diff ( CodeMirrorDiff {
1155+ doc: vec![ StringDiff {
1156+ from: 115 ,
1157+ to: Some ( 131 ) ,
1158+ insert: " # A comment\n " . to_string( )
1159+ } ] ,
1160+ doc_blocks: vec![ ]
1161+ } )
1162+ } ) ,
1163+ cursor_position: Some ( 4 ) ,
1164+ scroll_position: Some ( 0.0 )
1165+ } )
1166+ }
1167+ ) ;
1168+ codechat_server. send_result ( client_id, None ) . await . unwrap ( ) ;
1169+
1170+ Ok ( ( ) )
1171+ }
0 commit comments