SeleniumHQ / selenium-ide

Open Source record and playback test automation for the web.
https://selenium.dev/selenium-ide/
Apache License 2.0
2.81k stars 765 forks source link

Incorrect handling of quotes #824

Open ThibaudLopez opened 5 years ago

ThibaudLopez commented 5 years ago

🐛 Bug Report

Selenium IDE incorrectly handles JavaScript double quotes, single quotes, and back-ticks.

Code

Selenium IDE command line runner package: selianize file: command.js method escapeString at line 176: string.replace(/"/g, "'") method generateScript at line 266: `await driver.executeScript(\`${script.script}\`);`

Bugs

  1. The code string.replace(/"/g, "'") replaces double quotes with single quotes, but that breaks the syntax of the string if it already contains single quotes. It should escape instead of replace.

  2. replace and executeScript are not consistent with each other. They should both use double quotes or both back-ticks, with the corresponding escaping.

To reproduce

Steps to reproduce the behavior:

  1. Create a Selenium IDE test suite, test.side, with a Command execute script and a Target with a valid JavaScript expression that contains a mix of quotes, e.g. CSS selector document.querySelector("img[alt='hello, world']")
  2. Run the test suite in Selenium IDE (CTRL+R) to ensure it works correctly, 'test' completed successfully.
  3. Run the test suite with the Selenium IDE command line runner, selenium-side-runner test.side. It will execute methods escapeString and generateScript of module selianize. It will generate file side-suite-test/commons.js with the wrongly escaped JavaScript expression, await driver.executeScript(`document.querySelector('img[alt='hello, world']')`) which is not valid JavaScript anymore because of the quotes so it will throw SyntaxError: missing ) after argument list.

Expected behavior

selianize should generate valid JavaScript syntax, with the correct escaping, await driver.executeScript(`document.querySelector(\"img[alt='hello, world']\")`)

Project file reproducing this issue

test.side:

{
  "id": "1",
  "version": "2.0",
  "name": "test",
  "url": "https://example.com/",
  "tests": [{
    "id": "2",
    "name": "test",
    "commands": [{
      "id": "3",
      "comment": "",
      "command": "executeScript",
      "target": "document.querySelector(\"img[alt='hello, world']\")",
      "targets": [],
      "value": ""
    }]
  }],
  "suites": [{
    "id": "4",
    "name": "Default Suite",
    "persistSession": false,
    "parallel": false,
    "timeout": 300,
    "tests": ["2"]
  }],
  "urls": ["https://example.com/"],
  "plugins": []
}

Here are some more valid JavaScript examples with different usage of quotes:

document.querySelector('img[alt="hello, world"]')
document.querySelector(`img[alt="hello, world"]`)
document.querySelector("img[alt=\"hello, world\"]")
document.querySelector('img[alt=\"hello, world\"]')
document.querySelector(`img[alt=\"hello, world\"]`)
document.querySelector("img[alt='hello, world']")
document.querySelector(`img[alt='hello, world']`)
document.querySelector("img[alt=\'hello, world\']")
document.querySelector('img[alt=\'hello, world\']')
document.querySelector(`img[alt=\'hello, world\']`)

Workaround

One workaround is to separate the command in two in Selenium IDE:

  1. Save the CSS selector in a variable, Command store, Target img[alt='hello, world'] (without surrounding quotes), and Value selector (the variable name).
  2. Invoke the variable, Command execute script, Target document.querySelector(${selector})

Note: This workaround will work in selenium-side-runner but will fail in Selenium IDE.

Related code

The following code has the same bug, but I don't have good steps to reproduce it:

Selenium IDE Code Export to JavaScript Mocha package: code-export-javascript-mocha file: command.js method: emitExecuteScript line 429: script.replace(/"/g, "'") line 430: `await driver.executeScript("${scriptString}")`

Environment

I confirmed with these two environments:

Related issue

There is a related bug report SeleniumHQ/selenium/issues/4337 that was not described fully so it was closed prematurely.

Danc2050 commented 4 years ago

Issue is still an issue.

terrynguyen255 commented 3 years ago

Thank you @ThibaudLopez . Your work-around saved me

redescaflown commented 3 years ago

I have the same issue

Naxos84 commented 1 year ago

I tried Selenium IDE in Edge Browser today and stumbled upon this bug. image

That gives me the following error: image

Here is the project to reproduce this issue:

{
  "id": "f8ae4b49-0dd2-4a99-b7bf-58e59295906d",
  "version": "2.0",
  "name": "API",
  "url": "https://www.example.com",
  "tests": [{
    "id": "9c5ffdaa-adbd-402e-bb96-ba9e0a6d7cb8",
    "name": "Untitled",
    "commands": [{
      "id": "b079cb24-b72c-4598-8ddd-1140e4648613",
      "comment": "",
      "command": "executeScript",
      "target": "return \"Hello World\"",
      "targets": [],
      "value": "a"
    }, {
      "id": "d6b235c8-7475-43ac-bf92-176dce4e9c18",
      "comment": "",
      "command": "if",
      "target": "${a} === \"Hello World\"",
      "targets": [],
      "value": ""
    }, {
      "id": "725665da-3bf5-4353-851d-f451a25f8e3e",
      "comment": "",
      "command": "executeScript",
      "target": "return \"hello world\"",
      "targets": [],
      "value": "a"
    }, {
      "id": "4e0220f4-8d64-421b-b8b2-faf6e1b9f078",
      "comment": "",
      "command": "end",
      "target": "",
      "targets": [],
      "value": ""
    }, {
      "id": "521d1564-b663-4051-ad19-c34acb200ca9",
      "comment": "",
      "command": "assert",
      "target": "a",
      "targets": [],
      "value": "\"hello world\""
    }]
  }],
  "suites": [{
    "id": "c0aa26f6-b1b9-467c-b153-d13e3145b53d",
    "name": "Default Suite",
    "persistSession": false,
    "parallel": false,
    "timeout": 300,
    "tests": ["9c5ffdaa-adbd-402e-bb96-ba9e0a6d7cb8"]
  }],
  "urls": ["https://www.example.com/"],
  "plugins": []
}
AdrienVerstrepen commented 4 months ago

Does anyone have found a workaround for this issue with Selenium IDE ?

toddtarsi commented 4 months ago

@AdrienVerstrepen - It's not quite a workaround, but I think this is fixed in v4?

https://github.com/SeleniumHQ/selenium-ide/releases/tag/v4.0.1-beta.12