Appium-xcuitest-driver TypeError: Cannot read property sendCommand of undefined

I keep getting this error when running a test using XCUITest for iOS 10.2. The same test works for Android, so I would think it would work for iOS, with the correct XCUITest locator

Versions:
[email protected]
[email protected]

Logs:

dbug JSONWP Proxy Proxying [GET /status] to [GET http://localhost:8100/status] with no body
dbug JSONWP Proxy Got response with status 200: "{\n  \"value\" : {\n    \"state\" : \"success\",\n    \"os\" : {\n      \"name\" : \"iOS\",\n      \"version\" : \"10.2\"\n    },\n    \"ios\" : {\n      \"simulatorVersion\" : \"10.2\",\n      \"ip\" : \"192.168.0.102\"\n    },\n    \"build\" : {\n      \"time\" : \"Apr 11 2017 07:10:42\"\n    }\n  },\n  \"sessionId\" : \"FDF14050-6153-4C98-A765-6571B5C7DA4C\",\n  \"status\" : 0\n}"
dbug XCUITest WebDriverAgent running on ip '192.168.0.102'
dbug XCUITest WebDriverAgent successfully started after 22900ms
dbug BaseDriver Event 'wdaSessionAttempted' logged at 1491919854688 (07:10:54 GMT-0700 (PDT))
dbug XCUITest Sending createSession command to WDA
dbug JSONWP Proxy Proxying [POST /session] to [POST http://localhost:8100/session] with body: {"desiredCapabilities":{"bundleId":"com.yourdomain.nativescript","arguments":[],"environment":{},"shouldWaitForQuiescence":true,"shouldUseTestManagerForVisibilityDetection":false,"maxTypingFrequency":60,"shouldUseSingletonTestManager":true}}
dbug JSONWP Proxy Got response with status 200: {"value":{"sessionId":"E1CF47AB-1259-4067-86D1-C878ED1C0844","capabilities":{"device":"iphone","browserName":"nativescript","sdkVersion":"10.2","CFBundleIdentifier":"com.yourdomain.nativescript"}},"sessionId":"E1CF47AB-1259-4067-86D1-C878ED1C0844","status":0}
dbug BaseDriver Event 'wdaSessionStarted' logged at 1491919857850 (07:10:57 GMT-0700 (PDT))
dbug XCUITest Found WDA derived data folder: '/Users/me/Library/Developer/Xcode/DerivedData/WebDriverAgent-brdadhpuduowllgivnnvuygpwhzy'
info XCUITest Setting '555' permissions to '/Users/me/Library/Developer/Xcode/DerivedData/WebDriverAgent-brdadhpuduowllgivnnvuygpwhzy/Logs/Test/Attachments' folder
dbug XCUITest Found WDA derived data folder: '/Users/me/Library/Developer/Xcode/DerivedData/WebDriverAgent-chekivkjpgjwdlhdfvhwjrunhjmq'
info XCUITest Setting '555' permissions to '/Users/me/Library/Developer/Xcode/DerivedData/WebDriverAgent-chekivkjpgjwdlhdfvhwjrunhjmq/Logs/Test/Attachments' folder
dbug BaseDriver Event 'wdaPermsAdjusted' logged at 1491919857857 (07:10:57 GMT-0700 (PDT))
dbug BaseDriver Event 'wdaStarted' logged at 1491919857857 (07:10:57 GMT-0700 (PDT))
dbug XCUITest Setting initial orientation to 'PORTRAIT'
dbug JSONWP Proxy Proxying [POST /orientation] to [POST http://localhost:8100/session/E1CF47AB-1259-4067-86D1-C878ED1C0844/orientation] with body: {"orientation":"PORTRAIT"}
dbug JSONWP Proxy Got response with status 200: {"value":{},"sessionId":"E1CF47AB-1259-4067-86D1-C878ED1C0844","status":0}
dbug BaseDriver Event 'orientationSet' logged at 1491919857991 (07:10:57 GMT-0700 (PDT))
dbug BaseDriver Valid locator strategies for this request: xpath, id, name, class name, -ios predicate string, -ios class chain, accessibility id
dbug BaseDriver Waiting up to 0 ms for condition
dbug JSONWP Proxy Proxying [POST /elements] to [POST http://localhost:8100/session/E1CF47AB-1259-4067-86D1-C878ED1C0844/elements] with body: {"using":"class name","value":"XCUIElementTypeStaticText"}
dbug JSONWP Proxy Got response with status 200: {"value":[{"ELEMENT":"59831D79-134D-499A-A85B-E2935FD4E09A","type":"XCUIElementTypeStaticText","label":"Home"},{"ELEMENT":"431C02DE-6EE7-46F0-981E-D05228B23B82","type":"XCUIElementTypeStaticText","label":"I love technology!"},{"ELEMENT":"8412BB66-A26F-440C-AB89-6ED5A8C88B91","type":"XCUIElementTypeStaticText","label":"Your deployment of Angular Seed Advanced worked perfectly."},{"ELEMENT":"4E8576BB-5559-4B29-8AA7-A49AAB8E5663","type":"XCUIElementTypeStaticText","label":"For your reward, here is a list of awesome computer scientists:"},{"ELEMENT":"E520F239-7211-429D-8441-36AE240EEDA5","type":"XCUIElementTypeStaticText","label":"Edsger Dijkstra"},{"ELEMENT":"7C7EEC79-6C1D-42EA-B2EC-5AED03079526","type":"XCUIElementTypeStaticText","label":"Donald Knuth"},{"ELEMENT":"CB440B5C-BEBF-45AA-BCA2-35804610D7B4","type":"XCUIElementTypeStaticText","label":"Alan Turing"},{"ELEMENT":"379FFF52-3656-44C5-9665-B31BFD9F8FB1","type":"XCUIElementTypeStaticText","label":"Grace Hopper"},{"ELEMENT":"6E32EA95-FFFA-4720-89AA-38619A...
(node:31786) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): TypeError: Cannot read property 'sendCommand' of undefined
(node:31786) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Fdbug JSONWP Proxy Proxying [DELETE /session/6e45ba43-ca5f-4cfa-ae03-a308c380751c] to [DELETE http://localhost:8100/session/E1CF47AB-1259-4067-86D1-C878ED1C0844] with no body
dbug JSONWP Proxy Got response with status 200: "{\n  \"value\" : {\n\n  },\n  \"sessionId\" : \"2C9D97FE-F3F7-4CDB-8C48-F789F258DCD1\",\n  \"status\" : 0\n}"
info XCUITest Shutting down sub-processes
info XCUITest Shutting down xcodebuild process (pid 31881)
info XCUITest xcodebuild exited with code 'null' and signal 'SIGTERM'
dbug XCUITest Found WDA derived data folder: '/Users/me/Library/Developer/Xcode/DerivedData/WebDriverAgent-brdadhpuduowllgivnnvuygpwhzy'
info XCUITest Setting '755' permissions to '/Users/m12563/Library/Developer/Xcode/DerivedData/WebDriverAgent-brdadhpuduowllgivnnvuygpwhzy/Logs/Test/Attachments' folder
dbug XCUITest Found WDA derived data folder: '/Users/me/Library/Developer/Xcode/DerivedData/WebDriverAgent-chekivkjpgjwdlhdfvhwjrunhjmq'
info XCUITest Setting '755' permissions to '/Users/me/Library/Developer/Xcode/DerivedData/WebDriverAgent-chekivkjpgjwdlhdfvhwjrunhjmq/Logs/Test/Attachments' folder
dbug XCUITest Not clearing log files. Use `clearSystemFiles` capability to turn on.
dbug iOSLog Stopping iOS log capture

Test:

  it('should have an element', (done) => {
    locateElement(driver, 'class name', 'XCUIElementTypeStaticText').then((element) => {
      driver.deviceDriver.elementDisplayed(element.ELEMENT).then((isDisplayed) => {
        expect(isDisplayed).toBe(true);
        done();
      });
    });
  });
export async function locateElement(driver: Driver, strategy: string, element: string) {
  const elements = await driver.deviceDriver.findElements(strategy, element);
  return elements[0];
}

It looks like it is finding an element, but it just fails. I am having trouble debugging, because I cannot find where ‘sendCommand’ is called. Can someone help?

Try updating Node library
and updating xcode build tools

I have updated to the most recent stable version of node, 6.10.2, and Command Line Tools are on 8.3. Do you have any other ideas? Also, do you know where sendCommand is being called? I see where it is being called in the IosDriver but not in XCUITest, so I can’t debug the issue. I don’t know where the error is occurring. Let me know, thanks!

{“ELEMENT”:“59831D79-134D-499A-A85B-E2935FD4E09A”,“type”:“XCUIElementTypeStaticText”,“label”:“Home”}

Could you take a look at this element in Appium Desktop? Is the property ‘isDisplayed’ true?

I looked up the UnhandledPromiseRejectionWarning and found this:

That article suggests that your .then method needs a .catch to handle the exception you are seeing. I’m suspecting that the element found doesn’t have an ‘isDisplayed’ property.

I’m hardly a javascript expert but that’s what it looks like to me.

isDisplayed is what I named the result of the Promise returned by .elementDisplayed(). It could have been called anything, like ‘result’ or something. The test works fine with Android, but not with iOS. I just started building this framework, so this is a rough implementation of what I’m trying to do. I can handle Promise rejections later. Here’s the implementation of that method in IosDriver:

commands.elementDisplayed = async function (el) {
  el = unwrapEl(el);
  if (this.isWebContext()) {
    let atomsElement = this.useAtomsElement(el);
    return await this.executeAtom('is_displayed', [atomsElement]);
  } else {
    let command = `au.getElement('${el}').isDisplayed()`;
    return await this.uiAutoClient.sendCommand(command);
  }
};

Info on async/await :slight_smile:

I agree that the problem is somewhere in here, I just cannot find the implementation in appium-xcuitest-driver, so I don’t know what is being returned as undefined. Any other ideas?

As I said, I’m hardly a javascript expert. If it were me I would examine the element in question with debug statements and Appium Desktop. I think there is something wrong with the element found and that the later calls against that element are throwing the exception. Specifically it looks like ‘is_displayed’ is not present. I think that the fact that it works on Android has nothing to do with the problem at hand.

Hm, it should not be calling the code in the block with ‘is_displayed’, because this.isWebContext() is false. It seems like it is calling the code in the second block, but it’s not hitting that block when I throw a breakpoint in there. It is definitely finding the element. Either this.uiAutoClient or command are undefined. Does anyone know where I can find more information about XCUITest and what methods it implements from IosDriver? I assumed all of the same methods would be accessible and similarly implemented, but that doesn’t seem to be the case. Android Driver’s implementation of elementDisplayed is totally different, so that is why it is working, so you are right about that.

I was able to get this to work by using .getAttribute(‘visible’, element.ELEMENT)… instead of elementDisplayed(). I don’t know yet why it works ¯_(ツ)_/¯. Will update if I find out more information