Skip to content

Commit 8380cd6

Browse files
juangjsevaseva
authored andcommitted
In SafariDriver's page script, copy window properties to goog.global.
When the page script is injected, it's called with an empty 'this' object to avoid polluting the global namespace of the page under test. However, some Closure libraries look for properties on goog.global and fall back to worse or slower versions if those properties are absent. The specific motivating case is that if goog.async.nextTick can't find goog.global.MessageChannel, it will fall back to a method that injects an invisible iframe into the DOM. The page script's use of nextTick would cause it to create an iframe in the DOM of the page under test, which we'd like to avoid. Signed-off-by: Seva Lotoshnikov <[email protected]>
1 parent b4692ea commit 8380cd6

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

java/client/test/org/openqa/selenium/safari/CleanSessionTest.java

+10
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static org.junit.Assert.assertEquals;
2121
import static org.junit.Assert.assertTrue;
2222

23+
import org.openqa.selenium.By;
2324
import org.openqa.selenium.Cookie;
2425
import org.openqa.selenium.JavascriptExecutor;
2526
import org.openqa.selenium.remote.DesiredCapabilities;
@@ -107,6 +108,15 @@ public void doesNotLeakInternalMessagesToThePageUnderTest() {
107108
assertEquals(1L, numMessages);
108109
}
109110

111+
@Test
112+
public void doesNotCreateExtraIframeOnPageUnderTest() {
113+
driver.get(appServer.whereIs("messages.html"));
114+
assertEquals(0, driver.findElements(By.tagName("iframe")).size());
115+
116+
((JavascriptExecutor) driver).executeScript("return location.href;");
117+
assertEquals(0, driver.findElements(By.tagName("iframe")).size());
118+
}
119+
110120
private void assertHasCookie(Cookie cookie) {
111121
assertTrue(driver.manage().getCookies().contains(cookie));
112122
}

javascript/safari-driver/inject/page/page.js

+19
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ safaridriver.inject.page.encoder;
6363
safaridriver.inject.page.init = function() {
6464
goog.debug.LogManager.getRoot().setLevel(goog.debug.Logger.Level.INFO);
6565

66+
// The page script is installed with an empty 'this' object, to avoid
67+
// polluting the global namespace. But we still want Closure libraries to be
68+
// able to read the properties of window that would normally be in
69+
// goog.global, so we copy those into goog.global.
70+
if (window != goog.global) {
71+
copyWindowPropertiesTo(goog.global);
72+
}
73+
6674
var handler = new safaridriver.logging.ForwardingHandler(window);
6775
handler.captureConsoleOutput();
6876

@@ -97,6 +105,17 @@ safaridriver.inject.page.init = function() {
97105
return oldFn.toString();
98106
};
99107
}
108+
109+
function copyWindowPropertiesTo(obj) {
110+
goog.array.forEach(Object.getOwnPropertyNames(window), function(name) {
111+
if (!(name in obj)) {
112+
var descriptor = Object.getOwnPropertyDescriptor(window, name);
113+
if (descriptor) {
114+
Object.defineProperty(obj, name, descriptor);
115+
}
116+
}
117+
});
118+
}
100119
};
101120
goog.exportSymbol('init', safaridriver.inject.page.init);
102121

Binary file not shown.

0 commit comments

Comments
 (0)