diff --git a/lib/behat/behat_base.php b/lib/behat/behat_base.php index 6c8b5de0dd6..52767038530 100644 --- a/lib/behat/behat_base.php +++ b/lib/behat/behat_base.php @@ -619,9 +619,10 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext { * - large: 2560x1600 * * @param string $windowsize size of window. + * @param bool $viewport If true, changes viewport rather than window size * @throws ExpectationException */ - protected function resize_window($windowsize) { + protected function resize_window($windowsize, $viewport = false) { // Non JS don't support resize window. if (!$this->running_javascript()) { return; @@ -649,6 +650,25 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext { $width = (int) $size[0]; $height = (int) $size[1]; } + if ($viewport) { + // When setting viewport size, we set it so that the document width will be exactly + // as specified, assuming that there is a vertical scrollbar. (In cases where there is + // no scrollbar it will be slightly wider. We presume this is rare and predictable.) + // The window inner height will be as specified, which means the available viewport will + // actually be smaller if there is a horizontal scrollbar. We assume that horizontal + // scrollbars are rare so this doesn't matter. + $offset = $this->getSession()->getDriver()->evaluateScript( + 'return (function() { var before = document.body.style.overflowY;' . + 'document.body.style.overflowY = "scroll";' . + 'var result = {};' . + 'result.x = window.outerWidth - document.body.offsetWidth;' . + 'result.y = window.outerHeight - window.innerHeight;' . + 'document.body.style.overflowY = before;' . + 'return result; })();'); + $width += $offset['x']; + $height += $offset['y']; + } + $this->getSession()->getDriver()->resizeWindow($width, $height); } diff --git a/lib/tests/behat/behat_general.php b/lib/tests/behat/behat_general.php index 46ce3ef9aea..47027a2a67c 100644 --- a/lib/tests/behat/behat_general.php +++ b/lib/tests/behat/behat_general.php @@ -1057,13 +1057,15 @@ class behat_general extends behat_base { * Change browser window size small: 640x480, medium: 1024x768, large: 2560x1600, custom: widthxheight * * Example: I change window size to "small" or I change window size to "1024x768" + * or I change viewport size to "800x600". The viewport option is useful to guarantee that the + * browser window has same viewport size even when you run Behat on multiple operating systems. * * @throws ExpectationException - * @Then /^I change window size to "(small|medium|large|\d+x\d+)"$/ + * @Then /^I change (window|viewport) size to "(small|medium|large|\d+x\d+)"$/ * @param string $windowsize size of the window (small|medium|large|wxh). */ - public function i_change_window_size_to($windowsize) { - $this->resize_window($windowsize); + public function i_change_window_size_to($windowviewport, $windowsize) { + $this->resize_window($windowsize, $windowviewport === 'viewport'); } /**