fix: update chrome.tabs
for Manifest v3 (#39317)
This commit is contained in:
parent
f8b05bc127
commit
6d0e8044eb
6 changed files with 481 additions and 126 deletions
|
@ -3,13 +3,23 @@
|
||||||
"namespace": "tabs",
|
"namespace": "tabs",
|
||||||
"description": "Use the <code>chrome.tabs</code> API to interact with the browser's tab system. You can use this API to create, modify, and rearrange tabs in the browser.",
|
"description": "Use the <code>chrome.tabs</code> API to interact with the browser's tab system. You can use this API to create, modify, and rearrange tabs in the browser.",
|
||||||
"types": [
|
"types": [
|
||||||
{ "id": "MutedInfoReason",
|
{
|
||||||
|
"id": "MutedInfoReason",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "An event that caused a muted state change.",
|
"description": "An event that caused a muted state change.",
|
||||||
"enum": [
|
"enum": [
|
||||||
{"name": "user", "description": "A user input action set the muted state."},
|
{
|
||||||
{"name": "capture", "description": "Tab capture was started, forcing a muted state change."},
|
"name": "user",
|
||||||
{"name": "extension", "description": "An extension, identified by the extensionId field, set the muted state."}
|
"description": "A user input action set the muted state."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "capture",
|
||||||
|
"description": "Tab capture was started, forcing a muted state change."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "extension",
|
||||||
|
"description": "An extension, identified by the extensionId field, set the muted state."
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -37,29 +47,112 @@
|
||||||
"id": "Tab",
|
"id": "Tab",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {"type": "integer", "minimum": -1, "optional": true, "description": "The ID of the tab. Tab IDs are unique within a browser session. Under some circumstances a tab may not be assigned an ID; for example, when querying foreign tabs using the $(ref:sessions) API, in which case a session ID may be present. Tab ID can also be set to <code>chrome.tabs.TAB_ID_NONE</code> for apps and devtools windows."},
|
"id": {
|
||||||
// TODO(kalman): Investigate how this is ending up as -1 (based on window type? a bug?) and whether it should be optional instead.
|
"type": "integer",
|
||||||
"index": {"type": "integer", "minimum": -1, "description": "The zero-based index of the tab within its window."},
|
"minimum": -1,
|
||||||
"groupId": {"type": "integer", "minimum": -1, "description": "The ID of the group that the tab belongs to."},
|
"optional": true,
|
||||||
"windowId": {"type": "integer", "minimum": 0, "description": "The ID of the window that contains the tab."},
|
"description": "The ID of the tab. Tab IDs are unique within a browser session. Under some circumstances a tab may not be assigned an ID; for example, when querying foreign tabs using the $(ref:sessions) API, in which case a session ID may be present. Tab ID can also be set to <code>chrome.tabs.TAB_ID_NONE</code> for apps and devtools windows."
|
||||||
"openerTabId": {"type": "integer", "minimum": 0, "optional": true, "description": "The ID of the tab that opened this tab, if any. This property is only present if the opener tab still exists."},
|
},
|
||||||
"selected": {"type": "boolean", "description": "Whether the tab is selected.", "deprecated": "Please use $(ref:tabs.Tab.highlighted)."},
|
"index": {
|
||||||
"highlighted": {"type": "boolean", "description": "Whether the tab is highlighted."},
|
"type": "integer",
|
||||||
"active": {"type": "boolean", "description": "Whether the tab is active in its window. Does not necessarily mean the window is focused."},
|
"minimum": -1,
|
||||||
"pinned": {"type": "boolean", "description": "Whether the tab is pinned."},
|
"description": "The zero-based index of the tab within its window."
|
||||||
"audible": {"type": "boolean", "optional": true, "description": "Whether the tab has produced sound over the past couple of seconds (but it might not be heard if also muted). Equivalent to whether the 'speaker audio' indicator is showing."},
|
},
|
||||||
"discarded": {"type": "boolean", "description": "Whether the tab is discarded. A discarded tab is one whose content has been unloaded from memory, but is still visible in the tab strip. Its content is reloaded the next time it is activated."},
|
"groupId": {
|
||||||
"autoDiscardable": {"type": "boolean", "description": "Whether the tab can be discarded automatically by the browser when resources are low."},
|
"type": "integer",
|
||||||
"mutedInfo": {"$ref": "MutedInfo", "optional": true, "description": "The tab's muted state and the reason for the last state change."},
|
"minimum": -1,
|
||||||
"url": {"type": "string", "optional": true, "description": "The last committed URL of the main frame of the tab. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission and may be an empty string if the tab has not yet committed. See also $(ref:Tab.pendingUrl)."},
|
"description": "The ID of the group that the tab belongs to."
|
||||||
"pendingUrl": {"type": "string", "optional": true, "description": "The URL the tab is navigating to, before it has committed. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission and there is a pending navigation."},
|
},
|
||||||
"title": {"type": "string", "optional": true, "description": "The title of the tab. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission."},
|
"windowId": {
|
||||||
"favIconUrl": {"type": "string", "optional": true, "description": "The URL of the tab's favicon. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission. It may also be an empty string if the tab is loading."},
|
"type": "integer",
|
||||||
"status": {"type": "string", "optional": true, "description": "Either <em>loading</em> or <em>complete</em>."},
|
"minimum": 0,
|
||||||
"incognito": {"type": "boolean", "description": "Whether the tab is in an incognito window."},
|
"description": "The ID of the window that contains the tab."
|
||||||
"width": {"type": "integer", "optional": true, "description": "The width of the tab in pixels."},
|
},
|
||||||
"height": {"type": "integer", "optional": true, "description": "The height of the tab in pixels."},
|
"openerTabId": {
|
||||||
"sessionId": {"type": "string", "optional": true, "description": "The session ID used to uniquely identify a tab obtained from the $(ref:sessions) API."}
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"optional": true,
|
||||||
|
"description": "The ID of the tab that opened this tab, if any. This property is only present if the opener tab still exists."
|
||||||
|
},
|
||||||
|
"selected": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the tab is selected.",
|
||||||
|
"deprecated": "Please use $(ref:tabs.Tab.highlighted)."
|
||||||
|
},
|
||||||
|
"highlighted": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the tab is highlighted."
|
||||||
|
},
|
||||||
|
"active": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the tab is active in its window. Does not necessarily mean the window is focused."
|
||||||
|
},
|
||||||
|
"pinned": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the tab is pinned."
|
||||||
|
},
|
||||||
|
"audible": {
|
||||||
|
"type": "boolean",
|
||||||
|
"optional": true,
|
||||||
|
"description": "Whether the tab has produced sound over the past couple of seconds (but it might not be heard if also muted). Equivalent to whether the 'speaker audio' indicator is showing."
|
||||||
|
},
|
||||||
|
"discarded": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the tab is discarded. A discarded tab is one whose content has been unloaded from memory, but is still visible in the tab strip. Its content is reloaded the next time it is activated."
|
||||||
|
},
|
||||||
|
"autoDiscardable": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the tab can be discarded automatically by the browser when resources are low."
|
||||||
|
},
|
||||||
|
"mutedInfo": {
|
||||||
|
"$ref": "MutedInfo",
|
||||||
|
"optional": true,
|
||||||
|
"description": "The tab's muted state and the reason for the last state change."
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string",
|
||||||
|
"optional": true,
|
||||||
|
"description": "The last committed URL of the main frame of the tab. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission and may be an empty string if the tab has not yet committed. See also $(ref:Tab.pendingUrl)."
|
||||||
|
},
|
||||||
|
"pendingUrl": {
|
||||||
|
"type": "string",
|
||||||
|
"optional": true,
|
||||||
|
"description": "The URL the tab is navigating to, before it has committed. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission and there is a pending navigation."
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string",
|
||||||
|
"optional": true,
|
||||||
|
"description": "The title of the tab. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission."
|
||||||
|
},
|
||||||
|
"favIconUrl": {
|
||||||
|
"type": "string",
|
||||||
|
"optional": true,
|
||||||
|
"description": "The URL of the tab's favicon. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission. It may also be an empty string if the tab is loading."
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string",
|
||||||
|
"optional": true,
|
||||||
|
"description": "Either <em>loading</em> or <em>complete</em>."
|
||||||
|
},
|
||||||
|
"incognito": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the tab is in an incognito window."
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"type": "integer",
|
||||||
|
"optional": true,
|
||||||
|
"description": "The width of the tab in pixels."
|
||||||
|
},
|
||||||
|
"height": {
|
||||||
|
"type": "integer",
|
||||||
|
"optional": true,
|
||||||
|
"description": "The height of the tab in pixels."
|
||||||
|
},
|
||||||
|
"sessionId": {
|
||||||
|
"type": "string",
|
||||||
|
"optional": true,
|
||||||
|
"description": "The session ID used to uniquely identify a tab obtained from the $(ref:sessions) API."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -125,7 +218,13 @@
|
||||||
"type": "function",
|
"type": "function",
|
||||||
"description": "Reload a tab.",
|
"description": "Reload a tab.",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{"type": "integer", "name": "tabId", "minimum": 0, "optional": true, "description": "The ID of the tab to reload; defaults to the selected tab of the current window."},
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"name": "tabId",
|
||||||
|
"minimum": 0,
|
||||||
|
"optional": true,
|
||||||
|
"description": "The ID of the tab to reload; defaults to the selected tab of the current window."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"name": "reloadProperties",
|
"name": "reloadProperties",
|
||||||
|
@ -134,12 +233,16 @@
|
||||||
"bypassCache": {
|
"bypassCache": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"description": "Whether using any local cache. Default is false."
|
"description": "Whether to bypass local caching. Defaults to <code>false</code>."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
{"type": "function", "name": "callback", "optional": true, "parameters": []}
|
],
|
||||||
]
|
"returns_async": {
|
||||||
|
"name": "callback",
|
||||||
|
"optional": true,
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "get",
|
"name": "get",
|
||||||
|
@ -150,15 +253,17 @@
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"name": "tabId",
|
"name": "tabId",
|
||||||
"minimum": 0
|
"minimum": 0
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"type": "function",
|
"returns_async": {
|
||||||
"name": "callback",
|
"name": "callback",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{"name": "tab", "$ref": "Tab"}
|
{
|
||||||
]
|
"name": "tab",
|
||||||
|
"$ref": "Tab"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "connect",
|
"name": "connect",
|
||||||
|
@ -175,12 +280,21 @@
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"name": "connectInfo",
|
"name": "connectInfo",
|
||||||
"properties": {
|
"properties": {
|
||||||
"name": { "type": "string", "optional": true, "description": "Is passed into onConnect for content scripts that are listening for the connection event." },
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"optional": true,
|
||||||
|
"description": "Is passed into onConnect for content scripts that are listening for the connection event."
|
||||||
|
},
|
||||||
"frameId": {
|
"frameId": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"minimum": 0,
|
"minimum": 0,
|
||||||
"description": "Open a port to a specific <a href='webNavigation#frame_ids'>frame</a> identified by <code>frameId</code> instead of all frames in the tab."
|
"description": "Open a port to a specific <a href='webNavigation#frame_ids'>frame</a> identified by <code>frameId</code> instead of all frames in the tab."
|
||||||
|
},
|
||||||
|
"documentId": {
|
||||||
|
"type": "string",
|
||||||
|
"optional": true,
|
||||||
|
"description": "Open a port to a specific <a href='webNavigation#document_ids'>document</a> identified by <code>documentId</code> instead of all frames in the tab."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"optional": true
|
"optional": true
|
||||||
|
@ -193,7 +307,9 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "executeScript",
|
"name": "executeScript",
|
||||||
|
"deprecated": "Replaced by $(ref:scripting.executeScript) in Manifest V3.",
|
||||||
"type": "function",
|
"type": "function",
|
||||||
|
"description": "Injects JavaScript code into a page. For details, see the <a href='content_scripts#pi'>programmatic injection</a> section of the content scripts doc.",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
|
@ -206,9 +322,9 @@
|
||||||
"$ref": "extensionTypes.InjectDetails",
|
"$ref": "extensionTypes.InjectDetails",
|
||||||
"name": "details",
|
"name": "details",
|
||||||
"description": "Details of the script to run. Either the code or the file property must be set, but both may not be set at the same time."
|
"description": "Details of the script to run. Either the code or the file property must be set, but both may not be set at the same time."
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"type": "function",
|
"returns_async": {
|
||||||
"name": "callback",
|
"name": "callback",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"description": "Called after all the JavaScript has been executed.",
|
"description": "Called after all the JavaScript has been executed.",
|
||||||
|
@ -225,7 +341,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sendMessage",
|
"name": "sendMessage",
|
||||||
|
@ -252,13 +367,18 @@
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"minimum": 0,
|
"minimum": 0,
|
||||||
"description": "Send a message to a specific <a href='webNavigation#frame_ids'>frame</a> identified by <code>frameId</code> instead of all frames in the tab."
|
"description": "Send a message to a specific <a href='webNavigation#frame_ids'>frame</a> identified by <code>frameId</code> instead of all frames in the tab."
|
||||||
|
},
|
||||||
|
"documentId": {
|
||||||
|
"type": "string",
|
||||||
|
"optional": true,
|
||||||
|
"description": "Send a message to a specific <a href='webNavigation#document_ids'>document</a> identified by <code>documentId</code> instead of all frames in the tab."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"type": "function",
|
"returns_async": {
|
||||||
"name": "responseCallback",
|
"name": "callback",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
|
@ -268,7 +388,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "setZoom",
|
"name": "setZoom",
|
||||||
|
@ -286,15 +405,14 @@
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"name": "zoomFactor",
|
"name": "zoomFactor",
|
||||||
"description": "The new zoom factor. A value of <code>0</code> sets the tab to its current default zoom factor. Values greater than <code>0</code> specify a (possibly non-default) zoom factor for the tab."
|
"description": "The new zoom factor. A value of <code>0</code> sets the tab to its current default zoom factor. Values greater than <code>0</code> specify a (possibly non-default) zoom factor for the tab."
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"type": "function",
|
"returns_async": {
|
||||||
"name": "callback",
|
"name": "callback",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"description": "Called after the zoom factor has been changed.",
|
"description": "Called after the zoom factor has been changed.",
|
||||||
"parameters": []
|
"parameters": []
|
||||||
}
|
}
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "getZoom",
|
"name": "getZoom",
|
||||||
|
@ -307,9 +425,9 @@
|
||||||
"minimum": 0,
|
"minimum": 0,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"description": "The ID of the tab to get the current zoom factor from; defaults to the active tab of the current window."
|
"description": "The ID of the tab to get the current zoom factor from; defaults to the active tab of the current window."
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"type": "function",
|
"returns_async": {
|
||||||
"name": "callback",
|
"name": "callback",
|
||||||
"description": "Called with the tab's current zoom factor after it has been fetched.",
|
"description": "Called with the tab's current zoom factor after it has been fetched.",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
|
@ -320,7 +438,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "setZoomSettings",
|
"name": "setZoomSettings",
|
||||||
|
@ -338,15 +455,14 @@
|
||||||
"$ref": "ZoomSettings",
|
"$ref": "ZoomSettings",
|
||||||
"name": "zoomSettings",
|
"name": "zoomSettings",
|
||||||
"description": "Defines how zoom changes are handled and at what scope."
|
"description": "Defines how zoom changes are handled and at what scope."
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"type": "function",
|
"returns_async": {
|
||||||
"name": "callback",
|
"name": "callback",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"description": "Called after the zoom settings are changed.",
|
"description": "Called after the zoom settings are changed.",
|
||||||
"parameters": []
|
"parameters": []
|
||||||
}
|
}
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "getZoomSettings",
|
"name": "getZoomSettings",
|
||||||
|
@ -359,9 +475,9 @@
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"minimum": 0,
|
"minimum": 0,
|
||||||
"description": "The ID of the tab to get the current zoom settings from; defaults to the active tab of the current window."
|
"description": "The ID of the tab to get the current zoom settings from; defaults to the active tab of the current window."
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"type": "function",
|
"returns_async": {
|
||||||
"name": "callback",
|
"name": "callback",
|
||||||
"description": "Called with the tab's current zoom settings.",
|
"description": "Called with the tab's current zoom settings.",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
|
@ -372,7 +488,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "update",
|
"name": "update",
|
||||||
|
@ -454,16 +569,27 @@
|
||||||
"name": "onZoomChange",
|
"name": "onZoomChange",
|
||||||
"type": "function",
|
"type": "function",
|
||||||
"description": "Fired when a tab is zoomed.",
|
"description": "Fired when a tab is zoomed.",
|
||||||
"parameters": [{
|
"parameters": [
|
||||||
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"name": "ZoomChangeInfo",
|
"name": "ZoomChangeInfo",
|
||||||
"properties": {
|
"properties": {
|
||||||
"tabId": {"type": "integer", "minimum": 0},
|
"tabId": {
|
||||||
"oldZoomFactor": {"type": "number"},
|
"type": "integer",
|
||||||
"newZoomFactor": {"type": "number"},
|
"minimum": 0
|
||||||
"zoomSettings": {"$ref": "ZoomSettings"}
|
},
|
||||||
|
"oldZoomFactor": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"newZoomFactor": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"zoomSettings": {
|
||||||
|
"$ref": "ZoomSettings"
|
||||||
}
|
}
|
||||||
}]
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,7 +373,7 @@ describe('chrome extensions', () => {
|
||||||
const message = { method: 'executeScript', args: ['1 + 2'] };
|
const message = { method: 'executeScript', args: ['1 + 2'] };
|
||||||
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
|
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
|
||||||
|
|
||||||
const [,, responseString] = await once(w.webContents, 'console-message');
|
const [, , responseString] = await once(w.webContents, 'console-message');
|
||||||
const response = JSON.parse(responseString);
|
const response = JSON.parse(responseString);
|
||||||
|
|
||||||
expect(response).to.equal(3);
|
expect(response).to.equal(3);
|
||||||
|
@ -835,5 +835,121 @@ describe('chrome extensions', () => {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('chrome.tabs', () => {
|
||||||
|
let customSession: Session;
|
||||||
|
let w = null as unknown as BrowserWindow;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
customSession = session.fromPartition(`persist:${uuid.v4()}`);
|
||||||
|
await customSession.loadExtension(path.join(fixtures, 'extensions', 'tabs-api-async'));
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
w = new BrowserWindow({
|
||||||
|
show: false,
|
||||||
|
webPreferences: {
|
||||||
|
session: customSession,
|
||||||
|
nodeIntegration: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(closeAllWindows);
|
||||||
|
|
||||||
|
it('getZoom', async () => {
|
||||||
|
await w.loadURL(url);
|
||||||
|
|
||||||
|
const message = { method: 'getZoom' };
|
||||||
|
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
|
||||||
|
|
||||||
|
const [,, responseString] = await once(w.webContents, 'console-message');
|
||||||
|
|
||||||
|
const response = JSON.parse(responseString);
|
||||||
|
expect(response).to.equal(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('setZoom', async () => {
|
||||||
|
await w.loadURL(url);
|
||||||
|
|
||||||
|
const message = { method: 'setZoom', args: [2] };
|
||||||
|
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
|
||||||
|
|
||||||
|
const [,, responseString] = await once(w.webContents, 'console-message');
|
||||||
|
|
||||||
|
const response = JSON.parse(responseString);
|
||||||
|
expect(response).to.deep.equal(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getZoomSettings', async () => {
|
||||||
|
await w.loadURL(url);
|
||||||
|
|
||||||
|
const message = { method: 'getZoomSettings' };
|
||||||
|
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
|
||||||
|
|
||||||
|
const [,, responseString] = await once(w.webContents, 'console-message');
|
||||||
|
|
||||||
|
const response = JSON.parse(responseString);
|
||||||
|
expect(response).to.deep.equal({
|
||||||
|
defaultZoomFactor: 1,
|
||||||
|
mode: 'automatic',
|
||||||
|
scope: 'per-origin'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('setZoomSettings', async () => {
|
||||||
|
await w.loadURL(url);
|
||||||
|
|
||||||
|
const message = { method: 'setZoomSettings', args: [{ mode: 'disabled' }] };
|
||||||
|
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
|
||||||
|
|
||||||
|
const [,, responseString] = await once(w.webContents, 'console-message');
|
||||||
|
|
||||||
|
const response = JSON.parse(responseString);
|
||||||
|
expect(response).to.deep.equal({
|
||||||
|
defaultZoomFactor: 1,
|
||||||
|
mode: 'disabled',
|
||||||
|
scope: 'per-tab'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get', async () => {
|
||||||
|
await w.loadURL(url);
|
||||||
|
|
||||||
|
const message = { method: 'get' };
|
||||||
|
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
|
||||||
|
|
||||||
|
const [,, responseString] = await once(w.webContents, 'console-message');
|
||||||
|
|
||||||
|
const response = JSON.parse(responseString);
|
||||||
|
expect(response).to.have.property('active').that.is.a('boolean');
|
||||||
|
expect(response).to.have.property('autoDiscardable').that.is.a('boolean');
|
||||||
|
expect(response).to.have.property('discarded').that.is.a('boolean');
|
||||||
|
expect(response).to.have.property('groupId').that.is.a('number');
|
||||||
|
expect(response).to.have.property('highlighted').that.is.a('boolean');
|
||||||
|
expect(response).to.have.property('id').that.is.a('number');
|
||||||
|
expect(response).to.have.property('incognito').that.is.a('boolean');
|
||||||
|
expect(response).to.have.property('index').that.is.a('number');
|
||||||
|
expect(response).to.have.property('pinned').that.is.a('boolean');
|
||||||
|
expect(response).to.have.property('selected').that.is.a('boolean');
|
||||||
|
expect(response).to.have.property('url').that.is.a('string');
|
||||||
|
expect(response).to.have.property('windowId').that.is.a('number');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('reload', async () => {
|
||||||
|
await w.loadURL(url);
|
||||||
|
|
||||||
|
const message = { method: 'reload' };
|
||||||
|
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
|
||||||
|
|
||||||
|
const consoleMessage = once(w.webContents, 'console-message');
|
||||||
|
const finish = once(w.webContents, 'did-finish-load');
|
||||||
|
|
||||||
|
await Promise.all([consoleMessage, finish]).then(([[,, responseString]]) => {
|
||||||
|
const response = JSON.parse(responseString);
|
||||||
|
expect(response.status).to.equal('reloaded');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
1
spec/fixtures/extensions/chrome-api/main.js
vendored
1
spec/fixtures/extensions/chrome-api/main.js
vendored
|
@ -49,4 +49,5 @@ const dispatchTest = (event) => {
|
||||||
const { method, args = [] } = JSON.parse(event.data);
|
const { method, args = [] } = JSON.parse(event.data);
|
||||||
testMap[method](...args);
|
testMap[method](...args);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('message', dispatchTest, false);
|
window.addEventListener('message', dispatchTest, false);
|
||||||
|
|
52
spec/fixtures/extensions/tabs-api-async/background.js
vendored
Normal file
52
spec/fixtures/extensions/tabs-api-async/background.js
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/* global chrome */
|
||||||
|
|
||||||
|
const handleRequest = (request, sender, sendResponse) => {
|
||||||
|
const { method, args = [] } = request;
|
||||||
|
const tabId = sender.tab.id;
|
||||||
|
|
||||||
|
switch (method) {
|
||||||
|
case 'getZoom': {
|
||||||
|
chrome.tabs.getZoom(tabId).then(sendResponse);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'setZoom': {
|
||||||
|
const [zoom] = args;
|
||||||
|
chrome.tabs.setZoom(tabId, zoom).then(async () => {
|
||||||
|
const updatedZoom = await chrome.tabs.getZoom(tabId);
|
||||||
|
sendResponse(updatedZoom);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'getZoomSettings': {
|
||||||
|
chrome.tabs.getZoomSettings(tabId).then(sendResponse);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'setZoomSettings': {
|
||||||
|
const [settings] = args;
|
||||||
|
chrome.tabs.setZoomSettings(tabId, { mode: settings.mode }).then(async () => {
|
||||||
|
const zoomSettings = await chrome.tabs.getZoomSettings(tabId);
|
||||||
|
sendResponse(zoomSettings);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'get': {
|
||||||
|
chrome.tabs.get(tabId).then(sendResponse);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'reload': {
|
||||||
|
chrome.tabs.reload(tabId).then(() => {
|
||||||
|
sendResponse({ status: 'reloaded' });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||||
|
handleRequest(request, sender, sendResponse);
|
||||||
|
return true;
|
||||||
|
});
|
45
spec/fixtures/extensions/tabs-api-async/main.js
vendored
Normal file
45
spec/fixtures/extensions/tabs-api-async/main.js
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/* global chrome */
|
||||||
|
|
||||||
|
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||||
|
sendResponse(request);
|
||||||
|
});
|
||||||
|
|
||||||
|
const testMap = {
|
||||||
|
getZoomSettings () {
|
||||||
|
chrome.runtime.sendMessage({ method: 'getZoomSettings' }, response => {
|
||||||
|
console.log(JSON.stringify(response));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setZoomSettings (settings) {
|
||||||
|
chrome.runtime.sendMessage({ method: 'setZoomSettings', args: [settings] }, response => {
|
||||||
|
console.log(JSON.stringify(response));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getZoom () {
|
||||||
|
chrome.runtime.sendMessage({ method: 'getZoom', args: [] }, response => {
|
||||||
|
console.log(JSON.stringify(response));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setZoom (zoom) {
|
||||||
|
chrome.runtime.sendMessage({ method: 'setZoom', args: [zoom] }, response => {
|
||||||
|
console.log(JSON.stringify(response));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
get () {
|
||||||
|
chrome.runtime.sendMessage({ method: 'get' }, response => {
|
||||||
|
console.log(JSON.stringify(response));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
reload () {
|
||||||
|
chrome.runtime.sendMessage({ method: 'reload' }, response => {
|
||||||
|
console.log(JSON.stringify(response));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const dispatchTest = (event) => {
|
||||||
|
const { method, args = [] } = JSON.parse(event.data);
|
||||||
|
testMap[method](...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('message', dispatchTest, false);
|
15
spec/fixtures/extensions/tabs-api-async/manifest.json
vendored
Normal file
15
spec/fixtures/extensions/tabs-api-async/manifest.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "tabs-api-async",
|
||||||
|
"version": "1.0",
|
||||||
|
"content_scripts": [
|
||||||
|
{
|
||||||
|
"matches": [ "<all_urls>"],
|
||||||
|
"js": ["main.js"],
|
||||||
|
"run_at": "document_start"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"background": {
|
||||||
|
"service_worker": "background.js"
|
||||||
|
},
|
||||||
|
"manifest_version": 3
|
||||||
|
}
|
Loading…
Reference in a new issue