forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			336 lines
		
	
	
	
		
			9.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			336 lines
		
	
	
	
		
			9.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* Any copyright is dedicated to the Public Domain.
 | |
|  * http://creativecommons.org/publicdomain/zero/1.0/ */
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| // Test the Runtime execution context events
 | |
| 
 | |
| const DESTROYED = "Runtime.executionContextDestroyed";
 | |
| const CREATED = "Runtime.executionContextCreated";
 | |
| const CLEARED = "Runtime.executionContextsCleared";
 | |
| 
 | |
| add_task(async function noEventsWhenRuntimeDomainDisabled({ client }) {
 | |
|   const { Runtime } = client;
 | |
| 
 | |
|   const history = recordContextEvents(Runtime, 0);
 | |
|   await loadURL(PAGE_FRAME_URL);
 | |
|   await assertEventOrder({ history, expectedEvents: [] });
 | |
| });
 | |
| 
 | |
| add_task(async function noEventsAfterRuntimeDomainDisabled({ client }) {
 | |
|   const { Runtime } = client;
 | |
| 
 | |
|   await Runtime.enable();
 | |
|   await Runtime.disable();
 | |
| 
 | |
|   const history = recordContextEvents(Runtime, 0);
 | |
|   await loadURL(PAGE_FRAME_URL);
 | |
|   await assertEventOrder({ history, expectedEvents: [] });
 | |
| });
 | |
| 
 | |
| add_task(async function eventsWhenNavigatingWithNoFrames({ client }) {
 | |
|   const { Page, Runtime } = client;
 | |
| 
 | |
|   const previousContext = await enableRuntime(client);
 | |
|   const history = recordContextEvents(Runtime, 3);
 | |
| 
 | |
|   const { frameId } = await Page.navigate({ url: PAGE_FRAME_URL });
 | |
|   await assertEventOrder({ history });
 | |
| 
 | |
|   const { executionContextId: destroyedId } = history.findEvent(
 | |
|     DESTROYED
 | |
|   ).payload;
 | |
|   is(
 | |
|     destroyedId,
 | |
|     previousContext.id,
 | |
|     "The destroyed event reports the previous context id"
 | |
|   );
 | |
| 
 | |
|   const { context: contextCreated } = history.findEvent(CREATED).payload;
 | |
|   checkDefaultContext(contextCreated);
 | |
|   isnot(
 | |
|     contextCreated.id,
 | |
|     previousContext.id,
 | |
|     "The new execution context has a different id"
 | |
|   );
 | |
|   is(
 | |
|     contextCreated.auxData.frameId,
 | |
|     frameId,
 | |
|     "The execution context frame id is the same " +
 | |
|       "than the one returned by Page.navigate"
 | |
|   );
 | |
| });
 | |
| 
 | |
| add_task(async function eventsWhenNavigatingFrameSet({ client }) {
 | |
|   const { Runtime } = client;
 | |
| 
 | |
|   const previousContext = await enableRuntime(client);
 | |
| 
 | |
|   // Check navigation to a frameset
 | |
|   const historyTo = recordContextEvents(Runtime, 4);
 | |
|   await loadURL(FRAMESET_SINGLE_URL);
 | |
|   await assertEventOrder({
 | |
|     history: historyTo,
 | |
|     expectedEvents: [DESTROYED, CLEARED, CREATED, CREATED],
 | |
|   });
 | |
| 
 | |
|   const { executionContextId: destroyedId } = historyTo.findEvent(
 | |
|     DESTROYED
 | |
|   ).payload;
 | |
|   is(
 | |
|     destroyedId,
 | |
|     previousContext.id,
 | |
|     "The destroyed event reports the previous context id"
 | |
|   );
 | |
| 
 | |
|   const contexts = historyTo.findEvents(CREATED);
 | |
|   const createdTopContext = contexts[0].payload.context;
 | |
|   const createdFrameContext = contexts[1].payload.context;
 | |
| 
 | |
|   checkDefaultContext(createdTopContext);
 | |
|   isnot(
 | |
|     createdTopContext.id,
 | |
|     previousContext.id,
 | |
|     "The new execution context has a different id"
 | |
|   );
 | |
|   is(
 | |
|     createdTopContext.origin,
 | |
|     BASE_ORIGIN,
 | |
|     "The execution context origin is the frameset"
 | |
|   );
 | |
| 
 | |
|   checkDefaultContext(createdFrameContext);
 | |
|   isnot(
 | |
|     createdFrameContext.id,
 | |
|     createdTopContext.id,
 | |
|     "The new frame's execution context has a different id"
 | |
|   );
 | |
|   is(
 | |
|     createdFrameContext.origin,
 | |
|     BASE_ORIGIN,
 | |
|     "The frame's execution context origin is the frame"
 | |
|   );
 | |
| 
 | |
|   // Check navigation from a frameset
 | |
|   const historyFrom = recordContextEvents(Runtime, 4);
 | |
|   await loadURL(PAGE_FRAME_URL);
 | |
|   await assertEventOrder({
 | |
|     history: historyFrom,
 | |
|     // Bug 1644657: The cleared event should come last but we emit destroy events
 | |
|     // for the top-level context and for frames afterward. Chrome only sends out
 | |
|     // the cleared event on navigation.
 | |
|     expectedEvents: [DESTROYED, CLEARED, DESTROYED, CREATED],
 | |
|   });
 | |
| 
 | |
|   const destroyedContextIds = historyFrom.findEvents(DESTROYED);
 | |
|   is(
 | |
|     destroyedContextIds[0].payload.executionContextId,
 | |
|     createdTopContext.id,
 | |
|     "The destroyed event reports the previous context id"
 | |
|   );
 | |
|   is(
 | |
|     destroyedContextIds[1].payload.executionContextId,
 | |
|     createdFrameContext.id,
 | |
|     "The destroyed event reports the previous frame's context id"
 | |
|   );
 | |
| 
 | |
|   const { context: contextCreated } = historyFrom.findEvent(CREATED).payload;
 | |
|   checkDefaultContext(contextCreated);
 | |
|   isnot(
 | |
|     contextCreated.id,
 | |
|     createdTopContext.id,
 | |
|     "The new execution context has a different id"
 | |
|   );
 | |
|   is(
 | |
|     contextCreated.origin,
 | |
|     BASE_ORIGIN,
 | |
|     "The execution context origin is not the frameset"
 | |
|   );
 | |
| });
 | |
