Skip to content

Instantly share code, notes, and snippets.

@netraagal
Last active October 22, 2022 17:56
Show Gist options
  • Save netraagal/0c8335c310293a3c211c0f8b5cf53b53 to your computer and use it in GitHub Desktop.
Save netraagal/0c8335c310293a3c211c0f8b5cf53b53 to your computer and use it in GitHub Desktop.
Behat, MinkExtension & Selenium2 Driver - move, create, delete window or tab (depends on your configurations)
<?php
/**
* some functions to create a new tab/window (it's up to your personal settings),
* to move between them (to the right, to the left or by it's number in the list of windows.
* You can also close the current window or close all (the first window will be open as if you
* close it, the Scenario will fails).
*
* I block the actual driver is not an instance of Selenium2 driver, but I don't really remember
* if it's an obligation :)
*
* @author netraagal
*/
namespace App\Features;
use Behat\Mink\Driver\Selenium2Driver;
class WindowFeatureContext extends MinkContext implements SnippetAcceptingContext
{
/**
* iOpenANewWindow
* I use directly count() without -1 because I have noticed the number is not
* updated directly (if I do count()-1 i will get the second latest)
*
* @When /^(?:|I )open a new (?:window|tab)$/
*
* @return FeatureContext
*/
public function iOpenANewWindow(): self
{
$driver = $this->getSession()->getDriver();
if (!$driver instanceof Selenium2Driver)
return $this;
$driver->executeScript("window.open('/','_blank');");
$this->iSwitchToTheWindow(count($driver->getWindowNames()), true);
return $this;
}
/**
* iOpenANewWindowUrl
*
* @When /^(?:|I )open (?:|a )new (?:window|tab) on "(?P<url>[^"]+)"$/
*
* @param string $url
* @return FeatureContext
*/
public function iOpenANewWindowUrl(string $url): self
{
$driver = $this->getSession()->getDriver();
if (!$driver instanceof Selenium2Driver)
return $this;
$driver->executeScript("window.open('".$url."','_blank');");
$this->iSwitchToTheWindow(count($driver->getWindowNames()), true);
return $this;
}
/**
* iSwitchToTheWindow
* the $internalFunction allows me to not be bothered by the problem I mention in the iOpenANewWindow function
* or if the user want to use a window which do not exists (less than 0 or more than the max of windows)
*
* @When /^(?:|I )switch to (?:|the )(?:window|tab) "(?P<nb>\d+)"$/
*
* @param int $nb
* @param bool $internalFunction
* @return FeatureContext
*/
public function iSwitchToTheWindow(int $nb, bool $internalFunction = false): self
{
$driver = $this->getSession()->getDriver();
if (!$driver instanceof Selenium2Driver)
return $this;
$windowNames = $driver->getWindowNames();
if (!$internalFunction && ( $nb < 0 || $nb >= count($windowNames) ) )
{
throw new \Exception(
sprintf(
"Error : index of window out of bounds, given '%b' but number of windows is '%b'",
$nb,
count($windowNames)
)
);
}
$driver->switchToWindow($windowNames[$nb-1]);
return $this;
}
/**
* iSwitchToTheLeftWindow
* if I am on the first window, as for any browser, I go to the last
*
* @When /^(?:|I )switch to (?:|the )left (?:window|tab)$/
*
* @return FeatureContext
*/
public function iSwitchToTheLeftWindow(): self
{
$driver = $this->getSession()->getDriver();
if (!$driver instanceof Selenium2Driver)
return $this;
$windowNames = $driver->getWindowNames();
$current_window = array_search($driver->getWindowName(), $windowNames);
if ($current_window === 0)
{
$driver->switchToWindow($windowNames[count($windowNames)-1]);
}
else {
$driver->switchToWindow($windowNames[$current_window-1]);
}
return $this;
}
/**
* iSwitchToTheRightWindow
* if I am on the last window, as for any browser, I go to the first
*
* @When /^(?:|I )switch to (?:|the )right (?:window|tab)$/
*
* @return FeatureContext
* @throws Exception
*/
public function iSwitchToTheRightWindow(): self
{
$driver = $this->getSession()->getDriver();
if (!$driver instanceof Selenium2Driver)
return $this;
$windowNames = $driver->getWindowNames();
$current_window = array_search($driver->getWindowName(), $windowNames);
if ($current_window === count($windowNames)-1)
{
$driver->switchToWindow(0);
}
else {
$driver->switchToWindow($windowNames[$current_window+1]);
}
return $this;
}
/**
* reloadTheCurrentWindow
*
* @When /^(?:|I )reload (?:|the )current (?:window|tab)$/
*
* @return FeatureContext
*/
public function reloadTheCurrentWindow(): self
{
if (!$this->getSession()->getDriver() instanceof Selenium2Driver)
return $this;
$this->getSession()->getDriver()->reload();
return $this;
}
/**
* iCloseTheCurrentWindow
*
* @When /^(?:|I )close (?:|the )current (?:window|tab)$/
*
* @return FeatureContext
*/
public function iCloseTheCurrentWindow(): self
{
if (!$this->getSession()->getDriver() instanceof Selenium2Driver)
return $this;
$this->getSession()->getDriver()->executeScript("window.open('','_self').close();");
return $this;
}
/**
* iCloseAllWindows
* warning : the first tab/window will always be open
* as the driver must have a page to be functional
*
* @When /^(?:|I )close all (?:|the )(?:windows|tabs)$/
*
* @return FeatureContext
*/
public function iCloseAllWindows(): self
{
if (!$this->getSession()->getDriver() instanceof Selenium2Driver)
return $this;
$windowNames = $this->getSession()->getDriver()->getWindowNames();
for ($i = count($windowNames); $i > 0; $i--)
{
$this->iSwitchToTheWindow($i, true);
$this->iCloseTheCurrentWindow();
$this->waitMilliseconds(500);
}
$this->iAmOnHomepage();
return $this;
}
}
@lilru
Copy link

lilru commented Jan 31, 2019

I, im interested in Closing a tab so I copied that part but, it closes Chrome window, not the only tab

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment