Skip to content

Commit

Permalink
Cherry-pick 5e245ad. rdar://123407828
Browse files Browse the repository at this point in the history
    Allow tabs.update to be called without a tabID
    https://bugs.webkit.org/show_bug.cgi?id=269934
    rdar://123407828

    Reviewed by Timothy Hatcher.

    The tabID is an optional argument to tabs.update. We were always attempting to get the value of the optional.

    If it isn't passed, then it is meant to fall back to the active tab of the current context, which means:
    - If this was called from a popup, then the active tab of the popup's window
    - If this was called from the background page, then the active tab of the active window

    This required some refactoring to WebExtensionContext::getTab and WebExtensionContext::getCurrentTab to support this,
    and some tests were added calling this method without a tab ID from both contexts.

    * Source/WebKit/UIProcess/Extensions/Cocoa/API/WebExtensionContextAPITabsCocoa.mm:
    (WebKit::WebExtensionContext::tabsUpdate):
    (WebKit::WebExtensionContext::tabsReload):
    (WebKit::WebExtensionContext::tabsGoBack):
    (WebKit::WebExtensionContext::tabsGoForward):
    (WebKit::WebExtensionContext::tabsDetectLanguage):
    (WebKit::WebExtensionContext::tabsToggleReaderMode):
    (WebKit::WebExtensionContext::tabsGetZoom):
    (WebKit::WebExtensionContext::tabsSetZoom):
    (WebKit::WebExtensionContext::tabsExecuteScript):
    (WebKit::WebExtensionContext::tabsInsertCSS):
    (WebKit::WebExtensionContext::tabsRemoveCSS):
    * Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionContextCocoa.mm:
    (WebKit::WebExtensionContext::getWindow const):
    (WebKit::WebExtensionContext::getTab const):
    (WebKit::WebExtensionContext::getCurrentTab const):
    * Source/WebKit/UIProcess/Extensions/WebExtensionContext.h:
    * Source/WebKit/UIProcess/Extensions/WebExtensionContext.messages.in:
    * Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPITabsCocoa.mm:
    (WebKit::WebExtensionAPITabs::update):
    * Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPIAction.mm:
    (TestWebKitAPI::TEST):
    * Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPITabs.mm:
    (TestWebKitAPI::TEST):

    Canonical link: https://commits.webkit.org/275204@main

Identifier: 274471.485@safari-7619.1.5-branch
  • Loading branch information
b-weinstein authored and Dan Robson committed Feb 23, 2024
1 parent 7b50310 commit 3e55164
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
}).get()];
}

void WebExtensionContext::tabsUpdate(WebExtensionTabIdentifier tabIdentifier, const WebExtensionTabParameters& parameters, CompletionHandler<void(Expected<std::optional<WebExtensionTabParameters>, WebExtensionError>&&)>&& completionHandler)
void WebExtensionContext::tabsUpdate(WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> tabIdentifier, const WebExtensionTabParameters& parameters, CompletionHandler<void(Expected<std::optional<WebExtensionTabParameters>, WebExtensionError>&&)>&& completionHandler)
{
ASSERT(!parameters.audible);
ASSERT(!parameters.index);
Expand All @@ -126,7 +126,7 @@
ASSERT(!parameters.title);
ASSERT(!parameters.windowIdentifier);

RefPtr tab = getTab(tabIdentifier);
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier, IncludeExtensionViews::Yes);
if (!tab) {
completionHandler(toWebExtensionError(@"tabs.update()", nil, @"tab not found"));
return;
Expand Down Expand Up @@ -310,7 +310,7 @@

void WebExtensionContext::tabsReload(WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> tabIdentifier, ReloadFromOrigin reloadFromOrigin, CompletionHandler<void(Expected<void, WebExtensionError>&&)>&& completionHandler)
{
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier);
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier, IncludeExtensionViews::Yes);
if (!tab) {
completionHandler(toWebExtensionError(@"tabs.reload()", nil, @"tab not found"));
return;
Expand All @@ -324,7 +324,7 @@

void WebExtensionContext::tabsGoBack(WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> tabIdentifier, CompletionHandler<void(Expected<void, WebExtensionError>&&)>&& completionHandler)
{
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier);
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier, IncludeExtensionViews::Yes);
if (!tab) {
completionHandler(toWebExtensionError(@"tabs.goBack()", nil, @"tab not found"));
return;
Expand All @@ -335,7 +335,7 @@

void WebExtensionContext::tabsGoForward(WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> tabIdentifier, CompletionHandler<void(Expected<void, WebExtensionError>&&)>&& completionHandler)
{
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier);
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier, IncludeExtensionViews::Yes);
if (!tab) {
completionHandler(toWebExtensionError(@"tabs.goForward()", nil, @"tab not found"));
return;
Expand All @@ -346,7 +346,7 @@

void WebExtensionContext::tabsDetectLanguage(WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> tabIdentifier, CompletionHandler<void(Expected<String, WebExtensionError>&&)>&& completionHandler)
{
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier);
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier, IncludeExtensionViews::Yes);
if (!tab) {
completionHandler(toWebExtensionError(@"tabs.detectLanguage()", nil, @"tab not found"));
return;
Expand Down Expand Up @@ -419,7 +419,7 @@ static inline String toMIMEType(WebExtensionTab::ImageFormat format)

void WebExtensionContext::tabsToggleReaderMode(WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> tabIdentifier, CompletionHandler<void(Expected<void, WebExtensionError>&&)>&& completionHandler)
{
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier);
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier, IncludeExtensionViews::Yes);
if (!tab) {
completionHandler(toWebExtensionError(@"tabs.toggleReaderMode()", nil, @"tab not found"));
return;
Expand Down Expand Up @@ -485,7 +485,7 @@ static inline String toMIMEType(WebExtensionTab::ImageFormat format)

void WebExtensionContext::tabsGetZoom(WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> tabIdentifier, CompletionHandler<void(Expected<double, WebExtensionError>&&)>&& completionHandler)
{
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier);
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier, IncludeExtensionViews::Yes);
if (!tab) {
completionHandler(toWebExtensionError(@"tabs.getZoom()", nil, @"tab not found"));
return;
Expand All @@ -496,7 +496,7 @@ static inline String toMIMEType(WebExtensionTab::ImageFormat format)

void WebExtensionContext::tabsSetZoom(WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> tabIdentifier, double zoomFactor, CompletionHandler<void(Expected<void, WebExtensionError>&&)>&& completionHandler)
{
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier);
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier, IncludeExtensionViews::Yes);
if (!tab) {
completionHandler(toWebExtensionError(@"tabs.setZoom()", nil, @"tab not found"));
return;
Expand Down Expand Up @@ -550,7 +550,7 @@ static inline String toMIMEType(WebExtensionTab::ImageFormat format)

void WebExtensionContext::tabsExecuteScript(WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> tabIdentifier, const WebExtensionScriptInjectionParameters& parameters, CompletionHandler<void(Expected<InjectionResults, WebExtensionError>&&)>&& completionHandler)
{
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier);
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier, IncludeExtensionViews::Yes);
if (!tab) {
completionHandler(toWebExtensionError(@"tabs.executeScript()", nil, @"tab not found"));
return;
Expand Down Expand Up @@ -587,7 +587,7 @@ static inline String toMIMEType(WebExtensionTab::ImageFormat format)

void WebExtensionContext::tabsInsertCSS(WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> tabIdentifier, const WebExtensionScriptInjectionParameters& parameters, CompletionHandler<void(Expected<void, WebExtensionError>&&)>&& completionHandler)
{
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier);
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier, IncludeExtensionViews::Yes);
if (!tab) {
completionHandler(toWebExtensionError(@"tabs.insertCSS()", nil, @"tab not found"));
return;
Expand Down Expand Up @@ -615,7 +615,7 @@ static inline String toMIMEType(WebExtensionTab::ImageFormat format)

void WebExtensionContext::tabsRemoveCSS(WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> tabIdentifier, const WebExtensionScriptInjectionParameters& parameters, CompletionHandler<void(Expected<void, WebExtensionError>&&)>&& completionHandler)
{
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier);
RefPtr tab = getTab(webPageProxyIdentifier, tabIdentifier, IncludeExtensionViews::Yes);
if (!tab) {
completionHandler(toWebExtensionError(@"tabs.removeCSS()", nil, @"tab not found"));
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1406,7 +1406,7 @@ static _WKWebExtensionContextError toAPI(WebExtensionContext::Error error)

if (isCurrent(identifier)) {
if (webPageProxyIdentifier) {
if (auto tab = getCurrentTab(webPageProxyIdentifier.value(), ignoreExtensionAccess))
if (auto tab = getCurrentTab(webPageProxyIdentifier.value(), IncludeExtensionViews::Yes, ignoreExtensionAccess))
result = tab->window();
}

Expand Down Expand Up @@ -1488,23 +1488,54 @@ static _WKWebExtensionContextError toAPI(WebExtensionContext::Error error)
return result;
}

RefPtr<WebExtensionTab> WebExtensionContext::getTab(WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> identifier, IgnoreExtensionAccess ignoreExtensionAccess) const
RefPtr<WebExtensionTab> WebExtensionContext::getTab(WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> identifier, IncludeExtensionViews includeExtensionViews, IgnoreExtensionAccess ignoreExtensionAccess) const
{
if (identifier)
return getTab(identifier.value());
return getTab(identifier.value(), ignoreExtensionAccess);

if (m_backgroundWebView && webPageProxyIdentifier == m_backgroundWebView.get()._page->identifier())
return getCurrentTab(webPageProxyIdentifier, includeExtensionViews, ignoreExtensionAccess);
}

RefPtr<WebExtensionTab> WebExtensionContext::getCurrentTab(WebPageProxyIdentifier webPageProxyIdentifier, IncludeExtensionViews includeExtensionViews, IgnoreExtensionAccess ignoreExtensionAccess) const
{
if (includeExtensionViews == IncludeExtensionViews::Yes && m_backgroundWebView && webPageProxyIdentifier == m_backgroundWebView.get()._page->identifier()) {
if (RefPtr window = frontmostWindow())
return window->activeTab();
return nullptr;
}

RefPtr<WebExtensionTab> result;

for (auto entry : m_extensionPageTabMap) {
if (entry.key.identifier() == webPageProxyIdentifier) {
result = m_tabMap.get(entry.value);
// Search actions for the page.
if (includeExtensionViews == IncludeExtensionViews::Yes) {
for (auto entry : m_popupPageActionMap) {
if (entry.key.identifier() != webPageProxyIdentifier)
continue;

RefPtr tab = entry.value->tab();
RefPtr window = tab ? tab->window() : entry.value->window();

if (!tab && window)
tab = window->activeTab();

if (!tab)
continue;

result = tab;
break;
}
}

// Search open tabs for the page.
if (!result) {
for (auto entry : m_extensionPageTabMap) {
if (entry.key.identifier() == webPageProxyIdentifier) {
result = m_tabMap.get(entry.value);
break;
}
}
}

if (!result) {
for (Ref tab : openTabs()) {
for (WKWebView *webView in tab->webViews()) {
Expand Down Expand Up @@ -1536,55 +1567,6 @@ static _WKWebExtensionContextError toAPI(WebExtensionContext::Error error)
return result;
}

RefPtr<WebExtensionTab> WebExtensionContext::getCurrentTab(WebPageProxyIdentifier webPageProxyIdentifier, IgnoreExtensionAccess ignoreExtensionAccess) const
{
if (m_backgroundWebView && webPageProxyIdentifier == m_backgroundWebView.get()._page->identifier()) {
if (RefPtr window = frontmostWindow())
return window->activeTab();
return nullptr;
}

RefPtr<WebExtensionTab> result;

// Search actions for the page.
for (auto entry : m_popupPageActionMap) {
if (entry.key.identifier() != webPageProxyIdentifier)
continue;

RefPtr tab = entry.value->tab();
RefPtr window = tab ? tab->window() : entry.value->window();

if (!tab && window)
tab = window->activeTab();

if (!tab)
continue;

result = tab;
break;
}

// Search open tabs for the page.
if (!result)
result = getTab(webPageProxyIdentifier, std::nullopt, ignoreExtensionAccess);

if (!result) {
RELEASE_LOG_ERROR(Extensions, "Tab for page %{public}llu was not found", webPageProxyIdentifier.toUInt64());
return nullptr;
}

if (!result->isValid()) {
RELEASE_LOG_ERROR(Extensions, "Tab %{public}llu has nil delegate; reference not removed via didCloseTab: before release", result->identifier().toUInt64());
forgetTab(result->identifier());
return nullptr;
}

if (ignoreExtensionAccess == IgnoreExtensionAccess::No && !result->extensionHasAccess())
return nullptr;

return result;
}

void WebExtensionContext::forgetTab(WebExtensionTabIdentifier identifier) const
{
m_tabMap.remove(identifier);
Expand Down
7 changes: 4 additions & 3 deletions Source/WebKit/UIProcess/Extensions/WebExtensionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ class WebExtensionContext : public API::ObjectImpl<API::Object::Type::WebExtensi
enum class SuppressEvents : bool { No, Yes };
enum class UpdateWindowOrder : bool { No, Yes };
enum class IgnoreExtensionAccess : bool { No, Yes };
enum class IncludeExtensionViews : bool { No, Yes };

enum class Error : uint8_t {
Unknown = 1,
Expand Down Expand Up @@ -341,8 +342,8 @@ class WebExtensionContext : public API::ObjectImpl<API::Object::Type::WebExtensi

Ref<WebExtensionTab> getOrCreateTab(_WKWebExtensionTab *) const;
RefPtr<WebExtensionTab> getTab(WebExtensionTabIdentifier, IgnoreExtensionAccess = IgnoreExtensionAccess::No) const;
RefPtr<WebExtensionTab> getTab(WebPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> = std::nullopt, IgnoreExtensionAccess = IgnoreExtensionAccess::No) const;
RefPtr<WebExtensionTab> getCurrentTab(WebPageProxyIdentifier, IgnoreExtensionAccess = IgnoreExtensionAccess::No) const;
RefPtr<WebExtensionTab> getTab(WebPageProxyIdentifier, std::optional<WebExtensionTabIdentifier> = std::nullopt, IncludeExtensionViews = IncludeExtensionViews::No, IgnoreExtensionAccess = IgnoreExtensionAccess::No) const;
RefPtr<WebExtensionTab> getCurrentTab(WebPageProxyIdentifier, IncludeExtensionViews = IncludeExtensionViews::Yes, IgnoreExtensionAccess = IgnoreExtensionAccess::No) const;
void forgetTab(WebExtensionTabIdentifier) const;

void openNewTab(const WebExtensionTabParameters&, CompletionHandler<void(RefPtr<WebExtensionTab>)>&&);
Expand Down Expand Up @@ -726,7 +727,7 @@ class WebExtensionContext : public API::ObjectImpl<API::Object::Type::WebExtensi

// Tabs APIs
void tabsCreate(std::optional<WebPageProxyIdentifier>, const WebExtensionTabParameters&, CompletionHandler<void(Expected<std::optional<WebExtensionTabParameters>, WebExtensionError>&&)>&&);
void tabsUpdate(WebExtensionTabIdentifier, const WebExtensionTabParameters&, CompletionHandler<void(Expected<std::optional<WebExtensionTabParameters>, WebExtensionError>&&)>&&);
void tabsUpdate(WebPageProxyIdentifier, std::optional<WebExtensionTabIdentifier>, const WebExtensionTabParameters&, CompletionHandler<void(Expected<std::optional<WebExtensionTabParameters>, WebExtensionError>&&)>&&);
void tabsDuplicate(WebExtensionTabIdentifier, const WebExtensionTabParameters&, CompletionHandler<void(Expected<std::optional<WebExtensionTabParameters>, WebExtensionError>&&)>&&);
void tabsGet(WebExtensionTabIdentifier, CompletionHandler<void(Expected<std::optional<WebExtensionTabParameters>, WebExtensionError>&&)>&&);
void tabsGetCurrent(WebPageProxyIdentifier, CompletionHandler<void(Expected<std::optional<WebExtensionTabParameters>, WebExtensionError>&&)>&&);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ messages -> WebExtensionContext {

// Tabs APIs
TabsCreate(std::optional<WebKit::WebPageProxyIdentifier> webPageProxyIdentifier, WebKit::WebExtensionTabParameters creationParameters) -> (Expected<std::optional<WebKit::WebExtensionTabParameters>, WebKit::WebExtensionError> result)
TabsUpdate(WebKit::WebExtensionTabIdentifier tabIdentifier, WebKit::WebExtensionTabParameters updateParameters) -> (Expected<std::optional<WebKit::WebExtensionTabParameters>, WebKit::WebExtensionError> result)
TabsUpdate(WebKit::WebPageProxyIdentifier webPageProxyIdentifier, std::optional<WebKit::WebExtensionTabIdentifier> tabIdentifier, WebKit::WebExtensionTabParameters updateParameters) -> (Expected<std::optional<WebKit::WebExtensionTabParameters>, WebKit::WebExtensionError> result)
TabsDuplicate(WebKit::WebExtensionTabIdentifier tabIdentifier, WebKit::WebExtensionTabParameters creationParameters) -> (Expected<std::optional<WebKit::WebExtensionTabParameters>, WebKit::WebExtensionError> result)
TabsGet(WebKit::WebExtensionTabIdentifier tabIdentifier) -> (Expected<std::optional<WebKit::WebExtensionTabParameters>, WebKit::WebExtensionError> result)
TabsGetCurrent(WebKit::WebPageProxyIdentifier webPageProxyIdentifier) -> (Expected<std::optional<WebKit::WebExtensionTabParameters>, WebKit::WebExtensionError> result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ bool isValid(std::optional<WebExtensionTabIdentifier> identifier, NSString **out
if (!parseTabUpdateOptions(properties, parameters, @"properties", outExceptionString))
return;

WebProcess::singleton().sendWithAsyncReply(Messages::WebExtensionContext::TabsUpdate(tabIdentifer.value(), WTFMove(parameters)), [protectedThis = Ref { *this }, callback = WTFMove(callback)](Expected<std::optional<WebExtensionTabParameters>, WebExtensionError>&& result) {
WebProcess::singleton().sendWithAsyncReply(Messages::WebExtensionContext::TabsUpdate(page.webPageProxyIdentifier(), tabIdentifer, WTFMove(parameters)), [protectedThis = Ref { *this }, callback = WTFMove(callback)](Expected<std::optional<WebExtensionTabParameters>, WebExtensionError>&& result) {
if (!result) {
callback->reportError(result.error());
return;
Expand Down
45 changes: 45 additions & 0 deletions Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPIAction.mm
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,51 @@
[manager run];
}

TEST(WKWebExtensionAPIAction, UpdateTabFromPopupPage)
{
auto *popupScript = Util::constructScript(@[
@"const tab = await browser.tabs.getCurrent()",
@"browser.test.assertEq(typeof tab, 'object', 'The tab should be')",
@"browser.test.assertTrue(tab.active, 'The current tab should be active')",

@"browser.test.assertFalse(tab.mutedInfo.muted, 'The tab should not be initially muted')",

@"const updatedTab = await browser.tabs.update({",
@" muted: true,",
@"})",

@"browser.test.assertTrue(updatedTab.mutedInfo.muted, 'The tab should be muted after update')",

@"browser.test.notifyPass()"
]);

auto *backgroundScript = Util::constructScript(@[
@"browser.test.yield('Test Popup Action')"
]);

auto *resources = @{
@"background.js": backgroundScript,
@"popup.html": @"<script type='module' src='popup.js'></script>",
@"popup.js": popupScript
};

auto extension = adoptNS([[_WKWebExtension alloc] _initWithManifestDictionary:actionPopupManifest resources:resources]);
auto manager = adoptNS([[TestWebExtensionManager alloc] initForExtension:extension.get()]);

manager.get().internalDelegate.presentPopupForAction = ^(_WKWebExtensionAction *action) {
EXPECT_TRUE(action.presentsPopup);
EXPECT_NOT_NULL(action.popupWebView);
};

[manager loadAndRun];

EXPECT_NS_EQUAL(manager.get().yieldMessage, @"Test Popup Action");

[manager.get().context performActionForTab:manager.get().defaultTab];

[manager run];
}

TEST(WKWebExtensionAPIAction, SetDefaultActionProperties)
{
auto *popupPage = @"<b>Hello World!</b>";
Expand Down
25 changes: 25 additions & 0 deletions Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebExtensionAPITabs.mm
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,31 @@
[manager loadAndRun];
}

TEST(WKWebExtensionAPITabs, UpdateWithoutTabId)
{
auto *backgroundScript = Util::constructScript(@[
@"const allWindows = await browser.windows.getAll({ populate: true })",
@"const activeTab = allWindows[0].tabs[0]",

@"browser.test.assertFalse(activeTab.mutedInfo.muted, 'The tab should not be initially muted')",

@"const updatedTab = await browser.tabs.update({",
@" muted: true,",
@"})",

@"browser.test.assertTrue(updatedTab.mutedInfo.muted, 'The tab should be muted after update')",

@"browser.test.notifyPass()"
]);

auto extension = adoptNS([[_WKWebExtension alloc] _initWithManifestDictionary:tabsManifest resources:@{ @"background.js": backgroundScript }]);
auto manager = adoptNS([[TestWebExtensionManager alloc] initForExtension:extension.get()]);

EXPECT_EQ(manager.get().defaultWindow.tabs.count, 1lu);

[manager loadAndRun];
}

TEST(WKWebExtensionAPITabs, Get)
{
auto *backgroundScript = Util::constructScript(@[
Expand Down

0 comments on commit 3e55164

Please sign in to comment.