nightwatchjs / nightwatch

Integrated end-to-end testing framework written in Node.js and using W3C Webdriver API. Developed at @browserstack
https://nightwatchjs.org
MIT License
11.79k stars 1.31k forks source link

Execute() does not work, throws error suggesting it was not provided as a string to selenium executeScript() #2478

Closed tsibiski closed 3 years ago

tsibiski commented 4 years ago

Describe the bug

Using the execute method provided by Nightwatch, and after copying it straight from the documentation, and simply changing the argument passed in, I get an error. The error states:

TypeError: Converting circular structure to JSON --> starting at object with constructor 'NightwatchClient' | property '__transport' -> object with constructor 'JsonWireProtocol' --- property 'nightwatchInstance' closes the circle --> starting at object with constructor 'NightwatchClient' | property '__transport' -> object with constructor 'JsonWireProtocol' --- property 'nightwatchInstance' closes the circle at JSON.stringify (<anonymous>) Error while running .executeScript() protocol action: invalid argument: 'script' must be a string

Sample test

describe('Example Test', function() {

  before(browser => browser.url('URL to proprietary website only available on company VPN'));

  test('Example test', async function (browser) {

        await browser.waitForElementVisible("body", 20000);
        await browser.execute(function(elementNameString) {
        //Do anything at all in here. It does not execute.
        return;
        }, ["Example string"]);

    })         

  after(browser => browser.end());

});

Run with command

nightwatch tests/exampleTest.js -e chrome 
nightwatch tests/exampleTest.js

Verbose output

debug.log

```txt → Running command: execute ([Function], {0}) TypeError: Converting circular structure to JSON --> starting at object with constructor 'NightwatchClient' | property '__transport' -> object with constructor 'JsonWireProtocol' --- property 'nightwatchInstance' closes the circle --> starting at object with constructor 'NightwatchClient' | property '__transport' -> object with constructor 'JsonWireProtocol' --- property 'nightwatchInstance' closes the circle at JSON.stringify () Request POST /session/6919447268557fff91757da1b9b1e5af/execute { script: 'var passedArgs = Array.prototype.slice.call(arguments,0); return ' + 'function(el) {\n $("body").remove();\n ' + '//document.getElementById(el).scrollIntoView({behavior: "smooth", ' + 'block: "end", inline: "nearest"});\n return;\n ' + '}.apply(window, passedArgs);', args: [ Element { name: 'emailInput', __index: undefined, __selector: '#customer-email', locateStrategy: 'css selector', pseudoSelector: null, parent: Page { commandLoader: [Function: bound loadApi], __options: [Object], __client: [NightwatchClient], __api: [Object], __props: {}, __elements: [Object], __sections: {}, submit: [Function: submit], assert: [Object], verify: [Object], expect: [Object], closeWindow: [Function], deleteCookie: [Function], deleteCookies: [Function], end: [Function], getCookie: [Function], getCookies: [Function], getLog: [Function], getLogTypes: [Function], getTitle: [Function], getWindowPosition: [Function], getWindowRect: [Function], getWindowSize: [Function], init: [Function], injectScript: [Function], isLogAvailable: [Function], maximizeWindow: [Function], pause: [Function], perform: [Function], resizeWindow: [Function], saveScreenshot: [Function], setCookie: [Function], setWindowPosition: [Function], setWindowRect: [Function], setWindowSize: [Function], switchWindow: [Function], urlHash: [Function], useCss: [Function], useXpath: [Function], clearValue: [Function], click: [Function], getAttribute: [Function], getCssProperty: [Function], getElementProperty: [Function], getElementSize: [Function], getLocation: [Function], getLocationInView: [Function], getTagName: [Function], getText: [Function], getValue: [Function], isVisible: [Function], moveToElement: [Function], setValue: [Function], sendKeys: [Function], submitForm: [Function], waitForElementNotPresent: [Function], waitForElementNotVisible: [Function], waitForElementPresent: [Function], waitForElementVisible: [Function] }, resolvedElement: null } ] } Response 200 POST /session/6919447268557fff91757da1b9b1e5af/execute (672ms) { sessionId: '6919447268557fff91757da1b9b1e5af', status: 61, value: { message: "invalid argument: 'script' must be a string", error: [ ' (Session info: chrome=84.0.4147.135)', ' (Driver info: chromedriver=84.0.4147.30 ' + '(48b3e868b4cc0aa7e8149519690b6f6949e110a8-refs/branch-heads/4147@{#310}),platform=Windows ' + 'NT 10.0.18363 x86_64)' ] } } Error while running .executeScript() protocol action: invalid argument: 'script' must be a string```

Configuration

nightwatch.json

