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

setValue() command does not work and throws error in Edge #3324

Closed
DanLambe opened this issue Jan 14, 2019 · 33 comments
Closed

setValue() command does not work and throws error in Edge #3324

DanLambe opened this issue Jan 14, 2019 · 33 comments

Comments

@DanLambe
Copy link

DanLambe commented Jan 14, 2019

Edge WebdriverIO Issue

Environment (please complete the following information):

  • WebdriverIO version: 5.2.7
  • Mode: WDIO Testrunner
  • If WDIO Testrunner, running sync/async: sync
  • Node.js version: 10 LTS
  • NPM version: 6.4.1
  • Browser name and version: Edge 16
  • Platform name and version: Windows 10
  • Additional wdio packages used (if applicable): [ @wdio/browserstack-service , @wdio/cli, @wdio/junit-reporter, @wdio/local-runner, @wdio/mocha-framework,@wdio/spec-reporter, @wdio/sync]

Config of WebdriverIO
Base Config

exports.config = {
  waitforTimeout: 10000,
  user: process.env.BROWSERSTACK_USERNAME,
  key: process.env.BROWSERSTACK_ACCESS_KEY,
  host: 'hub.browserstack.com',
  exclude: [],
  execArgv: [],
  maxInstances: 6,
  capabilities: [],
  'browserstack.video': true,
  'browserstack.debug': true,
  'browserstack.networkLogs': true,
  debug: false,
  sync: true,
  logLevel: 'error',
  coloredLogs: true,
  deprecationWarnings: true,
  bail: 0,
  screenshotPath: 'test/e2e/errorShots/',
  reporters: [
    'spec',
    [
      'junit',
      {
        outputDir: './test/e2e/test-reports/',
        outputFileFormat: function(opts) {
          return `test-results-${opts.cid}.xml`
        }
      }
    ]
  ],
  framework: 'mocha',
  mochaOpts: {
    ui: 'bdd',
    timeout: 150000
  }

Edge Specific inherited config

const merge = require('deepmerge')
const wdioConf = require('./wdio.conf.js')

exports.config = merge(wdioConf.config, {
  host: 'hub.browserstack.com',
  services: ['browserstack'],
  exclude: ['test/e2e/specs/sanity-check/**/*.js'],
  specs: ['test/e2e/specs/**/*.js'],
  capabilities: [
    {
      browserName: 'edge',
      os: 'Windows',
      os_version: '10',
      name: 'Edge Single Test',
      build: 'Example Build',
      project: 'Example Project'
    }
  ],
  browserstackLocal: false
})

Describe the bug
In Edge 16 on Browserstack, WebdriverIO throws errors and is unable to send keys with the .setValue() command. The value never gets set and the only stack trace shown in the console is JSON format error: parameters object must contain pair with name "keysToSend" this same exact code executes in the latest chrome no problem.

To Reproduce
Steps to reproduce the behavior:
Make a barebones WDIO Test Runner app with BrowserStack services and specify edge and call the setValue() command on any field on any site to see this issue.

Expected behavior
setValue() command should clear input field and send keys like it does on Chrome and Firefox but for Edge.

Log
If applicable, add logs to help explain your problem.
https://gist.github.com/DanLambe/3e8857fd6b9aec5496eeff7fab098b6b

Additional context
This only started happening when I updated to the latest WDIO v5 project, not sure it this is a BrowserStack related issue or just implementation change that broke.

@wiedsche
Copy link

Can confirm issue. Same configuration (browserstack, wdio v5).

@christian-bromann
Copy link
Member

Can anyone provide wdio and edgedriver logs?

@DanLambe
Copy link
Author

Can anyone provide wdio and edgedriver logs?

WDIO logs on debug log level settings here, unfortunately it seems BrowserStack doesn't allow you access to the Edgedriver logs unlike chrome though.

@AdamOleszko
Copy link

I have the same issue using the selenium-standalone. Does anyone have a workaround to send value to the input until this issue will be resolved?

@christian-bromann
Copy link
Member

unfortunately it seems BrowserStack doesn't allow you access to the Edgedriver logs unlike chrome though.

This is unfortunate. Please reach out to their customer support as this error comes from Browserstack. WebdriverIO calls commands based on the definition of the WebDriver protocol. This wouldn't be the first time Browserstack deviates from this.

@fkleuver
Copy link

fkleuver commented Feb 3, 2019

@christian-bromann So did the WebDriver protocol change and you followed this change in v5?
An update to WDIO v5 caused this to stop working - BrowserStack version has remained the same.

@christian-bromann
Copy link
Member

Without any logs this is impossible to say.

@fkleuver
Copy link

fkleuver commented Feb 3, 2019

Without any logs this is impossible to say.

Can't argue with that :)

The error message I see in the BrowserStack logs: JSON format error: parameters object must contain pair with name "keysToSend"

So for starters, just like OP, this seems to happen only in Edge (17 to be precise - haven't tested other versions however). Chrome 68 and FF 61 work fine. Safari fails completely to begin with.

Anyway, the local console logs:

[Edge 17 Windows 10 #0-1] Error: Malformed type for "text" parameter of command elementSendKeys
[Edge 17 Windows 10 #0-1] Expected: string
[Edge 17 Windows 10 #0-1] Actual: number
[Edge 17 Windows 10 #0-1]
[Edge 17 Windows 10 #0-1] For more info see https://w3c.github.io/webdriver/#dfn-element-send-keys
[Edge 17 Windows 10 #0-1]
[Edge 17 Windows 10 #0-1]     at Element.<anonymous> ((...)\node_modules\webdriver\build\command.js:66:15)
[Edge 17 Windows 10 #0-1]     at Element.runCommand ((...)\node_modules\@wdio\sync\build\wrapCommand.js:32:32)
[Edge 17 Windows 10 #0-1]     at process._tickCallback (internal/process/next_tick.js:68:7)

This is when I call setValue(10) on an input element.
When I change that to setValue('10'), I get the same error in the console as the one I see in the BrowserStack logs:

[Edge 17 Windows 10 #0-1] Error: JSON format error: parameters object must contain pair with name "keysToSend"
[Edge 17 Windows 10 #0-1]     at getErrorFromResponseBody ((...)\node_modules\webdriver\build\utils.js:341:10)
[Edge 17 Windows 10 #0-1]     at Request._callback ((...)\node_modules\webdriver\build\request.js:113:64)
[Edge 17 Windows 10 #0-1]     at Request.self.callback ((...)\node_modules\request\request.js:185:22)
[Edge 17 Windows 10 #0-1]     at Request.emit (events.js:182:13)
[Edge 17 Windows 10 #0-1]     at Request.EventEmitter.emit (domain.js:441:20)
[Edge 17 Windows 10 #0-1]     at Request.<anonymous> ((...)\node_modules\request\request.js:1161:10)
[Edge 17 Windows 10 #0-1]     at Request.emit (events.js:182:13)
[Edge 17 Windows 10 #0-1]     at Request.EventEmitter.emit (domain.js:441:20)
[Edge 17 Windows 10 #0-1]     at IncomingMessage.<anonymous> ((...)\node_modules\request\request.js:1083:12)
[Edge 17 Windows 10 #0-1]     at Object.onceWrapper (events.js:273:13)

And again, in both cases it works fine in Chrome and FF.

@christian-bromann
Copy link
Member

If you take a look into the WebDriver protocol you will see that the send keys to element command takes a payload with a text property that is a string. I ran this scenario on Sauce Labs and it seems that it is an Edgedriver issue, getting:

java.lang.NullPointerException
	at org.openqa.selenium.remote.server.handler.SendKeys.setJsonParameters(SendKeys.java:41)
	at org.openqa.selenium.remote.server.rest.ResultConfig.handle(ResultConfig.java:99)
	at org.openqa.selenium.remote.server.JsonHttpCommandHandler.handleRequest(JsonHttpCommandHandler.java:79)
	at org.openqa.selenium.remote.server.DriverServlet.handleRequest(DriverServlet.java:202)
	at org.openqa.selenium.remote.server.DriverServlet.doPost(DriverServlet.java:164)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
	at org.openqa.selenium.remote.server.DriverServlet.service(DriverServlet.java:130)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at org.openqa.jetty.jetty.servlet.ServletHolder.handle(ServletHolder.java:428)
	at org.openqa.jetty.jetty.servlet.ServletHandler.dispatch(ServletHandler.java:680)
	at org.openqa.jetty.jetty.servlet.ServletHandler.handle(ServletHandler.java:571)
	at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1526)
	at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1479)
	at org.openqa.jetty.http.HttpServer.service(HttpServer.java:920)
	at org.openqa.jetty.http.HttpConnection.service(HttpConnection.java:820)
	at org.openqa.jetty.http.HttpConnection.handleNext(HttpConnection.java:986)
	at org.openqa.jetty.http.HttpConnection.handle(HttpConnection.java:837)
	at org.openqa.jetty.http.SocketListener.handleConnection(SocketListener.java:243)
	at org.openqa.jetty.util.ThreadedServer.handle(ThreadedServer.java:358)
	at org.openqa.jetty.util.ThreadPool$PoolThread.run(ThreadPool.java:537)

This should be reported in the Edgedriver project.

@fkleuver
Copy link

fkleuver commented Feb 3, 2019

Yep, you're absolutely right. I'll submit an issue to those folks tomorrow and report back in this thread once I've got news.
Thanks for taking a look!

@industral
Copy link

industral commented Feb 12, 2019

I found, that now with webdriver.io v5, Edge 17134, setValue sends as W3C Webdriver

2019-02-12T14:05:10.680Z INFO webdriver: [POST] http://127.0.0.1:4444/wd/hub/session/0E3A5B01-ACDC-4B40-B35D-2381F1A49CEF/element/94e90835-53e6-4124-a410-bc9eb039ebf6/value
2019-02-12T14:05:10.680Z INFO webdriver: DATA { text: 'test' }

That's as per https://w3c.github.io/webdriver/#dfn-element-send-keys

But shouldn't that be as JWP? https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidelementidvalue

e.g. with payload?

{
	"value": ["t", "e", "s", "t"]
}

I tried with postman to send as "value": ["t", "e", "s", "t"] and it works.

@christian-bromann
Copy link
Member

But shouldn't that be as JWP?

The driver is behaving inconsistent here. It would be hard to make a workaround for edge for this command.

@fkleuver did you raise an issue in the Edgedriver project?

@ghost
Copy link

ghost commented Apr 4, 2019

Hi @fkleuver I'm still facing the same issue, any update regarding that ?

@autoGirl
Copy link

autoGirl commented Apr 24, 2019

any updates on this issue? Still seeing the same behviour for Edge17

@logakarthi
Copy link

For me, I can able to enter the text using setValue() command in iOS, but the entered text is not visible in the text field.

POST element/5032/value
200

Command Request Body

{"value":["A","d","d"," ","t","w","o"," ","w","i","t","h"," ","t","h","r","e","e"," ","i","s"," ","e","q","u","a","l"," ","t","o"],"text":"Add two with three is equal to"}
Command Response Body

{"status":0, "value":null, "sessionId":"c7870791-0c55-438f-9acc-b5e99037832d"}

@fkleuver
Copy link

Apologies for not following up folks. When I was going to file an issue 3 months ago I ran into a wall with creating a repro for browserstack. We use the paid online version, and I just haven't had time to change everything up to make it work locally.

If anyone else is willing to submit an issue with repro to the selenium repo that would be much appreciated, otherwise I will probably revisit in a month or 2 when more urgent backlog items in our project are finished.

@stefancplace
Copy link

Is there any update? still experiencing the issue...

@fkleuver
Copy link

I've just opened an issue ad developer.microsoft.com: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/22429136/

@ruiquanwu
Copy link

If you send the jsonwp protocol (elementSendKeys) directly for edge, it will work.
https://webdriver.io/docs/api/jsonwp.html#elementsendkeys

sample code in typescript, you may need to override the existing typing.
const elementId = element.elementId;
browser.elementSendKeys(elementId, "", value.split(""));

@stefancplace
Copy link

in my tests I am currently using

export function waitForDisplayedAndSetValue(element: WebdriverIO.Element, value: string) {
    element.waitForDisplayed();
    element.scrollIntoView();
    element.setValue(value);
}

It would be really nice if I didn`t have to rewrite test code for specific Browsers, is there no other workaround?

@ruiquanwu
Copy link

ruiquanwu commented Jul 18, 2019

you can use a custom command like setInputValue()
browser.addCommand( "setInputValue", function(this: WebdriverIO.Element, value: string) { if (browser.capabilities.browserName!.includes("edge") { browser.elementSendKeys(this.elementId;, "", value.split("")); } else { this.setValue(value); } true, );

and then replace your element.setValue with setInputValue, that is workaround I can come up with.

@stefancplace
Copy link

so why not adding the distinction here https://github.com/webdriverio/webdriverio/blob/master/packages/webdriverio/src/commands/element/addValue.js ?

@rishoocplace
Copy link

    browser.addCommand('setInputValue', function( element: WebdriverIO.Element, value: string) {
            if (this.capabilities.browserName.toLowerCase().includes('edge')) {
                // @ts-ignore
                this.elementSendKeys(element.elementId, value.split());
            } else {
                this.setValue(value);
            }
        }
    );
    // @ts-ignore
    browser.setInputValue(element,value);

proposed solution leads to
Error: Malformed type for "text" parameter of command elementSendKeys Expected: string Actual: object
Passing as String leads to original exception

So why not change to JWP as mentioned above?

I found, that now with webdriver.io v5, Edge 17134, setValue sends as W3C Webdriver

2019-02-12T14:05:10.680Z INFO webdriver: [POST] http://127.0.0.1:4444/wd/hub/session/0E3A5B01-ACDC-4B40-B35D-2381F1A49CEF/element/94e90835-53e6-4124-a410-bc9eb039ebf6/value
2019-02-12T14:05:10.680Z INFO webdriver: DATA { text: 'test' }

That's as per https://w3c.github.io/webdriver/#dfn-element-send-keys

But shouldn't that be as JWP? https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidelementidvalue

e.g. with payload?

{
	"value": ["t", "e", "s", "t"]
}

I tried with postman to send as "value": ["t", "e", "s", "t"] and it works.

@ruiquanwu
Copy link

ruiquanwu commented Jul 25, 2019

you will also need to define the right typing for elementSendKeys, (currently it is not right)

in separate webdriver.d.ts file

declare namespace WebDriver {
interface Client {
elementSendKeys(elementId: string, text: string, value?: string[]): void;
}
}

@ruiquanwu
Copy link

ruiquanwu commented Jul 25, 2019

you should add true flag in the command if you want to directly use with the element.
https://webdriver.io/docs/customcommands.html#adding-custom-commands

Additionally, you can extend the element instance with your own set of commands, by passing 'true' as the final argument. By default element is expected to be existing in waitforTimeout milliseconds otherwise exception will be thrown.

@stefancplace
Copy link

stefancplace commented Jul 25, 2019

you will also need to define the right typing for elementSendKeys, (currently it is not right)

in separate webdriver.d.ts file

declare namespace WebDriver {
interface Client {
elementSendKeys(elementId: string, text: string, value?: string[]): void;
}
}

Thanks ruiquanwu by changing the typings I can actually set a Value in Edge on my local machine.
Yet locally overwriting the official webdriver typings doesnt help me at all in CI environment...

whats your suggestions, should we create a PR in the WebDriver Repository?

@ruiquanwu
Copy link

you can define a separate webdriver.d.ts file in your root directory with the above info,
it is the same approach for override/add typing when defining custom commands. ( it uses webdriverio.d.ts)
That way it will work for any environment if you have set up the compiler correctly.

Yes, a PR would be better but I don't have the time to read the contribution documents.

@YmerejRedienhcs
Copy link

YmerejRedienhcs commented Sep 30, 2019

Sorry, newbie question here -- @ruiquanwu @stefancplace -- can you describe the root directory into which that webdriver.d.ts needs to go? Is it the same directory that wdio.conf.js lives in? I'm not clear on where to put it. Thanks.

@ruiquanwu
Copy link

@YmerejRedienhcs I think in the project root directory will work. You may need to check type script typing definition for more details.

@leongaban
Copy link

leongaban commented Nov 14, 2019

Hi, this is still an issue for our team, has anyone been able to get setValue or addValue working for FireFox/Edge? We currently cannot test either browser with Webdriver. Using redux-forms.

https://stackoverflow.com/questions/58860806/how-to-fill-in-redux-form-inputs-in-firefox-edge-via-webdriver-automated-tests

Webdriver.io is an automated test lib.

In Chrome and Safari I'm able to use either setValue or addValue using xpaths to fill in a text input and submit a form during automated tests.

However in Edge/FireFox I cannot, these commands don't work.

Looking around I found a work-around involving browser.addCommand and browser.execute which I've used below and it will fill in the redux-form visually. However the form doesn't detect that the form has actually been filled :( So thus the automated Submit button won't continue if it's been clicked.

browser.execute workaround

browser.addCommand('setInputValue', function(element, value) {
    const webBrowser = browser.capabilities.browserName.toLowerCase();

    if (webBrowser === 'microsoftedge') {
        browser.execute((el, val) => {           
            const regex = /\'(.*)\'/; // pulls name out of xpath
            const extractedName = el.match(regex)[1];
            
            document.getElementsByName(extractedName)[0].focus();
            document.getElementsByName(extractedName)[0].value = val;

        }, element, value);
    }
    else {
        $(element).setValue(value);
    }
});

How it's used:

setFirstName: value => {
    const xpath = "//input[@name='firstName']";
    browser.setInputValue(xpath, value);
    // $(xpath).setValue(value); // <- normal webdriver method which doesn't work
}

Have any of you run into this issue before when using Webdriver to automate tests on FireFox or Edge?

@subhik7
Copy link

subhik7 commented Nov 25, 2019

Yes, I'm getting error with setValue() function in Edge browser after wdio version 5 upgrade . The same syntax works in Chrome and IE perfectly.

@goveanick
Copy link

This is still an issue, does anyone have an update from the ticket that was opened at Microsoft?

I see that @fkleuver opened a ticket a couple of months ago, but the link provided doesn't work
https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/22429136/

@kishan-maheshkumar
Copy link

I have same issue with Safari with same configuration. SetValue() not working. Please let me know any workaround or solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests