Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.

Commit 648f6ed

Browse files
andrewnicolsOndraM
authored andcommitted
Frame switching W3C Compliance
This change updates the frame functionality to comply with the W3C specification. Valid values of the `id` parameter are: - null - a Number between 0 and 2^16 - an Object representing a Web element When the value is null, set the current browsing context to the current top-level browsing context When the value is a valid Number, let window be the associated window of the current browsing context’s active document. When the value is an Object, let element be the result of trying to get a known element by web element reference id. Source: https://www.w3.org/TR/webdriver/#switch-to-frame
1 parent 1dcec4b commit 648f6ed

File tree

4 files changed

+122
-4
lines changed

4 files changed

+122
-4
lines changed

lib/Remote/RemoteTargetLocator.php

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,39 @@ public function defaultContent()
6262
/**
6363
* Switch to the iframe by its id or name.
6464
*
65-
* @param WebDriverElement|string $frame The WebDriverElement,
65+
* @param WebDriverElement|null|int|string $frame The WebDriverElement,
6666
* the id or the name of the frame.
67+
* When null, switch to the current top-level browsing context
68+
* When int, switch to the WindowProxy identified by the value
69+
* When an Element, switch to that Element.
70+
*
71+
* @throws \InvalidArgumentException
6772
* @return WebDriver The driver focused on the given frame.
6873
*/
6974
public function frame($frame)
7075
{
71-
if ($frame instanceof WebDriverElement) {
72-
$id = ['ELEMENT' => $frame->getID()];
76+
if ($this->isW3cCompliant) {
77+
if ($frame instanceof WebDriverElement) {
78+
$id = [JsonWireCompat::WEB_DRIVER_ELEMENT_IDENTIFIER => $frame->getID()];
79+
} elseif ($frame === null) {
80+
$id = null;
81+
} elseif (is_int($frame)) {
82+
$id = $frame;
83+
} else {
84+
throw new \InvalidArgumentException(
85+
'In W3C compliance mode frame must be either instance of WebDriverElement, integer or null'
86+
);
87+
}
7388
} else {
74-
$id = (string) $frame;
89+
if ($frame instanceof WebDriverElement) {
90+
$id = ['ELEMENT' => $frame->getID()];
91+
} elseif ($frame === null) {
92+
$id = null;
93+
} elseif (is_int($frame)) {
94+
$id = $frame;
95+
} else {
96+
$id = (string) $frame;
97+
}
7598
}
7699

77100
$params = ['id' => $id];

tests/functional/RemoteTargetLocatorTest.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,76 @@ public function testActiveElement()
7171
$this->assertSame('input', $activeElement->getTagName());
7272
$this->assertSame('test_name', $activeElement->getAttribute('name'));
7373
}
74+
75+
/**
76+
* @cover ::frame
77+
*/
78+
public function testShouldSwitchToFrameByItsId()
79+
{
80+
$parentPage = 'This is the host page which contains an iFrame';
81+
$firstChildFrame = 'This is the content of the iFrame';
82+
$secondChildFrame = 'open new window';
83+
84+
$this->driver->get($this->getTestPageUrl('page_with_frame.html'));
85+
86+
$this->assertContains($parentPage, $this->driver->getPageSource());
87+
88+
$this->driver->switchTo()->frame(0);
89+
$this->assertContains($firstChildFrame, $this->driver->getPageSource());
90+
91+
$this->driver->switchTo()->frame(null);
92+
$this->assertContains($parentPage, $this->driver->getPageSource());
93+
94+
$this->driver->switchTo()->frame(1);
95+
$this->assertContains($secondChildFrame, $this->driver->getPageSource());
96+
97+
$this->driver->switchTo()->frame(null);
98+
$this->assertContains($parentPage, $this->driver->getPageSource());
99+
}
100+
101+
/**
102+
* @cover ::frame
103+
*/
104+
public function testShouldSwitchToFrameByElement()
105+
{
106+
$this->driver->get($this->getTestPageUrl('page_with_frame.html'));
107+
108+
$element = $this->driver->findElement(WebDriverBy::id('iframe_content'));
109+
$this->driver->switchTo()->frame($element);
110+
111+
$this->assertContains('This is the content of the iFrame', $this->driver->getPageSource());
112+
}
113+
114+
/**
115+
* @cover ::frame
116+
* @group exclude-saucelabs
117+
*/
118+
public function testShouldNotAcceptStringAsFrameIdInW3cMode()
119+
{
120+
self::skipForJsonWireProtocol();
121+
122+
$this->driver->get($this->getTestPageUrl('page_with_frame.html'));
123+
124+
$this->expectException(\InvalidArgumentException::class);
125+
$this->expectExceptionMessage(
126+
'In W3C compliance mode frame must be either instance of WebDriverElement, integer or null'
127+
);
128+
129+
$this->driver->switchTo()->frame('iframe_content');
130+
}
131+
132+
/**
133+
* @cover ::frame
134+
* @group exclude-saucelabs
135+
*/
136+
public function testShouldAcceptStringAsFrameIdInJsonWireMode()
137+
{
138+
self::skipForW3cProtocol();
139+
140+
$this->driver->get($this->getTestPageUrl('page_with_frame.html'));
141+
142+
$this->driver->switchTo()->frame('iframe_content');
143+
144+
$this->assertContains('This is the content of the iFrame', $this->driver->getPageSource());
145+
}
74146
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>php-webdriver iFrame content page</title>
6+
</head>
7+
<body>
8+
<p>This is the content of the iFrame</p>
9+
</body>
10+
</html>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>php-webdriver test page</title>
6+
</head>
7+
<body>
8+
<p>This is the host page which contains an iFrame</p>
9+
<iframe src="iframe_content.html" name="iframe_content" id="iframe_content"></iframe>
10+
<iframe src="open_new_window.html" name="other_iframe_content" id="other_iframe_content"></iframe>
11+
<iframe src="upload.html" name="0"></iframe>
12+
</body>
13+
</html>

0 commit comments

Comments
 (0)