Passing variable into page.evaluate - PhantomJS - phantomjs

Is it possible to pass variables in a page.evaluate in my case below?
function myFunction(webpage, arg1, arg2){
var page = require('webpage').create();
page.viewportSize = { width: 1920, height: 1080 };
page.open(webpage, function (status){
if (status == 'success') {
page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js", function(){
page.evaluate(function(){
arg = arg1 + arg2;
console.log(arg);
});
});
}
else { phantom.exit(); }
});
}
I tried several methods found on the internet but nothing actually impossible to get to its variables.
Thank you in advance for your help :)

As usual, the answer is clearly stated in the documentation of evaluate function:
As of PhantomJS 1.6, JSON-serializable arguments can be passed to the function. In the following example, the text value of a DOM element is extracted. The following example achieves the same end goal as the previous example but the element is chosen based on a selector which is passed to the evaluate call:
The example that follows demonstrates the usage:
var title = page.evaluate(function(s) {
return document.querySelector(s).innerText;
}, 'title');
console.log(title);

I have phantomjs 1.5.0, so instead of compiling 1.6 or higher version I went for an alternative solution:
So I've saved arguments to selectors.js file
-------------selectors.js starts----------------
var selectors = "div.nice"
-------------selectors.js ends----------------
and then injected them into the page:
page.injectJs("selectors.js");
More details can be found here: http://phantomjs.org/api/webpage/method/inject-js.html

I use phantom 4.0.4, below works for me, https://www.npmjs.com/package/phantom
var arg = 'test'
page.evaluate(function(arg) {
console.log(arg)
}, arg);

Related

how to use dynamic assertion method name?

Let's say I have this in a test:
await t.expect(Selector('input')).ok()
And I would like to have (something like) this:
let func = 'ok';
await t.expect(Selector('input'))[func]()
This is so that I can have a map from selector to function, in order to iterate
over it and check whether some elements are in the page (ok) and some not (notOk).
My above attempt does not work and returns with an interesting error:
code: 'E1035',
data: [
'SyntaxError: test.js: await is a reserved word (325:14)'
]
I believe this is because Testcafe is doing some magic under the hood.
What would be the correct syntax to make it work?
It seems that you skipped the Selector property that you want to check (e.g. exists, visible, textContent, etc.). The following test example works properly with TestCafe v1.14.2:
import { Selector } from 'testcafe';
fixture`A set of examples that illustrate how to use TestCafe API`
.page`http://devexpress.github.io/testcafe/example/`;
const developerName = Selector('#developer-name');
const submitButton = Selector('#submit-button');
test('New Test', async t => {
await t
.typeText(developerName, 'Peter Parker')
.click(submitButton);
let assertFunc = 'ok';
await t.expect(Selector('#article-header').exists)[assertFunc]();
});

Protractor how to wait until browser.get to a url

await browser.wait(function() {
return browser.getCurrentUrl().then(function(url) {
return `cars/detail.aspx${browser.baseUrl}`;
});
}, 5000, "url err");
How do I make protractor wait until cars/detail.aspx${browser.baseUrl} is loaded?
I think you can use the urlContains expected condition in protractor to wait until the url contains something specific. You can refer to the documentation here.
I'm using this method, maybe it will be helpful
export function waitForUrlContains(url: string, customTimeout: number = E2E_TIMEOUT) {
return browser.getCurrentUrl().then(myUrl => {
return browser.wait(protractor.ExpectedConditions.urlContains(url), customTimeout, `URL do not contain: ${url}, and is: ${myUrl}`);
});
}
You can read the Protractor's API documentation for further information on different ways of waiting for an element (url in this case) https://www.protractortest.org/#/api
You have 2 ways actually:
const EC = protractor.ExpectedConditions;
const myUrl = 'cars/detail.aspx${browser.baseUrl}';
then:
return browser.wait(EC.urlIs(myUrl));
OR
return browser.wait(EC.urlContains(myUrl));

Using Babel with PhantomJS, evaluate function being executed in browser context doesn't have access to helper functions

