Diff
Modified: trunk/Tools/ChangeLog (292771 => 292772)
--- trunk/Tools/ChangeLog 2022-04-12 15:28:56 UTC (rev 292771)
+++ trunk/Tools/ChangeLog 2022-04-12 16:01:30 UTC (rev 292772)
@@ -1,3 +1,14 @@
+2022-04-12 Youenn Fablet <[email protected]>
+
+ Add persistent notification click API test
+ https://bugs.webkit.org/show_bug.cgi?id=238995
+
+ Reviewed by Brady Eidson.
+
+ * TestWebKitAPI/TestNotificationProvider.cpp:
+ * TestWebKitAPI/TestNotificationProvider.h:
+ * TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm:
+
2022-04-12 Carlos Alberto Lopez Perez <[email protected]>
[GTK][WPE] generate-bundle: fix typo/bug in the wrapper shell code for the bundle after r292109.
Modified: trunk/Tools/TestWebKitAPI/TestNotificationProvider.cpp (292771 => 292772)
--- trunk/Tools/TestWebKitAPI/TestNotificationProvider.cpp 2022-04-12 15:28:56 UTC (rev 292771)
+++ trunk/Tools/TestWebKitAPI/TestNotificationProvider.cpp 2022-04-12 16:01:30 UTC (rev 292772)
@@ -28,9 +28,12 @@
#include "WTFStringUtilities.h"
#include <WebKit/WKArray.h>
+#include <WebKit/WKContext.h>
#include <WebKit/WKMutableDictionary.h>
+#include <WebKit/WKNotification.h>
#include <WebKit/WKNotificationManager.h>
#include <WebKit/WKNumber.h>
+#include <WebKit/WKPage.h>
#include <WebKit/WKSecurityOriginRef.h>
#include <WebKit/WKString.h>
#include <wtf/text/WTFString.h>
@@ -37,6 +40,11 @@
namespace TestWebKitAPI {
+static void showWebNotification(WKPageRef page, WKNotificationRef notification, const void* clientInfo)
+{
+ static_cast<TestNotificationProvider*>(const_cast<void*>(clientInfo))->showWebNotification(page, notification);
+}
+
static WKDictionaryRef notificationPermissions(const void* clientInfo)
{
return static_cast<TestNotificationProvider*>(const_cast<void*>(clientInfo))->notificationPermissions();
@@ -47,7 +55,7 @@
{
m_provider = {
{ 0, this },
- 0, // showWebNotification
+ &TestWebKitAPI::showWebNotification,
0, // closeWebNotification
0, // didDestroyNotification
0, // addNotificationManager
@@ -103,4 +111,30 @@
WKNotificationManagerProviderDidRemoveNotificationPolicies(manager, wkOriginArray.get());
}
+static WKNotificationManagerRef notificationManagerForPage(WKPageRef page)
+{
+ if (page)
+ return WKContextGetNotificationManager(WKPageGetContext(page));
+
+ return WKNotificationManagerGetSharedServiceWorkerNotificationManager();
+}
+
+void TestNotificationProvider::showWebNotification(WKPageRef page, WKNotificationRef notification)
+{
+ auto notificationManager = notificationManagerForPage(page);
+ uint64_t identifier = WKNotificationGetID(notification);
+ WKNotificationManagerProviderDidShowNotification(notificationManager, identifier);
+
+ WKRetain(notificationManager);
+ m_pendingNotification = std::make_pair(notificationManager, identifier);
+}
+
+void TestNotificationProvider::simulateNotificationClick()
+{
+ callOnMainThread([pair = std::exchange(m_pendingNotification, { })] {
+ WKNotificationManagerProviderDidClickNotification(pair.first, pair.second);
+ WKRelease(pair.first);
+ });
+}
+
} // namespace TestWebKitAPI
Modified: trunk/Tools/TestWebKitAPI/TestNotificationProvider.h (292771 => 292772)
--- trunk/Tools/TestWebKitAPI/TestNotificationProvider.h 2022-04-12 15:28:56 UTC (rev 292771)
+++ trunk/Tools/TestWebKitAPI/TestNotificationProvider.h 2022-04-12 16:01:30 UTC (rev 292772)
@@ -40,14 +40,19 @@
explicit TestNotificationProvider(Vector<WKNotificationManagerRef>&&);
~TestNotificationProvider();
- WKDictionaryRef notificationPermissions() const;
void setPermission(const String& origin, bool allowed);
void resetPermission(const String& origin);
+ WKDictionaryRef notificationPermissions() const;
+ void showWebNotification(WKPageRef, WKNotificationRef);
+ void simulateNotificationClick();
+
private:
Vector<WKNotificationManagerRef> m_managers;
HashMap<String, bool> m_permissions;
WKNotificationProviderV0 m_provider;
+
+ std::pair<WKNotificationManagerRef, uint64_t> m_pendingNotification;
};
}
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm (292771 => 292772)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm 2022-04-12 15:28:56 UTC (rev 292771)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm 2022-04-12 16:01:30 UTC (rev 292772)
@@ -598,4 +598,109 @@
testInspectedServiceWorkerWithoutPage(enableServiceWorkerInspection);
}
+static constexpr auto fireNotificationClickEventMainBytes = R"SWRESOURCE(
+<script>
+function log(msg)
+{
+ window.webkit.messageHandlers.sw.postMessage(msg);
+}
+
+const channel = new MessageChannel();
+channel.port1._onmessage_ = (event) => log(event.data);
+navigator.serviceWorker._onmessage_ = (event) => log(event.data);
+
+navigator.serviceWorker.register('/sw.js').then((registration) => {
+ if (registration.active) {
+ registration.active.postMessage({port: channel.port2}, [channel.port2]);
+ return;
+ }
+ worker = registration.installing;
+ worker.addEventListener('statechange', function() {
+ if (worker.state == 'activated')
+ worker.postMessage({port: channel.port2}, [channel.port2]);
+ });
+}).catch(function(error) {
+ log("Registration failed with: " + error);
+});
+</script>
+)SWRESOURCE"_s;
+
+static constexpr auto fireNotificationClickEventScriptBytes = R"SWRESOURCE(
+let port;
+self.addEventListener("message", (event) => {
+ port = event.data.port;
+ port.postMessage("Ready");
+});
+self.addEventListener("push", (event) => {
+ self.registration.showNotification("notification");
+ try {
+ if (!event.data) {
+ port.postMessage("Received: null data");
+ return;
+ }
+ const value = event.data.text();
+ port.postMessage("Received: " + value);
+ if (value != 'Sweet Potatoes')
+ event.waitUntil(Promise.reject('I want sweet potatoes'));
+ } catch (e) {
+ port.postMessage("Got exception " + e);
+ }
+});
+self.addEventListener("notificationclick", async (event) => {
+ for (let client of await self.clients.matchAll({includeUncontrolled:true}))
+ client.postMessage("Received notificationclick");
+});
+)SWRESOURCE"_s;
+
+TEST(PushAPI, fireNotificationClickEvent)
+{
+ TestWebKitAPI::HTTPServer server({
+ { "/"_s, { fireNotificationClickEventMainBytes } },
+ { "/sw.js"_s, { {{ "Content-Type"_s, "application/_javascript_"_s }}, fireNotificationClickEventScriptBytes } }
+ }, TestWebKitAPI::HTTPServer::Protocol::Http);
+
+ [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
+
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+
+ auto provider = TestWebKitAPI::TestNotificationProvider({ [[configuration processPool] _notificationManagerForTesting], WKNotificationManagerGetSharedServiceWorkerNotificationManager() });
+ provider.setPermission(server.origin(), true);
+
+ auto messageHandler = adoptNS([[PushAPIMessageHandlerWithExpectedMessage alloc] init]);
+ [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
+
+ clearWebsiteDataStore([configuration websiteDataStore]);
+
+ expectedMessage = "Ready"_s;
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+ [webView loadRequest:server.request()];
+
+ TestWebKitAPI::Util::run(&done);
+
+ done = false;
+ pushMessageProcessed = false;
+ pushMessageSuccessful = false;
+ NSString *message = @"Sweet Potatoes";
+ expectedMessage = "Received: Sweet Potatoes"_s;
+
+ [[configuration websiteDataStore] _processPushMessage:messageDictionary([message dataUsingEncoding:NSUTF8StringEncoding], [server.request() URL]) completionHandler:^(bool result) {
+ pushMessageSuccessful = result;
+ pushMessageProcessed = true;
+ }];
+ TestWebKitAPI::Util::run(&done);
+
+ TestWebKitAPI::Util::run(&pushMessageProcessed);
+ EXPECT_TRUE(pushMessageSuccessful);
+
+ terminateNetworkProcessWhileRegistrationIsStored(configuration.get());
+
+ provider.simulateNotificationClick();
+
+ done = false;
+ expectedMessage = "Received notificationclick"_s;
+ TestWebKitAPI::Util::run(&done);
+
+ clearWebsiteDataStore([configuration websiteDataStore]);
+}
+
#endif // WK_HAVE_C_SPI