From cf2147abdbb0e749c7aee9da1da0c38618f1faea Mon Sep 17 00:00:00 2001 From: Chloe Han Date: Fri, 21 Feb 2025 09:46:55 -0500 Subject: [PATCH 1/3] async streaming ios update --- ios/demo/Sources/MockFlows.swift | 34 ++ .../ios/Tests/AsynNodePluginTests.swift | 299 ++++++++++++++++++ .../UITests/ChatMessageAssetUITests.swift | 11 + 3 files changed, 344 insertions(+) create mode 100644 plugins/reference-assets/swiftui/UITests/ChatMessageAssetUITests.swift diff --git a/ios/demo/Sources/MockFlows.swift b/ios/demo/Sources/MockFlows.swift index 378721d24..86ec08eb4 100644 --- a/ios/demo/Sources/MockFlows.swift +++ b/ios/demo/Sources/MockFlows.swift @@ -1398,6 +1398,37 @@ static let inputAssetPendingTransaction: String = """ } } """ + +static let chatMessageBasic: String = """ + { + "id": "chat", + "views": [ + { + "id": "1", + "type": "chat-message", + "value": "Hello World!" + } + ], + "navigation": { + "BEGIN": "FLOW_1", + "FLOW_1": { + "startState": "VIEW_1", + "VIEW_1": { + "state_type": "VIEW", + "ref": "1", + "transitions": { + "*": "END_Done" + } + }, + "END_Done": { + "state_type": "END", + "outcome": "DONE" + } + } + } + } + + """ public static let assetSections: [FlowLoader.FlowSection] = [ (title: "action", flows: [ @@ -1429,6 +1460,9 @@ static let inputAssetPendingTransaction: String = """ (title: "text", flows: [ (name: "basic", flow: MockFlows.textBasic), (name: "with link", flow: MockFlows.textWithLink) + ]), + (title: "chat message", flows: [ + (name: "basic", flow: MockFlows.chatMessageBasic), ]) ] diff --git a/plugins/async-node/ios/Tests/AsynNodePluginTests.swift b/plugins/async-node/ios/Tests/AsynNodePluginTests.swift index 1f7163ef9..bbf50f5ef 100644 --- a/plugins/async-node/ios/Tests/AsynNodePluginTests.swift +++ b/plugins/async-node/ios/Tests/AsynNodePluginTests.swift @@ -520,6 +520,273 @@ class AsyncNodePluginTests: XCTestCase { XCTAssertEqual(expectedMultiNode3Text, "test") XCTAssertEqual(expectedMultiNode4Text, "undefined") } + + func testChatMessageReplaceAsyncNodeWithProvidedNode() { + let handlerExpectation = XCTestExpectation(description: "first data did not change") + + let context = JSContext() + var count = 0 + + let resolve: AsyncHookHandler = { _,_ in + handlerExpectation.fulfill() + + if count == 1 { + return .singleNode(ReplacementNode.encodable( + AssetPlaceholderNode(asset: PlaceholderNode(id: "text", type: "text", value: "new node")) + )) + } + + return .singleNode(ReplacementNode.concrete(context?.evaluateScript("") ?? JSValue())) + } + + let asyncNodePluginPlugin = AsyncNodePluginPlugin() + let plugin = AsyncNodePlugin(plugins: [asyncNodePluginPlugin], resolve) + + plugin.context = context + + XCTAssertNotNil(asyncNodePluginPlugin.context) + + let player = HeadlessPlayerImpl(plugins: [ReferenceAssetsPlugin(), plugin], context: context ?? JSContext()) + + let textExpectation = XCTestExpectation(description: "newText found") + + var expectedNode1Text: String = "" + + player.hooks?.viewController.tap({ (viewController) in + viewController.hooks.view.tap { (view) in + view.hooks.onUpdate.tap { val in + count += 1 + + if count == 2 { + let newText1 = val + .objectForKeyedSubscript("values") + .objectAtIndexedSubscript(1) + .objectForKeyedSubscript("asset") + .objectForKeyedSubscript("value") + guard let textString1 = newText1?.toString() else { return XCTFail("newText was not a string") } + + expectedNode1Text = textString1 + textExpectation.fulfill() + } + } + } + }) + + player.start(flow: .chatMessageJson, completion: { _ in}) + + wait(for: [handlerExpectation, textExpectation], timeout: 5) + + XCTAssert(count == 2) + XCTAssertEqual(expectedNode1Text, "new node") + } + + func testChatMessageReplaceAsyncNodeWithMultiNode() { + let handlerExpectation = XCTestExpectation(description: "first data did not change") + + let context = JSContext() + var count = 0 + + let resolve: AsyncHookHandler = { _,_ in + handlerExpectation.fulfill() + + if count == 1 { + return .multiNode([ + ReplacementNode.encodable(AssetPlaceholderNode(asset: PlaceholderNode(id: "text-1", type: "text", value: "1st value in the multinode"))), + ReplacementNode.encodable(AssetPlaceholderNode(asset: PlaceholderNode(id: "text-2", type: "text", value: "2nd value in the multinode"))), + ]) + } + + return .singleNode(ReplacementNode.concrete(context?.evaluateScript("") ?? JSValue())) + } + + let asyncNodePluginPlugin = AsyncNodePluginPlugin() + let plugin = AsyncNodePlugin(plugins: [asyncNodePluginPlugin], resolve) + + plugin.context = context + + XCTAssertNotNil(asyncNodePluginPlugin.context) + + let player = HeadlessPlayerImpl(plugins: [ReferenceAssetsPlugin(), plugin], context: context ?? JSContext()) + + let textExpectation = XCTestExpectation(description: "newText found") + + var expectedMultiNode1Text: String = "" + var expectedMultiNode2Text: String = "" + + player.hooks?.viewController.tap({ (viewController) in + viewController.hooks.view.tap { (view) in + view.hooks.onUpdate.tap { val in + count += 1 + + if count == 2 { + let newText1 = val + .objectForKeyedSubscript("values") + .objectAtIndexedSubscript(1) + .objectForKeyedSubscript("asset") + .objectForKeyedSubscript("value") + guard let textString1 = newText1?.toString() else { return XCTFail("newText was not a string") } + expectedMultiNode1Text = textString1 + + let newText2 = val + .objectForKeyedSubscript("values") + .objectAtIndexedSubscript(2) + .objectForKeyedSubscript("asset") + .objectForKeyedSubscript("value") + guard let textString2 = newText2?.toString() else { return XCTFail("newText was not a string") } + + expectedMultiNode2Text = textString2 + textExpectation.fulfill() + } + } + } + }) + + player.start(flow: .chatMessageJson, completion: { _ in}) + + wait(for: [handlerExpectation, textExpectation], timeout: 5) + + XCTAssert(count == 2) + XCTAssertEqual(expectedMultiNode1Text, "1st value in the multinode") + XCTAssertEqual(expectedMultiNode2Text, "2nd value in the multinode") + } + + func testChatMessageReplaceAsyncNodeWithChatMessageAsset() { + let handlerExpectation = XCTestExpectation(description: "first data did not change") + + let context = JSContext() + var count = 0 + + let resolve: AsyncHookHandler = { _,_ in + handlerExpectation.fulfill() + + if count == 1 { + return .singleNode(ReplacementNode.encodable( + AssetPlaceholderNode(asset: PlaceholderNode(id: "text", type: "chat-message", value: "chat message")) + )) + } + + return .singleNode(ReplacementNode.concrete(context?.evaluateScript("") ?? JSValue())) + } + + let asyncNodePluginPlugin = AsyncNodePluginPlugin() + let plugin = AsyncNodePlugin(plugins: [asyncNodePluginPlugin], resolve) + + plugin.context = context + + XCTAssertNotNil(asyncNodePluginPlugin.context) + + let player = HeadlessPlayerImpl(plugins: [ReferenceAssetsPlugin(), plugin], context: context ?? JSContext()) + + let textExpectation = XCTestExpectation(description: "newText found") + + var expectedNode1Text: String = "" + + player.hooks?.viewController.tap({ (viewController) in + viewController.hooks.view.tap { (view) in + view.hooks.onUpdate.tap { val in + count += 1 + + if count == 2 { + let newText1 = val + .objectForKeyedSubscript("values") + .objectAtIndexedSubscript(1) + .objectForKeyedSubscript("asset") + .objectForKeyedSubscript("value") + guard let textString1 = newText1?.toString() else { return XCTFail("newText was not a string") } + + expectedNode1Text = textString1 + textExpectation.fulfill() + } + } + } + }) + + player.start(flow: .chatMessageJson, completion: { _ in}) + + wait(for: [handlerExpectation, textExpectation], timeout: 5) + + XCTAssert(count == 2) + XCTAssertEqual(expectedNode1Text, "chat message") + } + + func testChatMessageReplaceAsyncNodeWithChainedChatMessageAsset() { + let handlerExpectation = XCTestExpectation(description: "first data did not change") + + let context = JSContext() + var count = 0 + + let resolve: AsyncHookHandler = { _,_ in + handlerExpectation.fulfill() + + if count == 1 { + return .singleNode(ReplacementNode.encodable( + AssetPlaceholderNode(asset: PlaceholderNode(id: "chat", type: "chat-message", value: "chat message")) + )) + } else if count == 2 { + return .singleNode(ReplacementNode.encodable( + AssetPlaceholderNode(asset: PlaceholderNode(id: "text", type: "text", value: "chained chat message")) + )) + } + + return .singleNode(ReplacementNode.concrete(context?.evaluateScript("") ?? JSValue())) + } + + let asyncNodePluginPlugin = AsyncNodePluginPlugin() + let plugin = AsyncNodePlugin(plugins: [asyncNodePluginPlugin], resolve) + + plugin.context = context + + XCTAssertNotNil(asyncNodePluginPlugin.context) + + let player = HeadlessPlayerImpl(plugins: [ReferenceAssetsPlugin(), plugin], context: context ?? JSContext()) + + let textExpectation = XCTestExpectation(description: "newText found") + let textExpectation2 = XCTestExpectation(description: "newText found") + + var expectedNode1Text: String = "" + var expectedNode2Text: String = "" + + player.hooks?.viewController.tap({ (viewController) in + viewController.hooks.view.tap { (view) in + view.hooks.onUpdate.tap { val in + count += 1 + + if count == 2 { + let newText1 = val + .objectForKeyedSubscript("values") + .objectAtIndexedSubscript(1) + .objectForKeyedSubscript("asset") + .objectForKeyedSubscript("value") + guard let textString1 = newText1?.toString() else { return XCTFail("newText was not a string") } + + expectedNode1Text = textString1 + textExpectation.fulfill() + } + + if count == 3 { + let newText2 = val + .objectForKeyedSubscript("values") + .objectAtIndexedSubscript(2) + .objectForKeyedSubscript("asset") + .objectForKeyedSubscript("value") + guard let textString2 = newText2?.toString() else { return XCTFail("newText was not a string") } + + expectedNode2Text = textString2 + textExpectation2.fulfill() + } + } + } + }) + + player.start(flow: .chatMessageJson, completion: { _ in}) + + wait(for: [handlerExpectation, textExpectation], timeout: 5) + + XCTAssertEqual(expectedNode1Text, "chat message") + + wait(for: [textExpectation2], timeout: 5) + XCTAssertEqual(expectedNode2Text, "chained chat message") + } } extension String { @@ -577,6 +844,38 @@ extension String { """ } +extension String { + static let chatMessageJson = """ + { + "id": "generated-flow", + "views": [ + { + id: "1", + type: "chat-message", + value: "Hello World!", + }, + ], + "navigation": { + "BEGIN": "FLOW_1", + "FLOW_1": { + "startState": "VIEW_1", + "VIEW_1": { + "state_type": "VIEW", + "ref": "1", + "transitions": { + "*": "END_Done" + } + }, + "END_Done": { + "state_type": "END", + "outcome": "done" + } + } + } + } + """ +} + struct PlaceholderNode: Codable, Equatable, AssetData { public var id: String public var type: String diff --git a/plugins/reference-assets/swiftui/UITests/ChatMessageAssetUITests.swift b/plugins/reference-assets/swiftui/UITests/ChatMessageAssetUITests.swift new file mode 100644 index 000000000..fff0c140c --- /dev/null +++ b/plugins/reference-assets/swiftui/UITests/ChatMessageAssetUITests.swift @@ -0,0 +1,11 @@ + import XCTest + + class ChatMessageAssetUITests: BaseTestCase { + func testChatMessage() { + openFlow("chat message basic") + waitFor(app.otherElements["collection-async-1"]) + let value1 = app.staticTexts["1"].label + + XCTAssertEqual(value1, "Hello World!") + } + } From 3bcae32bc0b4d7aa75c01066d48701f3029a5351 Mon Sep 17 00:00:00 2001 From: Chloe Han Date: Wed, 26 Feb 2025 12:57:02 -0500 Subject: [PATCH 2/3] add callback test --- .../ios/Tests/AsynNodePluginTests.swift | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/plugins/async-node/ios/Tests/AsynNodePluginTests.swift b/plugins/async-node/ios/Tests/AsynNodePluginTests.swift index bbf50f5ef..2401181cf 100644 --- a/plugins/async-node/ios/Tests/AsynNodePluginTests.swift +++ b/plugins/async-node/ios/Tests/AsynNodePluginTests.swift @@ -787,6 +787,137 @@ class AsyncNodePluginTests: XCTestCase { wait(for: [textExpectation2], timeout: 5) XCTAssertEqual(expectedNode2Text, "chained chat message") } + + + func testChatMessageHandleMultipleUpdatesThroughCallback() { + + let handlerExpectation = XCTestExpectation(description: "first data did not change") + + guard let context = JSContext() else { + XCTFail("JSContext initialization failed") + return + } + + var count = 0 + var args: JSValue? + var callbackFunction: JSValue? + + let resolve: AsyncHookHandler = { node, callback in + handlerExpectation.fulfill() + callbackFunction = callback + + return .singleNode(.concrete(context.evaluateScript(""" + ( + {"asset": {"id": "text", "type": "text", "value":"new node from the hook 1"}} + ) + """) ?? JSValue())) + } + + let asyncNodePluginPlugin = AsyncNodePluginPlugin() + let plugin = AsyncNodePlugin(plugins: [asyncNodePluginPlugin], resolve) + + plugin.context = context + + XCTAssertNotNil(asyncNodePluginPlugin.context) + + let player = HeadlessPlayerImpl(plugins: [ReferenceAssetsPlugin(), plugin], context: context) + + let textExpectation = XCTestExpectation(description: "newText found") + let textExpectation2 = XCTestExpectation(description: "newText found") + let textExpectation3 = XCTestExpectation(description: "newText found") + + var expectedMultiNode1Text: String = "" + var expectedMultiNode2Text: String = "" + var expectedMultiNode3Text: String = "" + var expectedMultiNode4Text: String = "" + + player.hooks?.viewController.tap({ (viewController) in + viewController.hooks.view.tap { (view) in + view.hooks.onUpdate.tap { val in + count += 1 + + if count == 2 { + let newText1 = val + .objectForKeyedSubscript("values") + .objectAtIndexedSubscript(1) + .objectForKeyedSubscript("asset") + .objectForKeyedSubscript("value") + guard let textString1 = newText1?.toString() else { return XCTFail("newText was not a string") } + + expectedMultiNode1Text = textString1 + textExpectation.fulfill() + } + + if count == 3 { + let newText2 = val + .objectForKeyedSubscript("values") + .objectAtIndexedSubscript(1) + .objectForKeyedSubscript("asset") + .objectForKeyedSubscript("value") + guard let textString2 = newText2?.toString() else { return XCTFail("newText was not a string") } + + expectedMultiNode2Text = textString2 + textExpectation2.fulfill() + } + + if count == 4 { + + let newText3 = val + .objectForKeyedSubscript("values") + .objectAtIndexedSubscript(0) + .objectForKeyedSubscript("asset") + .objectForKeyedSubscript("value") + guard let textString3 = newText3?.toString() else { return XCTFail("newText was not a string") } + + let newText4 = val + .objectForKeyedSubscript("values") + .objectAtIndexedSubscript(1) + .objectForKeyedSubscript("asset") + .objectForKeyedSubscript("value") + guard let textString4 = newText4?.toString() else { return XCTFail("newText was not a string") } + + expectedMultiNode3Text = textString3 + expectedMultiNode4Text = textString4 + textExpectation3.fulfill() + } + } + } + }) + + player.start(flow: .chatMessageJson, completion: { _ in}) + + wait(for: [handlerExpectation, textExpectation], timeout: 5) + + XCTAssert(count == 2) + XCTAssertEqual(expectedMultiNode1Text, "new node from the hook 1") + + var replacementResult = AsyncNodeHandlerType.singleNode(.concrete(context.evaluateScript(""" + ( + {"asset": {"id": "text", "type": "text", "value":"new node from the hook 2"}} + ) + """) ?? JSValue())) + + args = replacementResult.handlerTypeToJSValue(context: context ?? JSContext()) + + let _ = callbackFunction?.call(withArguments: [args]) + + XCTAssert(count == 3) + XCTAssertEqual(expectedMultiNode2Text, "new node from the hook 2") + + + wait(for: [textExpectation2], timeout: 5) + + replacementResult = AsyncNodeHandlerType.emptyNode + + args = replacementResult.handlerTypeToJSValue(context: context ?? JSContext()) + + _ = callbackFunction?.call(withArguments: [args]) + + XCTAssert(count == 4) + // asset that the value at index 0 for the object + XCTAssertEqual(expectedMultiNode3Text, "Hello World!") + XCTAssertEqual(expectedMultiNode4Text, "undefined") + } } extension String { From 60e5c52a02d2dec4bd14e70e8e589191d43faa96 Mon Sep 17 00:00:00 2001 From: Chloe Han Date: Thu, 27 Feb 2025 18:24:59 -0500 Subject: [PATCH 3/3] update content --- ios/demo/Sources/MockFlows.swift | 6 +- .../ios/Tests/AsynNodePluginTests.swift | 114 ++++++------------ .../UITests/ChatMessageAssetUITests.swift | 4 +- 3 files changed, 41 insertions(+), 83 deletions(-) diff --git a/ios/demo/Sources/MockFlows.swift b/ios/demo/Sources/MockFlows.swift index 86ec08eb4..20325d4da 100644 --- a/ios/demo/Sources/MockFlows.swift +++ b/ios/demo/Sources/MockFlows.swift @@ -1406,7 +1406,11 @@ static let chatMessageBasic: String = """ { "id": "1", "type": "chat-message", - "value": "Hello World!" + "value": { + id: "text", + type: "text", + value: "chat message", + }, } ], "navigation": { diff --git a/plugins/async-node/ios/Tests/AsynNodePluginTests.swift b/plugins/async-node/ios/Tests/AsynNodePluginTests.swift index 2401181cf..1393e9cf9 100644 --- a/plugins/async-node/ios/Tests/AsynNodePluginTests.swift +++ b/plugins/async-node/ios/Tests/AsynNodePluginTests.swift @@ -579,76 +579,6 @@ class AsyncNodePluginTests: XCTestCase { XCTAssert(count == 2) XCTAssertEqual(expectedNode1Text, "new node") } - - func testChatMessageReplaceAsyncNodeWithMultiNode() { - let handlerExpectation = XCTestExpectation(description: "first data did not change") - - let context = JSContext() - var count = 0 - - let resolve: AsyncHookHandler = { _,_ in - handlerExpectation.fulfill() - - if count == 1 { - return .multiNode([ - ReplacementNode.encodable(AssetPlaceholderNode(asset: PlaceholderNode(id: "text-1", type: "text", value: "1st value in the multinode"))), - ReplacementNode.encodable(AssetPlaceholderNode(asset: PlaceholderNode(id: "text-2", type: "text", value: "2nd value in the multinode"))), - ]) - } - - return .singleNode(ReplacementNode.concrete(context?.evaluateScript("") ?? JSValue())) - } - - let asyncNodePluginPlugin = AsyncNodePluginPlugin() - let plugin = AsyncNodePlugin(plugins: [asyncNodePluginPlugin], resolve) - - plugin.context = context - - XCTAssertNotNil(asyncNodePluginPlugin.context) - - let player = HeadlessPlayerImpl(plugins: [ReferenceAssetsPlugin(), plugin], context: context ?? JSContext()) - - let textExpectation = XCTestExpectation(description: "newText found") - - var expectedMultiNode1Text: String = "" - var expectedMultiNode2Text: String = "" - - player.hooks?.viewController.tap({ (viewController) in - viewController.hooks.view.tap { (view) in - view.hooks.onUpdate.tap { val in - count += 1 - - if count == 2 { - let newText1 = val - .objectForKeyedSubscript("values") - .objectAtIndexedSubscript(1) - .objectForKeyedSubscript("asset") - .objectForKeyedSubscript("value") - guard let textString1 = newText1?.toString() else { return XCTFail("newText was not a string") } - expectedMultiNode1Text = textString1 - - let newText2 = val - .objectForKeyedSubscript("values") - .objectAtIndexedSubscript(2) - .objectForKeyedSubscript("asset") - .objectForKeyedSubscript("value") - guard let textString2 = newText2?.toString() else { return XCTFail("newText was not a string") } - - expectedMultiNode2Text = textString2 - textExpectation.fulfill() - } - } - } - }) - - player.start(flow: .chatMessageJson, completion: { _ in}) - - wait(for: [handlerExpectation, textExpectation], timeout: 5) - - XCTAssert(count == 2) - XCTAssertEqual(expectedMultiNode1Text, "1st value in the multinode") - XCTAssertEqual(expectedMultiNode2Text, "2nd value in the multinode") - } func testChatMessageReplaceAsyncNodeWithChatMessageAsset() { let handlerExpectation = XCTestExpectation(description: "first data did not change") @@ -660,9 +590,24 @@ class AsyncNodePluginTests: XCTestCase { handlerExpectation.fulfill() if count == 1 { - return .singleNode(ReplacementNode.encodable( - AssetPlaceholderNode(asset: PlaceholderNode(id: "text", type: "chat-message", value: "chat message")) - )) + return .singleNode(.concrete(context?.evaluateScript(""" + ({"asset": {"id": "2", "type": "chat-message", "value": { + "id": "text2", + "type": "text", + "value": "chat message2", + }}}) + """) ?? JSValue())) + +// +// return .singleNode(.concrete(context.evaluateScript(""" +// ( +// {"asset": {"id": "1", "type": "chat-message", "value": { +// "id": "text", +// "type": "text", +// "value": "chat message2", +// }}} +// ) +// """) ?? JSValue())) } return .singleNode(ReplacementNode.concrete(context?.evaluateScript("") ?? JSValue())) @@ -706,7 +651,7 @@ class AsyncNodePluginTests: XCTestCase { wait(for: [handlerExpectation, textExpectation], timeout: 5) XCTAssert(count == 2) - XCTAssertEqual(expectedNode1Text, "chat message") + XCTAssertEqual(expectedNode1Text, "chat message2") } func testChatMessageReplaceAsyncNodeWithChainedChatMessageAsset() { @@ -719,9 +664,14 @@ class AsyncNodePluginTests: XCTestCase { handlerExpectation.fulfill() if count == 1 { - return .singleNode(ReplacementNode.encodable( - AssetPlaceholderNode(asset: PlaceholderNode(id: "chat", type: "chat-message", value: "chat message")) - )) + return .singleNode(.concrete(context?.evaluateScript(""" + ({"asset": {"id": "2", "type": "chat-message", "value": { + "id": "text2", + "type": "text", + "value": "chat message2", + }}}) + """) ?? JSValue())) + } else if count == 2 { return .singleNode(ReplacementNode.encodable( AssetPlaceholderNode(asset: PlaceholderNode(id: "text", type: "text", value: "chained chat message")) @@ -782,7 +732,7 @@ class AsyncNodePluginTests: XCTestCase { wait(for: [handlerExpectation, textExpectation], timeout: 5) - XCTAssertEqual(expectedNode1Text, "chat message") + XCTAssertEqual(expectedNode1Text, "chat message2") wait(for: [textExpectation2], timeout: 5) XCTAssertEqual(expectedNode2Text, "chained chat message") @@ -915,7 +865,7 @@ class AsyncNodePluginTests: XCTestCase { XCTAssert(count == 4) // asset that the value at index 0 for the object - XCTAssertEqual(expectedMultiNode3Text, "Hello World!") + XCTAssertEqual(expectedMultiNode3Text, "chat message") XCTAssertEqual(expectedMultiNode4Text, "undefined") } } @@ -983,7 +933,11 @@ extension String { { id: "1", type: "chat-message", - value: "Hello World!", + value: { + id: "text", + type: "text", + value: "chat message", + }, }, ], "navigation": { diff --git a/plugins/reference-assets/swiftui/UITests/ChatMessageAssetUITests.swift b/plugins/reference-assets/swiftui/UITests/ChatMessageAssetUITests.swift index fff0c140c..43488538f 100644 --- a/plugins/reference-assets/swiftui/UITests/ChatMessageAssetUITests.swift +++ b/plugins/reference-assets/swiftui/UITests/ChatMessageAssetUITests.swift @@ -4,8 +4,8 @@ func testChatMessage() { openFlow("chat message basic") waitFor(app.otherElements["collection-async-1"]) - let value1 = app.staticTexts["1"].label + let value1 = app.staticTexts["text"].label - XCTAssertEqual(value1, "Hello World!") + XCTAssertEqual(value1, "chat message") } }