@networkpro/web 1.6.5 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CODE_OF_CONDUCT.md +2 -2
  2. package/LICENSE.md +20 -9
  3. package/README.md +57 -13
  4. package/_redirects +1 -0
  5. package/cspell.json +2 -0
  6. package/package.json +7 -7
  7. package/playwright.config.js +1 -0
  8. package/src/lib/components/FullWidthSection.svelte +19 -4
  9. package/src/lib/components/LegalNav.svelte +31 -29
  10. package/src/lib/components/PostHog.svelte +20 -8
  11. package/src/lib/components/layout/Footer.svelte +1 -1
  12. package/src/lib/components/layout/HeaderDefault.svelte +2 -2
  13. package/src/lib/components/layout/HeaderHome.svelte +2 -2
  14. package/src/lib/images.js +3 -2
  15. package/src/lib/index.js +2 -1
  16. package/src/lib/meta.js +6 -1
  17. package/src/lib/pages/LicenseContent.svelte +17 -17
  18. package/src/lib/pages/PrivacyContent.svelte +116 -6
  19. package/src/lib/pages/PrivacyDashboard.svelte +240 -0
  20. package/src/lib/pages/TermsUseContent.svelte +1 -1
  21. package/src/lib/styles/css/default.css +23 -10
  22. package/src/lib/styles/global.min.css +1 -3
  23. package/src/lib/utils/privacy.js +18 -3
  24. package/src/lib/utils/trackingCookies.js +40 -0
  25. package/src/lib/utils/trackingStatus.js +46 -0
  26. package/src/lib/utils/utm.js +8 -1
  27. package/src/routes/about/+page.svelte +1 -7
  28. package/src/routes/foss-spotlight/+page.svelte +1 -7
  29. package/src/routes/license/+page.svelte +2 -8
  30. package/src/routes/privacy/+page.server.js +18 -0
  31. package/src/routes/{privacy-policy → privacy}/+page.svelte +5 -11
  32. package/src/routes/{privacy-policy → privacy-dashboard}/+page.server.js +2 -2
  33. package/src/routes/privacy-dashboard/+page.svelte +69 -0
  34. package/src/routes/terms-conditions/+page.svelte +2 -8
  35. package/src/routes/terms-of-use/+page.svelte +2 -8
  36. package/src/service-worker.js +31 -6
  37. package/static/robots.txt +2 -1
  38. package/static/sitemap.xml +10 -22
  39. package/tests/e2e/app.spec.js +50 -68
  40. package/tests/e2e/mobile.spec.js +32 -42
  41. package/tests/e2e/shared/helpers.js +57 -0
@@ -14,12 +14,6 @@ This file is part of Network Pro.
14
14
  import SocialMedia from "$lib/components/SocialMedia.svelte";
15
15
  import MetaTags from "$lib/components/MetaTags.svelte";
16
16
 