| 
 | |
| add_task(async function eventsWhenNavigatingBackWithNoFrames({ client }) {
 | |
|   const { Runtime } = client;
 | |
| 
 | |
|   // Load an initial URL so that navigating back will work
 | |
|   await loadURL(PAGE_FRAME_URL);
 | |
|   const previousContext = await enableRuntime(client);
 | |
| 
 | |
|   const executionContextCreated = Runtime.executionContextCreated();
 | |
|   await loadURL(PAGE_URL);
 | |
|   const { context: createdContext } = await executionContextCreated;
 | |
| 
 | |
|   const history = recordContextEvents(Runtime, 3);
 | |
|   gBrowser.selectedBrowser.goBack();
 | |
|   await assertEventOrder({ history });
 | |
| 
 | |
|   const { executionContextId: destroyedId } = history.findEvent(
 | |
|     DESTROYED
 | |
|   ).payload;
 | |
|   is(
 | |
|     destroyedId,
 | |
|     createdContext.id,
 | |
|     "The destroyed event reports the current context id"
 | |
|   );
 | |
| 
 | |
|   const { context } = history.findEvent(CREATED).payload;
 | |
|   checkDefaultContext(context);
 | |
|   is(
 | |
|     context.origin,
 | |
|     previousContext.origin,
 | |
|     "The new execution context has the same origin as the previous one."
 | |
|   );
 | |
|   isnot(
 | |
|     context.id,
 | |
|     previousContext.id,
 | |
|     "The new execution context has a different id"
 | |
|   );
 | |
|   ok(context.auxData.isDefault, "The execution context is the default one");
 | |
|   is(
 | |
|     context.auxData.frameId,
 | |
|     previousContext.auxData.frameId,
 | |
|     "The execution context frame id is always the same"
 | |
|   );
 | |
|   is(context.auxData.type, "default", "Execution context has 'default' type");
 | |
|   is(context.name, "", "The default execution context is named ''");
 | |
| 
 | |
|   const { result } = await Runtime.evaluate({
 | |
|     contextId: context.id,
 | |
|     expression: "location.href",
 | |
|   });
 | |
|   is(
 | |
|     result.value,
 | |
|     PAGE_FRAME_URL,
 | |
|     "Runtime.evaluate works and is against the page we just navigated to"
 | |
|   );
 | |
| });
 | |
| 
 | |