```js // Autogenerated by Nightwatch // Refer to the online docs for more details: https://nightwatchjs.org/gettingstarted/configuration/ const Services = {}; loadServices(); 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: [], // See https://nightwatchjs.org/guide/working-with-page-objects/ page_objects_path: './tests/pageObjects', // See https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands custom_commands_path: '', // See https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-assertions custom_assertions_path: '', // See https://nightwatchjs.org/guide/#external-globals globals_path : '', webdriver: {}, test_settings: { default: { disable_error_log: false, launch_url: 'https://nightwatchjs.org', screenshots: { enabled: false, path: 'screens', on_failure: true }, desiredCapabilities: { browserName : 'firefox' }, webdriver: { start_process: true, server_path: (Services.geckodriver ? Services.geckodriver.path : '') } }, firefox: { desiredCapabilities : { browserName : 'firefox', alwaysMatch: { // Enable this if you encounter unexpected SSL certificate errors in Firefox // acceptInsecureCerts: true, 'moz:firefoxOptions': { args: [ // '-headless', // '-verbose' ], } } }, webdriver: { start_process: true, port: 4444, server_path: (Services.geckodriver ? Services.geckodriver.path : ''), cli_args: [ // very verbose geckodriver logs // '-vv' ] } }, chrome: { desiredCapabilities : { browserName : 'chrome', chromeOptions : { // This tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78) // w3c: false, // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/ args: [ //'--no-sandbox', //'--ignore-certificate-errors', //'--allow-insecure-localhost', //'--headless' ] } }, webdriver: { start_process: true, port: 4444, server_path: (Services.chromedriver ? Services.chromedriver.path : ''), cli_args: [ // --verbose ] } }, ////////////////////////////////////////////////////////////////////////////////// // Configuration for when using the browserstack.com cloud service | // | // Please set the username and access key by setting the environment variables: | // - BROWSERSTACK_USER | // - BROWSERSTACK_KEY | // .env files are supported | ////////////////////////////////////////////////////////////////////////////////// browserstack: { selenium: { host: 'hub-cloud.browserstack.com', port: 443 }, // More info on configuring capabilities can be found on: // https://www.browserstack.com/automate/capabilities?tag=selenium-4 desiredCapabilities: { 'bstack:options' : { local: 'false', userName: '${BROWSERSTACK_USER}', accessKey: '${BROWSERSTACK_KEY}', } }, disable_error_log: true, webdriver: { keep_alive: true, start_process: true } }, 'browserstack.chrome': { extends: 'browserstack', desiredCapabilities: { browserName: 'chrome', chromeOptions : { // This tells Chromedriver to run using the legacy JSONWire protocol // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/ w3c: false } } }, 'browserstack.firefox': { extends: 'browserstack', desiredCapabilities: { browserName: 'firefox' } }, 'browserstack.ie': { extends: 'browserstack', desiredCapabilities: { browserName: 'IE', browserVersion: '11.0', 'bstack:options' : { os: 'Windows', osVersion: '10', local: 'false', seleniumVersion: '3.5.2', resolution: '1366x768' } } }, ////////////////////////////////////////////////////////////////////////////////// // Configuration for when using the Selenium service, either locally or remote, | // like Selenium Grid | ////////////////////////////////////////////////////////////////////////////////// selenium: { // Selenium Server is running locally and is managed by Nightwatch selenium: { start_process: true, port: 4444, server_path: (Services.seleniumServer ? Services.seleniumServer.path : ''), cli_args: { 'webdriver.gecko.driver': (Services.geckodriver ? Services.geckodriver.path : ''), 'webdriver.chrome.driver': (Services.chromedriver ? Services.chromedriver.path : '') } } }, 'selenium.chrome': { extends: 'selenium', desiredCapabilities: { browserName: 'chrome', chromeOptions : { w3c: false } } }, 'selenium.firefox': { extends: 'selenium', desiredCapabilities: { browserName: 'firefox', 'moz:firefoxOptions': { args: [ // '-headless', // '-verbose' ] } } } } }; function loadServices() { try { Services.seleniumServer = require('selenium-server'); } catch (err) {} try { Services.chromedriver = require('chromedriver'); } catch (err) {} try { Services.geckodriver = require('geckodriver'); } catch (err) {} } ```

Your Environment

Firefox and Chrome, identical error

| nightwatch --version | 1.3.7 | | npm --version | 6.9.0 | | yarn --version | not installed | | node --version | 12.3.1 |

| chromedriver | 84.0.4147.30 | | geckodriver | 1.20.0 | | selenium-server | 3.141.59 |

| macOS Mojave | 10.14.6 |

beatfactor commented 4 years ago

That's not a complete sample test and your verbose output indicate that something else is going on. Also, can you please fix the formatting?

tsibiski commented 4 years ago

I'm sorry, I've tried everything to fix the formatting. I've googled to figure out why this is doing this. But it refuses to format that as code. Whether or not I put it inside the code "back tick" tags or not, it always renders like it does above.

I added the standard test logic around the example.

beatfactor commented 4 years ago

You can put any public url there.

Is that the default unmodified config? Are you able to reproduce it with the sample test?

tsibiski commented 4 years ago

I am able to reproduce it 100% no matter what, sample project with just that logic or not. This makes Nightwatch extremely limited use for me unfortunately.

tsibiski commented 4 years ago

So your API documentation shows that I need to pass functions into this method: https://nightwatchjs.org/api/execute.html#apimethod-page

In reality, it is only accepting a string with javascript, for example: browser.execute('window.scrollTo(0,document.body.scrollHeight);');

That works now.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had any recent activity. If possible, please retry using the latest Nightwatch version and update the issue with any relevant details. If no further activity occurs, it will be closed. Thank you for your contribution.