I'm trying to use PhantomJS with a script that's compiled by Babel from ES6 to ES5.
For some of the features, Babel puts in some helper functions at the end of the file (like _asyncToGenerator and _typeof) to evaluate the code.
But in Phantom, there's a function evaluate(function(){…}) which is executed in the browser context, so it doesn't have access to those helper functions babel puts in.
Ex, if I have a code:
var page = require('webpage').create();
page.open(url, function(status) {
var title = page.evaluate(function() {
typeof(document.title);
});
});
It compiles to
var page = require('webpage').create();
page.open(url, function(status) {
var title = page.evaluate(function Executed_in_Browser_Context() {
_typeof(document.title);
});
});
function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; }
Notice the typeof has been changed to _typeof (for some feature involving ES6 Symbols)
Here, the function Executed_in_Browser_Context is executed in browser context, and so it doesn't have access to the function _typeof defined in the file at the bottom. And so it results in error
Can't find variable: _typeof
How to solve this?
I tried copying the _typeof inside Executed_in_Browser_Context (pre-compilation) but then upon compiling, Babel sees that and thinks that it may be some other function that I have in my code, and just renames its own to _typeof2 resulting in same error.

phantomjs global variables call in page.evaluate

I want to know how to use a varaible globally in phantomjs so that it can be used in the page.evaluate function also.
I have gone through some previous answers but but able to understand well
JSON-serializable arguments can be passed to page.evaluate.
Here is a very basic the following example using this technique :
page.open('http://stackoverflow.com/', function(status) {
var title = page.evaluate(function(s) {
return document.querySelector(s).innerText;
}, 'title');
console.log(title);
phantom.exit();
});

dojo - programmatic way to show invalid message

dojo newbie - giving it a shot.
After submitting a form, If an error is returned from the server I would like to show that message on the dijit.form.ValidationTextBox
var user_email = dijit.byId("login_user_email");
user_email.set("invalidMessage", data["result"]["user_email"]);
//need to force show the tooltip but how???
Any help much appreciated.
See it in action at jsFiddle.
Just show tooltip:
var textBox = bijit.byId("validationTextBox");
dijit.showTooltip(
textBox.get("invalidMessage"),
textBox.domNode,
textBox.get("tooltipPosition"),
!textBox.isLeftToRight()
);
Temporarily switch textBox validator, force validation, restore the original validator:
var originalValidator = textBox.validator;
textBox.validator = function() {return false;}
textBox.validate();
textBox.validator = originalValidator;
Or do both at once.
I think you can show the tooltip via myVTB.displayMessage('this is coming from back end validation'); method
you need to do the validation in the validator-method. like here http://docs.dojocampus.org/dijit/form/ValidationTextBox-tricks
you also need to focus the widget to show up the message! dijit.byId("whatever").focus()
#arber solution is the best when using the new dojo. Just remember to set the focus to the TextBox before calling the "displayMessage" method.
I am using dojo 1.10 which works create as follows:
function showCustomMessage(textBox, message){
textBox.focus();
textBox.set("state", "Error");
textBox.displayMessage(message);
}
Dojo reference guid for ValidationTextBox: https://dojotoolkit.org/reference-guide/1.10/dijit/form/ValidationTextBox.html
I know this question is ancient, but hopefully this'll help someone. Yes, you should use validators, but if you have a reason not to, this will display the message and invalidate the field:
function(textbox, state /*"Error", "Incomplete", ""*/, message) {
textbox.focus();
textbox.set("state", state);
textbox.set("message", message);
}
You can call directly the "private" function:
textBox._set('state', 'Error');
You get the same result as #phusick suggested but with less code and arguably in a more direct and clean way.
Notes:
_set is available to ValidationTextBox as declared on its base class dijit/_WidgetBase.
Live demo:
http://jsfiddle.net/gibbok/kas7aopq/
dojo.require("dijit.form.Button");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.Tooltip");
dojo.ready(function() {
var textBox = dijit.byId("validationTextBox");
dojo.connect(dijit.byId("tooltipBtn"), "onClick", function() {
dijit.showTooltip(
textBox.get('invalidMessage'),
textBox.domNode,
textBox.get('tooltipPosition'), !textBox.isLeftToRight()
);
});
dojo.connect(dijit.byId("validatorBtn"), "onClick", function() {
// call the internal function which set the widget as in error state
textBox._set('state', 'Error');
/*
code not necessary
var originalValidator = textBox.validator;
textBox.validator = function() {return false;}
textBox.validate();
textBox.validator = originalValidator;
*/
});
});