nightwatch
nightwatch copied to clipboard
updateValue is appending instead of replacing the value of an input field
Description of the bug/issue
I'm using updateValue
to edit a form that already has values in the input fields. However, updateValue
is only appending text instead of replacing the text.
Steps to reproduce
- git clone https://github.com/chris-jackson-actionqa/simple-budget.git
- git checkout update-value-bug
- npm i
- npm run dev
- in a separate terminal,
npx nightwatch -e chrome test/bills/editBill.ts
Sample test
describe("Edit Bill", () => {
beforeEach(() => {
browser.navigateTo("/bills");
browser.refresh();
// Add new bill
browser.updateValue("#billName", "Test Bill");
browser.updateValue("#billAmount", "100");
browser.updateValue("#billDate", "20");
browser.element.findByText("Add").click();
browser.element.findByText("Test Bill").click();
});
it("should edit bill", async () => {
// Edit bill
await browser.pause(2000);
await browser.updateValue("#billName", "2");
// browser.updateValue("#billAmount", "200");
// browser.updateValue("#billDate", "25");
await browser.pause(2000);
await browser.element.findByText("Save").click();
await browser.element.findByText("Test Bill2");
await browser.pause(2000);
});
});
Command to run
npx nightwatch -e chrome test/bills/editBill.ts
Verbose Output
[Edit Bill] Test Suite
────────────────────────────────────────────
⠋ Starting ChromeDriver on port 9515...
Starting ChromeDriver with server_path=/Users/christopherjackson/Documents/mydev/simple-budget/frontend/node_modules/chromedriver/lib/chromedriver/chromedriver...
Request POST /session
{
capabilities: {
firstMatch: [ {} ],
alwaysMatch: {
browserName: 'chrome',
'goog:chromeOptions': { w3c: true, args: [] }
}
}
⠼ Starting ChromeDriver on port 9515...
Response 200 POST /session (1136ms)
{
value: {
capabilities: {
acceptInsecureCerts: false,
browserName: 'chrome',
browserVersion: '121.0.6167.160',
chrome: {
chromedriverVersion: '120.0.6099.109 (3419140ab665596f21b385ce136419fde0924272-refs/branch-heads/6099@{#1483})',
userDataDir: '/var/folders/t3/_n_1bbmd0h74sqb0bv7hlr6r0000gn/T/.org.chromium.Chromium.FpG9e7'
},
'fedcm:accounts': true,
'goog:chromeOptions': { debuggerAddress: 'localhost:52518' },
networkConnectionEnabled: false,
pageLoadStrategy: 'normal',
platformName: 'mac',
proxy: {},
setWindowRect: true,
strictFileInteractability: false,
timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },
unhandledPromptBehavior: 'dismiss and notify',
'webauthn:extension:credBlob': true,
'webauthn:extension:largeBlob': true,
'webauthn:extension:minPinLength': true,
'webauthn:extension:prf': true,
'webauthn:virtualAuthenticators': true
},
sessionId: '7ffa6cc922f6360f2d274e813bb02c48'
}
ℹ Connected to ChromeDriver on port 9515 (1186ms).
Using: chrome (121.0.6167.160) on MAC.
Received session with ID: 7ffa6cc922f6360f2d274e813bb02c48
→ Running [before]:
→ Completed [before].
Running should edit bill:
───────────────────────────────────────────────────────────────────────────────────────────────────
→ Running [beforeEach]:
→ Running command: navigateTo ('/bills')
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/url
{ url: 'http://localhost:3001/bills' }
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/url (798ms)
{ value: null }
→ Completed command: navigateTo ('/bills') (800ms)
→ Running command: refresh ()
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/refresh
{}
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/refresh (129ms)
{ value: null }
→ Completed command: refresh () (129ms)
→ Running command: updateValue ('#billName', 'Test Bill')
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements
{ using: 'css selector', value: '#billName' }
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements (10ms)
{
value: [
{
'element-6066-11e4-a52e-4f735466cecf': '27A6123B043D9ED60D135F7300FF3B6F_element_7'
}
]
}
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_7/clear
{}
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_7/clear (28ms)
{ value: null }
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_7/clear
{}
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_7/clear (17ms)
{ value: null }
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_7/value
{
text: 'Test Bill',
value: [
'T', 'e', 's',
't', ' ', 'B',
'i', 'l', 'l'
]
}
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_7/value (172ms)
{ value: null }
→ Completed command: updateValue ('#billName', 'Test Bill') (231ms)
→ Running command: updateValue ('#billAmount', '100')
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements
{ using: 'css selector', value: '#billAmount' }
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements (8ms)
{
value: [
{
'element-6066-11e4-a52e-4f735466cecf': '27A6123B043D9ED60D135F7300FF3B6F_element_11'
}
]
}
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_11/clear
{}
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_11/clear (25ms)
{ value: null }
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_11/clear
{}
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_11/clear (18ms)
{ value: null }
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_11/value
{ text: '100', value: [ '1', '0', '0' ] }
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_11/value (30ms)
{ value: null }
→ Completed command: updateValue ('#billAmount', '100') (83ms)
→ Running command: updateValue ('#billDate', '20')
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements
{ using: 'css selector', value: '#billDate' }
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements (9ms)
{
value: [
{
'element-6066-11e4-a52e-4f735466cecf': '27A6123B043D9ED60D135F7300FF3B6F_element_12'
}
]
}
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_12/clear
{}
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_12/clear (23ms)
{ value: null }
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_12/clear
{}
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_12/clear (17ms)
{ value: null }
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_12/value
{ text: '20', value: [ '2', '0' ] }
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_12/value (32ms)
{ value: null }
→ Completed command: updateValue ('#billDate', '20') (82ms)
→ Running command: element.find ({ By(xpath, .//*[text()="Add"]) })
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements
{ using: 'xpath', value: './/*[text()="Add"]' }
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements (9ms)
{
value: [
{
'element-6066-11e4-a52e-4f735466cecf': '27A6123B043D9ED60D135F7300FF3B6F_element_16'
}
]
}
→ Completed command: element.find ({ By(xpath, .//*[text()="Add"]) }) (10ms)
→ Running command: element().clickElement ()
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_16/click
{}
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_16/click (35ms)
{ value: null }
→ Completed command: element().clickElement () (37ms)
→ Running command: element.find ({ By(xpath, .//*[text()="Test Bill"]) })
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements
{ using: 'xpath', value: './/*[text()="Test Bill"]' }
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements (23ms)
{
value: [
{
'element-6066-11e4-a52e-4f735466cecf': '27A6123B043D9ED60D135F7300FF3B6F_element_17'
}
]
}
→ Completed command: element.find ({ By(xpath, .//*[text()="Test Bill"]) }) (24ms)
→ Running command: element().clickElement ()
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_17/click
{}
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_17/click (38ms)
{ value: null }
→ Completed command: element().clickElement () (38ms)
→ Completed [beforeEach].
→ Running command: pause (2000)
→ Completed command: pause (2000) (2002ms)
→ Running command: updateValue ('#billName', '2')
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements
{ using: 'css selector', value: '#billName' }
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements (6ms)
{
value: [
{
'element-6066-11e4-a52e-4f735466cecf': '27A6123B043D9ED60D135F7300FF3B6F_element_19'
}
]
}
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_19/clear
{}
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_19/clear (35ms)
{ value: null }
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_19/clear
{}
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_19/clear (49ms)
{ value: null }
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_19/value
{ text: '2', value: [ '2' ] }
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_19/value (58ms)
{ value: null }
→ Completed command: updateValue ('#billName', '2') (150ms)
→ Running command: pause (2000)
→ Completed command: pause (2000) (2002ms)
→ Running command: element.find ({ By(xpath, .//*[text()="Save"]) })
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements
{ using: 'xpath', value: './/*[text()="Save"]' }
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements (12ms)
{
value: [
{
'element-6066-11e4-a52e-4f735466cecf': '27A6123B043D9ED60D135F7300FF3B6F_element_23'
}
]
}
→ Completed command: element.find ({ By(xpath, .//*[text()="Save"]) }) (12ms)
→ Running command: element().clickElement ()
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_23/click
{}
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/element/27A6123B043D9ED60D135F7300FF3B6F_element_23/click (48ms)
{ value: null }
→ Completed command: element().clickElement () (48ms)
→ Running command: element.find ({ By(xpath, .//*[text()="Test Bill2"]) })
Request POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements
{ using: 'xpath', value: './/*[text()="Test Bill2"]' }
Response 200 POST /session/7ffa6cc922f6360f2d274e813bb02c48/elements (8ms)
{
value: [
{
'element-6066-11e4-a52e-4f735466cecf': '27A6123B043D9ED60D135F7300FF3B6F_element_24'
}
]
}
→ Completed command: element.find ({ By(xpath, .//*[text()="Test Bill2"]) }) (9ms)
→ Running command: pause (2000)
→ Completed command: pause (2000) (2001ms)
→ Running [afterEach]:
→ Completed [afterEach].
No assertions ran.
→ Running [after]:
→ Completed [after].
→ Running command: end (true)
→ Running command: session ('delete', [Function])
Request DELETE /session/7ffa6cc922f6360f2d274e813bb02c48
Response 200 DELETE /session/7ffa6cc922f6360f2d274e813bb02c48 (55ms)
{ value: null }
→ Completed command: session ('delete', [Function]) (58ms)
Wrote log file to: /Users/christopherjackson/Documents/mydev/simple-budget/frontend/logs/bills/editBill_chromedriver.log
→ Completed command: end (true) (63ms)
ChromeDriver process closed.
Wrote HTML report file to: /Users/christopherjackson/Documents/mydev/simple-budget/frontend/tests_output/nightwatch-html-report/index.html
Wrote Rerun Json report file to: /Users/christopherjackson/Documents/mydev/simple-budget/frontend/tests_output/minimal_report.json
Wrote JSON report file to: /Users/christopherjackson/Documents/mydev/simple-budget/frontend/tests_output/bills/CHROME_121.0.6167.160__editBill.json
Wrote XML report file to: /Users/christopherjackson/Documents/mydev/simple-budget/frontend/tests_output/bills/CHROME_121.0.6167.160__editBill.xml
Analytics send event:
{
client_id: '169a5087-43e2-49ea-8ab7-77e4b521dd18',
non_personalized_ads: true,
timestamp_micros: 1708102135529000,
events: [
{
name: 'nw_test_run',
params: {
arg_parallel: 'undefined',
browser_name: 'chrome',
test_workers_enabled: false,
use_xpath: false,
is_bstack: false,
test_runner: 'default',
event_time: 1708102126131000,
env_os: 'darwin/23.2.0/Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz',
env_lang: 'en_US.UTF-8',
env_nw_version: '3.4.1',
env_node_version: 'node v18.19.0',
test_env: 'chrome',
run_id: '58520e4b-afc9-45ae-93d7-ce4da210437e'
}
}
]
}
Nightwatch Configuration
// Refer to the online docs for more details:
// https://nightwatchjs.org/gettingstarted/configuration/
//
// _ _ _ _ _ _ _
// | \ | |(_) | | | | | | | |
// | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__
// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \
// | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | |
// \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_|
// __/ |
// |___/
module.exports = {
// An array of folders (excluding subfolders) where your tests are located;
// if this is not specified, the test source must be passed as the second argument to the test runner.
src_folders: ["test", "nightwatch"],
// See https://nightwatchjs.org/guide/concepts/page-object-model.html
page_objects_path: [],
// See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html
custom_commands_path: [],
// See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html
custom_assertions_path: [],
// See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html
plugins: [
// "@nightwatch/react"
],
// See https://nightwatchjs.org/guide/concepts/test-globals.html
globals_path: "",
vite_dev_server: {
start_vite: true,
port: 5173,
},
webdriver: {},
test_workers: {
enabled: true,
},
test_settings: {
default: {
disable_error_log: false,
launch_url: "http://localhost:3001",
screenshots: {
enabled: false,
path: "screens",
on_failure: true,
},
desiredCapabilities: {
browserName: "chrome",
},
webdriver: {
start_process: true,
server_path: "",
},
},
firefox: {
desiredCapabilities: {
browserName: "firefox",
alwaysMatch: {
acceptInsecureCerts: true,
"moz:firefoxOptions": {
args: [
// '-headless',
// '-verbose'
],
},
},
},
webdriver: {
start_process: true,
server_path: "",
cli_args: [
// very verbose geckodriver logs
// '-vv'
],
},
},
chrome: {
desiredCapabilities: {
browserName: "chrome",
"goog:chromeOptions": {
// More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
//
// w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
w3c: true,
args: [
//'--no-sandbox',
//'--ignore-certificate-errors',
//'--allow-insecure-localhost',
//'--headless'
],
},
},
webdriver: {
start_process: true,
server_path: "",
cli_args: [
// --verbose
],
},
},
},
usage_analytics: {
enabled: true,
log_path: "./logs/analytics",
client_id: "169a5087-43e2-49ea-8ab7-77e4b521dd18",
},
};
Nightwatch.js Version
3.4.1
Node Version
v18.19.0
Browser
Version 121.0.6167.139 (Official Build) (x86_64)
Operating System
macOS Sonoma 14.2.1 (23C71)
Additional Information
No response
Does it only append in Chrome or does it append in Firefox as well?
I haven't tried Firefox.
-- Chris Jackson
On Fri, Feb 16, 2024 at 9:48 AM Priyansh Garg @.***> wrote:
Does it only append in Chrome or does it append in Firefox as well?
— Reply to this email directly, view it on GitHub https://github.com/nightwatchjs/nightwatch/issues/4026#issuecomment-1948977467, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB2UI262GQ3SM5UBWHNPXMTYT6LVXAVCNFSM6AAAAABDMK2MA2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNBYHE3TONBWG4 . You are receiving this because you authored the thread.Message ID: @.***>
browser.clearValue isn't clearing the value, either.
I had to write the following code to clear the input:
async function clearValue(browser, selector) {
const value = await browser.getValue(selector);
for (let i = 0; i < value.length; i++) {
await browser.element(selector).sendKeys("\uE003");
}
}
That code works to clear the input, but not browser.clearValue
I tried this on Firefox and the updateValue
command is working fine over there.
This bug seems to be only present in Chromium-based browsers (Chrome, Edge, etc.) where the clear command is not able to reset the value of input fields and still return a 200 response code, and it needs to be fixed by browser vendors only. Moreover, it seems to be happening in React applications mostly.
But if the issue is not fixed by the browser vendors sooner, maybe we could add a fallback to the clearValue
command in Nightwatch where if the input field contains a value even after the completion of the clearValue
command, Nightwatch would fall back to the workaround suggested by you.
cc: @AutomatedTester
Edit: The issue seems to be present in Safari browser as well.
Thank you for investigating. I'm not sure what the proper course of action
is. If updateValue
or clearValue
aren't working as expected, they
should fail with an error message explaining how to workaround the issue.
Otherwise, test writers are going to waste a ton of time trying to figure
out what went wrong.
-- Chris Jackson
On Tue, Feb 20, 2024 at 12:40 AM Priyansh Garg @.***> wrote:
I tried this on Firefox and the updateValue command is working fine over there.
This bug seems to be only present in Chromium-based browsers (Chrome, Edge, etc.) where the clear command is not able to reset the value of input fields and still return a 200 response code, and it needs to be fixed by browser vendors only. Moreover, it seems to be happening in React applications mostly.
But if the issue is not fixed by the browser vendors sooner, maybe we could add a fallback to the clearValue command in Nightwatch where if the input field contains a value even after the completion of the clearValue command, Nightwatch would fall back to the workaround suggested by you.
cc: @AutomatedTester https://github.com/AutomatedTester
— Reply to this email directly, view it on GitHub https://github.com/nightwatchjs/nightwatch/issues/4026#issuecomment-1953719575, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB2UI2ZVPYFSL5Q5YK6WC5DYUROOVAVCNFSM6AAAAABDMK2MA2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNJTG4YTSNJXGU . You are receiving this because you authored the thread.Message ID: @.***>
You're absolutely right. But how Nightwatch works is when you execute the clearValue
command it sends an HTTP request to the webdriver server (chromedriver, geckodriver, etc.) to clear the field and the webdriver sends back a response based on whether the task was successfully completed or not.
In this case, the webdriver server is sending back a 200 response code even when the input field isn't actually cleared, and so, because of the 200 response code, Nightwatch assumes that the webdriver must have completed its task and moves on.
The next course of action here (on our side) would be to narrow down the issue further (to find out what's actually causing it) and then raise it with the Chrome/Safari team.
But since that might take long, I think it'd be better to add a fallback in the clearValue
command in Nightwatch to handle such cases. I'll raise a new issue for that shortly.
I'll trust your judgement. Thank you for investigating this. And I appreciate your quick response.
-- Chris Jackson
On Wed, Feb 21, 2024 at 2:15 AM Priyansh Garg @.***> wrote:
You're absolutely right. But how Nightwatch works is when you execute the clearValue command it sends an HTTP request to the webdriver server (chromedriver, geckodriver, etc.) to clear the field and the webdriver sends back a response based on whether the task was successfully completed or not.
In this case, the webdriver server is sending back a 200 response code even when the input field isn't actually cleared, and so, because of the 200 response code, Nightwatch assumes that the webdriver must have completed its task and moves on.
The next course of action here (on our side) would be to narrow down the issue further (to find out what's actually causing it) and then raise it with the Chrome/Safari team.
But since that might take long, I think it'd be better to add a fallback in the clearValue command in Nightwatch to handle such cases. I'll raise a new issue for that shortly.
— Reply to this email directly, view it on GitHub https://github.com/nightwatchjs/nightwatch/issues/4026#issuecomment-1956315464, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB2UI27VSZHCF2VCHZ5ALMDYUXCMNAVCNFSM6AAAAABDMK2MA2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNJWGMYTKNBWGQ . You are receiving this because you authored the thread.Message ID: @.***>
This should ideally be resolved in the latest release of Nightwatch (v3.6.1
), can you please check?