8000 executeJS outside scope · Issue #429 · gemini-testing/gemini · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Sep 21, 2022. It is now read-only.
This repository was archived by the owner on Sep 21, 2022. It is now read-only.

executeJS outside scope #429

Closed
Closed

Description

Is it possible to pass any other arguments than window to 'executeJS(function(window))' ?
I would like to inject Redux state, but don't know if it is possible with Gemini (and I would like to avoid pasting it directly inside the function, because it contains ~3000 LOC).

Activity

  1. sipayRT commented on May 30, 2016

    @sipayRT
    Member

    hi. no, you can't do it throw API. But there is another variant. @eGavr can you show your variant here?

  2. rhoog commented on Jun 23, 2016

    @rhoog

    I just hit the same problem. Currently I've solved it using the piece of code below. It's a bit hacky though and it's quite possible that the code can be improved upon.

    getOptions = function (options) {
        var defaultOptions = {
            "env": 'prod',
        };
        return Object.assign(defaultOptions, options || {});
    }
    
    loadTest = function (window) {
        window.loadJSFunction( /* REPLACEME */ );
    }
    
    /*
     **  Copied from https://github.com/gemini-testing/gemini/blob/master/lib/tests-api/actions-builder.js and modified to accept dynamic options
     */
    function serializeFunc(func, options) {
        return '(' + func.toString().replace('/* REPLACEME */', JSON.stringify(options)) + '(window));';
    }
    
    /*
     **  Copied from https://github.com/gemini-testing/gemini/blob/master/lib/tests-api/actions-builder.js and modified to accept dynamic options
     */
    myExecuteJS = function (callback, options) {
        if (typeof callback !== 'function') {
            throw new TypeError('executeJS argument should be function');
        }
    
        this._pushAction(this.executeJS, function executeJS(browser) {
            return browser.execute(serializeFunc(callback, options));
        });
        return this;
    };
    
    gemini.suite('firsttest', function (suite) {
        suite.setUrl('/test.html')
            .setCaptureElements(['#testContainer']);
    
        gemini.suite('fullpage', function (suite) {
            suite.before(function (actions, find) {
                    actions.executeJS = myExecuteJS;
                    actions.executeJS(loadTest, getOptions({
                        "env": "test"
                    }));
                    actions.wait(1000);
                })
                .capture('test');
        })
    })
  3. eGavr commented on Jun 23, 2016

    @eGavr
    Contributor

    @Pszek @rhoog

    As @sipayRT has said there is no a straight way to pass any other arguments to method executeJS, but we are using the next hack to make closure work in this method:

    var format = require('util').format;
    
    /**
     * Helper which supports closure in callback of method '.executeJS'
     *
     * @param {Function} fn – callback of method '.executeJS'
     * @param {Object} vars – variables to be injected
     */
    exports.executeJsInjector = function(fn, vars) {
        var varsToExport = Object.keys(vars)
            .map(function(v) {
                return format('var %s = "%s";', v, vars[v]);
            })
            .join('\n');
    
        return new Function([
            varsToExport,
            format('(%s)(window)', fn.toString())
        ].join('\n'));
    };

    This hack can be used like this:

    actions
      .click('.ololo')
      .executeJS(executeJsInjector(moveCaretToTheEnd, {controlSelector: controlSelector}));

    where controlSelector is the variable which will be injected to function moveCaretToTheEnd. And function moveCaretToTheEnd will be passed as a callback to method executeJS.

  4. ghost closed this as completedon Jun 25, 2016
  5. ThaneshR commented on Mar 21, 2017

    @ThaneshR

    Both approaches look real hacky. Will the actions.executeJS be updated to allow external functions to be passed in?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0