How do I fix the browser window size in Behat 3 / Mink? - behat

I want to run all my Behat/mink tests at a mobile display resolution. What would be really nice is to run all the tests with Chrome in dev tools mode where you can select "iPhone 5/SE" and so on to get a simulation of running on that device.
So, I tried to implement something like this myself by setting the display resolution in FeatureContext.
Here's an SO question on how to resize browser windows with Behat 2. And there's sample code for setting the window resolution in Behat/Mink/Drupal.
Based on these examples, I added the following code to my FeatureContext:
/**
* #BeforeScenario
*/
public function resizeWindow()
{
$this->getSession()->resizeWindow(100, 500, 'current');
}
However, I'm getting this error:
Fatal error: Call to a member function window() on null
(Behat\Testwork\Call\Exception\FatalThrowableError)
I also tried:
Using BeforeStep instead of BeforeScenario (result: same error)
Adding a step "I set the resolution to A x B" (result: I can resize the window in tests this way, but when I submit a form in a test, the screen resolution is reset; to fix this, I can add the step to set the resolution after each other step, but that is very inefficient)
I tried setting the window size as a chrome switch in behat.yml, but I couldn't get this to work either (the window size didn't change)
My goal: to force all tests to be executed under Chrome with a fixed window size

To do this in #BeforeScenario:
/**
* #BeforeScenario
*/
public function resizeWindow()
{
if ($this->getSession()->getDriver() instanceof Selenium2Driver) {
$this->getMink()->getSession()->start();
$this->getSession()->resizeWindow(100, 500, 'current');
}
}
To do this in #BeforeStep:
/**
* #BeforeStep
*/
public function resizeWindowStep()
{
$is_session = $this->getMink()->isSessionStarted();
if (!$is_session) {
$this->getMink()->getSession()->start();
}
$this->getSession()->resizeWindow(100, 500, 'current');
}

Related

I cannot open the webcam in p5.js

