Is possible to reload page if at waitfor is not accepted - geb

Is possible to reload page if at waitfor is not accepted? I want to wait for status shows ok on static page but it require a reload of the page. is possible by Geb
Below pseudo example is to illustrate what I want:
class SomeStatusPage extends Page {
static at = {
waitFor {
satusDiv.displayed
if(!satusDivOK.displayed) {
tryReload() //The page is static, so try reload and if status went to ok
}
}
}
static content = {
satusDiv {$("div#status) }
satusDivOK {satusDiv.find(text: "status is ok") }
}
}

In Geb 2.2 refreshWaitFor() method was added which does exactly what you are asking for.

Related

defining page after issubmit

Im writting my first module in Prestashop. When I submit data in backoffice it loads the configuration page of my module. But I want to stay at the form. How can I achieve this?
if (Tools::isSubmit('toggleanswers')) {
$id_answer = Tools::getValue('id_answer');
if($this->toggleAnswer($id_answer)) {
$this->_html .= $this->displayConfirmation($this->l('Entry status changed'));
}
else {
$this->_html .= $this->displayError(implode($this->_errors, '<br />'));
}
}
This is how my function looks like. After Clicking on toggle it shouldn't return to configuration page... The url of my form looks like this: /index.php?controller=AdminModules&configure=questions&module_name=questions&id_question=1&updatequestions&token=ccd237618500f4c18f42d1a4fe971aa9
If I understand what do you want, you should change your code in this:
if (Tools::isSubmit('toggleanswers')) {
$id_answer = Tools::getValue('id_answer');
if($this->toggleAnswer($id_answer)) {
Tools::redirectAdmin($this->context->link->getAdminLink('AdminModules', true).'&conf=6&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name.'&id_question='.$id_question.'&update_questions');
}
else
{
$this->_html .= $this->displayError(implode($this->_errors, ''));
}
}
If you have managed good the post process and if is all ok you should redirected on the form of your 'question' with default message of changed status otherwise it will display the errors.

Geb Modules showing an error

I'm working on a geb page object with a repeating set of UI elements a div container with a text input and button within.
I am attempting the following:
class MyModule extends Module{
static content = {
textInput {$("input.editTextField")}
removeInputButton {$("button.removeButton")}
}
}
class MyPage extends Page{
static content = {
myInputs { index ->
$("div.container", index).module(MyModule)
}
}
In IntelliJ the code is highlighted in MyPage on ("div.container, index) when I hover over this I see "'$' in 'geb.Page' cannot be applied to '(java.lang.String.?)'
My goal is to be able pick an iteration of the UI and to perform something like:
myInputs(0).textInput = 'foo'
myInputs(1).textInput = 'bar'
myInputs(5).removeInputButton.click()
I've referred to the documentation for Geb but by all accounts this should work. Any help would be appreciated.
This will work, it's just that your code is not type safe enough for IntelliJ to know which method you're calling. If you change your content definition to:
myInputs { int index ->
$("div.container", index).module(MyModule)
}
then the warning will disappear.

How to run a server url in a Dojo DOH test

The Dojo DOH examples and tutorials do not seem to cover this case. I have a server url for which I want to write tests. I want the target page to show in the TestPage tab and then have multiple tests run against it. The closest example I could find is an html file that defines some tests and then a widget in the body, but I can't do that with a url over which I do not have control. I have done it with a page that fires the robot.init function, but I would like to use the test runner page.
I finally came up with this:
...
doh.register("login tests", [
{
name: "load",
timeout: 20000,
runTest: function(){
var d = new doh.Deferred();
testPage = dom.byId("testBody");
console.log("in load, testPage: " + testPage);
doh.showTestPage();
testPage.src = path;
robot.sequence(function() {
console.log("in load, sequence: ");
testpageBody = testPage.contentDocument.getElementsByTagName("body")[0];
console.log("in load, testpageBody: " + testpageBody);
var bdy = query(".headerFooterLoaded", testpageBody)[0];
console.log("in load, headerFooterLoaded: " + bdy);
if (!!bdy) {
d.callback(true);
} else {
d.errback(new Error("Node with class 'headerFooterLoaded' not found."));
}
}, 8000);
return d;
}
},
...
I tried to catch an iframe onload event, but had no luck.
Hope this helps someone

Mink: wait for page to load in #BeforeStep

I want to execute some javascript on page in #BeforeStep hook that depends on jQuery. However jQuery is not defined at that time, in fact page is blank.
Here's what I am trying to achive:
/**
* #BeforeStep #javascript
*/
public function registerAjaxEventHandlers()
{
$javascript = <<<JS
window.jQuery(document).ready(function () {
if (window.__ajaxStatus !== undefined) {
return;
}
window.__ajaxStatus = 'none';
$('body').ajaxStop(function() {
window.__ajaxStatus = 'idle';
});
$('body').ajaxStart(function() {
window.__ajaxStatus = 'in-flight';
});
});
JS;
//$this->getSession()->wait(5000, 'window.jQuery !== undefined');
$this->getSession()->executeScript($javascript);
}
I figured maybe I could wait for the page to load jQuery first (commented line), but it is not true. Seems like execution is halted until that hook is processed.
What is the right place in behat/mink ecosystem to execute javascript on page?
How about this?
$this->getSession()->wait(5000, 'typeof window.jQuery == "function"');
Your javascript is execute before the step, i.e. before the page is loaded. But if you load a page, all kinds of ondomload/pageload JavaScript will be firing already as well.
If you are happy to run it after the initial page, you can use #AfterStep like this:
/**
* #AfterStep
*/
public function set_selenium_css_selector (Behat\Behat\Event\StepEvent $event) {
$this->getSession()->wait(10, 'jQuery ("body").addClass ("selenium")');
}

Detecting browser print event

Is it possible to detect when a user is printing something from their browser?
To complicate matters, if we are presenting a user with a PDF document in a new window is it possible to detect the printing of that document ( assuming the user prints it from the browser window)?
The closest I've been able to find is if we implement custom print functionality (something like this) and track when that is invoked
I'm primarily interested in a solution that works for internet explorer (6 or later)
You can now detect a print request in IE 5+, Firefox 6+, Chrome 9+, and Safari 5+ using the following technique:
(function() {
var beforePrint = function() {
console.log('Functionality to run before printing.');
};
var afterPrint = function() {
console.log('Functionality to run after printing');
};
if (window.matchMedia) {
var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener(function(mql) {
if (mql.matches) {
beforePrint();
} else {
afterPrint();
}
});
}
window.onbeforeprint = beforePrint;
window.onafterprint = afterPrint;
}());
I go into more detail into what this is doing and what it can be used for at http://tjvantoll.com/2012/06/15/detecting-print-requests-with-javascript/.
For Internet Exploder, there are the events window.onbeforeprint and window.onafterprint but they don't work with any other browser and as a result they are usually useless.
They seem to work exactly the same for some reason, both executing their event handlers before the printing window opens.
But in case you want it anyway despite these caveats, here's an example:
window.onbeforeprint = function() {
alert("Printing shall commence!");
}
For anyone reading this on 2020.
The addListener function is mostly deprecated in favor of addEventListener except for Safari:
if (window.matchMedia) {
const media = window.matchMedia("print");
const myFunc = mediaQueryList => {
if (mediaQueryList.matches) {
doStuff();
}
};
try {
media.addEventListener("change", myFunc);
} catch (error) {
try {
media.addListener(myFunc);
} catch (error) {
console.debug('Error', error)
}
}
}
Reference: This other S.O question
If it's only for tracking purposes, perhaps you could set a background url in CSS print media to a server page (.aspx, .php, etc) and then do something on the server?
This guy claims it works.
This is not as versitile as TJ's solution, but it may be less buggy (see TJs blog post for issues he found) when only tracking is needed.