Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XCUITestDriver returns StaleElementReferenceError: Element does not exist in cache #18839

Open
3 tasks done
ilendemli opened this issue Jul 4, 2023 · 25 comments
Open
3 tasks done
Labels
Bug a problem that needs fixing Mobile Safari related to mobile Safari driver

Comments

@ilendemli
Copy link

ilendemli commented Jul 4, 2023

Do I have the most recent component updates?

  • I use the most recent available driver/plugin and server versions

Is the component officially supported by the Appium team?

  • I have verified the component repository is present under the Appium organization in GitHub

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

For some reason, after quickly switching back and forth between the NATIVE_APP and WEBVIEW context (doing getContexts before switching) in our test cases, locating elements fail because of StaleElementReferenceError. getPageSource fails with Method threw 'org.openqa.selenium.WebDriverException' exception.

[debug] [ios-device] Received message from Web Inspector:
[debug] [ios-device] {
[debug] [ios-device]   "__argument": {
[debug] [ios-device]     "WIRApplicationIdentifierKey": "PID:33769",
[debug] [ios-device]     "WIRMessageDataTypeKey": "WIRMessageDataTypeFull",
[debug] [ios-device]     "WIRDestinationKey": "d5038e8c-c470-4150-989e-ccb31941c4fd",
[debug] [ios-device]     "WIRMessageDataKey": "{\"method\":\"Target.dispatchMessageFromTarget\",\"params\":{\"targetId\":\"page-27\",\"message\":\"{\\\"result\\\":{\\\"result\\\":{\\\"type\\\":\\\"object\\\",\\\"objectId\\\":\\\"{\\\\\\\"injectedScriptId\\\\\\\":1,\\\\\\\"id\\\\\\\":2}\\\",\\\"className\\\":\\\"k\\\",\\\"description\\\":\\\"StaleElementReferenceError: Element does not exist in cache\\\"},\\\"wasThrown\\\":true},\\\"id\\\":298}\"}}"
[debug] [ios-device]   },
[debug] [ios-device]   "__selector": "_rpc_applicationSentData:"
[debug] [ios-device] }

The webpage is shown in a hybrid app. It is inspectable through Safari.

Expected Behavior

Getting Element after switching context to WEBVIEW should not fail.

Minimal Reproducible Example

I have no example to provide at the moment but will try to create one to reproduce the issue.

Environment

  • Operating system: MacOS & iOS
  • Appium server version (output of appium --version): 2023.5.2
  • Appium driver(s) and their version(s): WDA 5.5.1
  • Appium plugin(s) and their version(s):
  • Node.js version (output of node --version): 20.2.0
  • npm version (output of npm --version): 9.6.6
  • Last component(s) version which did not exhibit the problem:
  • Platform and version under test: iOS 16.5
  • Real device or emulator/simulator: Real device

Link to Appium Logs

No response

Futher Information

No response

@ilendemli ilendemli added Bug a problem that needs fixing Needs Triage bugs which are not yet confirmed labels Jul 4, 2023
@mykola-mokhnach
Copy link
Collaborator

Maybe the internal elements cache is refreshed every time the web view context is switched. Try to locate elements instead of using cached ones as a workaround

@mykola-mokhnach mykola-mokhnach added Mobile Safari related to mobile Safari driver Needs Info typically non-actionable; needs author to respond and removed Bug a problem that needs fixing Needs Triage bugs which are not yet confirmed labels Jul 4, 2023
@mykola-mokhnach
Copy link
Collaborator

Also, it is not possible to help more without the full server log

@ilendemli
Copy link
Author

We are already using locators as far as i know. I will try to provide a log but have to redact a lot.

@mykola-mokhnach
Copy link
Collaborator

mykola-mokhnach commented Jul 4, 2023

We are already using locators as far as i know.

sorry, I don't get that. Locators are required anyway. What I am talking about is instead of using something like:

element = driver.find_element(locator)
text = element.text
# do some context switching
element.click()

change it to

text = driver.find_element(locator).text
# do some context switching
driver.find_element(locator).click()

@mykola-mokhnach
Copy link
Collaborator

Closed because of no response

@ilendemli
Copy link
Author

ilendemli commented Jul 10, 2023