In p5js editor, I wanted to test the example called capture to turn on my webcam on my mac pro.
The code must be correct since I used the example that already existed, but the camera is not turning on and I do not know why.
the console says:
{
"constraintName": "",
"message": "",
"name": "InvalidStateError"
}
let capture;
function setup() {
createCanvas(390, 240);
capture = createCapture(VIDEO);
capture.size(320, 240);
//capture.hide();
}
function draw() {
background(255);
image(capture, 0, 0, 320, 240);
filter(INVERT);
}
Using the P5.js webcam feature requires the user to click "allow" before allowing the camera. This code executes on the P5.js web editor ( https://editor.p5js.org/ ). It looks like this :
If you want to execute the code locally, I would recommend using a Node Static Server or an editor with built-in capabilities of running a server locally. I personally use Brackets ( http://brackets.io/ ), which allows you to run HTML websites in a contained static node environment through Google Chrome. I tried executing this example on Brackets and it worked fine.

move mouse to position using geckodriver

I'm using intern testing with Selenium to automate the functional tests (link).
And we need to be able to run against multiple browsers. So we focused more on Chrome, but also we were able to run the tests against IE and Firefox, but after geckodriver was released and we switched to it, most of the tests that are implying mouse events are failing, for example when I'm calling moveMouseTo() I'm getting the following Exception:
Executing: [mousemove: 7 false])
WARN - Exception thrown
org.openqa.selenium.UnsupportedCommandException: mouseMoveTo
I've found a similar question about hovering on an element and I managed to make it work with intern by executing the code from moveMouseTo function like we had the mouse events broken, so I just commented that if related to brokenMouseEvents
//if (this.capabilities.brokenMouseEvents) {
if(element){
return element.getPosition().then(function(position){
return self.execute(simulateMouse, [ {
action: 'mousemove',
position: position,
element: element,
xOffset: xOffset,
yOffset: yOffset
} ]).then(function (newPosition) {
self._lastMousePosition = newPosition;
});
})
} else{
return self.execute(simulateMouse, [ {
action: 'mousemove',
position: self._lastMousePosition,
element: element,
xOffset: xOffset,
yOffset: yOffset
} ]).then(function (newPosition) {
self._lastMousePosition = newPosition;
});
}
//}
But doing this breaks the scrolling, since moveMouseTo() can be used also to scroll for an element and also we cannot use it since the moveMouseTo() function is defined in node modules, and it will fail when we try to run the tests in Jenkins.
Another idea, I think it will be to build a wrapper function to treat the case when we're running against Firefox, and in that case we should execute another code, and for the other browsers we can call moveMouseTo(), but in this case I'm not sure how to fix the scrolling issues.
Does anyone have any idea?
Thanks!
I think to move to an element you can use Actions class
Actions ac= new Actions(driver);
ac.movetoElement().build().preform();
Try this to move to an element:
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript(arguments[0].scrollIntoView();", webElement);

nightWatch resizeWindow sets different values on different browsers

module.exports = {
"resizeWindow" : function (browser) {
browser
.url("about:blank")
.waitForElementVisible("body", 1)
.resizeWindow(960, 600)
.execute(function(){
alert(document.body.clientWidth);
})
}
};
alert values:
internet explorer: 944
chrome: 944
firfefox: 946
It could at least all be the same
I also opened an issue on github: https://github.com/beatfactor/nightwatch/issues/377
any ideas ? :)
edit:
I found the problem is that selenium sets browser window width which unless maximized, has its frame and browser body width is always narrower than window width.
Any ideas how to set browser body width, not window width ?
If you know the difference between the window width and body width, you could write a custom command which takes the browser as an argument and resizes it based on the current browser environment.
I.e
exports.command = function() {
var browserName = this.options.desiredCapabilities.browserName;
if (browserName === 'firefox') {
this
.resizeWindow(974, 600)
}
// allows command to be chained
return this;
};
It's not the most elegant solution, but it should work. Add whatever other browsers you need, with the correct width + browserWidthOffset, and simply call it at the beginning of each test.

Browser How to maximize the browser automatically while playback

How to maximize the browser automatically while playback the web application script in rational functional tester(Rational Functional Tester)?
Simply call maximize() on the BrowserTestObject:
startApp("Google");
browser_htmlBrowser().maximize();
Or record the click on the maximize Button, which gives you:
browser_htmlBrowser(document_google(),DEFAULT_FLAGS).maximize();
The following code will find the open browsers and maximize the ones found
void maximizeBrowsers()
{
TestObject[] browsers = find(atChild(".class","Html.HtmlBrowser"));
System.out.println("Browsers found : "+ browsers.length);
for(TestObject browser:browsers)
{
//add addional check if required to get to the right browser
((BrowserTestObject)browser).maximize();
}
unregister(browsers);
}
startBrowser("Internet Explorer","www.google.com");
browser_htmlBrowser().click();

Chrome WebDriver hungs when currently selected frame closed

I am working on creation of automated test for some Web Application. This application is very complex. In fact it is text editor for specific content. As a part of functionality it has some pop-up frames. You may open this pop-up? make some changes and save them - closing current frame. May problem is in that fact, that close button situated inside frame will be eliminating. And this force Chrome WebDriver to hung. My first try was like this:
driver.findElement(By.xpath("//input[#id='insert']")).click();
driver.switchTo().defaultContent();
But it hungs on first line after executinh click command as this command close frame.
Then I change to this(I have JQuery on the page):
driver.executeScript("$(\"input#insert\").click()");
driver.switchTo().defaultContent();
But this leads to same result.
Then I use this solution:
driver.executeScript("setTimeout(function(){$(\"input#insert\").click()}, 10)");
driver.switchTo().defaultContent();
And it hungs on second line. Only this solution works:
driver.executeScript("setTimeout(function(){$(\"input#insert\").click()}, 100)");
driver.switchTo().defaultContent();
but only if you don't take into account, that it is unstable - some timing issue may occur.
So may question is there more cleaner and more stable way for switch out from closed frame?
P.S.: executeScript - self defined function to decrease amount of code. It simply executer some js on page.
Update:
I realized I was wrong. This problem is not for all iframes. It's occur when tinyMCE popup used. Situation is exactly like in this topic. So it's doubtful I will find answer here, but who knows. Solution described above will help, but only for very short amount of time, meaning that after several seconds pass chromedriver will hangs on next command.
This is how i would do it in Ruby, hopefully you can change it for java
$driver.find_element(:xpath, "//input[#id='insert']").click
$wait.until {$driver.window_handles.size < 2} #this will "explicitly wait" for the window to close
handles = $driver.window_handles #get available window handles
$driver.switch_to.window(handles[0]) #navigate to default in this case the First window handle
hope this helps
Problem was in this line of tinyMCEPopup code:
DOM.setAttrib(id + '_ifr', 'src', 'javascript:""'); // Prevent leak
Executing this script on page fix hang problem(but possibly creates leaks :) ):
(function() {
var domVar;
if (window.tinymce && window.tinymce.DOM) {
domVar = window.tinymce.DOM
}
else if (window.tinyMCE && window.tinyMCE.DOM) {
domVar = window.tinyMCE.DOM
}
else {
return;
}
var tempVar = domVar.setAttrib;console.log(123)
domVar.setAttrib = function(id, attr, val) {
if (attr == 'src' && typeof(val)== 'string' &&(val + "").trim().match(/javascript\s*:\s*("\s*"|'\s*')/)) {
console.log("Cool");
return;
}
else {
tempVar.apply(this, arguments);
}
}
}());
Bug and solution also described here
Note. Code above should be added to parent frame, not into popup frame.