diff --git a/partitioned-popins/partitioned-popins.permission-all.tentative.sub.https.window.js b/partitioned-popins/partitioned-popins.permission-all.tentative.sub.https.window.js
new file mode 100644
index 00000000000000..83eb092905c612
--- /dev/null
+++ b/partitioned-popins/partitioned-popins.permission-all.tentative.sub.https.window.js
@@ -0,0 +1,32 @@
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+
+'use strict';
+
+// Spec: https://explainers-by-googlers.github.io/partitioned-popins/
+// Step 1 (window) Set up listener to resolve messages as they come in.
+// Step 2 (window) Open iframe for other origin.
+// Step 3 (iframe) Open partitioned popin.
+// Step 4 (popin) Cleanup.
+// Step 5 (iframe) Report success.
+// Step 6 (window) Cleanup.
+
+async_test(t => {
+ const id = String(Date.now());
+ // Step 1
+ window.addEventListener("message", t.step_func(e => {
+ switch (e.data.type) {
+ case 'popin':
+ // Step 6
+ assert_equals(e.data.message, "Success");
+ t.done();
+ break;
+ }
+ }));
+
+ // Step 2
+ const iframe = document.createElement("iframe");
+ iframe.allow = "popins";
+ iframe.src = "https://{{hosts[alt][]}}:{{ports[https][0]}}/partitioned-popins/resources/partitioned-popins.permissions-iframe.html";
+ document.body.appendChild(iframe);
+}, "Verify Partitioned Popins in an iframe work when the policy is *");
diff --git a/partitioned-popins/partitioned-popins.permission-all.tentative.sub.https.window.js.headers b/partitioned-popins/partitioned-popins.permission-all.tentative.sub.https.window.js.headers
new file mode 100644
index 00000000000000..36ba34ecd53462
--- /dev/null
+++ b/partitioned-popins/partitioned-popins.permission-all.tentative.sub.https.window.js.headers
@@ -0,0 +1 @@
+Permissions-Policy: popins=*
diff --git a/partitioned-popins/partitioned-popins.permission-default.tentative.sub.https.window.js b/partitioned-popins/partitioned-popins.permission-default.tentative.sub.https.window.js
new file mode 100644
index 00000000000000..613d8dbb5f2da2
--- /dev/null
+++ b/partitioned-popins/partitioned-popins.permission-default.tentative.sub.https.window.js
@@ -0,0 +1,31 @@
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+
+'use strict';
+
+// Spec: https://explainers-by-googlers.github.io/partitioned-popins/
+// Step 1 (window) Set up listener to resolve messages as they come in.
+// Step 2 (window) Open iframe for other origin.
+// Step 3 (iframe) Open partitioned popin.
+// Step 4 (popin) Cleanup.
+// Step 5 (iframe) Report failure.
+// Step 6 (window) Cleanup.
+
+async_test(t => {
+ const id = String(Date.now());
+ // Step 1
+ window.addEventListener("message", t.step_func(e => {
+ switch (e.data.type) {
+ case 'popin':
+ // Step 6
+ assert_equals(e.data.message, "Failure");
+ t.done();
+ break;
+ }
+ }));
+
+ // Step 2
+ const iframe = document.createElement("iframe");
+ iframe.src = "https://{{hosts[alt][]}}:{{ports[https][0]}}/partitioned-popins/resources/partitioned-popins.permissions-iframe.html";
+ document.body.appendChild(iframe);
+}, "Verify Partitioned Popins in an iframe fails when the policy isn't set");
diff --git a/partitioned-popins/partitioned-popins.permission-self.tentative.sub.https.window.js b/partitioned-popins/partitioned-popins.permission-self.tentative.sub.https.window.js
new file mode 100644
index 00000000000000..5930442aa872d7
--- /dev/null
+++ b/partitioned-popins/partitioned-popins.permission-self.tentative.sub.https.window.js
@@ -0,0 +1,32 @@
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+
+'use strict';
+
+// Spec: https://explainers-by-googlers.github.io/partitioned-popins/
+// Step 1 (window) Set up listener to resolve messages as they come in.
+// Step 2 (window) Open iframe for other origin.
+// Step 3 (iframe) Open partitioned popin.
+// Step 4 (popin) Cleanup.
+// Step 5 (iframe) Report failure.
+// Step 6 (window) Cleanup.
+
+async_test(t => {
+ const id = String(Date.now());
+ // Step 1
+ window.addEventListener("message", t.step_func(e => {
+ switch (e.data.type) {
+ case 'popin':
+ // Step 6
+ assert_equals(e.data.message, "Failure");
+ t.done();
+ break;
+ }
+ }));
+
+ // Step 2
+ const iframe = document.createElement("iframe");
+ iframe.allow = "popins";
+ iframe.src = "https://{{hosts[alt][]}}:{{ports[https][0]}}/partitioned-popins/resources/partitioned-popins.permissions-iframe.html";
+ document.body.appendChild(iframe);
+}, "Verify Partitioned Popins in an iframe fail when the policy is 'self'");
diff --git a/partitioned-popins/partitioned-popins.permission-self.tentative.sub.https.window.js.headers b/partitioned-popins/partitioned-popins.permission-self.tentative.sub.https.window.js.headers
new file mode 100644
index 00000000000000..0d61ec4d3e4c52
--- /dev/null
+++ b/partitioned-popins/partitioned-popins.permission-self.tentative.sub.https.window.js.headers
@@ -0,0 +1 @@
+Permissions-Policy: popins=self
diff --git a/partitioned-popins/resources/partitioned-popins.permissions-iframe.html b/partitioned-popins/resources/partitioned-popins.permissions-iframe.html
new file mode 100644
index 00000000000000..fe41057b7bb160
--- /dev/null
+++ b/partitioned-popins/resources/partitioned-popins.permissions-iframe.html
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/partitioned-popins/resources/partitioned-popins.permissions-popin.html b/partitioned-popins/resources/partitioned-popins.permissions-popin.html
new file mode 100644
index 00000000000000..1009ee687a29a9
--- /dev/null
+++ b/partitioned-popins/resources/partitioned-popins.permissions-popin.html
@@ -0,0 +1,12 @@
+
+
+
+
+