@@ -57,9 +57,7 @@ public class BlockEditorScreen: ScreenObject {
5757 public func enterTextInTitle( text: String ) -> BlockEditorScreen {
5858 let titleView = app. otherElements [ " Post title. Empty " ] . firstMatch // Uses a localized string
5959 XCTAssert ( titleView. waitForExistence ( timeout: 3 ) , " Title View does not exist! " )
60-
61- titleView. tap ( )
62- titleView. typeText ( text)
60+ type ( text: text, in: titleView)
6361
6462 return self
6563 }
@@ -72,7 +70,7 @@ public class BlockEditorScreen: ScreenObject {
7270 addBlock ( " Paragraph block " )
7371
7472 let paragraphView = app. otherElements [ " Paragraph Block. Row 1. Empty " ] . textViews. element ( boundBy: 0 )
75- paragraphView . typeText ( text)
73+ type ( text: text , in : paragraphView )
7674
7775 return self
7876 }
@@ -368,4 +366,44 @@ public class BlockEditorScreen: ScreenObject {
368366 editorCloseButton. coordinate ( withNormalizedOffset: CGVector ( dx: 0 , dy: 0 ) ) . tap ( )
369367 return try BlockEditorScreen ( )
370368 }
369+
370+ // This could be moved as an XCUIApplication method via an extension if needed elsewhere.
371+ private func type( text: String , in element: XCUIElement ) {
372+ // A simple implementation here would be:
373+ //
374+ // element.tap()
375+ // element.typeText(text)
376+ //
377+ // But as of a recent (but not pinpointed at the time of writing) Gutenberg update, that is not enough.
378+ // The test would fail with: Neither element nor any descendant has keyboard focus.
379+ // (E.g.: https://buildkite.com/automattic/wordpress-ios/builds/15598)
380+ //
381+ // The following is a convoluted but seemingly robust approach that bypasses the keyboard by using the pasteboard instead.
382+ UIPasteboard . general. string = text
383+
384+ // Safety check
385+ XCTAssertTrue ( element. waitForExistence ( timeout: 1 ) )
386+
387+ element. doubleTap ( )
388+
389+ let pasteButton = app. menuItems [ " Paste " ]
390+
391+ if pasteButton. waitForExistence ( timeout: 1 ) == false {
392+ // Drill in hierarchy looking for it
393+ var found = false
394+ element. descendants ( matching: . any) . enumerated ( ) . forEach { e in
395+ guard found == false else { return }
396+
397+ e. element. firstMatch. doubleTap ( )
398+
399+ if pasteButton. waitForExistence ( timeout: 1 ) {
400+ found = true
401+ }
402+ }
403+ }
404+
405+ XCTAssertTrue ( pasteButton. exists, " Could not find menu item paste button. " )
406+
407+ pasteButton. tap ( )
408+ }
371409}
0 commit comments