17
- /**
18
- * @type {string}
19
- * Style class for the horizontal rule element.
20
- */
21
- const hrStyle = "hr-styled";
22
-
23
17
  /**
24
18
  * @type {string}
25
19
  * Style class for the div element.
@@ -48,7 +42,7 @@ This file is part of Network Pro.
48
42
  <SocialMedia />
49
43
  </section>
50
44
 
51
- <hr class={hrStyle} />
45
+ <hr />
52
46
 
53
47
  <div class={spaceStyle}></div>
54
48
 
@@ -14,12 +14,6 @@ This file is part of Network Pro.
14
14
  import SocialMedia from "$lib/components/SocialMedia.svelte";
15
15
  import MetaTags from "$lib/components/MetaTags.svelte";
16
16
 
17
- /**
18
- * @type {string}
19
- * Style class for the horizontal rule element.
20
- */
21
- const hrStyle = "hr-styled";
22
-
23
17
  /**
24
18
  * @type {string}
25
19
  * Style class for the div element.
@@ -49,7 +43,7 @@ This file is part of Network Pro.
49
43
  </section>
50
44
  <!-- END SOCIAL MEDIA -->
51
45
 
52
- <hr class={hrStyle} />
46
+ <hr />
53
47
 
54
48
  <div class={spaceStyle}></div>
55
49
 
@@ -14,12 +14,6 @@ This file is part of Network Pro.
14
14
  import SocialMedia from "$lib/components/SocialMedia.svelte";
15
15
  import MetaTags from "$lib/components/MetaTags.svelte";
16
16
 
17
- /**
18
- * @type {string}
19
- * Style class for the horizontal rule element.
20
- */
21
- const hrStyle = "hr-styled";
22
-
23
17
  /**
24
18
  * @type {string}
25
19
  * Style class for the div element.
@@ -34,7 +28,7 @@ This file is part of Network Pro.
34
28
  <link rel="canonical" href="https://netwk.pro/license" />
35
29
 
36
30
  <section id="license">
37
- <FullWidthSection>
31
+ <FullWidthSection containerClass="readable">
38
32
  <!-- BEGIN LEGAL, COPYRIGHT, AND LICENSING -->
39
33
  <section id="main-content">
40
34
  <LicenseContent />
@@ -49,7 +43,7 @@ This file is part of Network Pro.
49
43
  </section>
50
44
  <!-- END SOCIAL MEDIA -->
51
45
 
52
- <hr class={hrStyle} />
46
+ <hr />
53
47
 
54
48
  <div class={spaceStyle}></div>
55
49
 
@@ -0,0 +1,18 @@
1
+ /* ==========================================================================
2
+ src/routes/privacy/+page.server.js
3
+
4
+ Copyright © 2025 Network Pro Strategies (Network Pro™)
5
+ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
+ This file is part of Network Pro.
7
+ ========================================================================== */
8
+
9
+ import { defaultMeta, meta } from "$lib/meta.js";
10
+
11
+ export const prerender = false;
12
+
13
+ /** @type {import('./$types').PageServerLoad} */
14
+ export function load() {
15
+ return {
16
+ meta: meta["/privacy"] || defaultMeta,
17
+ };
18
+ }
@@ -1,5 +1,5 @@
1
1
  <!-- ==========================================================================
2
- src/routes/privacy-policy/+page.svelte
2
+ src/routes/privacy/+page.svelte
3
3
 
4
4
  Copyright © 2025 Network Pro Strategies (Network Pro™)
5
5
  SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
@@ -14,12 +14,6 @@ This file is part of Network Pro.
14
14
  import SocialMedia from "$lib/components/SocialMedia.svelte";
15
15
  import MetaTags from "$lib/components/MetaTags.svelte";
16
16
 
17
- /**
18
- * @type {string}
19
- * Style class for the horizontal rule element.
20
- */
21
- const hrStyle = "hr-styled";
22
-
23
17
  /**
24
18
  * @type {string}
25
19
  * Style class for the div element.
@@ -31,10 +25,10 @@ This file is part of Network Pro.
31
25
 
32
26
  <MetaTags title={data.meta.title} description={data.meta.description} />
33
27
 
34
- <link rel="canonical" href="https://netwk.pro/privacy-policy" />
28
+ <link rel="canonical" href="https://netwk.pro/privacy" />
35
29
 
36
- <section id="privacy-policy">
37
- <FullWidthSection>
30
+ <section id="privacy">
31
+ <FullWidthSection containerClass="readable">
38
32
  <!-- BEGIN PRIVACY POLICY -->
39
33
  <section id="main-content">
40
34
  <PrivacyContent />
@@ -49,7 +43,7 @@ This file is part of Network Pro.
49
43
  </section>
50
44
  <!-- END SOCIAL MEDIA -->
51
45
 
52
- <hr class={hrStyle} />
46
+ <hr />
53
47
 
54
48
  <div class={spaceStyle}></div>
55
49
 
@@ -1,5 +1,5 @@
1
1
  /* ==========================================================================
2
- src/routes/privacy-policy/+page.server.js
2
+ src/routes/privacy/+page.server.js
3
3
 
4
4
  Copyright © 2025 Network Pro Strategies (Network Pro™)
5
5
  SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
@@ -13,6 +13,6 @@ export const prerender = false;
13
13
  /** @type {import('./$types').PageServerLoad} */
