WWW-Mechanize-PhantomJS

 view release on metacpan or  search on metacpan

lib/WWW/Mechanize/PhantomJS/ghostdriver/request_handlers/webelement_request_handler.js  view on Meta::CPAN

        interactableRes = JSON.parse(interactableRes);
        if (interactableRes && interactableRes.status !== 0) {
            return interactableRes;
        }

        if (!interactableRes.value) {
            return {
                status: _errors.FAILED_CMD_STATUS_CODES.ElementNotVisible,
                value: {message: "Element is not displayed"}
            };
        }

        coords = _getPosition();
        if (coords && coords.status !== 0) {
            return coords;
        }
        _session.inputs.mouseMove(_session, coords);
        _session.inputs.mouseButtonClick(_session, "click", "left");
        _log.debug("Click at: " + JSON.stringify(coords));

        return {status: 0, value: null};
    },

    _normalizeSpecialChars = function(str) {
        var resultStr = "",
            i, ilen;

        for(i = 0, ilen = str.length; i < ilen; ++i) {
            switch(str[i]) {
                case '\b':
                    resultStr += '\uE003';  //< Backspace
                    break;
                case '\t':
                    resultStr += '\uE004';  // Tab
                    break;
                case '\r':
                    resultStr += '\uE006';  // Return
                    if (str.length > i+1 && str[i+1] === '\n') {    //< Return on Windows
                        ++i; //< skip the next '\n'
                    }
                    break;
                case '\n':
                    resultStr += '\uE007';  // Enter
                    break;
                default:
                    resultStr += str[i];
                    break;
            }
        }

        return resultStr;
    },

    _postValueCommand = function(req, res) {
        var postObj = JSON.parse(req.post),
            currWindow = _protoParent.getSessionCurrWindow.call(this, _session, req),
            typeRes,
            text,
            isFileInputRes,
            isContentEditableRes,
            fsModule = require("fs"),
            abortCallback = false,
            multiFileText;

        isFileInputRes = currWindow.evaluate(require("./webdriver_atoms.js").get("is_file_input"), _getJSON());
        isFileInputRes = JSON.parse(isFileInputRes);
        if (isFileInputRes && isFileInputRes.status !== 0) {
            res.respondBasedOnResult(_session, req, isFileInputRes);
            return;
        }

        // Ensure all required parameters are available
        if (typeof(postObj) === "object" && typeof(postObj.value) === "object") {
            // Normalize input: some binding might send an array of single characters
            text = postObj.value.join("");

            // Detect if it's an Input File type (that requires special behaviour), and the File actually exists
            if (isFileInputRes.value) {

                // split files by \n like chromedriver
                multiFileText = text.split("\n");

                // abort if file does not exist
                for (var i = 0; i < multiFileText.length; ++i) {
                    if (!fsModule.exists(multiFileText[i])) {
                        _log.debug("File does not exist: " + multiFileText[i]);
                        res.success(_session.getId());
                        return;
                    }
                }

                // this indirectly clicks on the head element
                // hack to workaround phantomjs uploadFile api which requires a selector
                currWindow.uploadFile("head", multiFileText);

                // Click on the element!
                typeRes = _nativeClick();
                res.respondBasedOnResult(_session, req, typeRes);
                return;

            } else {
                // Normalize for special characters
                text = _normalizeSpecialChars(text);

                // Execute the "type" atom on an empty string only to force focus to the element.
                // TODO: This is a hack that needs to be corrected with a proper method to set focus.
                isContentEditableRes = currWindow.evaluate(require("./webdriver_atoms.js").get("is_content_editable"), _getJSON());
                isContentEditableRes = JSON.parse(isContentEditableRes);
                if (isContentEditableRes && isContentEditableRes.status !== 0) {
                    res.respondBasedOnResult(_session, req, isContentEditableRes);
                    return;
                }
                if (isContentEditableRes.value) {
                    // must use native click to focus on content editable element
                    typeRes = _nativeClick();
                } else {
                    typeRes = currWindow.evaluate(require("./webdriver_atoms.js").get("type"), _getJSON(), "");
                    typeRes = JSON.parse(typeRes);
                }

                if (typeRes && typeRes.status !== 0) {
                    abortCallback = true;           //< handling the error here
                    res.respondBasedOnResult(_session, req, typeRes);
                    return;
                }

                currWindow.execFuncAndWaitForLoad(function() {

                        // Send keys to the page, using Native Events
                        _session.inputs.sendKeys(_session, text);

                        // Only clear the modifier keys if this was called using element.sendKeys().
                        // Calling this from the Advanced Interactions API doesn't clear the modifier keys.
                        if (req.urlParsed.file === _const.VALUE) {
                            _session.inputs.clearModifierKeys(_session);
                        }
                    },
                    function(status) {                   //< onLoadFinished
                        // Report Load Finished, only if callbacks were not "aborted"
                        if (!abortCallback) {
                            res.success(_session.getId());
                        }
                    },
                    function(errMsg) {
                        var errCode = errMsg === "timeout"
                            ? _errors.FAILED_CMD_STATUS_CODES.Timeout
                            : _errors.FAILED_CMD_STATUS_CODES.UnknownError;

                        // Report Load Error, only if callbacks were not "aborted"
                        if (!abortCallback) {
                            _errors.handleFailedCommandEH(errCode, "Pageload initiated by click failed. Cause: " + errMsg, req, res, _session);
                        }
                    });
            }
            return;
        }

        throw _errors.createInvalidReqMissingCommandParameterEH(req);
    },

    _getNameCommand = function(req, res) {
        var result = JSON.parse(_protoParent.getSessionCurrWindow.call(this, _session, req).evaluate(
                require("./webdriver_atoms.js").get("get_name"),
                _getJSON()));

        res.respondBasedOnResult(_session, req, result);
    },

    _getAttributeCommand = function(req, res) {
        var attributeValueAtom = require("./webdriver_atoms.js").get("get_attribute_value"),
            result;

        if (typeof(req.urlParsed.file) === "string" && req.urlParsed.file.length > 0) {
            // Read the attribute
            result = _protoParent.getSessionCurrWindow.call(this, _session, req).evaluate(
                attributeValueAtom,     // < Atom to read an attribute
                _getJSON(),             // < Element to read from
                req.urlParsed.file);    // < Attribute to read

            res.respondBasedOnResult(_session, req, result);
            return;
        }

        throw _errors.createInvalidReqMissingCommandParameterEH(req);
    },

    _getTextCommand = function(req, res) {
        var result = _protoParent.getSessionCurrWindow.call(this, _session, req).evaluate(
            require("./webdriver_atoms.js").get("get_text"),
            _getJSON());
        res.respondBasedOnResult(_session, req, result);
    },

    _getEqualsCommand = function(req, res) {
        var result;

        if (typeof(req.urlParsed.file) === "string" && req.urlParsed.file.length > 0) {
            result = JSON.parse(_protoParent.getSessionCurrWindow.call(this, _session, req).evaluate(
                require("./webdriver_atoms.js").get("equals"),
                _getJSON(), _getJSON(req.urlParsed.file)));

            res.respondBasedOnResult(_session, req, result);
            return;
        }

        throw _errors.createInvalidReqMissingCommandParameterEH(req);
    },

    _postSubmitCommand = function(req, res) {
        var currWindow = _protoParent.getSessionCurrWindow.call(this, _session, req),
            submitRes,
            abortCallback = false;

        currWindow.execFuncAndWaitForLoad(function() {
                // do the submit
                submitRes = currWindow.evaluate(require("./webdriver_atoms.js").get("submit"), _getJSON());

                // If Submit was NOT positive, status will be set to something else than '0'
                submitRes = JSON.parse(submitRes);
                if (submitRes && submitRes.status !== 0) {
                    abortCallback = true;           //< handling the error here
                    res.respondBasedOnResult(_session, req, submitRes);
                }
            },
            function(status) {                   //< onLoadFinished
                // Report about the Load, only if it was not already handled
                if (!abortCallback) {
                    res.success(_session.getId());
                }
            },

lib/WWW/Mechanize/PhantomJS/ghostdriver/request_handlers/webelement_request_handler.js  view on Meta::CPAN


                // If Click was NOT positive, status will be set to something else than '0'
                clickRes = JSON.parse(clickRes);
                if (clickRes && clickRes.status !== 0) {
                    abortCallback = true;           //< handling the error here
                    res.respondBasedOnResult(_session, req, clickRes);
                }
            },
            function(status) {                   //< onLoadFinished
                // Report Load Finished, only if callbacks were not "aborted"
                if (!abortCallback) {
                    res.success(_session.getId());
                }
            },
            function(errMsg) {
                var errCode = errMsg === "timeout"
                    ? _errors.FAILED_CMD_STATUS_CODES.Timeout
                    : _errors.FAILED_CMD_STATUS_CODES.UnknownError;

                // Report Load Error, only if callbacks were not "aborted"
                if (!abortCallback) {
                    _errors.handleFailedCommandEH(errCode, "Pageload initiated by click failed. Cause: " + errMsg, req, res, _session);
                }
            });
    },

    _getSelectedCommand = function(req, res) {
        var result = JSON.parse(_protoParent.getSessionCurrWindow.call(this, _session, req).evaluate(
                require("./webdriver_atoms.js").get("is_selected"),
                _getJSON()));

        res.respondBasedOnResult(_session, req, result);
    },

    _postClearCommand = function(req, res) {
        var result = _protoParent.getSessionCurrWindow.call(this, _session, req).evaluate(
                require("./webdriver_atoms.js").get("clear"),
                _getJSON());
        res.respondBasedOnResult(_session, req, result);
    },

    _getCssCommand = function(req, res) {
        var cssPropertyName = req.urlParsed.file,
            result;

        // Check that a property name was indeed provided
        if (typeof(cssPropertyName) === "string" || cssPropertyName.length > 0) {
            result = _protoParent.getSessionCurrWindow.call(this, _session, req).evaluate(
                require("./webdriver_atoms.js").get("get_value_of_css_property"),
                _getJSON(),
                cssPropertyName);

            res.respondBasedOnResult(_session, req, result);
            return;
        }

        throw _errors.createInvalidReqMissingCommandParameterEH(req);
    },

    _getAttribute = function(currWindow, attributeName) {
        var attributeValueAtom = require("./webdriver_atoms.js").get("get_attribute_value"),
            result = currWindow.evaluate(
                attributeValueAtom, // < Atom to read an attribute
                _getJSON(),         // < Element to read from
                attributeName);     // < Attribute to read

        return JSON.parse(result).value;
    },


    /**
     * This method can generate any Element JSON: just provide an ID.
     * Will return the one of the current Element if no ID is provided.
     * @param elementId ID of the Element to describe in JSON format,
     *      or undefined to get the one fo the current Element.
     */
    _getJSON = function(elementId) {
        return {
            "ELEMENT" : elementId || _getId()
        };
    },

    _getId = function() {
        return _id;
    },
    _getSession = function() {
        return _session;
    };

    // public:
    return {
        handle : _handle,
        getId : _getId,
        getJSON : _getJSON,
        getSession : _getSession,
        postValueCommand : _postValueCommand,
        getLocation : _getLocation,
        getLocationInView: _getLocationInView,
        getSize: _getSize
    };
};
// prototype inheritance:
ghostdriver.WebElementReqHand.prototype = new ghostdriver.RequestHandler();



( run in 0.447 second using v1.01-cache-2.11-cpan-39bf76dae61 )