Bug 1690308 - [marionette] Report StaleElementReference error after cross-group navigations. r=marionette-reviewers,jgraham

Cross-group navigations cause a swap of the current top-level
browsing context. The only unique identifier is the browser id
the browsing context actually lives in. If it's equal also
treat the browsing context as the same.

Differential Revision: https://phabricator.services.mozilla.com/D104525
This commit is contained in:
Henrik Skupin 2021-02-12 12:21:56 +00:00
Родитель b392049f19
Коммит 293677c0f6
2 изменённых файлов: 49 добавлений и 4 удалений

Просмотреть файл

@ -784,12 +784,19 @@ element.findClosest = function(startNode, selector) {
* The DOM element to generate the identifier for.
*
* @return {object} The ContentDOMReference ElementIdentifier for the DOM
* element augmented with a Marionette WebElement reference.
* element augmented with a Marionette WebElement reference, and some
* additional properties.
*/
element.getElementId = function(el) {
const id = ContentDOMReference.get(el);
const webEl = WebElement.from(el);
const id = ContentDOMReference.get(el);
const browsingContext = BrowsingContext.get(id.browsingContextId);
id.webElRef = webEl.toJSON();
id.browserId = browsingContext.browserId;
id.isTopLevel = !browsingContext.parent;
return id;
};
@ -816,8 +823,20 @@ element.getElementId = function(el) {
* active document.
*/
element.resolveElement = function(id, win) {
// Don't allow elements whose browsing context differs from the current one.
if (id.browsingContextId != win?.browsingContext.id) {
let sameBrowsingContext;
if (id.isTopLevel) {
// Cross-group navigations cause a swap of the current top-level browsing
// context. The only unique identifier is the browser id the browsing
// context actually lives in. If it's equal also treat the browsing context
// as the same (bug 1690308).
// If the element's browsing context is a top-level browsing context,
sameBrowsingContext = id.browserId == win?.browsingContext.browserId;
} else {
// For non top-level browsing contexts check for equality directly.
sameBrowsingContext = id.browsingContextId == win?.browsingContext.id;
}
if (!sameBrowsingContext) {
throw new error.NoSuchElementError(
`Web element reference not seen before: ${JSON.stringify(id.webElRef)}`
);

Просмотреть файл

@ -293,6 +293,32 @@ class TestNavigate(BaseNavigationTestCase):
self.marionette.navigate("about:robots")
self.assertFalse(self.is_remote_tab)
@skip_if_framescript("Bug 1690308: Won't be fixed for framescript mode")
def test_stale_element_after_remoteness_change(self):
self.marionette.navigate(self.test_page_file_url)
self.assertTrue(self.is_remote_tab)
elem = self.marionette.find_element(By.ID, "file-url")
self.marionette.navigate("about:robots")
self.assertFalse(self.is_remote_tab)
# Force a GC to get rid of the replaced browsing context.
with self.marionette.using_context("chrome"):
self.marionette.execute_async_script(
"""
const resolve = arguments[0];
var memSrv = Cc["@mozilla.org/memory-reporter-manager;1"]
.getService(Ci.nsIMemoryReporterManager);
Services.obs.notifyObservers(null, "child-mmu-request", null);
memSrv.minimizeMemoryUsage(resolve);
"""
)
with self.assertRaises(errors.StaleElementException):
elem.click()
def test_about_blank_for_new_docshell(self):
self.assertEqual(self.marionette.get_url(), "about:blank")