14
14
  export function load() {
15
15
  return {
16
- meta: meta["/privacy-policy"] || defaultMeta,
16
+ meta: meta["/privacy-dashboard"] || defaultMeta,
17
17
  };
18
18
  }
@@ -0,0 +1,69 @@
1
+ <!-- ==========================================================================
2
+ src/routes/privacy-dashboard/+page.svelte
3
+
4
+ Copyright © 2025 Network Pro Strategies (Network Pro™)
5
+ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
+ This file is part of Network Pro.
7
+ ========================================================================== -->
8
+
9
+ <script>
10
+ import Badges from "$lib/components/Badges.svelte";
11
+ import FullWidthSection from "$lib/components/FullWidthSection.svelte";
12
+ import PrivacyDashboard from "$lib/pages/PrivacyDashboard.svelte";
13
+ import LegalNav from "$lib/components/LegalNav.svelte";
14
+ import SocialMedia from "$lib/components/SocialMedia.svelte";
15
+ import MetaTags from "$lib/components/MetaTags.svelte";
16
+
17
+ /**
18
+ * @type {string}
19
+ * Style class for the horizontal rule element.
20
+ */
21
+ const hrStyle = "hr-styled";
22
+
23
+ /**
24
+ * @type {string}
25
+ * Style class for the div element.
26
+ */
27
+ const spaceStyle = "spacer";
28
+
29
+ export let data;
30
+ </script>
31
+
32
+ <MetaTags title={data.meta.title} description={data.meta.description} />
33
+
34
+ <link rel="canonical" href="https://netwk.pro/privacy-dashboard" />
35
+
36
+ <section id="privacy">
37
+ <FullWidthSection containerClass="readable">
38
+ <!-- BEGIN PRIVACY DASHBOARD -->
39
+ <section id="main-content">
40
+ <PrivacyDashboard />
41
+ </section>
42
+ <!-- END PRIVACY DASHBOARD -->
43
+
44
+ <div class={spaceStyle}></div>
45
+
46
+ <!-- BEGIN SOCIAL MEDIA -->
47
+ <section id="social-media">
48
+ <SocialMedia />
49
+ </section>
50
+ <!-- END SOCIAL MEDIA -->
51
+
52
+ <hr />
53
+
54
+ <div class={spaceStyle}></div>
55
+
56
+ <!-- BEGIN LEGAL -->
57
+ <section id="legal-nav">
58
+ <LegalNav />
59
+ </section>
60
+ <!-- END LEGAL -->
61
+
62
+ <div class={spaceStyle}></div>
63
+
64
+ <!-- BEGIN BADGES -->
65
+ <section id="badges">
66
+ <Badges />
67
+ </section>
68
+ </FullWidthSection>
69
+ </section>
@@ -14,12 +14,6 @@ This file is part of Network Pro.
14
14
  import SocialMedia from "$lib/components/SocialMedia.svelte";
15
15
  import MetaTags from "$lib/components/MetaTags.svelte";
16
16
 
