blob: 11088e02384558bfbd83ccdec589f5efa17e0a26 [file] [log] [blame] [edit]
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "config.h"
#import "WebExtensionUtilities.h"
#if ENABLE(WK_WEB_EXTENSIONS_SIDEBAR)
#import <WebKit/WKPreferencesPrivate.h>
#import <WebKit/_WKFeature.h>
#import <WebKit/_WKWebExtensionSidebar.h>
namespace TestWebKitAPI {
#pragma mark - Constants
static constexpr auto *sidebarActionManifest = @{
@"manifest_version": @3,
@"name": @"SidebarAction Test",
@"description": @"SidebarAction Test",
@"version": @"1",
@"permissions": @[],
@"background": @{
@"scripts": @[ @"background.js", ],
@"type": @"module",
@"persistent": @NO,
},
@"sidebar_action": @{
@"default_title": @"Test Sidebar",
@"default_panel": @"sidebar.html",
@"default_icon": @{
@"16": @"sidebar-16.png",
@"32": @"sidebar-32.png",
},
@"open_at_install": @NO,
},
};
static auto *sidePanelManifest = @{
@"manifest_version": @3,
@"name": @"SidePanel Test",
@"description": @"SidePanel Test",
@"version": @"1",
@"permissions": @[ @"sidePanel" ],
@"background": @{
@"scripts": @[ @"background.js" ],
@"type": @"module",
@"persistent": @NO,
},
@"side_panel": @{
@"default_path": @"sidebar.html",
},
@"action": @{
@"default_title": @"Test Action",
@"default_popup": @"sidebar.html",
},
};
static auto *sidebarActionAndPanelManifest = @{
@"manifest_version": @3,
@"name": @"Sidebar Test (both)",
@"description": @"Sidebar Test (both)",
@"version": @"1",
@"permissions": @[ @"sidePanel" ],
@"background": @{
@"scripts": @[ @"background.js" ],
@"type": @"module",
@"persistent": @NO,
},
@"sidebar_action": @{
@"default_title": @"Test Sidebar",
@"default_panel": @"sidebar.html",
@"default_icon": @{
@"16": @"sidebar-16.png",
@"32": @"sidebar-32.png",
},
@"open_at_install": @NO,
},
};
static auto *neitherSidebarActionNorPanelManifest = @{
@"manifest_version": @3,
@"name": @"Sidebar Test (neither)",
@"description": @"Sidebar Test (neither)",
@"version": @"1",
@"permissions": @[],
@"background": @{
@"scripts": @[ @"background.js", ],
@"type": @"module",
@"persistent": @NO,
},
};
#pragma mark - Test Fixture
// This test fixture allows us to use sidebarConfig (which enables the sidebar feature flag) without manually constructing one on each run
class WKWebExtensionAPISidebar : public testing::Test {
protected:
WKWebExtensionAPISidebar()
{
sidebarConfig = WKWebExtensionControllerConfiguration.nonPersistantConfiguration;
if (!sidebarConfig.webViewConfiguration)
sidebarConfig.webViewConfiguration = [[WKWebViewConfiguration alloc] init];
for (_WKFeature *feature in [WKPreferences _features]) {
if ([feature.key isEqualToString:@"WebExtensionSidebarEnabled"])
[sidebarConfig.webViewConfiguration.preferences _setEnabled:YES forFeature:feature];
}
}
RetainPtr<TestWebExtensionManager> getManagerFor(NSArray<NSString *> *script, NSDictionary<NSString *, id> *manifest)
{
return getManagerFor(@{ @"background.js" : Util::constructScript(script) }, manifest);
}
RetainPtr<TestWebExtensionManager> getManagerFor(NSDictionary<NSString *, id> *resources, NSDictionary<NSString *, id> *manifest)
{
return Util::parseExtension(manifest, resources, sidebarConfig);
}
WKWebExtensionControllerConfiguration *sidebarConfig;
RetainPtr<WKWebExtension> extension;
};
#pragma mark - Common Tests
TEST_F(WKWebExtensionAPISidebar, APISUnavailableWhenManifestDoesNotRequest)
{
auto *script = @[
@"browser.test.assertDeepEq(browser.sidebarAction, undefined)",
@"browser.test.assertDeepEq(browser.sidePanel, undefined)",
@"browser.test.notifyPass()",
];
Util::loadAndRunExtension(neitherSidebarActionNorPanelManifest, @{ @"background.js": Util::constructScript(script) }, sidebarConfig);
}
#pragma mark - SidebarAction Tests
TEST_F(WKWebExtensionAPISidebar, SidebarActionAPIAvailableWhenManifestRequests)
{
auto *script = @[
@"browser.test.assertFalse(browser.sidebarAction === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.close === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.getPanel === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.getTitle === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.isOpen === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.open === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.setIcon === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.setPanel === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.setTitle === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.toggle === undefined)",
@"browser.test.assertDeepEq(browser.sidePanel, undefined)",
@"browser.test.notifyPass()",
];
Util::loadAndRunExtension(sidebarActionManifest, @{ @"background.js": Util::constructScript(script) }, sidebarConfig);
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionAPIAvailableWhenManifestRequestsBoth)
{
auto *script = @[
@"browser.test.assertFalse(browser.sidebarAction === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.close === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.getPanel === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.getTitle === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.isOpen === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.open === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.setIcon === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.setPanel === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.setTitle === undefined)",
@"browser.test.assertFalse(browser.sidebarAction.toggle === undefined)",
@"browser.test.assertDeepEq(browser.sidePanel, undefined)",
@"browser.test.notifyPass()",
];
Util::loadAndRunExtension(sidebarActionAndPanelManifest, @{ @"background.js": Util::constructScript(script) }, sidebarConfig);
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionAPIDisallowsMissingArguments)
{
auto *script = @[
@"browser.test.assertThrows(() => browser.sidebarAction.getTitle())",
@"browser.test.assertThrows(() => browser.sidebarAction.setTitle())",
@"browser.test.assertThrows(() => browser.sidebarAction.getPanel())",
@"browser.test.assertThrows(() => browser.sidebarAction.setPanel())",
@"browser.test.assertThrows(() => browser.sidebarAction.isOpen())",
@"browser.test.assertThrows(() => browser.sidebarAction.setIcon())",
@"browser.test.notifyPass()",
];
Util::loadAndRunExtension(sidebarActionManifest, @{ @"background.js": Util::constructScript(script) }, sidebarConfig);
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionAPIGlobalTitlePersists)
{
auto *script = @[
@"await browser.sidebarAction.setTitle({ title: 'Here is a title' })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({}), 'Here is a title')",
@"browser.test.notifyPass()",
];
Util::loadAndRunExtension(sidebarActionManifest, @{ @"background.js": Util::constructScript(script) }, sidebarConfig);
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionAPIWindowSpecificTitlePersists)
{
auto *script = @[
@"let windows = await browser.windows.getAll()",
@"let [window1, window2] = windows",
@"await browser.sidebarAction.setTitle({ windowId: window1.id, title: 'window-specific title' })",
@"await browser.sidebarAction.setTitle({ title: 'global title' })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ windowId: window1.id }), 'window-specific title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({}), 'global title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ windowId: window2.id }), 'global title')",
@"browser.test.notifyPass()",
];
auto manager = getManagerFor(script, sidebarActionManifest);
[manager openNewWindow];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionAPITabSpecificTitlePersists)
{
auto *script = @[
@"let tabs = await browser.tabs.query({})",
@"let [tab1, tab2] = tabs",
@"await browser.sidebarAction.setTitle({ tabId: tab1.id, title: 'tab-specific title' })",
@"await browser.sidebarAction.setTitle({ title: 'global title' })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ tabId: tab1.id }), 'tab-specific title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({}), 'global title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ tabId: tab2.id }), 'global title')",
@"browser.test.notifyPass()",
];
auto manager = getManagerFor(script, sidebarActionManifest);
[manager.get().defaultWindow openNewTab];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionAPIMixedSpecificityTitlesNotConfused)
{
auto *script = @[
@"let allWindows = await browser.windows.getAll()",
@"let [window1, window2] = allWindows",
@"let window1Tabs = await browser.tabs.query({ windowId: window1.id })",
@"let window2Tabs = await browser.tabs.query({ windowId: window2.id })",
@"await browser.sidebarAction.setTitle({ title: 'global title' })",
@"await browser.sidebarAction.setTitle({ windowId: window1.id, title: 'window specific title' })",
@"await browser.sidebarAction.setTitle({ tabId: window1Tabs[0].id, title: 'window 1 tab specific title' })",
@"await browser.sidebarAction.setTitle({ tabId: window2Tabs[0].id, title: 'window 2 tab specific title' })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ tabId: window1Tabs[0].id }), 'window 1 tab specific title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ tabId: window1Tabs[1].id }), 'window specific title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ windowId: window1.id }), 'window specific title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ tabId: window2Tabs[0].id }), 'window 2 tab specific title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ tabId: window2Tabs[1].id }), 'global title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ windowId: window2.id }), 'global title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({}), 'global title')",
@"browser.test.notifyPass()",
];
auto manager = getManagerFor(script, sidebarActionManifest);
[manager.get().defaultWindow openNewTab];
auto window2 = [manager openNewWindow];
[window2 openNewTab];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionAPIWindowSpecificPanelPersists)
{
auto *script = @[
@"let windows = await browser.windows.getAll()",
@"let [window1, window2] = windows",
@"await browser.sidebarAction.setPanel({ windowId: window1.id, panel: '/sidebar-1.html' })",
@"await browser.sidebarAction.setPanel({ panel: '/sidebar-2.html' })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ windowId: window1.id }), '/sidebar-1.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), '/sidebar-2.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ windowId: window2.id }), '/sidebar-2.html')",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js" : Util::constructScript(script),
@"sidebar-1.html" : @"<h1>Sidebar 1</h1>",
@"sidebar-2.html" : @"<h1>Sidebar 2</h1>",
};
auto manager = getManagerFor(resources, sidebarActionManifest);
[manager openNewWindow];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionAPITabSpecificDocumentPersists)
{
auto *script = @[
@"let tabs = await browser.tabs.query({})",
@"let [tab1, tab2] = tabs",
@"await browser.sidebarAction.setPanel({ tabId: tab1.id, panel: '/sidebar-1.html' })",
@"await browser.sidebarAction.setPanel({ panel: '/sidebar-2.html' })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ tabId: tab1.id }), '/sidebar-1.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), '/sidebar-2.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ tabId: tab2.id }), '/sidebar-2.html')",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js" : Util::constructScript(script),
@"sidebar-1.html" : @"<h1>Sidebar 1</h1>",
@"sidebar-2.html" : @"<h1>Sidebar 2</h1>",
};
auto manager = getManagerFor(resources, sidebarActionManifest);
[manager openNewWindow];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionDocumentsMixedSpecificityNotConfused)
{
auto *script = @[
@"let allWindows = await browser.windows.getAll()",
@"let [window1, window2] = allWindows",
@"let window1Tabs = await browser.tabs.query({ windowId: window1.id })",
@"let window2Tabs = await browser.tabs.query({ windowId: window2.id })",
@"await browser.sidebarAction.setPanel({ panel: '/global-sidebar.html' })",
@"await browser.sidebarAction.setPanel({ windowId: window1.id, panel: '/window-1-window-sidebar.html' })",
@"await browser.sidebarAction.setPanel({ tabId: window1Tabs[0].id, panel: '/window-1-tab-sidebar.html' })",
@"await browser.sidebarAction.setPanel({ tabId: window2Tabs[0].id, panel: '/window-2-tab-sidebar.html' })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ tabId: window1Tabs[0].id }), '/window-1-tab-sidebar.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ tabId: window1Tabs[1].id }), '/window-1-window-sidebar.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ windowId: window1.id }), '/window-1-window-sidebar.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ tabId: window2Tabs[0].id }), '/window-2-tab-sidebar.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ tabId: window2Tabs[1].id }), '/global-sidebar.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ windowId: window2.id }), '/global-sidebar.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), '/global-sidebar.html')",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js" : Util::constructScript(script),
@"window1-window-sidebar.html" : @"<h1>Window 1 Window Sidebar</h1>",
@"window1-tab-sidebar.html" : @"<h1>Window 1 Tab Sidebar</h1>",
@"window2-tab-sidebar.html" : @"<h1>Window 2 Tab Sidebar</h1>",
@"global-sidebar.html" : @"<h1>Global Sidebar</h1>",
};
auto manager = getManagerFor(resources, sidebarActionManifest);
[manager.get().defaultWindow openNewTab];
auto window2 = [manager openNewWindow];
[window2 openNewTab];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionChangeGlobalTitle)
{
auto *script = @[
@"await browser.sidebarAction.setTitle({ title: 'Here is a title' })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({}), 'Here is a title')",
@"await browser.sidebarAction.setTitle({ title: 'Here is a different title' })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({}), 'Here is a different title')",
@"browser.test.notifyPass()",
];
Util::loadAndRunExtension(sidebarActionManifest, @{ @"background.js": Util::constructScript(script) }, sidebarConfig);
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionChangeWindowTitle)
{
auto *script = @[
@"let windows = await browser.windows.getAll()",
@"let [window1, window2] = windows",
@"await browser.sidebarAction.setTitle({ title: 'global title' })",
@"await browser.sidebarAction.setTitle({ windowId: window1.id, title: 'window-specific title' })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ windowId: window1.id }), 'window-specific title')",
@"await browser.sidebarAction.setTitle({ windowId: window1.id, title: 'another window-specific title' })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ windowId: window1.id }), 'another window-specific title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({}), 'global title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ windowId: window2.id }), 'global title')",
@"browser.test.notifyPass()",
];
auto manager = getManagerFor(script, sidebarActionManifest);
[manager openNewWindow];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionChangeTabTitle)
{
auto *script = @[
@"let tabs = await browser.tabs.query({})",
@"let [tab1, tab2] = tabs",
@"await browser.sidebarAction.setTitle({ tabId: tab1.id, title: 'tab-specific title' })",
@"await browser.sidebarAction.setTitle({ title: 'global title' })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ tabId: tab1.id }), 'tab-specific title')",
@"await browser.sidebarAction.setTitle({ tabId: tab1.id, title: 'new tab-specific title' })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ tabId: tab1.id }), 'new tab-specific title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({}), 'global title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ tabId: tab2.id }), 'global title')",
@"browser.test.notifyPass()",
];
auto manager = getManagerFor(script, sidebarActionManifest);
[manager.get().defaultWindow openNewTab];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionChangeGlobalPanel)
{
auto *script = @[
@"await browser.sidebarAction.setPanel({ panel: '/sidebar-1.html' })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), '/sidebar-1.html')",
@"await browser.sidebarAction.setPanel({ panel: '/sidebar-2.html' })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), '/sidebar-2.html')",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js" : Util::constructScript(script),
@"sidebar-1.html" : @"<h1>Sidebar 1</h1>",
@"sidebar-2.html" : @"<h1>Sidebar 2</h1>",
};
auto manager = getManagerFor(resources, sidebarActionManifest);
[manager openNewWindow];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionChangeWindowPanel)
{
auto *script = @[
@"let windows = await browser.windows.getAll()",
@"let [window1, window2] = windows",
@"await browser.sidebarAction.setPanel({ panel: '/sidebar-global.html' })",
@"await browser.sidebarAction.setPanel({ windowId: window1.id, panel: '/sidebar-1.html' })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ windowId: window1.id }), '/sidebar-1.html')",
@"await browser.sidebarAction.setPanel({ windowId: window1.id, panel: '/sidebar-2.html' })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ windowId: window1.id }), '/sidebar-2.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), '/sidebar-global.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ windowId: window2.id }), '/sidebar-global.html')",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js" : Util::constructScript(script),
@"sidebar-global.html" : @"<h1>Global Sidebar</h1>",
@"sidebar-1.html" : @"<h1>Sidebar 2</h1>",
@"sidebar-2.html" : @"<h1>Sidebar 2</h1>",
};
auto manager = getManagerFor(resources, sidebarActionManifest);
[manager openNewWindow];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionChangeTabPanel)
{
auto *script = @[
@"let tabs = await browser.tabs.query({})",
@"let [tab1, tab2] = tabs",
@"await browser.sidebarAction.setPanel({ panel: '/sidebar-global.html' })",
@"await browser.sidebarAction.setPanel({ tabId: tab1.id, panel: '/sidebar-1.html' })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ tabId: tab1.id }), '/sidebar-1.html')",
@"await browser.sidebarAction.setPanel({ tabId: tab1.id, panel: '/sidebar-2.html' })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ tabId: tab1.id }), '/sidebar-2.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), '/sidebar-global.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ tabId: tab2.id }), '/sidebar-global.html')",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js" : Util::constructScript(script),
@"sidebar-global.html" : @"<h1>Global Sidebar</h1>",
@"sidebar-1.html" : @"<h1>Sidebar 2</h1>",
@"sidebar-2.html" : @"<h1>Sidebar 2</h1>",
};
auto manager = getManagerFor(resources, sidebarActionManifest);
[manager openNewWindow];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionClearGlobalTitle)
{
auto *script = @[
@"browser.test.assertEq(await browser.sidebarAction.getTitle({}), 'Test Sidebar')",
@"await browser.sidebarAction.setTitle({ title: 'A new global title' })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({}), 'A new global title')",
@"await browser.sidebarAction.setTitle({ title: null })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({}), 'Test Sidebar')",
@"browser.test.notifyPass()",
];
Util::loadAndRunExtension(sidebarActionManifest, @{ @"background.js": Util::constructScript(script) }, sidebarConfig);
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionClearWindowTitle)
{
auto *script = @[
@"let windows = await browser.windows.getAll()",
@"let [window1, window2] = windows",
@"await browser.sidebarAction.setTitle({ title: 'global title' })",
@"await browser.sidebarAction.setTitle({ windowId: window1.id, title: 'window-specific title' })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ windowId: window1.id }), 'window-specific title')",
@"await browser.sidebarAction.setTitle({ windowId: window1.id, title: null })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ windowId: window1.id }), 'global title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({}), 'global title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ windowId: window2.id }), 'global title')",
@"browser.test.notifyPass()",
];
auto manager = getManagerFor(script, sidebarActionManifest);
[manager openNewWindow];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionClearTabTitle)
{
auto *script = @[
@"let tabs = await browser.tabs.query({})",
@"let [tab1, tab2] = tabs",
@"await browser.sidebarAction.setTitle({ tabId: tab1.id, title: 'tab-specific title' })",
@"await browser.sidebarAction.setTitle({ title: 'global title' })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ tabId: tab1.id }), 'tab-specific title')",
@"await browser.sidebarAction.setTitle({ tabId: tab1.id, title: null })",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ tabId: tab1.id }), 'global title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({}), 'global title')",
@"browser.test.assertEq(await browser.sidebarAction.getTitle({ tabId: tab2.id }), 'global title')",
@"browser.test.notifyPass()",
];
auto manager = getManagerFor(script, sidebarActionManifest);
[manager.get().defaultWindow openNewTab];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionClearGlobalPanel)
{
auto *script = @[
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), 'sidebar.html')",
@"await browser.sidebarAction.setPanel({ panel: '/sidebar-1.html' })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), '/sidebar-1.html')",
@"await browser.sidebarAction.setPanel({ panel: null })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), 'sidebar.html')",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js" : Util::constructScript(script),
@"sidebar-1.html" : @"<h1>Sidebar 1</h1>",
};
auto manager = getManagerFor(resources, sidebarActionManifest);
[manager openNewWindow];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionClearWindowPanel)
{
auto *script = @[
@"let windows = await browser.windows.getAll()",
@"let [window1, window2] = windows",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), 'sidebar.html')",
@"await browser.sidebarAction.setPanel({ windowId: window1.id, panel: '/sidebar-1.html' })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ windowId: window1.id }), '/sidebar-1.html')",
@"await browser.sidebarAction.setPanel({ windowId: window1.id, panel: null })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ windowId: window1.id }), 'sidebar.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), 'sidebar.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ windowId: window2.id }), 'sidebar.html')",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js" : Util::constructScript(script),
@"sidebar-1.html" : @"<h1>Sidebar 1</h1>",
};
auto manager = getManagerFor(resources, sidebarActionManifest);
[manager openNewWindow];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionClearTabPanel)
{
auto *script = @[
@"let tabs = await browser.tabs.query({})",
@"let [tab1, tab2] = tabs",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), 'sidebar.html')",
@"await browser.sidebarAction.setPanel({ tabId: tab1.id, panel: '/sidebar-1.html' })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ tabId: tab1.id }), '/sidebar-1.html')",
@"await browser.sidebarAction.setPanel({ tabId: tab1.id, panel: null })",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ tabId: tab1.id }), 'sidebar.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({}), 'sidebar.html')",
@"browser.test.assertEq(await browser.sidebarAction.getPanel({ tabId: tab2.id }), 'sidebar.html')",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js" : Util::constructScript(script),
@"sidebar-1.html" : @"<h1>Sidebar 1</h1>",
};
auto manager = getManagerFor(resources, sidebarActionManifest);
[manager openNewWindow];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionOpenFailsWithoutUserGesture)
{
auto *script = @[
@"browser.test.assertThrows(() => browser.sidebarAction.open())",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js": Util::constructScript(script),
@"sidebar.html": @"<h1>Sidebar</h1>",
};
int presentSidebarCallCount = 0;
int *presentSidebarCallCountPtr = &presentSidebarCallCount;
auto manager = getManagerFor(resources, sidebarActionManifest);
manager.get().internalDelegate.presentSidebar = ^(_WKWebExtensionSidebar *) {
(*presentSidebarCallCountPtr)++;
};
[manager loadAndRun];
EXPECT_EQ(presentSidebarCallCount, 0);
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionCloseFailsWithoutUserGesture)
{
auto *script = @[
@"browser.test.assertThrows(() => browser.sidebarAction.close())",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js": Util::constructScript(script),
@"sidebar.html": @"<h1>Sidebar</h1>",
};
int closeSidebarCallCount = 0;
int *closeSidebarCallCountPtr = &closeSidebarCallCount;
auto manager = getManagerFor(resources, sidebarActionManifest);
manager.get().internalDelegate.closeSidebar = ^(_WKWebExtensionSidebar *) {
(*closeSidebarCallCountPtr)++;
};
[manager loadAndRun];
EXPECT_EQ(closeSidebarCallCount, 0);
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionToggleFailsWithoutUserGesture)
{
auto *script = @[
@"browser.test.assertThrows(() => browser.sidebarAction.toggle())",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js": Util::constructScript(script),
@"sidebar.html": @"<h1>Sidebar</h1>",
};
int openSidebarCallCount = 0;
int *openSidebarCallCountPtr = &openSidebarCallCount;
int closeSidebarCallCount = 0;
int *closeSidebarCallCountPtr = &closeSidebarCallCount;
auto manager = getManagerFor(resources, sidebarActionManifest);
manager.get().internalDelegate.presentSidebar = ^(_WKWebExtensionSidebar *) {
(*openSidebarCallCountPtr)++;
};
manager.get().internalDelegate.closeSidebar = ^(_WKWebExtensionSidebar *) {
(*closeSidebarCallCountPtr)++;
};
[manager loadAndRun];
EXPECT_EQ(openSidebarCallCount, 0);
EXPECT_EQ(closeSidebarCallCount, 0);
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionOpenSucceedsWithUserGesture)
{
auto *script = @[
@"await browser.test.runWithUserGesture(() => {",
@" return browser.test.assertSafeResolve(() => browser.sidebarAction.open())",
@"})",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js": Util::constructScript(script),
@"sidebar.html": @"<h1>Sidebar</h1>",
};
int presentSidebarCallCount = 0;
int *presentSidebarCallCountPtr = &presentSidebarCallCount;
auto manager = getManagerFor(resources, sidebarActionManifest);
manager.get().internalDelegate.presentSidebar = ^(_WKWebExtensionSidebar *sidebar) {
(*presentSidebarCallCountPtr)++;
EXPECT_NOT_NULL(sidebar.associatedTab);
EXPECT_NOT_NULL(sidebar.webExtensionContext);
EXPECT_NOT_NULL(sidebar.title);
EXPECT_NOT_NULL(sidebar.webView);
EXPECT_NOT_NULL(sidebar.viewController);
NSURL *webViewURL = sidebar.webView.URL;
EXPECT_NS_EQUAL(webViewURL.scheme, @"webkit-extension");
EXPECT_NS_EQUAL(webViewURL.path, @"/sidebar.html");
};
[manager loadAndRun];
EXPECT_EQ(presentSidebarCallCount, 1);
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionCloseSucceedsWithUserGesture)
{
auto *script = @[
@"await browser.test.runWithUserGesture(() => {",
@" return browser.test.assertSafeResolve(() => browser.sidebarAction.close())",
@"})",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js": Util::constructScript(script),
@"sidebar.html": @"<h1>Sidebar</h1>",
};
int closeSidebarCallCount = 0;
int *closeSidebarCallCountPtr = &closeSidebarCallCount;
auto manager = getManagerFor(resources, sidebarActionManifest);
manager.get().internalDelegate.closeSidebar = ^(_WKWebExtensionSidebar *sidebar) {
(*closeSidebarCallCountPtr)++;
// Make sure all the properties are still there when delegate closeSidebar is called, since the sidebar is still displayed at the moment of the call
EXPECT_NOT_NULL(sidebar.associatedTab);
EXPECT_NOT_NULL(sidebar.webExtensionContext);
EXPECT_NOT_NULL(sidebar.title);
EXPECT_NOT_NULL(sidebar.webView);
EXPECT_NOT_NULL(sidebar.viewController);
NSURL *webViewURL = sidebar.webView.URL;
EXPECT_NS_EQUAL(webViewURL.scheme, @"webkit-extension");
EXPECT_NS_EQUAL(webViewURL.path, @"/sidebar.html");
};
[manager loadAndRun];
EXPECT_EQ(closeSidebarCallCount, 1);
}
TEST_F(WKWebExtensionAPISidebar, SidebarActionToggleSucceedsWithUserGesture)
{
auto *script = @[
@"await browser.test.runWithUserGesture(() => {",
@" return browser.test.assertSafeResolve(() => browser.sidebarAction.toggle())",
@"})",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js": Util::constructScript(script),
@"sidebar.html": @"<h1>Sidebar</h1>",
};
int openSidebarCallCount = 0;
int *openSidebarCallCountPtr = &openSidebarCallCount;
auto manager = getManagerFor(resources, sidebarActionManifest);
manager.get().internalDelegate.presentSidebar = ^(_WKWebExtensionSidebar *) {
(*openSidebarCallCountPtr)++;
};
[manager loadAndRun];
EXPECT_EQ(openSidebarCallCount, 1);
}
#pragma mark - SidePanel Tests
TEST_F(WKWebExtensionAPISidebar, SidePanelAPIAvailableWhenManifestRequests)
{
auto *script = @[
@"browser.test.assertFalse(browser.sidePanel === undefined)",
@"browser.test.assertFalse(browser.sidePanel?.open === undefined)",
@"browser.test.assertFalse(browser.sidePanel?.getOptions === undefined)",
@"browser.test.assertFalse(browser.sidePanel?.setOptions === undefined)",
@"browser.test.assertFalse(browser.sidePanel?.getPanelBehavior === undefined)",
@"browser.test.assertFalse(browser.sidePanel?.setPanelBehavior === undefined)",
@"browser.test.assertDeepEq(browser.sidebarAction, undefined)",
@"browser.test.notifyPass()",
];
Util::loadAndRunExtension(sidePanelManifest, @{ @"background.js": Util::constructScript(script) }, sidebarConfig);
}
TEST_F(WKWebExtensionAPISidebar, SidePanelAPIDisallowsMissingArguments)
{
auto *script = @[
@"browser.test.assertThrows(() => browser.sidePanel.getOptions())",
@"browser.test.assertThrows(() => browser.sidePanel.setOptions())",
@"browser.test.assertThrows(() => browser.sidePanel.setPanelBehavior())",
@"browser.test.assertThrows(() => browser.sidePanel.open())",
@"browser.test.notifyPass()",
];
Util::loadAndRunExtension(sidePanelManifest, @{ @"background.js": Util::constructScript(script) }, sidebarConfig);
}
TEST_F(WKWebExtensionAPISidebar, SidePanelAPIGlobalPathPersists)
{
auto *script = @[
@"await browser.sidePanel.setOptions({ path: '/sidebar-1.html' })",
@"let options = await browser.sidePanel.getOptions({})",
@"browser.test.assertEq(options.path, '/sidebar-1.html')",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js": Util::constructScript(script),
@"sidebar-1.html": @"<h1>Sidebar 1</h1>",
};
Util::loadAndRunExtension(sidePanelManifest, resources, sidebarConfig);
}
TEST_F(WKWebExtensionAPISidebar, SidePanelAPITabPathPersists)
{
auto *script = @[
@"let tabs = await browser.tabs.query({})",
@"let [tab1, tab2] = tabs",
@"await browser.sidePanel.setOptions({ tabId: tab1.id, path: '/sidebar-1.html' })",
@"await browser.sidePanel.setOptions({ path: '/sidebar-global.html' })",
@"let tabOptions = await browser.sidePanel.getOptions({ tabId: tab1.id })",
@"let otherTabOptions = await browser.sidePanel.getOptions({ tabId: tab2.id })",
@"let globalOptions = await browser.sidePanel.getOptions({})",
@"browser.test.assertEq(tabOptions.path, '/sidebar-1.html')",
@"browser.test.assertEq(otherTabOptions.path, '/sidebar-global.html')",
@"browser.test.assertEq(globalOptions.path, '/sidebar-global.html')",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js": Util::constructScript(script),
@"sidebar-global.html": @"<h1>Global Sidebar</h1>",
@"sidebar-1.html": @"<h1>Sidebar 1</h1>",
};
auto manager = getManagerFor(resources, sidePanelManifest);
[manager.get().defaultWindow openNewTab];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidePanelAPIGlobalEnablePersists)
{
auto *script = @[
@"let startingOptions = await browser.sidePanel.getOptions({})",
@"browser.test.assertTrue(startingOptions.enabled)",
@"await browser.sidePanel.setOptions({ enabled: false })",
@"let options = await browser.sidePanel.getOptions({})",
@"browser.test.assertFalse(options.enabled)",
@"browser.test.notifyPass()",
];
Util::loadAndRunExtension(sidePanelManifest, @{ @"background.js": Util::constructScript(script) }, sidebarConfig);
}
TEST_F(WKWebExtensionAPISidebar, SidePanelAPITabEnablePersists)
{
auto *script = @[
@"let tabs = await browser.tabs.query({})",
@"let [tab1, tab2] = tabs",
@"let startingOptions = await browser.sidePanel.getOptions({})",
@"browser.test.assertTrue(startingOptions.enabled)",
@"await browser.sidePanel.setOptions({ tabId: tab1.id, enabled: false })",
@"let tabOptions = await browser.sidePanel.getOptions({ tabId: tab1.id })",
@"let otherTabOptions = await browser.sidePanel.getOptions({ tabId: tab2.id })",
@"let globalOptions = await browser.sidePanel.getOptions({})",
@"browser.test.assertFalse(tabOptions.enabled)",
@"browser.test.assertTrue(otherTabOptions.enabled)",
@"browser.test.assertTrue(globalOptions.enabled)",
@"browser.test.notifyPass()",
];
auto manager = getManagerFor(script, sidePanelManifest);
[manager.get().defaultWindow openNewTab];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidePanelAPIModifyGlobalPath)
{
auto *script = @[
@"await browser.sidePanel.setOptions({ path: '/sidebar-1.html' })",
@"let preModOptions = await browser.sidePanel.getOptions({})",
@"browser.test.assertEq(preModOptions.path, '/sidebar-1.html')",
@"await browser.sidePanel.setOptions({ path: '/sidebar-2.html' })",
@"let postModOptions = await browser.sidePanel.getOptions({})",
@"browser.test.assertEq(postModOptions.path, '/sidebar-2.html')",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js" : Util::constructScript(script),
@"sidebar-1.html" : @"<h1>Sidebar 1</h1>",
@"sidebar-2.html" : @"<h1>Sidebar 2</h1>",
};
Util::loadAndRunExtension(sidePanelManifest, resources, sidebarConfig);
}
TEST_F(WKWebExtensionAPISidebar, SidePanelAPIModifyTabPath)
{
auto *script = @[
@"let tabs = await browser.tabs.query({})",
@"let [tab1, tab2] = tabs",
@"await browser.sidePanel.setOptions({ tabId: tab1.id, path: '/sidebar-1.html' })",
@"await browser.sidePanel.setOptions({ path: '/sidebar-global.html' })",
@"let preModTabOptions = await browser.sidePanel.getOptions({ tabId: tab1.id })",
@"browser.test.assertEq(preModTabOptions.path, '/sidebar-1.html')",
@"await browser.sidePanel.setOptions({ tabId: tab1.id, path: '/sidebar-2.html' })",
@"let postModTabOptions = await browser.sidePanel.getOptions({ tabId: tab1.id })",
@"browser.test.assertEq(postModTabOptions.path, '/sidebar-2.html')",
@"let otherTabOptions = await browser.sidePanel.getOptions({ tabId: tab2.id })",
@"let globalOptions = await browser.sidePanel.getOptions({})",
@"browser.test.assertEq(otherTabOptions.path, '/sidebar-global.html')",
@"browser.test.assertEq(globalOptions.path, '/sidebar-global.html')",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js" : Util::constructScript(script),
@"sidebar-global.html" : @"<h1>Global Sidebar</h1>",
@"sidebar-1.html" : @"<h1>Sidebar 1</h1>",
@"sidebar-2.html" : @"<h1>Sidebar 2</h1>",
};
auto manager = getManagerFor(resources, sidePanelManifest);
[manager.get().defaultWindow openNewTab];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidePanelModifyGlobalEnable)
{
auto *script = @[
@"let startingOptions = await browser.sidePanel.getOptions({})",
@"browser.test.assertTrue(startingOptions.enabled)",
@"await browser.sidePanel.setOptions({ enabled: false })",
@"let preModOptions = await browser.sidePanel.getOptions({})",
@"browser.test.assertFalse(preModOptions.enabled)",
@"await browser.sidePanel.setOptions({ enabled: true })",
@"let postModOptions = await browser.sidePanel.getOptions({})",
@"browser.test.assertTrue(postModOptions.enabled)",
@"browser.test.notifyPass()",
];
Util::loadAndRunExtension(sidePanelManifest, @{ @"background.js": Util::constructScript(script) }, sidebarConfig);
}
TEST_F(WKWebExtensionAPISidebar, SidePanelModifyTabEnable)
{
auto *script = @[
@"let tabs = await browser.tabs.query({})",
@"let [tab1, tab2] = tabs",
@"await browser.sidePanel.setOptions({ enabled: true })",
@"await browser.sidePanel.setOptions({ tabId: tab1.id, enabled: true })",
@"let preModTabOptions = await browser.sidePanel.getOptions({ tabId: tab1.id })",
@"browser.test.assertTrue(preModTabOptions.enabled)",
@"await browser.sidePanel.setOptions({ tabId: tab1.id, enabled: false })",
@"let postModTabOptions = await browser.sidePanel.getOptions({ tabId: tab1.id })",
@"browser.test.assertFalse(postModTabOptions.enabled)",
@"let otherTabOptions = await browser.sidePanel.getOptions({ tabId: tab2.id })",
@"let globalOptions = await browser.sidePanel.getOptions({})",
@"browser.test.assertTrue(otherTabOptions.enabled)",
@"browser.test.assertTrue(globalOptions.enabled)",
@"browser.test.notifyPass()",
];
auto manager = getManagerFor(script, sidePanelManifest);
[manager.get().defaultWindow openNewTab];
[manager loadAndRun];
}
TEST_F(WKWebExtensionAPISidebar, SidePanelOpenForTabFailsWithoutUserGesture)
{
auto *script = @[
@"let tabs = await browser.tabs.query({})",
@"await browser.sidePanel.open({ tabId: tabs[0].id })",
@" .then(() => browser.test.notifyFail('sidePanel.open() did not throw without user gesture'))",
@" .catch(() => browser.test.notifyPass())",
];
auto *resources = @{
@"background.js": Util::constructScript(script),
@"sidebar.html": @"<h1>Sidebar</h1>",
};
int presentSidebarCallCount = 0;
int *presentSidebarCallCountPtr = &presentSidebarCallCount;
auto manager = getManagerFor(resources, sidePanelManifest);
manager.get().internalDelegate.presentSidebar = ^(_WKWebExtensionSidebar *) {
(*presentSidebarCallCountPtr)++;
};
[manager loadAndRun];
EXPECT_EQ(presentSidebarCallCount, 0);
}
TEST_F(WKWebExtensionAPISidebar, SidePanelOpenForWindowFailsWithoutUserGesture)
{
auto *script = @[
@"let window = await browser.windows.getCurrent()",
@"await browser.sidePanel.open({ windowId: window.id })",
@" .then(() => browser.test.notifyFail('sidePanel.open() did not throw without user gesture'))",
@" .catch(() => browser.test.notifyPass())",
];
auto *resources = @{
@"background.js": Util::constructScript(script),
@"sidebar.html": @"<h1>Sidebar</h1>",
};
int presentSidebarCallCount = 0;
int *presentSidebarCallCountPtr = &presentSidebarCallCount;
auto manager = getManagerFor(resources, sidePanelManifest);
manager.get().internalDelegate.presentSidebar = ^(_WKWebExtensionSidebar *) {
(*presentSidebarCallCountPtr)++;
};
[manager loadAndRun];
EXPECT_EQ(presentSidebarCallCount, 0);
}
TEST_F(WKWebExtensionAPISidebar, SidePanelOpenForTabSucceedsWithUserGesture)
{
auto *script = @[
@"var tabs = await browser.tabs.query({})",
@"await browser.test.runWithUserGesture(() => {",
@" return browser.test.assertSafeResolve(() => browser.sidePanel.open({ tabId: tabs[0].id }))",
@"})",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js": Util::constructScript(script),
@"sidebar.html": @"<h1>Sidebar</h1>",
};
int presentSidebarCallCount = 0;
int *presentSidebarCallCountPtr = &presentSidebarCallCount;
auto manager = getManagerFor(resources, sidePanelManifest);
manager.get().internalDelegate.presentSidebar = ^(_WKWebExtensionSidebar *sidebar) {
(*presentSidebarCallCountPtr)++;
EXPECT_NOT_NULL(sidebar.associatedTab);
EXPECT_NOT_NULL(sidebar.webExtensionContext);
EXPECT_NOT_NULL(sidebar.title);
EXPECT_NOT_NULL(sidebar.webView);
EXPECT_NOT_NULL(sidebar.viewController);
NSURL *webViewURL = sidebar.webView.URL;
EXPECT_NS_EQUAL(webViewURL.scheme, @"webkit-extension");
EXPECT_NS_EQUAL(webViewURL.path, @"/sidebar.html");
};
[manager loadAndRun];
EXPECT_EQ(presentSidebarCallCount, 1);
}
TEST_F(WKWebExtensionAPISidebar, SidePanelOpenForWindowSucceedsWithUserGesture)
{
auto *script = @[
@"var currentWindow = await browser.windows.getCurrent()",
@"await browser.test.runWithUserGesture(() => {",
@" return browser.test.assertSafeResolve(() => browser.sidePanel.open({ windowId: currentWindow.id }))",
@"})",
@"browser.test.notifyPass()",
];
auto *resources = @{
@"background.js": Util::constructScript(script),
@"sidebar.html": @"<h1>Sidebar</h1>",
};
int presentSidebarCallCount = 0;
int *presentSidebarCallCountPtr = &presentSidebarCallCount;
auto manager = getManagerFor(resources, sidePanelManifest);
auto *defaultWindow = [manager defaultWindow];
auto *newWindow = [manager openNewWindow];
[manager focusWindow:defaultWindow];
manager.get().internalDelegate.presentSidebar = ^(_WKWebExtensionSidebar *sidebar) {
(*presentSidebarCallCountPtr)++;
EXPECT_NOT_NULL(sidebar.associatedTab);
EXPECT_NOT_NULL(sidebar.webExtensionContext);
EXPECT_NOT_NULL(sidebar.title);
EXPECT_NOT_NULL(sidebar.webView);
EXPECT_NOT_NULL(sidebar.viewController);
NSURL *webViewURL = sidebar.webView.URL;
EXPECT_NS_EQUAL(webViewURL.scheme, @"webkit-extension");
EXPECT_NS_EQUAL(webViewURL.path, @"/sidebar.html");
EXPECT_FALSE([newWindow.tabs containsObject:sidebar.associatedTab]);
EXPECT_TRUE([defaultWindow.tabs containsObject:sidebar.associatedTab]);
};
[manager loadAndRun];
EXPECT_EQ(presentSidebarCallCount, 1);
}
TEST_F(WKWebExtensionAPISidebar, SidePanelSetPanelBehaviorPersists)
{
auto *script = @[
@"let panelBehavior = await browser.sidePanel.getPanelBehavior()",
@"browser.test.assertFalse(panelBehavior.openPanelOnActionClick)",
@"await browser.test.assertSafeResolve(() => browser.sidePanel.setPanelBehavior({ openPanelOnActionClick: true }))",
@"let newPanelBehavior = await browser.sidePanel.getPanelBehavior()",
@"browser.test.assertTrue(newPanelBehavior.openPanelOnActionClick)",
@"await browser.test.assertSafeResolve(() => browser.sidePanel.setPanelBehavior({ openPanelOnActionClick: false }))",
@"let newNewPanelBehavior = await browser.sidePanel.getPanelBehavior()",
@"browser.test.assertFalse(newNewPanelBehavior.openPanelOnActionClick)",
@"browser.test.notifyPass()",
];
Util::loadAndRunExtension(sidePanelManifest, @{ @"background.js": Util::constructScript(script) }, sidebarConfig);
}
TEST_F(WKWebExtensionAPISidebar, SidePanelOpensSidebarOnActionClickWhenConfigured)
{
auto *script = @[
@"await browser.sidePanel.setPanelBehavior({ openPanelOnActionClick: true })",
@"let initialPanelBehavior = await browser.sidePanel.getPanelBehavior()",
@"browser.test.assertTrue(initialPanelBehavior.openPanelOnActionClick)",
@"browser.test.sendMessage('Perform action')",
@"await browser.sidePanel.setPanelBehavior({ openPanelOnActionClick: false })",
@"let newPanelBehavior = await browser.sidePanel.getPanelBehavior()",
@"browser.test.assertFalse(newPanelBehavior.openPanelOnActionClick)",
@"browser.test.sendMessage('Perform action again')",
];
auto *resources = @{
@"background.js": Util::constructScript(script),
@"sidebar.html": @"<h1>Sidebar</h1>",
};
int presentSidebarCallCount = 0;
int *presentSidebarCallCountPtr = &presentSidebarCallCount;
int presentActionPopupCallCount = 0;
int *presentActionPopupCallCountPtr = &presentActionPopupCallCount;
auto manager = getManagerFor(resources, sidePanelManifest);
manager.get().internalDelegate.presentPopupForAction = ^(WKWebExtensionAction *action) {
(*presentActionPopupCallCountPtr)++;
[manager done];
};
manager.get().internalDelegate.presentSidebar = ^(_WKWebExtensionSidebar *) {
(*presentSidebarCallCountPtr)++;
};
[manager load];
[manager runUntilTestMessage:@"Perform action"];
[manager.get().context performActionForTab:manager.get().defaultTab];
[manager runUntilTestMessage:@"Perform action again"];
EXPECT_EQ(presentSidebarCallCount, 1);
EXPECT_EQ(presentActionPopupCallCount, 0);
[manager.get().context performActionForTab:manager.get().defaultTab];
[manager run];
EXPECT_EQ(presentSidebarCallCount, 1);
EXPECT_EQ(presentActionPopupCallCount, 1);
}
} // namespace TestWebKitAPI
#endif // ENABLE(WK_WEB_EXTENSIONS_SIDEBAR)