| add_task(async function eventsWhenReloadingPageWithNoFrames({ client }) {
 | |
|   const { Page, Runtime } = client;
 | |
| 
 | |
|   // Load an initial URL so that reload will work
 | |
|   await loadURL(PAGE_FRAME_URL);
 | |
|   const previousContext = await enableRuntime(client);
 | |
| 
 | |
|   await Page.enable();
 | |
| 
 | |
|   const history = recordContextEvents(Runtime, 3);
 | |
|   const frameNavigated = Page.frameNavigated();
 | |
|   gBrowser.selectedBrowser.reload();
 | |
|   await frameNavigated;
 | |
| 
 | |
|   await assertEventOrder({ history });
 | |
| 
 | |
|   const { executionContextId } = history.findEvent(DESTROYED).payload;
 | |
|   is(
 | |
|     executionContextId,
 | |
|     previousContext.id,
 | |
|     "The destroyed event reports the previous context id"
 | |
|   );
 | |
| 
 | |
|   const { context } = history.findEvent(CREATED).payload;
 | |
|   checkDefaultContext(context);
 | |
|   is(
 | |
|     context.auxData.frameId,
 | |
|     previousContext.auxData.frameId,
 | |
|     "The execution context frame id is the same as before reloading"
 | |
|   );
 | |
| 
 | |
|   isnot(
 | |
|     executionContextId,
 | |
|     context.id,
 | |
|     "The destroyed id is different from the created one"
 | |
|   );
 | |
| });
 | |
| 
 | |
| add_task(async function eventsWhenNavigatingByLocationWithNoFrames({ client }) {
 | |
|   const { Runtime } = client;
 | |
| 
 | |
|   const previousContext = await enableRuntime(client);
 | |
|   const history = recordContextEvents(Runtime, 3);
 | |
| 
 | |
|   await Runtime.evaluate({
 | |
|     contextId: previousContext.id,
 | |
|     expression: `window.location = '${PAGE_FRAME_URL}';`,
 | |
|   });
 | |
|   await assertEventOrder({ history });
 | |
| 
 | |
|   const { executionContextId: destroyedId } = history.findEvent(
 | |
|     DESTROYED
 | |
|   ).payload;
 | |
|   is(
 | |
|     destroyedId,
 | |
|     previousContext.id,
 | |
|     "The destroyed event reports the previous context id"
 | |
|   );
 | |
| 
 | |
|   const { context: createdContext } = history.findEvent(CREATED).payload;
 | |
|   checkDefaultContext(createdContext);
 | |
|   is(
 | |
|     createdContext.auxData.frameId,
 | |
|     previousContext.auxData.frameId,
 | |
|     "The execution context frame id is identical " +
 | |
|       "to the one from before before setting the window's location"
 | |
|   );
 | |
|   isnot(
 | |
|     destroyedId,
 | |
|     createdContext.id,
 | |
|     "The destroyed id is different from the created one"
 | |
|   );
 | |
| });
 | |
| 
 | |
| function recordContextEvents(Runtime, total) {
 | |
|   const history = new RecordEvents(total);
 | |
| 
 | |
|   history.addRecorder({
 | |
|     event: Runtime.executionContextDestroyed,
 | |
|     eventName: DESTROYED,
 | |
|     messageFn: payload => {
 | |
|       return `Received ${DESTROYED} for id ${payload.executionContextId}`;
 | |
|     },
 | |
|   });
 | |
|   history.addRecorder({
 | |
|     event: Runtime.executionContextCreated,
 | |
|     eventName: CREATED,
 | |
|     messageFn: ({ context }) => {
 | |
|       return (
 | |
|         `Received ${CREATED} for id ${context.id}` +
 | |
|         ` type: ${context.auxData.type}` +
 | |
|         ` name: ${context.name}` +
 | |
|         ` origin: ${context.origin}`
 | |
|       );
 | |
|     },
 | |
|   });
 | |
|   history.addRecorder({
 | |
|     event: Runtime.executionContextsCleared,
 | |
|     eventName: CLEARED,
 | |
|   });
 | |
| 
 | |
|   return history;
 | |
| }
 | |
| 
 | |
| async function assertEventOrder(options = {}) {
 | |
|   const { history, expectedEvents = [DESTROYED, CLEARED, CREATED] } = options;
 | |
|   const events = await history.record();
 | |
|   const eventNames = events.map(item => item.eventName);
 | |
|   info(`Expected events: ${expectedEvents}`);
 | |
|   info(`Received events: ${eventNames}`);
 | |
| 
 | |
|   is(
 | |
|     events.length,
 | |
|     expectedEvents.length,
 | |
|     "Received expected number of Runtime context events"
 | |
|   );
 | |
|   Assert.deepEqual(
 | |
|     events.map(item => item.eventName),
 | |
|     expectedEvents,
 | |
|     "Received Runtime context events in expected order"
 | |
|   );
 | |
| }
 | |
| 
 | |
| function checkDefaultContext(context) {
 | |
|   ok(!!context.id, "The execution context has an id");
 | |
|   ok(context.auxData.isDefault, "The execution context is the default one");
 | |
|   is(context.auxData.type, "default", "Execution context has 'default' type");
 | |
|   ok(!!context.origin, "The execution context has an origin");
 | |
|   is(context.name, "", "The default execution context is named ''");
 | |
| }
 | 
