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

updateValue is appending instead of replacing the value of an input field #4026

Open
chris-jackson-actionqa opened this issue Feb 16, 2024 · 8 comments

Comments

@chris-jackson-actionqa
Copy link

chris-jackson-actionqa commented Feb 16, 2024

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

  1. git clone https://github.com/chris-jackson-actionqa/simple-budget.git
  2. git checkout update-value-bug
  3. npm i
  4. npm run dev
  5. 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

@garg3133
Copy link
Member

Does it only append in Chrome or does it append in Firefox as well?

@chris-jackson-actionqa
Copy link
Author

chris-jackson-actionqa commented Feb 16, 2024 via email

@chris-jackson-actionqa
Copy link
Author

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

@garg3133
Copy link
Member

garg3133 commented Feb 20, 2024

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.

@chris-jackson-actionqa
Copy link
Author

chris-jackson-actionqa commented Feb 20, 2024 via email

@garg3133
Copy link
Member

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.

@chris-jackson-actionqa
Copy link
Author

chris-jackson-actionqa commented Feb 22, 2024 via email

@garg3133
Copy link
Member

This should ideally be resolved in the latest release of Nightwatch (v3.6.1), can you please check?

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

2 participants