microsoft / WinAppDriver

Windows Application Driver
MIT License
3.66k stars 1.4k forks source link

Succesful element click returns malformed response #654

Open hankbot opened 5 years ago

hankbot commented 5 years ago

Using WebdriverIO and Appium I'm able to click on an element successfully, e.g. a button in Calculator, but the response does not contain the expected NULL value. This results in WebdriverIO interpreting the click as failed.

According to the WC3 spec the click should "Return success with data null. " WinAppDriver is returning success, but is failing to return an explicit value of NULL.

https://w3c.github.io/webdriver/#element-click

An issue has been filed for WebdriverIO but I believe the issue is due to WinAppDriver.

https://github.com/webdriverio/webdriverio/issues/2775#issuecomment-428650139

This WebdriverIO sample recreates the error

describe('webdriver.io click one', () => {
  it('should click the one button', () => {
    const btn = driver.findElement('name', 'One');
    driver.elementClick(btn['ELEMENT']);
  })
});

This is the Appium output that illustrates the missing NULL value. The currently returned response is: [debug] [WD Proxy] Got response with status 200: {"sessionId":"60D8F800-BEE0-42FF-B8DF-EA120FEAF7CD","status":0}

More complete output below

[WinAppDriver] [STDOUT] ==========================================
[WinAppDriver] [STDOUT] POST /wd/hub/session/60D8F800-BEE0-42FF-B8DF-EA120FEAF7CD/element/42.2755824.4.56/click HTTP/1.1
[WinAppDriver] [STDOUT] Accept: application/json, */*
[WinAppDriver] [STDOUT] Connection: close
[WinAppDriver] [STDOUT] Content-Length: 2
[WinAppDriver] [STDOUT] Content-Type: application/json; charset=utf-8
[WinAppDriver] [STDOUT] Host: 127.0.0.1:4724
[WinAppDriver] [STDOUT] User-Agent: appium
[WinAppDriver] [STDOUT]
[WinAppDriver] [STDOUT] {}
[WinAppDriver] [STDOUT] HTTP/1.1 200 OK
[WinAppDriver] [STDOUT] Content-Length: 63
[WinAppDriver] [STDOUT] Content-Type: application/json
[WinAppDriver] [STDOUT]
[WinAppDriver] [STDOUT] {"sessionId":"60D8F800-BEE0-42FF-B8DF-EA120FEAF7CD","status":0}
[debug] [WD Proxy] Got response with status 200: {"sessionId":"60D8F800-BEE0-42FF-B8DF-EA120FEAF7CD","status":0}
[WD Proxy] Replacing sessionId 60D8F800-BEE0-42FF-B8DF-EA120FEAF7CD with 9b2575cd-7b8c-4786-afae-4e2353029430
[HTTP] <-- POST /wd/hub/session/9b2575cd-7b8c-4786-afae-4e2353029430/element/42.2755824.4.56/click 200 820 ms - 63
[HTTP]
[HTTP] --> POST /wd/hub/session/9b2575cd-7b8c-4786-afae-4e2353029430/element/42.2755824.4.56/click
[HTTP] {}
[MJSONWP (9b2575cd)] Driver proxy active, passing request on via HTTP proxy
[debug] [WD Proxy] Matched '/wd/hub/session/9b2575cd-7b8c-4786-afae-4e2353029430/element/42.2755824.4.56/click' to command name 'click'
[debug] [WD Proxy] Proxying [POST /wd/hub/session/9b2575cd-7b8c-4786-afae-4e2353029430/element/42.2755824.4.56/click] to [POST http://127.0.0.1:4724/wd/hub/session/60D8F800-BEE0-42FF-B8DF-EA120FEAF7CD/element/42.2755824.4.56/click] with body: {}
[WinAppDriver] [STDOUT]
[WinAppDriver] [STDOUT]
[WinAppDriver] [STDOUT] ==========================================
hankbot commented 5 years ago

I attempted introduce a workaround in WebdriverIO but it was not accepted due to WinAppDriver's behavior being at fault.

https://github.com/webdriverio/webdriverio/pull/3809#issuecomment-479391710

Jack-Barry commented 5 years ago

Has any workaround been found for this? We're trying to get a native Windows app automated but without clicks working properly it's a non-starter.

ndimer commented 5 years ago

Same here - really annoying!

@timotiusmargo @yodurr - any ideas?

Jack-Barry commented 5 years ago

I've been trying to find a workaround on this, and wonder if the stale element error is the culprit here. In fact, I cannot seem to find a way to pull up an element by ID using any of the /session/:sessionId/element/:id endpoints.

Here's a minimal demo script that I'm running written in TypeScript:

import WebDriver from 'webdriver'

async function demo() {
  const capabilities = {
    platformName: 'Windows',
    platformVersion: '10.0',
    app: 'my-app-name.exe',
    appWorkingDir: 'path/to/my-app'
  }

  const session = await WebDriver.newSession({
    port: 4723,
    path: '',
    capabilities
  })

  const element = await session.findElement('xpath', '//*')
  // @ts-ignore
  const elementId = element.ELEMENT
  console.log(elementId)                // This is fine, confirms that an element was found
  await session.elementClick(elementId) // This throws an error
}

demo()

The elementClick function retries 3 times, but keeps receiving a stale element reference error so it fails. From what I understand, the stale element reference should only be an issue if the DOM has been updated or refreshed. Is there something I'm missing about how WinAppDriver is presenting the DOM maybe? Not sure if it makes a difference but this script is run to try and automate a classic Windows application.

ndimer commented 5 years ago

stale element

I don't think the problem is in Stale Element. The reason why WDIO throws an error is that WDIO expects 'value' property in every reply from WinAppDriver. However, when running commands like "click", WinAppDriver just returns "status: 0" reply, with no "value" property. I guess other drivers just ignore that fact and return success status. But WDIO claims that this is not compatible with W3C certificate, thus throwing an error.

I think Microsoft must fix WinAppDriver to include "value" properly or even release WAD as an open-source, so the community can help to fix such issues. But in meantime, I am going to submit a PR to Appium project, as "value" property can be added on Appium level, whenever the underlying driver doesn't return it in the response body. Stay tuned...

andrerleao commented 5 years ago

WinAppDriver needs to include value key on the response object even when value is NULL ( e.g. return obj for actions like click). #740

Jack-Barry commented 5 years ago

It would be wonderful if this could be addressed. Our team has had to implement a rather cumbersome workaround - we use a CLI tool written in C# to interact with WinAppDriver that our JS code then sends commands to and receives responses back from to process. It works, but it's really hacky.

image

ajitesh11 commented 2 years ago

@hassanuz @timotiusmargo Is there any plan for fixing this issue ? This seems like a complete stopper for so many projects who want to use wdio-winappdriver. Getting this fixed would be greatly appreciated by entire test community who want to use wdio. Is there any work around for this issue, until this gets fixed for real , it would really help.

vagisha-nidhi195 commented 2 years ago

@hassanuz @timotiusmargo Is there any plan on fixing this? We have a test framework setup with webdriverIO which we would want to re-use for winapp UWP app. Any update on plans would be really appreciated!