-
+
{{ ftl('vpn-shared-waitlist-link') }}
@@ -173,7 +173,7 @@
) %}
{{ ftl('vpn-shared-features-full-list-servers', url='https://mullvad.net/servers/', attrs='target="_blank" rel="external noopener noreferrer"') }}
-
+
{{ ftl('vpn-shared-subscribe-link') }}
@@ -198,7 +198,7 @@
class_name='vpn-content-media-left-half vpn-more-countries-coming-soon'
) %}
-
+
{{ ftl('vpn-shared-waitlist-link') }}
diff --git a/bedrock/products/templates/products/vpn/pricing-refresh.html b/bedrock/products/templates/products/vpn/pricing-refresh.html
index 043a91524e2..76d010e5358 100644
--- a/bedrock/products/templates/products/vpn/pricing-refresh.html
+++ b/bedrock/products/templates/products/vpn/pricing-refresh.html
@@ -52,7 +52,7 @@
{{ ftl('vpn-pricing-one-subscription') }}
{{ ftl('vpn-pricing-vpn-not-available') }}
-
+
{{ ftl('vpn-shared-waitlist-link') }}
diff --git a/bedrock/products/templates/products/vpn/pricing.html b/bedrock/products/templates/products/vpn/pricing.html
index dc2cbce5daa..1f5c08466ed 100644
--- a/bedrock/products/templates/products/vpn/pricing.html
+++ b/bedrock/products/templates/products/vpn/pricing.html
@@ -60,7 +60,7 @@
{{ ftl('vpn-share
class_name='vpn-content-media-left-half vpn-more-countries-coming-soon'
) %}
-
+
{{ ftl('vpn-shared-waitlist-link') }}
diff --git a/tests/functional/products/vpn/__init__.py b/tests/functional/products/vpn/__init__.py
deleted file mode 100644
index 448bb8652d6..00000000000
--- a/tests/functional/products/vpn/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at https://mozilla.org/MPL/2.0/.
diff --git a/tests/functional/products/vpn/test_features.py b/tests/functional/products/vpn/test_features.py
deleted file mode 100644
index 9f83e312a60..00000000000
--- a/tests/functional/products/vpn/test_features.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-import pytest
-
-from pages.products.vpn.features import VPNFeaturesPage
-
-
-@pytest.mark.nondestructive
-@pytest.mark.parametrize(
- "country",
- [
- ("us"),
- ("ca"),
- ("my"),
- ("nz"),
- ("sg"),
- ("gb"),
- ("de"),
- ("fr"),
- ("at"),
- ("be"),
- ("ch"),
- ("es"),
- ("it"),
- ("ie"),
- ("nl"),
- ("se"),
- ("fi"),
- ],
-)
-def test_vpn_available_in_country(country, base_url, selenium):
- page = VPNFeaturesPage(selenium, base_url, params=f"?geo={country}").open()
- # Footer
- assert not page.is_join_waitlist_footer_button_displayed
- assert page.is_get_vpn_footer_button_displayed
-
-
-@pytest.mark.nondestructive
-def test_vpn_not_available_in_country(base_url, selenium):
- page = VPNFeaturesPage(selenium, base_url, params="?geo=cn").open()
- # Footer
- assert page.is_join_waitlist_footer_button_displayed
- assert not page.is_get_vpn_footer_button_displayed
diff --git a/tests/functional/products/vpn/test_landing.py b/tests/functional/products/vpn/test_landing.py
deleted file mode 100644
index e82e9b7f172..00000000000
--- a/tests/functional/products/vpn/test_landing.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-import pytest
-
-from pages.products.vpn.landing import VPNLandingPage
-
-
-@pytest.mark.nondestructive
-@pytest.mark.parametrize(
- "country",
- [
- ("us"),
- ("ca"),
- ("my"),
- ("nz"),
- ("sg"),
- ("gb"),
- ("de"),
- ("fr"),
- ("at"),
- ("be"),
- ("ch"),
- ("es"),
- ("it"),
- ("ie"),
- ("nl"),
- ("se"),
- ("fi"),
- ],
-)
-def test_vpn_available_in_country(country, base_url, selenium):
- page = VPNLandingPage(selenium, base_url, locale="de", params=f"?xv=legacy&geo={country}").open()
- # Hero
- assert not page.is_join_waitlist_hero_button_displayed
- assert page.is_get_vpn_hero_button_displayed
-
- # Navigation
- assert not page.is_join_waitlist_navigation_button_displayed
- assert page.is_get_vpn_navigation_button_displayed
-
- # Pricing section
- assert page.is_get_vpn_monthly_button_displayed
- assert page.is_get_vpn_12_months_button_displayed
-
- # VPN + Relay bundle is only available in US & Canada.
- # Currently disabled in production behind a switch.
- # if country in ["us", "ca"]:
- # assert page.is_get_vpn_relay_button_displayed
- # else:
- # assert not page.is_get_vpn_relay_button_displayed
-
- # Waitlist features section
- assert not page.is_join_waitlist_features_button_displayed
-
- # Connect section
- assert not page.is_join_waitlist_coming_soon_button_displayed
- assert page.is_get_vpn_conntect_now_button_displayed
-
- # Footer
- assert not page.is_join_waitlist_footer_button_displayed
- assert page.is_get_vpn_footer_button_displayed
-
-
-@pytest.mark.nondestructive
-def test_vpn_not_available_in_country(base_url, selenium):
- page = VPNLandingPage(selenium, base_url, locale="de", params="?xv=legacy&geo=cn").open()
- # Hero
- assert page.is_join_waitlist_hero_button_displayed
- assert not page.is_get_vpn_hero_button_displayed
-
- # Navigation
- assert page.is_join_waitlist_navigation_button_displayed
- assert not page.is_get_vpn_navigation_button_displayed
-
- # Pricing section
- assert not page.is_get_vpn_monthly_button_displayed
- assert not page.is_get_vpn_12_months_button_displayed
- assert not page.is_get_vpn_relay_button_displayed
-
- # Waitlist features section
- assert page.is_join_waitlist_features_button_displayed
-
- # Connect section
- assert page.is_join_waitlist_coming_soon_button_displayed
- assert not page.is_get_vpn_conntect_now_button_displayed
-
- # Footer
- assert page.is_join_waitlist_footer_button_displayed
- assert not page.is_get_vpn_footer_button_displayed
diff --git a/tests/functional/products/vpn/test_pricing.py b/tests/functional/products/vpn/test_pricing.py
deleted file mode 100644
index 0e6613e873b..00000000000
--- a/tests/functional/products/vpn/test_pricing.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-import pytest
-
-from pages.products.vpn.pricing import VPNPricingPage
-
-
-@pytest.mark.nondestructive
-@pytest.mark.parametrize(
- "country",
- [
- ("us"),
- ("ca"),
- ("my"),
- ("nz"),
- ("sg"),
- ("gb"),
- ("de"),
- ("fr"),
- ("at"),
- ("be"),
- ("ch"),
- ("es"),
- ("it"),
- ("ie"),
- ("nl"),
- ("se"),
- ("fi"),
- ],
-)
-def test_vpn_pricing_available_in_country(country, base_url, selenium):
- page = VPNPricingPage(selenium, base_url, locale="de", params=f"?xv=legacy&geo={country}").open()
- assert page.is_get_vpn_monthly_button_displayed
- assert page.is_get_vpn_12_months_button_displayed
- assert not page.is_join_waitlist_button_displayed
-
-
-@pytest.mark.nondestructive
-def test_vpn_pricing_not_available_in_country(base_url, selenium):
- page = VPNPricingPage(selenium, base_url, locale="de", params="?xv=legacy&geo=cn").open()
- assert not page.is_get_vpn_monthly_button_displayed
- assert not page.is_get_vpn_12_months_button_displayed
- assert page.is_join_waitlist_button_displayed
diff --git a/tests/functional/products/vpn/test_resource_center.py b/tests/functional/products/vpn/test_resource_center.py
deleted file mode 100644
index 8eb55dd631c..00000000000
--- a/tests/functional/products/vpn/test_resource_center.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-import pytest
-
-from pages.products.vpn.resource_center import VPNResourceCenterHomePage
-
-
-@pytest.mark.nondestructive
-@pytest.mark.parametrize(
- "locale",
- [
- ("en-US"),
- ],
-)
-def test_vpn_available_in_country(locale, base_url, selenium):
- page = VPNResourceCenterHomePage(
- selenium,
- base_url,
- ).open()
-
- # Light test that the VRC page renders at all
- assert page.is_resource_center_header_displayed
-
- # ...and that it has at least one article
- assert page.is_article_card_with_link_displayed
diff --git a/tests/pages/products/vpn/__init__.py b/tests/pages/products/vpn/__init__.py
deleted file mode 100644
index 448bb8652d6..00000000000
--- a/tests/pages/products/vpn/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at https://mozilla.org/MPL/2.0/.
diff --git a/tests/pages/products/vpn/features.py b/tests/pages/products/vpn/features.py
deleted file mode 100644
index 704ef7e0d72..00000000000
--- a/tests/pages/products/vpn/features.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-from selenium.webdriver.common.by import By
-
-from pages.base import BasePage
-
-
-class VPNFeaturesPage(BasePage):
- _URL_TEMPLATE = "/{locale}/products/vpn/features/{params}"
-
- # Footer
- _get_vpn_footer_button_locator = (By.CSS_SELECTOR, '.c-aside.footer .mzp-c-button[data-cta-text="Get Mozilla VPN"]')
- _join_waitlist_footer_button_locator = (By.CSS_SELECTOR, '.c-aside.footer .mzp-c-button[data-cta-text="Join the VPN Waitlist"]')
-
- # Footer
-
- @property
- def is_get_vpn_footer_button_displayed(self):
- return self.is_element_displayed(*self._get_vpn_footer_button_locator)
-
- @property
- def is_join_waitlist_footer_button_displayed(self):
- return self.is_element_displayed(*self._join_waitlist_footer_button_locator)
diff --git a/tests/pages/products/vpn/landing.py b/tests/pages/products/vpn/landing.py
deleted file mode 100644
index 6c071d1bea5..00000000000
--- a/tests/pages/products/vpn/landing.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-from selenium.webdriver.common.by import By
-
-from pages.base import BasePage
-
-
-class VPNLandingPage(BasePage):
- _URL_TEMPLATE = "/{locale}/products/vpn/{params}"
-
- # Hero
- _get_vpn_hero_button_locator = (By.CSS_SELECTOR, '.vpn-hero .mzp-c-button[data-cta-text="Scroll to pricing"]')
- _join_waitlist_hero_button_locator = (By.CSS_SELECTOR, '.vpn-hero .mzp-c-button[data-cta-text="Join the VPN Waitlist"]')
-
- # Navigation
- _get_vpn_navigation_button_locator = (By.CSS_SELECTOR, '.c-navigation-shoulder .mzp-c-button[data-cta-text="Get Mozilla VPN"]')
- _join_waitlist_navigation_button_locator = (By.CSS_SELECTOR, '.c-navigation-shoulder .mzp-c-button[data-cta-text="Join the VPN Waitlist"]')
-
- # Pricing section
- _get_vpn_monthly_button_locator = (By.CSS_SELECTOR, ".vpn-pricing-monthly .mzp-c-button")
- _get_vpn_12_months_button_locator = (By.CSS_SELECTOR, ".vpn-pricing-12-months .mzp-c-button")
- _get_vpn_relay_button_locator = (By.CSS_SELECTOR, ".vpn-pricing-12-months .vpn-pricing-add-on-bundle .mzp-c-button")
-
- # Waitlist features section
- _join_waitlist_features_button_locator = (By.CSS_SELECTOR, '.vpn-waitlist-feature-block .mzp-c-button[data-cta-text="Join the VPN Waitlist"]')
-
- # Connect section
- _get_vpn_conntect_now_button_locator = (By.CSS_SELECTOR, '.vpn-connect-to-countries-and-servers .mzp-c-button[data-cta-text="Scroll to pricing"]')
- _join_waitlist_coming_soon_button_locator = (
- By.CSS_SELECTOR,
- '.vpn-more-countries-coming-soon .mzp-c-button[data-cta-text="Join the VPN Waitlist"]',
- )
-
- # Footer
- _get_vpn_footer_button_locator = (By.CSS_SELECTOR, '.vpn-footer .mzp-c-button[data-cta-text="Scroll to pricing"]')
- _join_waitlist_footer_button_locator = (By.CSS_SELECTOR, '.vpn-footer .mzp-c-button[data-cta-text="Join the VPN Waitlist"]')
-
- # Hero
-
- @property
- def is_get_vpn_hero_button_displayed(self):
- return self.is_element_displayed(*self._get_vpn_hero_button_locator)
-
- @property
- def is_join_waitlist_hero_button_displayed(self):
- return self.is_element_displayed(*self._join_waitlist_hero_button_locator)
-
- # Navigation
-
- @property
- def is_get_vpn_navigation_button_displayed(self):
- return self.is_element_displayed(*self._get_vpn_navigation_button_locator)
-
- @property
- def is_join_waitlist_navigation_button_displayed(self):
- return self.is_element_displayed(*self._join_waitlist_navigation_button_locator)
-
- # Pricing section
-
- @property
- def is_get_vpn_monthly_button_displayed(self):
- return self.is_element_displayed(*self._get_vpn_monthly_button_locator)
-
- @property
- def is_get_vpn_12_months_button_displayed(self):
- return self.is_element_displayed(*self._get_vpn_12_months_button_locator)
-
- @property
- def is_get_vpn_relay_button_displayed(self):
- return self.is_element_displayed(*self._get_vpn_relay_button_locator)
-
- # Waitlist Features section
-
- @property
- def is_join_waitlist_features_button_displayed(self):
- return self.is_element_displayed(*self._join_waitlist_features_button_locator)
-
- # Connect section
-
- @property
- def is_get_vpn_conntect_now_button_displayed(self):
- return self.is_element_displayed(*self._get_vpn_conntect_now_button_locator)
-
- @property
- def is_join_waitlist_coming_soon_button_displayed(self):
- return self.is_element_displayed(*self._join_waitlist_coming_soon_button_locator)
-
- # Footer
-
- @property
- def is_get_vpn_footer_button_displayed(self):
- return self.is_element_displayed(*self._get_vpn_footer_button_locator)
-
- @property
- def is_join_waitlist_footer_button_displayed(self):
- return self.is_element_displayed(*self._join_waitlist_footer_button_locator)
diff --git a/tests/pages/products/vpn/pricing.py b/tests/pages/products/vpn/pricing.py
deleted file mode 100644
index e93c9d28f0a..00000000000
--- a/tests/pages/products/vpn/pricing.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-from selenium.webdriver.common.by import By
-
-from pages.base import BasePage
-
-
-class VPNPricingPage(BasePage):
- _URL_TEMPLATE = "/{locale}/products/vpn/pricing/{params}"
-
- _get_vpn_monthly_button_locator = (By.CSS_SELECTOR, ".vpn-pricing-monthly .mzp-c-button")
- _get_vpn_12_months_button_locator = (By.CSS_SELECTOR, ".vpn-pricing-12-months .mzp-c-button")
- _join_waitlist_button_locator = (By.CSS_SELECTOR, '.vpn-more-countries-coming-soon .mzp-c-button[data-cta-text="Join the VPN Waitlist"]')
-
- @property
- def is_get_vpn_monthly_button_displayed(self):
- return self.is_element_displayed(*self._get_vpn_monthly_button_locator)
-
- @property
- def is_get_vpn_12_months_button_displayed(self):
- return self.is_element_displayed(*self._get_vpn_12_months_button_locator)
-
- @property
- def is_join_waitlist_button_displayed(self):
- return self.is_element_displayed(*self._join_waitlist_button_locator)
diff --git a/tests/pages/products/vpn/resource_center.py b/tests/pages/products/vpn/resource_center.py
deleted file mode 100644
index 036ab240c2f..00000000000
--- a/tests/pages/products/vpn/resource_center.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at https://mozilla.org/MPL/2.0/.
-
-from selenium.webdriver.common.by import By
-
-from pages.base import BasePage
-
-
-class VPNResourceCenterHomePage(BasePage):
- _URL_TEMPLATE = "/{locale}/products/vpn/resource-center/"
-
- # Header unit
- _resource_center_header_locator = (By.CSS_SELECTOR, ".mzp-c-callout.resource-center-page-header.resource-center-hero")
-
- # Article link
- _resource_center_article_link_locator = (By.CSS_SELECTOR, ".resource-center-articles .mzp-c-card a.mzp-c-card-block-link")
-
- @property
- def is_resource_center_header_displayed(self):
- return self.is_element_displayed(*self._resource_center_header_locator)
-
- @property
- def is_article_card_with_link_displayed(self):
- return self.is_element_displayed(*self._resource_center_article_link_locator)
diff --git a/tests/playwright/specs/products/vpn/vpn-features.spec.js b/tests/playwright/specs/products/vpn/vpn-features.spec.js
new file mode 100644
index 00000000000..df35d995ed5
--- /dev/null
+++ b/tests/playwright/specs/products/vpn/vpn-features.spec.js
@@ -0,0 +1,123 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+'use strict';
+
+const { test, expect } = require('@playwright/test');
+const openPage = require('../../../scripts/open-page');
+const url = '/en-US/products/vpn/features/';
+const availableCountries = ['us', 'ca', 'gb', 'de', 'fr'];
+const unavailableCountries = ['cn'];
+
+test.describe(
+ `${url} page`,
+ {
+ tag: '@vpn'
+ },
+ () => {
+ for (const country of availableCountries) {
+ test.describe('VPN available', () => {
+ test.beforeEach(async ({ page, browserName }) => {
+ await openPage(url + `?geo=${country}`, page, browserName);
+ });
+
+ test(`Country code: ${country}`, async ({ page }) => {
+ const getVpnPostConvenientButton = page.getByTestId(
+ 'get-mozilla-vpn-post-convenient-button'
+ );
+ const getVpnPostSecureButton = page.getByTestId(
+ 'get-mozilla-vpn-post-secure-button'
+ );
+ const getVpnPostFlexibleButton = page.getByTestId(
+ 'get-mozilla-vpn-post-flexible-button'
+ );
+ const getVpnFooterButton = page.getByTestId(
+ 'get-mozilla-vpn-footer-button'
+ );
+
+ const joinWaitlistConvenientButton = page.getByTestId(
+ 'join-waitlist-post-convenient-button'
+ );
+ const joinWaitlistPostSecureButton = page.getByTestId(
+ 'join-waitlist-post-secure-button'
+ );
+ const joinWaitlistPostFlexibleButton = page.getByTestId(
+ 'join-waitlist-post-flexible-button'
+ );
+ const joinWaitlistFooterButton = page.getByTestId(
+ 'join-waitlist-footer-button'
+ );
+
+ // Assert Get Mozilla VPN buttons are displayed.
+ await expect(getVpnPostConvenientButton).toBeVisible();
+ await expect(getVpnPostSecureButton).toBeVisible();
+ await expect(getVpnPostFlexibleButton).toBeVisible();
+ await expect(getVpnFooterButton).toBeVisible();
+
+ // Assert Join Waitlist buttons are not displayed.
+ await expect(
+ joinWaitlistConvenientButton
+ ).not.toBeVisible();
+ await expect(
+ joinWaitlistPostSecureButton
+ ).not.toBeVisible();
+ await expect(
+ joinWaitlistPostFlexibleButton
+ ).not.toBeVisible();
+ await expect(joinWaitlistFooterButton).not.toBeVisible();
+ });
+ });
+ }
+
+ for (const country of unavailableCountries) {
+ test.describe('VPN not available', () => {
+ test.beforeEach(async ({ page, browserName }) => {
+ await openPage(url + `?geo=${country}`, page, browserName);
+ });
+
+ test(`Country code: ${country}`, async ({ page }) => {
+ const getVpnPostConvenientButton = page.getByTestId(
+ 'get-mozilla-vpn-post-convenient-button'
+ );
+ const getVpnPostSecureButton = page.getByTestId(
+ 'get-mozilla-vpn-post-secure-button'
+ );
+ const getVpnPostFlexibleButton = page.getByTestId(
+ 'get-mozilla-vpn-post-flexible-button'
+ );
+ const getVpnFooterButton = page.getByTestId(
+ 'get-mozilla-vpn-footer-button'
+ );
+
+ const joinWaitlistConvenientButton = page.getByTestId(
+ 'join-waitlist-post-convenient-button'
+ );
+ const joinWaitlistPostSecureButton = page.getByTestId(
+ 'join-waitlist-post-secure-button'
+ );
+ const joinWaitlistPostFlexibleButton = page.getByTestId(
+ 'join-waitlist-post-flexible-button'
+ );
+ const joinWaitlistFooterButton = page.getByTestId(
+ 'join-waitlist-footer-button'
+ );
+
+ // Assert Join Waitlist buttons not displayed.
+ await expect(joinWaitlistConvenientButton).toBeVisible();
+ await expect(joinWaitlistPostSecureButton).toBeVisible();
+ await expect(joinWaitlistPostFlexibleButton).toBeVisible();
+ await expect(joinWaitlistFooterButton).toBeVisible();
+
+ // Assert Get Mozilla VPN buttons are not displayed.
+ await expect(getVpnPostConvenientButton).not.toBeVisible();
+ await expect(getVpnPostSecureButton).not.toBeVisible();
+ await expect(getVpnPostFlexibleButton).not.toBeVisible();
+ await expect(getVpnFooterButton).not.toBeVisible();
+ });
+ });
+ }
+ }
+);
diff --git a/tests/playwright/specs/products/vpn/vpn-landing-old.spec.js b/tests/playwright/specs/products/vpn/vpn-landing-old.spec.js
new file mode 100644
index 00000000000..415e2a7a4ca
--- /dev/null
+++ b/tests/playwright/specs/products/vpn/vpn-landing-old.spec.js
@@ -0,0 +1,141 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+'use strict';
+
+const { test, expect } = require('@playwright/test');
+const openPage = require('../../../scripts/open-page');
+const url = '/de/products/vpn/?xv=legacy';
+const availableCountries = ['us', 'ca', 'gb', 'de', 'fr'];
+const unavailableCountries = ['cn'];
+
+test.describe(
+ `${url} page`,
+ {
+ tag: '@vpn'
+ },
+ () => {
+ for (const country of availableCountries) {
+ test.describe('VPN available', () => {
+ test.beforeEach(async ({ page, browserName }) => {
+ await openPage(url + `&geo=${country}`, page, browserName);
+ });
+
+ test(`Country code: ${country}`, async ({ page }) => {
+ const getVpnNavButton = page.getByTestId(
+ 'get-mozilla-vpn-nav-button'
+ );
+ const getVpnPrimaryButton = page.getByTestId(
+ 'get-mozilla-vpn-primary-button'
+ );
+ const getVpnTwelveMonthButton = page.getByTestId(
+ 'get-mozilla-vpn-12-month-button'
+ );
+ const getVpnMonthlyButton = page.getByTestId(
+ 'get-mozilla-vpn-monthly-button'
+ );
+ const getVpnSecondaryButton = page.getByTestId(
+ 'get-mozilla-vpn-secondary-button'
+ );
+ const getVpnFooterButton = page.getByTestId(
+ 'get-mozilla-vpn-footer-button'
+ );
+
+ const waitlistNavButton = page.getByTestId(
+ 'join-waitlist-nav-button'
+ );
+ const waitlistPrimaryButton = page.getByTestId(
+ 'join-waitlist-primary-button'
+ );
+ const waitlistPricingButton = page.getByTestId(
+ 'join-waitlist-pricing-button'
+ );
+ const waitlistSecondaryButton = page.getByTestId(
+ 'join-waitlist-secondary-button'
+ );
+ const waitlistFooterButton = page.getByTestId(
+ 'join-waitlist-footer-button'
+ );
+
+ // Assert Get Mozilla VPN buttons are displayed.
+ await expect(getVpnNavButton).toBeVisible();
+ await expect(getVpnPrimaryButton).toBeVisible();
+ await expect(getVpnTwelveMonthButton).toBeVisible();
+ await expect(getVpnMonthlyButton).toBeVisible();
+ await expect(getVpnSecondaryButton).toBeVisible();
+ await expect(getVpnFooterButton).toBeVisible();
+
+ // Assert Join Waitlist buttons are not displayed.
+ await expect(waitlistPrimaryButton).not.toBeVisible();
+ await expect(waitlistNavButton).not.toBeVisible();
+ await expect(waitlistPricingButton).not.toBeVisible();
+ await expect(waitlistSecondaryButton).not.toBeVisible();
+ await expect(waitlistFooterButton).not.toBeVisible();
+ });
+ });
+ }
+
+ for (const country of unavailableCountries) {
+ test.describe('VPN not available', () => {
+ test.beforeEach(async ({ page, browserName }) => {
+ await openPage(url + `&geo=${country}`, page, browserName);
+ });
+
+ test(`Country code: ${country}`, async ({ page }) => {
+ const getVpnNavButton = page.getByTestId(
+ 'get-mozilla-vpn-nav-button'
+ );
+ const getVpnPrimaryButton = page.getByTestId(
+ 'get-mozilla-vpn-primary-button'
+ );
+ const getVpnTwelveMonthButton = page.getByTestId(
+ 'get-mozilla-vpn-12-month-button'
+ );
+ const getVpnMonthlyButton = page.getByTestId(
+ 'get-mozilla-vpn-monthly-button'
+ );
+ const getVpnSecondaryButton = page.getByTestId(
+ 'get-mozilla-vpn-secondary-button'
+ );
+ const getVpnFooterButton = page.getByTestId(
+ 'get-mozilla-vpn-footer-button'
+ );
+
+ const waitlistNavButton = page.getByTestId(
+ 'join-waitlist-nav-button'
+ );
+ const waitlistPrimaryButton = page.getByTestId(
+ 'join-waitlist-primary-button'
+ );
+ const waitlistPricingButton = page.getByTestId(
+ 'join-waitlist-pricing-button'
+ );
+ const waitlistSecondaryButton = page.getByTestId(
+ 'join-waitlist-secondary-button'
+ );
+ const waitlistFooterButton = page.getByTestId(
+ 'join-waitlist-footer-button'
+ );
+
+ // Assert Join Waitlist buttons are displayed.
+ await expect(waitlistNavButton).toBeVisible();
+ await expect(waitlistPrimaryButton).toBeVisible();
+ await expect(waitlistPricingButton).toBeVisible();
+ await expect(waitlistSecondaryButton).toBeVisible();
+ await expect(waitlistFooterButton).toBeVisible();
+
+ // Assert Get Mozilla VPN buttons are not displayed.
+ await expect(getVpnNavButton).not.toBeVisible();
+ await expect(getVpnPrimaryButton).not.toBeVisible();
+ await expect(getVpnTwelveMonthButton).not.toBeVisible();
+ await expect(getVpnMonthlyButton).not.toBeVisible();
+ await expect(getVpnSecondaryButton).not.toBeVisible();
+ await expect(getVpnFooterButton).not.toBeVisible();
+ });
+ });
+ }
+ }
+);
diff --git a/tests/playwright/specs/products/vpn/vpn-pricing-old.spec.js b/tests/playwright/specs/products/vpn/vpn-pricing-old.spec.js
new file mode 100644
index 00000000000..4b014e01309
--- /dev/null
+++ b/tests/playwright/specs/products/vpn/vpn-pricing-old.spec.js
@@ -0,0 +1,77 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+'use strict';
+
+const { test, expect } = require('@playwright/test');
+const openPage = require('../../../scripts/open-page');
+const url = '/de/products/vpn/pricing/?xv=legacy';
+const availableCountries = ['us', 'ca', 'gb', 'de', 'fr'];
+const unavailableCountries = ['cn'];
+
+test.describe(
+ `${url} page`,
+ {
+ tag: '@vpn'
+ },
+ () => {
+ for (const country of availableCountries) {
+ test.describe('VPN available', () => {
+ test.beforeEach(async ({ page, browserName }) => {
+ await openPage(url + `&geo=${country}`, page, browserName);
+ });
+
+ test(`Country code: ${country}`, async ({ page }) => {
+ const getVpnTwelveMonthButton = page.getByTestId(
+ 'get-mozilla-vpn-12-month-button'
+ );
+ const getVpnMonthlyButton = page.getByTestId(
+ 'get-mozilla-vpn-monthly-button'
+ );
+
+ const waitlistButton = page.getByTestId(
+ 'join-waitlist-button'
+ );
+
+ // Assert Get Mozilla VPN buttons are displayed.
+ await expect(getVpnTwelveMonthButton).toBeVisible();
+ await expect(getVpnMonthlyButton).toBeVisible();
+
+ // Assert Join Waitlist button is not displayed.
+ await expect(waitlistButton).not.toBeVisible();
+ });
+ });
+ }
+
+ for (const country of unavailableCountries) {
+ test.describe('VPN not available', () => {
+ test.beforeEach(async ({ page, browserName }) => {
+ await openPage(url + `&geo=${country}`, page, browserName);
+ });
+
+ test(`Country code: ${country}`, async ({ page }) => {
+ const getVpnTwelveMonthButton = page.getByTestId(
+ 'get-mozilla-vpn-12-month-button'
+ );
+ const getVpnMonthlyButton = page.getByTestId(
+ 'get-mozilla-vpn-monthly-button'
+ );
+
+ const waitlistButton = page.getByTestId(
+ 'join-waitlist-button'
+ );
+
+ // Assert Join Waitlist button is displayed.
+ await expect(waitlistButton).toBeVisible();
+
+ // Assert Get Mozilla VPN buttons are not displayed.
+ await expect(getVpnTwelveMonthButton).not.toBeVisible();
+ await expect(getVpnMonthlyButton).not.toBeVisible();
+ });
+ });
+ }
+ }
+);
diff --git a/tests/playwright/specs/products/vpn/vpn-pricing.spec.js b/tests/playwright/specs/products/vpn/vpn-pricing.spec.js
new file mode 100644
index 00000000000..993d41c22ba
--- /dev/null
+++ b/tests/playwright/specs/products/vpn/vpn-pricing.spec.js
@@ -0,0 +1,77 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+'use strict';
+
+const { test, expect } = require('@playwright/test');
+const openPage = require('../../../scripts/open-page');
+const url = '/en-US/products/vpn/pricing/';
+const availableCountries = ['us', 'ca', 'gb', 'de', 'fr'];
+const unavailableCountries = ['cn'];
+
+test.describe(
+ `${url} page`,
+ {
+ tag: '@vpn'
+ },
+ () => {
+ for (const country of availableCountries) {
+ test.describe('VPN available', () => {
+ test.beforeEach(async ({ page, browserName }) => {
+ await openPage(url + `?geo=${country}`, page, browserName);
+ });
+
+ test(`Country code: ${country}`, async ({ page }) => {
+ const getVpnTwelveMonthButton = page.getByTestId(
+ 'get-mozilla-vpn-12-month-button'
+ );
+ const getVpnMonthlyButton = page.getByTestId(
+ 'get-mozilla-vpn-monthly-button'
+ );
+
+ const waitlistButton = page.getByTestId(
+ 'join-waitlist-button'
+ );
+
+ // Assert Get Mozilla VPN buttons are displayed.
+ await expect(getVpnTwelveMonthButton).toBeVisible();
+ await expect(getVpnMonthlyButton).toBeVisible();
+
+ // Assert Join Waitlist button is not displayed.
+ await expect(waitlistButton).not.toBeVisible();
+ });
+ });
+ }
+
+ for (const country of unavailableCountries) {
+ test.describe('VPN not available', () => {
+ test.beforeEach(async ({ page, browserName }) => {
+ await openPage(url + `?geo=${country}`, page, browserName);
+ });
+
+ test(`Country code: ${country}`, async ({ page }) => {
+ const getVpnTwelveMonthButton = page.getByTestId(
+ 'get-mozilla-vpn-12-month-button'
+ );
+ const getVpnMonthlyButton = page.getByTestId(
+ 'get-mozilla-vpn-monthly-button'
+ );
+
+ const waitlistButton = page.getByTestId(
+ 'join-waitlist-button'
+ );
+
+ // Assert Join Waitlist button is displayed.
+ await expect(waitlistButton).toBeVisible();
+
+ // Assert Get Mozilla VPN buttons are not displayed.
+ await expect(getVpnTwelveMonthButton).not.toBeVisible();
+ await expect(getVpnMonthlyButton).not.toBeVisible();
+ });
+ });
+ }
+ }
+);