Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to specify new window type #833

Merged
merged 2 commits into from Nov 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
64 changes: 35 additions & 29 deletions lib/Remote/RemoteTargetLocator.php
Expand Up @@ -2,7 +2,7 @@

namespace Facebook\WebDriver\Remote;

use Facebook\WebDriver\WebDriver;
use Facebook\WebDriver\Exception\UnsupportedOperationException;
use Facebook\WebDriver\WebDriverAlert;
use Facebook\WebDriver\WebDriverElement;
use Facebook\WebDriver\WebDriverTargetLocator;
Expand All @@ -12,25 +12,22 @@
*/
class RemoteTargetLocator implements WebDriverTargetLocator
{
/** @var ExecuteMethod */
/** @var RemoteExecuteMethod */
protected $executor;
/** @var WebDriver */
/** @var RemoteWebDriver */
protected $driver;
/** @var bool */
protected $isW3cCompliant;

public function __construct($executor, $driver, $isW3cCompliant = false)
public function __construct(RemoteExecuteMethod $executor, RemoteWebDriver $driver, $isW3cCompliant = false)
{
$this->executor = $executor;
$this->driver = $driver;
$this->isW3cCompliant = $isW3cCompliant;
}

/**
* Set the current browsing context to the current top-level browsing context.
* This is the same as calling `RemoteTargetLocator::frame(null);`
*
* @return WebDriver The driver focused on the top window or the first frame.
* @return RemoteWebDriver
*/
public function defaultContent()
{
Expand All @@ -41,16 +38,10 @@ public function defaultContent()
}

/**
* Switch to the iframe by its id or name.
*
* @param WebDriverElement|null|int|string $frame The WebDriverElement,
* the id or the name of the frame.
* When null, switch to the current top-level browsing context
* When int, switch to the WindowProxy identified by the value
* When an Element, switch to that Element.
*
* @throws \InvalidArgumentException
* @return WebDriver The driver focused on the given frame.
* @param WebDriverElement|null|int|string $frame The WebDriverElement, the id or the name of the frame.
* When null, switch to the current top-level browsing context When int, switch to the WindowProxy identified
* by the value. When an Element, switch to that Element.
* @return RemoteWebDriver
*/
public function frame($frame)
{
Expand Down Expand Up @@ -87,7 +78,7 @@ public function frame($frame)
/**
* Switch to the parent iframe.
*
* @return WebDriver The driver focused on the given frame.
* @return RemoteWebDriver This driver focused on the parent frame
*/
public function parent()
{
Expand All @@ -97,11 +88,8 @@ public function parent()
}

/**
* Switch the focus to another window by its handle.
*
* @param string $handle The handle of the window to be focused on.
* @return WebDriver The driver focused on the given window.
* @see WebDriver::getWindowHandles
* @return RemoteWebDriver
*/
public function window($handle)
{
Expand All @@ -117,20 +105,38 @@ public function window($handle)
}

/**
* Switch to the currently active modal dialog for this particular driver
* instance.
* Creates a new browser window and switches the focus for future commands of this driver to the new window.
*
* @return WebDriverAlert
* @see https://w3c.github.io/webdriver/#new-window
* @param string $windowType The type of a new browser window that should be created. One of [tab, window].
* The created window is not guaranteed to be of the requested type; if the driver does not support the requested
* type, a new browser window will be created of whatever type the driver does support.
* @throws UnsupportedOperationException
* @return RemoteWebDriver This driver focused on the given window
*/
public function newWindow($windowType = self::WINDOW_TYPE_TAB)
{
if ($windowType !== self::WINDOW_TYPE_TAB && $windowType !== self::WINDOW_TYPE_WINDOW) {
throw new \InvalidArgumentException('Window type must by either "tab" or "window"');
}

if (!$this->isW3cCompliant) {
throw new UnsupportedOperationException('New window is only supported in W3C mode');
}

$response = $this->executor->execute(DriverCommand::NEW_WINDOW, ['type' => $windowType]);

$this->window($response['handle']);

return $this->driver;
}

public function alert()
{
return new WebDriverAlert($this->executor);
}

/**
* Switches to the element that currently has focus within the document
* currently "switched to", or the body element if this cannot be detected.
*
* @return RemoteWebElement
*/
public function activeElement()
Expand Down
16 changes: 4 additions & 12 deletions lib/Remote/RemoteWebDriver.php
Expand Up @@ -2,7 +2,6 @@

namespace Facebook\WebDriver\Remote;

use Facebook\WebDriver\Exception\UnsupportedOperationException;
use Facebook\WebDriver\Interactions\WebDriverActions;
use Facebook\WebDriver\JavaScriptExecutor;
use Facebook\WebDriver\WebDriver;
Expand Down Expand Up @@ -203,20 +202,13 @@ public function close()
/**
* Create a new top-level browsing context.
*
* @return RemoteWebDriver The current instance.
* @codeCoverageIgnore
* @deprecated Use $driver->switchTo()->newWindow()
* @return WebDriver The current instance.
*/
public function newWindow()
{
if (!$this->isW3cCompliant) {
throw new UnsupportedOperationException('New window is only supported in W3C mode');
}

$response = $this->execute(DriverCommand::NEW_WINDOW, []);
$handle = $response['handle'];

$this->switchTo()->window($handle);

return $this;
return $this->switchTo()->newWindow();
}

/**
Expand Down
30 changes: 20 additions & 10 deletions lib/WebDriverTargetLocator.php
Expand Up @@ -7,9 +7,14 @@
*/
interface WebDriverTargetLocator
{
/** @var string */
const WINDOW_TYPE_WINDOW = 'window';
/** @var string */
const WINDOW_TYPE_TAB = 'tab';

/**
* Switch to the main document if the page contains iframes. Otherwise, switch
* to the first frame on the page.
* Set the current browsing context to the current top-level browsing context.
* This is the same as calling `RemoteTargetLocator::frame(null);`
*
* @return WebDriver The driver focused on the top window or the first frame.
*/
Expand All @@ -18,17 +23,20 @@ public function defaultContent();
/**
* Switch to the iframe by its id or name.
*
* @param WebDriverElement|string $frame The WebDriverElement,
* the id or the name of the frame.
* @param WebDriverElement|null|int|string $frame The WebDriverElement, the id or the name of the frame.
* When null, switch to the current top-level browsing context When int, switch to the WindowProxy identified
* by the value. When an Element, switch to that Element.
*
* @throws \InvalidArgumentException
* @return WebDriver The driver focused on the given frame.
*/
public function frame($frame);

// TODO: Add in next major release (BC)
///**
// * Switch to the parent iframe.
// *
// * @todo Add in next major release (BC)
// * @return WebDriver The driver focused on the given frame.
// * @return WebDriver This driver focused on the parent frame
// */
//public function parent();

Expand All @@ -41,17 +49,19 @@ public function frame($frame);
*/
public function window($handle);

// TODO: Add in next major release (BC)
//public function newWindow($windowType = self::WINDOW_TYPE_TAB);

/**
* Switch to the currently active modal dialog for this particular driver
* instance.
* Switch to the currently active modal dialog for this particular driver instance.
*
* @return WebDriverAlert
*/
public function alert();

/**
* Switches to the element that currently has focus within the document
* currently "switched to", or the body element if this cannot be detected.
* Switches to the element that currently has focus within the document currently "switched to",
* or the body element if this cannot be detected.
*
* @return WebDriverElement
*/
Expand Down
34 changes: 34 additions & 0 deletions tests/functional/RemoteTargetLocatorTest.php
Expand Up @@ -111,6 +111,40 @@ public function testShouldSwitchToFrameByElement()
$this->compatAssertStringContainsString('This is the content of the iFrame', $this->driver->getPageSource());
}

/**
* @group exclude-saucelabs
* @covers ::window
*/
public function testShouldCreateNewWindow()
{
self::skipForJsonWireProtocol('Create new window is not supported in JsonWire protocol');

// Ensure that the initial context matches.
$initialHandle = $this->driver->getWindowHandle();
$this->driver->get($this->getTestPageUrl('index.html'));
$this->assertEquals($this->getTestPageUrl('index.html'), $this->driver->getCurrentUrl());
$source = $this->driver->getPageSource();
$this->compatAssertStringContainsString('<h1 id="welcome">', $source);
$this->compatAssertStringContainsString('Welcome to the php-webdriver testing page.', $source);
$windowHandles = $this->driver->getWindowHandles();
$this->assertCount(1, $windowHandles);

// Create a new window
$this->driver->switchTo()->newWindow();

$windowHandles = $this->driver->getWindowHandles();
$this->assertCount(2, $windowHandles);

$newWindowHandle = $this->driver->getWindowHandle();
$this->driver->get($this->getTestPageUrl('upload.html'));
$this->assertEquals($this->getTestPageUrl('upload.html'), $this->driver->getCurrentUrl());
$this->assertNotEquals($initialHandle, $newWindowHandle);

// Switch back to original context.
$this->driver->switchTo()->window($initialHandle);
$this->assertEquals($this->getTestPageUrl('index.html'), $this->driver->getCurrentUrl());
}

/**
* @group exclude-saucelabs
*/
Expand Down
34 changes: 0 additions & 34 deletions tests/functional/RemoteWebDriverTest.php
Expand Up @@ -47,40 +47,6 @@ public function testShouldGetPageSource()
$this->compatAssertStringContainsString('Welcome to the php-webdriver testing page.', $source);
}

/**
* @group exclude-saucelabs
* @covers ::window
*/
public function testShouldCreateNewWindow()
{
self::skipForJsonWireProtocol('Create new window is not supported in JsonWire protocol');

// Ensure that the initial context matches.
$initialHandle = $this->driver->getWindowHandle();
$this->driver->get($this->getTestPageUrl('index.html'));
$this->assertEquals($this->getTestPageUrl('index.html'), $this->driver->getCurrentUrl());
$source = $this->driver->getPageSource();
$this->compatAssertStringContainsString('<h1 id="welcome">', $source);
$this->compatAssertStringContainsString('Welcome to the php-webdriver testing page.', $source);
$windowHandles = $this->driver->getWindowHandles();
$this->assertCount(1, $windowHandles);

// Create a new window
$this->driver->newWindow();

$windowHandles = $this->driver->getWindowHandles();
$this->assertCount(2, $windowHandles);

$newWindowHandle = $this->driver->getWindowHandle();
$this->driver->get($this->getTestPageUrl('upload.html'));
$this->assertEquals($this->getTestPageUrl('upload.html'), $this->driver->getCurrentUrl());
$this->assertNotEquals($initialHandle, $newWindowHandle);

// Switch back to original context.
$this->driver->switchTo()->window($initialHandle);
$this->assertEquals($this->getTestPageUrl('index.html'), $this->driver->getCurrentUrl());
}

/**
* @covers ::getSessionID
* @covers ::isW3cCompliant
Expand Down