@mykola-mokhnach Hey, sorry I haven't had any time looking into this. In the meantime I downgraded nodejs to 16.20.1 and npm to 8.19.4 because I had some issues connecting to my phone. We still have the problem so please reopen this. Here is the server log with our informations redacted: https://gist.github.com/ilendemli/30afdc6719755648466c9036d5dcb0cb. If you need any assistance regarding this please contact me and I can share more information privately.

We are basically doing the same test twice in one run, it hangs during the second run, where there is a new WebView context.

EDIT: Also this gets printed when logging to a file: (node:16444) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 _rpc_applicationConnected: listeners added to [RpcMessageHandler]. Use emitter.setMaxListeners() to increase limit

Safari can inspect page with no issues after appium server is closed.

@mykola-mokhnach
Copy link
Collaborator

The log above shows that Appium 1 is used, which we don't support. Please upgrade to Appium 2 first. Also, have you applied the above workaround in your client code?

@ilendemli
Copy link
Author

I will try to get this running with Appium 2 again soon and provide you a log. Afaik I had the same issue with it back when I managed to run this. We also tried the workaround, but in our case we first switch the context when try to find elements using the locator, so it's basically:

# do some context switching
driver.find_element(locator).click()

@ilendemli
Copy link
Author

@mykola-mokhnach here is the server log from appium 2 running the same test: https://gist.github.com/ilendemli/c89c0ba717e0fe5284c0daa9c6d69702

@jlipps
Copy link
Member

jlipps commented Jul 10, 2023

The element you're trying to get the text of is an alert? Alerts are typically native elements (not webview ones), so I would work with the alert in the native context.

@ilendemli
Copy link
Author

ilendemli commented Jul 10, 2023

@jlipps no, line 6433 i get current contexts, 6440 i set the context, 6481 i try to find the element using css selector in webcontext, fails, but should not, ignore the infobubble alert stuff for the moment

follow from line 1867, it's literally the same test flow twice in code, second time does not go through

EDIT: when i log the server to a file, i get the this error printed (node:16444) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 _rpc_applicationConnected: listeners added to [RpcMessageHandler]. Use emitter.setMaxListeners() to increase limit and the connection to the device drops

EDIT: this makes no sense