17
- /**
18
- * @type {string}
19
- * Style class for the horizontal rule element.
20
- */
21
- const hrStyle = "hr-styled";
22
-
23
17
  /**
24
18
  * @type {string}
25
19
  * Style class for the div element.
@@ -34,7 +28,7 @@ This file is part of Network Pro.
34
28
  <link rel="canonical" href="https://netwk.pro/terms-conditions" />
35
29
 
36
30
  <section id="terms-conditions">
37
- <FullWidthSection>
31
+ <FullWidthSection containerClass="readable">
38
32
  <!-- BEGIN TERMS AND CONDITIONS -->
39
33
  <section id="main-content">
40
34
  <TermsConditionsContent />
@@ -49,7 +43,7 @@ This file is part of Network Pro.
49
43
  </section>
50
44
  <!-- END SOCIAL MEDIA -->
51
45
 
52
- <hr class={hrStyle} />
46
+ <hr />
53
47
 
54
48
  <div class={spaceStyle}></div>
55
49
 
@@ -14,12 +14,6 @@ This file is part of Network Pro.
14
14
  import SocialMedia from "$lib/components/SocialMedia.svelte";
15
15
  import MetaTags from "$lib/components/MetaTags.svelte";
16
16
 
17
- /**
18
- * @type {string}
19
- * Style class for the horizontal rule element.
20
- */
21
- const hrStyle = "hr-styled";
22
-
23
17
  /**
24
18
  * @type {string}
25
19
  * Style class for the div element.
@@ -34,7 +28,7 @@ This file is part of Network Pro.
34
28
  <link rel="canonical" href="https://netwk.pro/terms-of-use" />
35
29
 
36
30
  <section id="terms-of-use">
37
- <FullWidthSection>
31
+ <FullWidthSection containerClass="readable">
38
32
  <!-- BEGIN TERMS OF USE -->
39
33
  <section id="main-content">
40
34
  <TermsUseContent />
@@ -49,7 +43,7 @@ This file is part of Network Pro.
49
43
  </section>
50
44
  <!-- END SOCIAL MEDIA -->
51
45
 
52
- <hr class={hrStyle} />
46
+ <hr />
53
47
 
54
48
  <div class={spaceStyle}></div>
55
49
 
@@ -11,6 +11,8 @@ const sw = /** @type {ServiceWorkerGlobalScope} */ (
11
11
  /** @type {unknown} */ (self)
12
12
  );
13
13
 
14
+ /// <reference types="vite/client" />
15
+
14
16
  const isDev = location.hostname === "localhost";
15
17
  const disallowedHosts = [
16
18
  "us.i.posthog.com", // Add PostHog to disallowed hosts
@@ -130,14 +132,35 @@ sw.addEventListener("activate", (event) => {
130
132
  );
131
133
  });
132
134
 
135
+ /**
136
+ * Determine if a request should be skipped by the service worker.
137
+ * Specifically filters out dev/build files, module imports, and source files.
138
+ * Only active in development mode.
139
+ *
140
+ * @param {URL} url
141
+ * @returns {boolean}
142
+ */
143
+ function shouldSkipDevModule(url) {
144
+ if (!isDev) return false;
145
+
146
+ return (
147
+ url.pathname.startsWith("/@fs") ||
148
+ url.pathname.startsWith("/node_modules") ||
149
+ url.pathname.includes(".vite") ||
150
+ url.pathname.includes(".svelte-kit") ||
151
+ !!url.pathname.match(/\.(js|ts|svelte)$/)
152
+ );
153
+ }
154
+
133
155
  // 🔹 Fetch event