[HTTP] --> POST /wd/hub/session/57002fb2-4526-4012-b21b-c631b5688ea2/elements
[HTTP] {"using":"css selector","value":"#travelStationFromInput"}
[debug] [XCUITestDriver@0aa1 (57002fb2)] Calling AppiumDriver.findElements() with args: ["css selector","#travelStationFromInput","57002fb2-4526-4012-b21b-c631b5688ea2"]
[debug] [XCUITestDriver@0aa1 (57002fb2)] Executing command 'findElements'
[debug] [XCUITestDriver@0aa1 (57002fb2)] Valid locator strategies for this request: xpath, id, name, class name, -ios predicate string, -ios class chain, accessibility id, css selector
[debug] [XCUITestDriver@0aa1 (57002fb2)] Waiting up to 0 ms for condition
[debug] [RemoteDebugger] Executing atom 'find_elements' with 'args=["css selector","#travelStationFromInput",null]; frames=:wdc:1689009811709'
[debug] [RemoteDebugger] Wrapping script for frame ':wdc:1689009811709'
[debug] [RemoteDebugger] Sending javascript command: '(function (window) { var document = window.docu...'
[debug] [RemoteDebugger] Sending '_rpc_forwardSocketData:' message to app 'PID:19814', page '3', target 'page-29' (id: 634): 'Runtime.evaluate'
[debug] [RemoteDebugger] Sending to Web Inspector took 92ms
[debug] [XCUITestDriver@0aa1 (57002fb2)] Matched '/alert/text' to command name 'getAlertText'
[debug] [XCUITestDriver@0aa1 (57002fb2)] Proxying [GET /alert/text] to [GET http://127.0.0.1:8100/session/D4D39557-3ABC-4DCE-9656-687C3C9741BC/alert/text] with no body
[debug] [XCUITestDriver@0aa1 (57002fb2)] Error received while executing atom: Remote debugger error with code 'undefined': StaleElementReferenceError: Element does not exist in cache
[debug] [XCUITestDriver@0aa1 (57002fb2)] Encountered internal error running command: Error: Remote debugger error with code 'undefined': StaleElementReferenceError: Element does not exist in cache
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at RpcMessageHandler.<anonymous> (/Users/user/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-remote-debugger/lib/rpc/rpc-client.js:265:27)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at Object.onceWrapper (node:events:628:26)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at RpcMessageHandler.emit (node:events:513:28)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at RpcMessageHandler.dispatchDataMessage (/Users/user/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-remote-debugger/lib/rpc/rpc-message-handler.js:95:14)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at RpcMessageHandler.handleDataMessage (/Users/user/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-remote-debugger/lib/rpc/rpc-message-handler.js:210:16)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at RpcMessageHandler.handleMessage (/Users/user/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-remote-debugger/lib/rpc/rpc-message-handler.js:68:20)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at RpcClientRealDevice.onData [as receive] (/Users/user/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-remote-debugger/lib/rpc/rpc-client-real-device.js:52:31)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at PlistServiceDecoder.<anonymous> (/Users/user/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-ios-device/lib/webinspector/index.js:220:7)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at PlistServiceDecoder.emit (node:events:513:28)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at addChunk (node:internal/streams/readable:315:12)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at readableAddChunk (node:internal/streams/readable:289:9)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at PlistServiceDecoder.push (node:internal/streams/readable:228:10)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at PlistServiceDecoder._decode (/Users/user/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-ios-device/lib/plist-service/transformer/plist-service-decoder.js:27:10)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at PlistServiceDecoder._transform (/Users/user/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-ios-device/lib/plist-service/transformer/plist-service-decoder.js:14:10)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at PlistServiceDecoder.Transform._write (node:internal/streams/transform:205:23)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at writeOrBuffer (node:internal/streams/writable:391:12)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at _write (node:internal/streams/writable:332:10)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at PlistServiceDecoder.Writable.write (node:internal/streams/writable:336:10)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at LengthBasedSplitter.ondata (node:internal/streams/readable:754:22)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at LengthBasedSplitter.emit (node:events:513:28)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at addChunk (node:internal/streams/readable:315:12)
[debug] [XCUITestDriver@0aa1 (57002fb2)]     at readableAddChunk (node:internal/streams/readable:289:9)
[HTTP] <-- POST /wd/hub/session/57002fb2-4526-4012-b21b-c631b5688ea2/elements 500 2106 ms - 778
[HTTP]
[XCUITestDriver@0aa1 (57002fb2)] Got response with status 404: {"value":{"error":"no such alert","message":"An attempt was made to operate on a modal dialog when one was not open","traceback":""},"sessionId":"D4D39557-3ABC-4DCE-9656-687C3C9741BC"}
[debug] [W3C] Matched W3C error code 'no such alert' to NoSuchAlertError

@mykola-mokhnach mykola-mokhnach added Needs Triage bugs which are not yet confirmed and removed Needs Info typically non-actionable; needs author to respond labels Jul 10, 2023
@jlipps
Copy link
Member

jlipps commented Jul 10, 2023

OK, the error appears to be happening when Appium is checking whether an alert is obscuring the webview. @mykola-mokhnach can you tell whether this error is coming from WDA or the driver?

@mykola-mokhnach
Copy link
Collaborator

This error is coming from the remote debugger or the atom itself. I cannot say for sure.

@jlipps
Copy link
Member

jlipps commented Jul 11, 2023

@mykola-mokhnach are you sure?

[debug] [XCUITestDriver@0aa1 (57002fb2)] Proxying [GET /alert/text] to [GET http://127.0.0.1:8100/session/D4D39557-3ABC-4DCE-9656-687C3C9741BC/alert/text] with no body

This looks like it's being proxied to WDA

@mykola-mokhnach
Copy link
Collaborator

mykola-mokhnach commented Jul 11, 2023

Yes, I am 100% sure.

[debug] [XCUITestDriver@0aa1 (57002fb2)] Encountered internal error running command: Error: Remote debugger error with code 'undefined': StaleElementReferenceError: Element does not exist in cache

This error might only come from the remote debugger. Also the stacktrace is pretty obvious

@ilendemli
Copy link
Author

I would love to help but I am not sure how to setup the IDE to run and debug appium and its node_modules. My breakpoint that I set in the module do not trigger.

@scottpage1317
Copy link

Is the element you're trying to locate deeply nested? The only time I see the StaleElementReferenceError on iOS is because of this issue

@ilendemli
Copy link
Author

ilendemli commented Jul 13, 2023

@scottpage1317 Not sure that is the reason, as it works for the first run, but does not for the second. To get an overview: One Test case, where the same steps are run a second time. Presses a button natively to open a webview, navigates through a form setting the fields, submits, does a purchase, all while switching between native and web context for each input, then dismisses the WebView. And then repeats the same steps. Goes trough up to until this issue happens.

Edit: Anyway i will try setting those attributes described there and will report back.
Edit 2: No change with "settings[customSnapshotTimeout]": 0, "settings[snapshotMaxDepth]": 100

@ilendemli
Copy link
Author

ilendemli commented Jul 13, 2023

I can reproduce the alert/text issue reliable, but I am not sure if that is related to this StaleElementReferenceError:
image

it basically happens when you close the webview without switching to native context beforehand
Example project: Archive.zip
Log: https://gist.github.com/ilendemli/d66b866407dac72ee269faf5e84f16de

Steps to reproduce: Run app with appium inspector, open webview, switch context to webview, close webview, see server log

@ilendemli
Copy link
Author

ilendemli commented Jul 14, 2023

I managed to get StaleElementReferenceError with the example project here.
Archive.zip

Create a test case where you

  1. press the button to open the webview
  2. switch context to webview
  3. get frame element
  4. switch to frame element
  5. get html elements text
  6. switch back to native context
  7. close webview

repeat steps 1-7 in a loop

AppiumLocator webViewButtonLocator = new AppiumLocator(AppiumLocatorStrategy.XPATH, "//XCUIElementTypeStaticText[@name=\"OPEN WEBVIEW\"]");

ui.withLocator(webViewButtonLocator)
        .whenClickableAfter(MobileConfig.getTimeoutConfig().tiny())
        .clickIt();

ui.pause(MobileConfig.getTimeoutConfig().shorter());

String contextName = ui.getContextHandles().stream().filter(c -> c.startsWith("WEBVIEW")).findFirst().get();
ui.context(contextName);

AppiumLocator frameLocator = new AppiumLocator(AppiumLocatorStrategy.CSS, "iframe");

ui.withLocator(frameLocator)
        .switchToFrame(MobileConfig.getTimeoutConfig().tiny());

AppiumLocator identifierLocator = new AppiumLocator(AppiumLocatorStrategy.CSS, "#identifier");

ui.withLocator(identifierLocator)
        .whenVisibleAfter(MobileConfig.getTimeoutConfig().tiny())
        .getText();

ui.context("NATIVE_APP");

AppiumLocator closeButtonLocator = new AppiumLocator(AppiumLocatorStrategy.XPATH, "//XCUIElementTypeButton[@name=\"Close\"]");

ui.withLocator(closeButtonLocator)
        .whenClickableAfter(MobileConfig.getTimeoutConfig().tiny())
        .clickIt();

@jlipps
Copy link
Member

jlipps commented Jul 19, 2023

thanks @ilendemli a repro is useful. the investigation/solution might take some time as there is a lot of updating work that needs to be done on the remote debugger code and the selenium atoms.

@mochi08
Copy link

mochi08 commented Jul 28, 2023

Can you try setting your snapshotMaxDepth to 62 and see if it works? For our app we were using 100 before and it was working fine, but recently it's giving us the "stale element reference" error. What I discovered is that setting the snapshotMaxDepth value to a number larger than 62 will result in this error.

@mykola-mokhnach mykola-mokhnach added Bug a problem that needs fixing and removed Needs Triage bugs which are not yet confirmed labels Aug 22, 2023
@ilendemli
Copy link
Author

ilendemli commented Aug 28, 2023

Sorry for the late response, we were in the process to move everything to Appium 2. We now have a Selenium Grid 4 running with Appium 2 and we still have the issue. snapshotMaxDepth does not help. I think the main issue is the WebView process being killed while still being in the WebView Context. Appium Inspector hangs in there as well. In our case it also fails to switch to the new webview process' context. Feel free to contact me if someone wants to have a private talk where I demonstrate the issue.

@rolandmoldovan
Copy link

rolandmoldovan commented Nov 3, 2023

Can you try setting your snapshotMaxDepth to 62 and see if it works? For our app we were using 100 before and it was working fine, but recently it's giving us the "stale element reference" error. What I discovered is that setting the snapshotMaxDepth value to a number larger than 62 will result in this error.

Have you discovered a solution to the problem you've described? I've been encountering the same issue for a while and haven't been able to find a resolution or workaround.

@tamaniniandre
Copy link

Same issue here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug a problem that needs fixing Mobile Safari related to mobile Safari driver
Projects
None yet
Development

No branches or pull requests

7 participants