134
156
  sw.addEventListener("fetch", (event) => {
135
157
  const requestUrl = new URL(event.request.url);
136
158
 
137
- // ✅ Skip handling for non-local requests (cross-origin)
138
- if (requestUrl.origin !== location.origin) {
139
- return; // let the browser handle external requests
140
- }
159
+ // ✅ Skip cross-origin requests
160
+ if (requestUrl.origin !== location.origin) return;
161
+
162
+ // ✅ Skip internal dev/module files (only in dev)
163
+ if (shouldSkipDevModule(requestUrl)) return;
141
164
 
142
165
  if (isDev) console.log("[SW] Fetch intercepted:", event.request.url);
143
166
 
@@ -153,17 +176,19 @@ sw.addEventListener("fetch", (event) => {
153
176
  if (event.request.mode === "navigate") {
154
177
  const preloadResponse = await event.preloadResponse;
155
178
  if (preloadResponse) {
156
- if (isDev)
179
+ if (isDev) {
157
180
  console.log(
158
181
  "[SW] Using preload response for:",
159
182
  event.request.url,
160
183
  );
184
+ }
161
185
  return preloadResponse;
162
186
  }
163
187
  }
164
188
 
165
189
  if (isDev)
166
190
  console.log("[SW] Fetching from network:", event.request.url);
191
+
167
192
  return await fetch(event.request);
168
193
  } catch (err) {
169
194
  if (isDev) {
@@ -188,4 +213,4 @@ sw.addEventListener("fetch", (event) => {
188
213
  );
189
214
  });
190
215
 
191
- // @cspell:ignore precaching licdn
216
+ // @cspell:ignore precaching
package/static/robots.txt CHANGED
@@ -1,9 +1,10 @@
1
1
  # robots.txt
2
2
  #
3
+ # Copyright © 2025 Network Pro Strategies (Network Pro™)
3
4
  # SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
4
5
  # This file is part of Network Pro
5
6
  #
6
- # www.robotstxt.org/
7
+ # www.robotstxt.org
7
8
 
8
9
  User-agent: *
9
10
 
@@ -1,5 +1,5 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <!-- Sitemap last updated on 2025-05-18 -->
2
+ <!-- Sitemap last updated on 2025-05-28 -->
3
3
 
4
4
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
5
5
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  <loc>https://netwk.pro</loc>
9
9
 
10
- <lastmod>2025-05-24</lastmod>
10
+ <lastmod>2025-05-28</lastmod>
11
11
 
12
12
  <changefreq>weekly</changefreq>
13
13
 
@@ -19,7 +19,7 @@
19
19
 
20
20
  <loc>https://netwk.pro/foss-spotlight</loc>
21
21
 
22
- <lastmod>2025-05-18</lastmod>
22
+ <lastmod>2025-05-27</lastmod>
23
23
 
24
24
  <changefreq>weekly</changefreq>
25
25
 
@@ -29,9 +29,9 @@
29
29
 
30
30
  <url>
31
31
 
32
- <loc>https://netwk.pro/contact</loc>
32
+ <loc>https://netwk.pro/privacy-dashboard</loc>
33
33
 
34
- <lastmod>2025-05-24</lastmod>
34
+ <lastmod>2025-05-28</lastmod>
35
35
 
36
36
  <changefreq>monthly</changefreq>
37
37
 
@@ -41,21 +41,9 @@
41
41
 
42
42
  <url>
43
43
 
44
- <loc>https://netwk.pro/privacy-rights</loc>
44
+ <loc>https://netwk.pro/privacy</loc>
45
45
 
46
- <lastmod>2025-05-24</lastmod>
47
-
48
- <changefreq>monthly</changefreq>
49
-
50
- <priority>0.7</priority>
51
-
52
- </url>
53
-
54
- <url>
55
-
56
- <loc>https://netwk.pro/privacy-policy</loc>
57
-
58
- <lastmod>2025-05-23</lastmod>
46
+ <lastmod>2025-05-28</lastmod>
59
47
 
60
48
  <changefreq>monthly</changefreq>
61
49
 
@@ -67,7 +55,7 @@
67
55
 
68
56
  <loc>https://netwk.pro/license</loc>
69
57
 
70
- <lastmod>2025-05-24</lastmod>
58
+ <lastmod>2025-05-28</lastmod>
71
59
 
72
60
  <changefreq>monthly</changefreq>
73
61
 
@@ -79,7 +67,7 @@
79
67
 
80
68
  <loc>https://netwk.pro/terms-of-use</loc>
81
69
 
82
- <lastmod>2025-05-21</lastmod>
70
+ <lastmod>2025-05-27</lastmod>
83
71
 
84
72
  <changefreq>monthly</changefreq>
85
73
 
@@ -91,7 +79,7 @@
91
79
 
92
80
  <loc>https://netwk.pro/terms-conditions</loc>
93
81
 
94
- <lastmod>2025-05-08</lastmod>
82
+ <lastmod>2025-05-27</lastmod>
95
83
 
96
84
  <changefreq>monthly</changefreq>
97
85
 
@@ -6,123 +6,105 @@ SPDX-License-Identifier: CC-BY-4.0 OR GPL-3.0-or-later
6
6
  This file is part of Network Pro.
7
7
  ========================================================================== */
8
8
 
9
- import { expect, test } from "@playwright/test";
9
+ /**
10
+ * @file app.spec.js
11
+ * @description Runs Playwright E2E tests with desktop and root route assertions.
12
+ * @module tests/e2e
13
+ * @author SunDevil311
14
+ * @updated 2025-05-29
15
+ */
10
16
 
17
+ import { expect, test } from "@playwright/test";
18
+ import {
19
+ getFooter,
20
+ getVisibleNav,
21
+ setDesktopView,
22
+ setMobileView,
23
+ } from "./shared/helpers.js";
24
+
25
+ // Root route should load successfully with the correct title
11
26
  test.describe("Desktop Tests", () => {
12
- // Simplified Test for Title on Desktop
13
27
  test("should load successfully with the correct title", async ({
14
28
  page,
15
29
  browserName,
16
30
  }) => {
17
- if (browserName === "webkit") {
18
- test.skip(); // Skip WebKit if it's problematic
19
- }
20
-
21
- await page.setViewportSize({ width: 1280, height: 720 });
22
-
23
- // Add a small timeout before navigating to the page
24
- await page.waitForTimeout(1500); // Wait for 1.5 seconds
31
+ if (browserName === "webkit") test.skip();
25
32
 
33
+ await setDesktopView(page);
26
34
  await page.goto("/");
27
-
28
- // Wait for the page to fully load
29
- await page.waitForLoadState("load", { timeout: 60000 }); // Wait until the page is fully loaded
30
-
31
- // Assert that the title matches
35
+ await page.waitForLoadState("load", { timeout: 60000 });
32
36
  await expect(page).toHaveTitle(/Locking Down Networks/);
33
37
  });
34
38
 
35
- // Simplified Test for Navigation Bar
39
+ // Root route should display nav bar and about link
36
40
  test("should display the navigation bar and 'about' link", async ({
37
41
  page,
38
42
  }) => {
39
- await page.setViewportSize({ width: 1280, height: 720 });
40
-
41
- // Add a small timeout before navigating to the page
42
- await page.waitForTimeout(1500); // Wait for 1.5 seconds
43
-
43
+ await setDesktopView(page);
44
44
  await page.goto("/");
45
45
 
46
- // Ensure the navigation bar is visible
47
- const nav = page.locator("nav");
48
- await expect(nav).toBeVisible();
46
+ const nav = await getVisibleNav(page);
49
47
 
50
- // Check for 'about' route in the navigation
51
- const aboutLink = nav.locator("a", { hasText: "about" });
48
+ const aboutLink = nav.getByRole("link", { name: "about" });
52
49
  await expect(aboutLink).toBeVisible();
53
- await expect(aboutLink).toHaveAttribute("href", "/about"); // Ensure it points to the correct route
50
+ await expect(aboutLink).toHaveAttribute("href", "/about");
54
51
  });
55
52
 
56
- // Simplified Footer Visibility Test
53
+ // Root route should display the footer properly
57
54
  test("should display the footer correctly", async ({ page }) => {
58
- await page.setViewportSize({ width: 1280, height: 720 });
59
-
60
- // Add a small timeout before navigating to the page
61
- await page.waitForTimeout(1500); // Wait for 1.5 seconds
62
-
55
+ await setDesktopView(page);
63
56
  await page.goto("/");
64
57
 
65
- // Check that the footer is visible
66
58
  const footer = page.locator("footer");
67
59
  await expect(footer).toBeVisible();
68
60
  });
69
61
 
70
- // Simplified Test for Clickable Links (e.g., 'about' link)
71
- test("should ensure the 'about' link is clickable", async ({ page }) => {
72
- await page.setViewportSize({ width: 1280, height: 720 });
62
+ // About route should display the footer properly
63
+ test("should render the 'about' page with footer visible", async ({
64
+ page,
65
+ }) => {
66
+ await setDesktopView(page);
67
+ await page.goto("/about");
73
68
 
74
- // Add a small timeout before navigating to the page
75
- await page.waitForTimeout(1500); // Wait for 1.5 seconds
69
+ const footer = getFooter(page);
70
+ await expect(footer).toBeVisible();
71
+ });
76
72
 
73
+ // Root route should have a clickable "about" link
74
+ test("should ensure the 'about' link is clickable", async ({ page }) => {
75
+ await setDesktopView(page);
77
76
  await page.goto("/");
78
77
 
79
- // Ensure the "about" link is visible and clickable
80
- const aboutLink = page.locator("a", { hasText: "about" });
81
- await expect(aboutLink).toBeVisible();
82
- await aboutLink.click();
78
+ const nav = await getVisibleNav(page);
83
79
 
84
- // Wait for the URL to update instead of relying on navigation
85
- await page.waitForURL("/about", { timeout: 60000 }); // Wait for the correct URL
80
+ const aboutLink = nav.getByRole("link", { name: "about" });
81
+ await expect(aboutLink).toBeVisible({ timeout: 60000 });
82
+ await aboutLink.click();
86
83
 
87
- // Assert that it navigates to the correct route
84
+ await page.waitForURL("/about", { timeout: 60000 });
88
85
  await expect(page).toHaveURL(/\/about/);
89
86
  });
90
- });
87
+ }); // End Desktop Tests
91
88
 
89
+ // Root route should load successfully with the correct title (mobile)
92
90
  test.describe("Mobile Tests", () => {
93
- // Simplified Test for correct title on mobile
94
91
  test("should load successfully with the correct title on mobile", async ({
95
92
  page,
96
93
  browserName,
97
94
  }) => {
98
- if (browserName === "webkit") {
99
- test.skip(); // Skip WebKit if it's problematic
100
- }
101
-
102
- await page.setViewportSize({ width: 375, height: 667 }); // Mobile size (e.g., iPhone 6)
103
-
104
- // Add a small timeout before navigating to the page
105
- await page.waitForTimeout(1500); // Wait for 1.5 seconds
95
+ if (browserName === "webkit") test.skip();
106
96
 
97
+ await setMobileView(page);
107
98
  await page.goto("/");
108
-
109
- // Wait for the page to fully load
110
- await page.waitForLoadState("load", { timeout: 60000 }); // Wait until the page is fully loaded
111
-
112
- // Assert that the title matches
99
+ await page.waitForLoadState("load", { timeout: 60000 });
113
100
  await expect(page).toHaveTitle(/Locking Down Networks/);
114
101
  });
115
102
 
116
- // Simplified Test for mobile content visibility
103
+ // Root route should display headings properly on mobile
117
104
  test("should display main content correctly on mobile", async ({ page }) => {
118
- await page.setViewportSize({ width: 375, height: 667 }); // Mobile size
119
-
120
- // Add a small timeout before navigating to the page
121
- await page.waitForTimeout(1500); // Wait for 1.5 seconds
122
-
105
+ await setMobileView(page);
123
106
  await page.goto("/");
124
107
 
125
- // Check that the main heading is visible on mobile
126
108
  const mainHeading = page.locator("h1, h2");
127
109
  await expect(mainHeading).toBeVisible();
128
110
  });