website

#astro#js#html#css

git clone https://git.pyrossh.dev/website

木 Personal website of pyrossh. Built with astrojs, shiki, vite.


7bf85c2 — pyrossh 2025-05-03T14:06:38+05:30
add playwright

Generated files not shown: bun.lock, package-lock.json

.gitignore CHANGED
@@ -22,3 +22,9 @@ pnpm-debug.log*
22
22
 
23
23
  # jetbrains setting folder
24
24
  .idea/
25
+
26
+ # Playwright
27
+ /test-results/
28
+ /playwright-report/
29
+ /blob-report/
30
+ /playwright/.cache/
package.json CHANGED
@@ -15,5 +15,9 @@
15
15
  "@tailwindcss/vite": "^4.1.4",
16
16
  "astro": "^5.7.5",
17
17
  "tailwindcss": "^4.1.4"
18
+ },
19
+ "devDependencies": {
20
+ "@playwright/test": "^1.52.0",
21
+ "@types/node": "^22.15.3"
18
22
  }
19
23
  }
playwright.config.ts ADDED
@@ -0,0 +1,25 @@
1
+ import { defineConfig, devices } from '@playwright/test';
2
+
3
+ export default defineConfig({
4
+ testDir: './tests',
5
+ fullyParallel: true,
6
+ forbidOnly: !!process.env.CI,
7
+ retries: process.env.CI ? 2 : 0,
8
+ workers: process.env.CI ? 1 : undefined,
9
+ reporter: 'html',
10
+ use: {
11
+ baseURL: 'http://localhost:4321',
12
+ trace: 'on-first-retry',
13
+ },
14
+ projects: [
15
+ {
16
+ name: 'chromium',
17
+ use: { ...devices['Desktop Chrome'] },
18
+ },
19
+ ],
20
+ webServer: {
21
+ command: 'bun run dev',
22
+ url: 'http://localhost:4321',
23
+ reuseExistingServer: !process.env.CI,
24
+ },
25
+ });
public/robots.txt DELETED
@@ -1,4 +0,0 @@
1
- User-agent: *
2
- Allow: /
3
-
4
- Sitemap: https://pyrossh.dev/sitemap.xml
src/layouts/Base.astro CHANGED
@@ -14,7 +14,7 @@ interface Props {
14
14
 
15
15
  const { title, description } = Astro.props;
16
16
  const canonicalURL = new URL(Astro.url.pathname, Astro.site);
17
- const image = "/blog-placeholder-1.jpg";
17
+ const image = "/favicon.png";
18
18
  ---
19
19
 
20
20
  <!doctype html>
src/pages/cv/index.astro CHANGED
@@ -1,235 +1,292 @@
1
1
  ---
2
- import Layout from '@/layouts/Base.astro';
2
+ import Layout from "@/layouts/Base.astro";
3
3
  ---
4
4
 
5
- <Layout title="pyrossh | cv" description="Peter John's CV">
6
- <div>
7
- <section>
8
- <h3>Equal Experts</h3>
9
- <h4>Software Developer, Oct 2018 - present</h4>
10
- <h5>
11
- Making Software. Better. Equal Experts is a network of talented, experienced software
12
- consultants, specialising in agile delivery.
13
- </h5>
14
- <div>
15
- These are the client projects I worked on,
16
- <ul>
17
- <li>
18
- <h6>John Lewis <span>(Mar '21 - Aug '24)</span></h6>
19
- <ul class="*:list-disc">
20
- <li>
21
- Built a quiz memory game with leaderboard scoring to improve engagement during
22
- Christmas
23
- </li>
24
- <li>
25
- Implemented new features for customer self-serve actions in returns, cancellations,
26
- tracking
27
- </li>
28
- <li>
29
- Refactored the old self-serve React app to use Nextjs and removed a large dependency
30
- on redux
31
- </li>
32
- <li>
33
- Ran many experiments in the customer services and order pages to improve our metrics
34
- and reduce contacts
35
- </li>
36
- <li>
37
- Built the new Product Description Page (PDP) for Simple Carpets using a micro
38
- frontend architecture
39
- </li>
40
- <li>
41
- <b>Technologies & Tools</b>: Nodejs, Nextjs, Reactjs, Kotlin, K8s, Grafana, Kibana,
42
- Firestore, Google Sheets API, Monetate, Adobe Analytics, Scene7, Adobe AEM
43
- </li>
44
- </ul>
45
- </li>
46
- <li>
47
- <h6>iOWNA <span>(Mar '20 - Mar '21)</span></h6>
48
- <ul class="*:list-disc">
49
- <li>Built a Content Editor for curators to create content on our platform</li>
50
- <li>
51
- Built the iOWNA crossplatform app in react-native that works in android, ios, and
52
- web using one codebase.
53
- </li>
54
- <li>Implemented Admin specific functionalities in the web app</li>
55
- <li>Implemented an in-app OTA update method using expo and semantic versioning.</li>
56
- <li>Built the iOWNA marketing website</li>
57
- <li>
58
- Built the Health Questionnaire clinician/patient feedback form feature with push
59
- notifications
60
- </li>
61
- <li>
62
- <b>Technologies & Tools</b>: Go, Javascript, React Native, Expo, GraphQL,
63
- Serverless, AppSync, Cognito, Dynamodb, API Gateway, Lambda, Cloudformation
64
- </li>
65
- </ul>
66
- </li>
67
- <li>
68
- <h6>Zeta <span>(Nov '19 - Feb '20)</span></h6>
69
- <ul class="*:list-disc">
70
- <li>
71
- Added multiple download formats (pdf,html,xlsx) for reports in the Reporting Center
72
- </li>
73
- <li>
74
- Created a Groovy Script to automate creating ACL in sandbox authorization framework
75
- </li>
76
- <li>Integrated Camunda Workflow Engine into Zeta services in Operations Center</li>
77
- <li>
78
- Built a few workflows on Camunda and integrated it with some internal services
79
- </li>
80
- <li>
81
- Built a custom k8s CRD using the operator framework to automate creating ACL in
82
- sandbox using custom resources
83
- </li>
84
- <li>
85
- <b>Technologies & Tools</b>: Go, Java, Springboot, Camunda, Postgres, Docker, K8s
86
- </li>
87
- </ul>
88
- </li>
89
- <li>
90
- <h6>Lifebox <span>(Oct '18 - Oct '19)</span></h6>
91
- <ul class="*:list-disc">
92
- <li>Added search functionality to the hospital procedure codes</li>
93
- <li>
94
- Converted the Health Questionnaire from json to native go code making it easier to
95
- make changes to it
96
- </li>
97
- <li>
98
- Integrated with SAP using HL7 message format to create patients, episodes,
99
- schedule/cancel procedures
100
- </li>
101
- <li>
102
- Built the Patient Document repository for uploading, downloading patient files
103
- </li>
104
- <li>Built the patients online reports view using the data from SAP</li>
105
- <li>
106
- <b>Technologies & Tools</b>: Go, Javascript, Reactjs, K6, Serverless, Grafana,
107
- Cognito, Dynamodb, API Gateway , Lambda, GraphQL, Cloudformation, SQLite3
108
- </li>
109
- </ul>
110
- </li>
111
- </ul>
112
- </div>
113
- </section>
114
- <section>
115
- <h3>Numberz</h3>
116
- <h4>Full Stack Developer, Sept 2016 - Oct 2018</h4>
117
- <h5>
118
- Numberz integrates banking with your day-2-day business work-flows freeing up a lot of
119
- effort, time and heart-burn, to help your business grow.
120
- </h5>
121
- <ul class="*:list-disc">
122
- <li>Implemented new features and fixed bugs on the numberz android app</li>
123
- <li>Integrated numberz with Tally ERP (export and import of sales, purchases)</li>
124
- <li>
125
- Implemented CI and Devops within out system to ease our deployment process using docker
126
- and docker-compose
127
- </li>
128
- <li>
129
- Created a slack bot called deploybot which was used to deploy our microservices to our
130
- servers
131
- </li>
132
- <li>Started tech talks on Thursdays to discuss cutting edge technologies</li>
133
- <li>Architected and built the Notification Service using rabbitmq and nodejs</li>
134
- <li>Built the Multi-User and Multi-Company Features</li>
135
- <li>
136
- Implemented and lead a team on integration with the GSTN System so that customers could
137
- file their GST Taxes within our product
138
- </li>
139
- <li>Architected and built the numberz Identity Management Service(IMS)</li>
140
- <li>Architected our new product called the Numberz Accounts Receivable (AR)</li>
141
- <li>Laid down the architecture for the frontend and backend</li>
142
- <li>
143
- Built these core features for our new AR Product - Auto Reminders, Manual Reminders, User
144
- Management, Cash Discounting, CFO Dashboard Metrics
145
- </li>
146
- <li>
147
- <b>Technologies & Tools</b>: Nodejs, Mongodb, Postgres, GraphQL, Ansible, K8s, Typescript,
148
- Reactjs
149
- </li>
150
- </ul>
151
- </section>
152
- <section>
153
- <h3>Playlyfe</h3>
154
- <h4>Full Stack Developer, Apr 2014 - Sept 2016</h4>
155
- <h5>
156
- Playlyfe is an online Gamification Platform which empowers anyone to design and implement a
157
- gamified system.
158
- </h5>
159
- <ul class="*:list-disc">
160
- <li>Built the Playlyfe Hybrid Mobile app using Phonegap for Android and iOS</li>
161
- <li>Built the leaderboard system using Mongodb, Redis and Couchbase as the datastore</li>
162
- <li>Migration of data from v1 to v2 of the API</li>
163
- <li>Built SDKs for the Playlyfe v2 API in C#, Java, Python, Ruby, PHP, Nodejs, Gos</li>
164
- <li>Maintained the job server and wrote most of the background jobs</li>
165
- <li>
166
- Added documentation to most of the REST API and created the Developer Console which was
167
- Like Swagger UI
168
- </li>
169
- <li>Integrated our REST API in Leanosphere's LMS</li>
170
- <li>Integrated the REST API in Knolskape's product Aktivlearn LMS</li>
171
- <li>Integrated the REST API in Linkstreet's LMS</li>
172
- <li>
173
- Integrated the REST API in Moodle LMS by creating an admin plugin to add Gamification
174
- features
175
- </li>
176
- <li>Rebuilt the core platform in golang for performance and developement speed</li>
177
- <li>Built the GraphQL API for our cutting edge product Catalyst</li>
178
- <li>
179
- Convinced the boss to create our own scripting language plscript for our rule engine.
180
- </li>
181
- <li>Build a REST API for our product catalyst for a POC with Vodafone</li>
182
- <li>
183
- Built the Quiz, Review, Match, Tournament features in Catalyst for a major project with HP
184
- </li>
185
- <li>Added gamification features to Saudi Matches a popular game tracking app</li>
186
- <li>
187
- <b>Technologies & Tools</b>: Nodejs, Coffeescript, Angularjs, Mongodb, Couchbase, Redis,
188
- Seaweedfs, Postgres, Golang, GraphQL, Relay, React
189
- </li>
190
- </ul>
191
- </section>
192
- </div>
5
+ <Layout title="cv" description="Peter John's CV">
6
+ <div>
7
+ <section>
8
+ <h3>Equal Experts</h3>
9
+ <h4>Software Developer, Oct 2018 - present</h4>
10
+ <h5>
11
+ Making Software. Better. Equal Experts is a network of talented,
12
+ experienced software consultants, specialising in agile delivery.
13
+ </h5>
14
+ <div>
15
+ These are the client projects I worked on,
16
+ <ul>
17
+ <li>
18
+ <h6>John Lewis <span>(Mar '21 - Aug '24)</span></h6>
19
+ <ul class="*:list-disc">
20
+ <li>
21
+ Built a quiz memory game with leaderboard scoring to improve
22
+ engagement during Christmas
23
+ </li>
24
+ <li>
25
+ Implemented new features for customer self-serve actions in
26
+ returns, cancellations, tracking
27
+ </li>
28
+ <li>
29
+ Refactored the old self-serve React app to use Nextjs and
30
+ removed a large dependency on redux
31
+ </li>
32
+ <li>
33
+ Ran many experiments in the customer services and order pages to
34
+ improve our metrics and reduce contacts
35
+ </li>
36
+ <li>
37
+ Built the new Product Description Page (PDP) for Simple Carpets
38
+ using a micro frontend architecture
39
+ </li>
40
+ <li>
41
+ <b>Technologies & Tools</b>: Nodejs, Nextjs, Reactjs, Kotlin,
42
+ K8s, Grafana, Kibana, Firestore, Google Sheets API, Monetate,
43
+ Adobe Analytics, Scene7, Adobe AEM
44
+ </li>
45
+ </ul>
46
+ </li>
47
+ <li>
48
+ <h6>iOWNA <span>(Mar '20 - Mar '21)</span></h6>
49
+ <ul class="*:list-disc">
50
+ <li>
51
+ Built a Content Editor for curators to create content on our
52
+ platform
53
+ </li>
54
+ <li>
55
+ Built the iOWNA crossplatform app in react-native that works in
56
+ android, ios, and web using one codebase.
57
+ </li>
58
+ <li>Implemented Admin specific functionalities in the web app</li>
59
+ <li>
60
+ Implemented an in-app OTA update method using expo and semantic
61
+ versioning.
62
+ </li>
63
+ <li>Built the iOWNA marketing website</li>
64
+ <li>
65
+ Built the Health Questionnaire clinician/patient feedback form
66
+ feature with push notifications
67
+ </li>
68
+ <li>
69
+ <b>Technologies & Tools</b>: Go, Javascript, React Native, Expo,
70
+ GraphQL, Serverless, AppSync, Cognito, Dynamodb, API Gateway,
71
+ Lambda, Cloudformation
72
+ </li>
73
+ </ul>
74
+ </li>
75
+ <li>
76
+ <h6>Zeta <span>(Nov '19 - Feb '20)</span></h6>
77
+ <ul class="*:list-disc">
78
+ <li>
79
+ Added multiple download formats (pdf,html,xlsx) for reports in
80
+ the Reporting Center
81
+ </li>
82
+ <li>
83
+ Created a Groovy Script to automate creating ACL in sandbox
84
+ authorization framework
85
+ </li>
86
+ <li>
87
+ Integrated Camunda Workflow Engine into Zeta services in
88
+ Operations Center
89
+ </li>
90
+ <li>
91
+ Built a few workflows on Camunda and integrated it with some
92
+ internal services
93
+ </li>
94
+ <li>
95
+ Built a custom k8s CRD using the operator framework to automate
96
+ creating ACL in sandbox using custom resources
97
+ </li>
98
+ <li>
99
+ <b>Technologies & Tools</b>: Go, Java, Springboot, Camunda,
100
+ Postgres, Docker, K8s
101
+ </li>
102
+ </ul>
103
+ </li>
104
+ <li>
105
+ <h6>Lifebox <span>(Oct '18 - Oct '19)</span></h6>
106
+ <ul class="*:list-disc">
107
+ <li>
108
+ Added search functionality to the hospital procedure codes
109
+ </li>
110
+ <li>
111
+ Converted the Health Questionnaire from json to native go code
112
+ making it easier to make changes to it
113
+ </li>
114
+ <li>
115
+ Integrated with SAP using HL7 message format to create patients,
116
+ episodes, schedule/cancel procedures
117
+ </li>
118
+ <li>
119
+ Built the Patient Document repository for uploading, downloading
120
+ patient files
121
+ </li>
122
+ <li>
123
+ Built the patients online reports view using the data from SAP
124
+ </li>
125
+ <li>
126
+ <b>Technologies & Tools</b>: Go, Javascript, Reactjs, K6,
127
+ Serverless, Grafana, Cognito, Dynamodb, API Gateway , Lambda,
128
+ GraphQL, Cloudformation, SQLite3
129
+ </li>
130
+ </ul>
131
+ </li>
132
+ </ul>
133
+ </div>
134
+ </section>
135
+ <section>
136
+ <h3>Numberz</h3>
137
+ <h4>Full Stack Developer, Sept 2016 - Oct 2018</h4>
138
+ <h5>
139
+ Numberz integrates banking with your day-2-day business work-flows
140
+ freeing up a lot of effort, time and heart-burn, to help your business
141
+ grow.
142
+ </h5>
143
+ <ul class="*:list-disc">
144
+ <li>
145
+ Implemented new features and fixed bugs on the numberz android app
146
+ </li>
147
+ <li>
148
+ Integrated numberz with Tally ERP (export and import of sales,
149
+ purchases)
150
+ </li>
151
+ <li>
152
+ Implemented CI and Devops within out system to ease our deployment
153
+ process using docker and docker-compose
154
+ </li>
155
+ <li>
156
+ Created a slack bot called deploybot which was used to deploy our
157
+ microservices to our servers
158
+ </li>
159
+ <li>
160
+ Started tech talks on Thursdays to discuss cutting edge technologies
161
+ </li>
162
+ <li>
163
+ Architected and built the Notification Service using rabbitmq and
164
+ nodejs
165
+ </li>
166
+ <li>Built the Multi-User and Multi-Company Features</li>
167
+ <li>
168
+ Implemented and lead a team on integration with the GSTN System so
169
+ that customers could file their GST Taxes within our product
170
+ </li>
171
+ <li>
172
+ Architected and built the numberz Identity Management Service(IMS)
173
+ </li>
174
+ <li>
175
+ Architected our new product called the Numberz Accounts Receivable
176
+ (AR)
177
+ </li>
178
+ <li>Laid down the architecture for the frontend and backend</li>
179
+ <li>
180
+ Built these core features for our new AR Product - Auto Reminders,
181
+ Manual Reminders, User Management, Cash Discounting, CFO Dashboard
182
+ Metrics
183
+ </li>
184
+ <li>
185
+ <b>Technologies & Tools</b>: Nodejs, Mongodb, Postgres, GraphQL,
186
+ Ansible, K8s, Typescript, Reactjs
187
+ </li>
188
+ </ul>
189
+ </section>
190
+ <section>
191
+ <h3>Playlyfe</h3>
192
+ <h4>Full Stack Developer, Apr 2014 - Sept 2016</h4>
193
+ <h5>
194
+ Playlyfe is an online Gamification Platform which empowers anyone to
195
+ design and implement a gamified system.
196
+ </h5>
197
+ <ul class="*:list-disc">
198
+ <li>
199
+ Built the Playlyfe Hybrid Mobile app using Phonegap for Android and
200
+ iOS
201
+ </li>
202
+ <li>
203
+ Built the leaderboard system using Mongodb, Redis and Couchbase as the
204
+ datastore
205
+ </li>
206
+ <li>Migration of data from v1 to v2 of the API</li>
207
+ <li>
208
+ Built SDKs for the Playlyfe v2 API in C#, Java, Python, Ruby, PHP,
209
+ Nodejs, Gos
210
+ </li>
211
+ <li>Maintained the job server and wrote most of the background jobs</li>
212
+ <li>
213
+ Added documentation to most of the REST API and created the Developer
214
+ Console which was Like Swagger UI
215
+ </li>
216
+ <li>Integrated our REST API in Leanosphere's LMS</li>
217
+ <li>Integrated the REST API in Knolskape's product Aktivlearn LMS</li>
218
+ <li>Integrated the REST API in Linkstreet's LMS</li>
219
+ <li>
220
+ Integrated the REST API in Moodle LMS by creating an admin plugin to
221
+ add Gamification features
222
+ </li>
223
+ <li>
224
+ Rebuilt the core platform in golang for performance and developement
225
+ speed
226
+ </li>
227
+ <li>Built the GraphQL API for our cutting edge product Catalyst</li>
228
+ <li>
229
+ Convinced the boss to create our own scripting language plscript for
230
+ our rule engine.
231
+ </li>
232
+ <li>
233
+ Build a REST API for our product catalyst for a POC with Vodafone
234
+ </li>
235
+ <li>
236
+ Built the Quiz, Review, Match, Tournament features in Catalyst for a
237
+ major project with HP
238
+ </li>
239
+ <li>
240
+ Added gamification features to Saudi Matches a popular game tracking
241
+ app
242
+ </li>
243
+ <li>
244
+ <b>Technologies & Tools</b>: Nodejs, Coffeescript, Angularjs, Mongodb,
245
+ Couchbase, Redis, Seaweedfs, Postgres, Golang, GraphQL, Relay, React
246
+ </li>
247
+ </ul>
248
+ </section>
249
+ </div>
193
250
  </Layout>
194
251
  <style>
195
- b {
252
+ b {
196
- font-weight: 600;
253
+ font-weight: 600;
197
- }
254
+ }
198
255
 
199
- ul {
256
+ ul {
200
- margin: 0.5rem;
257
+ margin: 0.5rem;
201
- padding-left: 1rem;
258
+ padding-left: 1rem;
202
- }
259
+ }
203
260
 
204
- li {
261
+ li {
205
- list-style-type: disc;
262
+ list-style-type: disc;
206
- list-style-position: outside;
263
+ list-style-position: outside;
207
- }
264
+ }
208
265
 
209
- h3 {
266
+ h3 {
210
- font-weight: 700;
267
+ font-weight: 700;
211
- font-size: 1.4rem;
268
+ font-size: 1.4rem;
212
- margin-top: 0.5rem;
269
+ margin-top: 0.5rem;
213
- margin-bottom: 0.5rem;
270
+ margin-bottom: 0.5rem;
214
- }
271
+ }
215
272
 
216
- h4 {
273
+ h4 {
217
- font-weight: 600;
274
+ font-weight: 600;
218
- margin-top: 0.5rem;
275
+ margin-top: 0.5rem;
219
- }
276
+ }
220
277
 
221
- h5 {
278
+ h5 {
222
- margin-top: 0.5rem;
279
+ margin-top: 0.5rem;
223
- }
280
+ }
224
281
 
225
- h6 {
282
+ h6 {
226
- font-weight: 600;
283
+ font-weight: 600;
227
- margin-top: 0.5rem;
284
+ margin-top: 0.5rem;
228
285
 
229
- span {
286
+ span {
230
- font-family: sans-serif;
287
+ font-family: sans-serif;
231
- font-weight: 400;
288
+ font-weight: 400;
232
- font-size: 0.95rem;
289
+ font-size: 0.95rem;
233
- }
290
+ }
234
- }
291
+ }
235
292
  </style>
src/pages/posts/index.astro CHANGED
@@ -8,7 +8,7 @@ const posts = (await getCollection("content")).sort(
8
8
  );
9
9
  ---
10
10
 
11
- <Layout>
11
+ <Layout title="Posts" description="Posts">
12
12
  <h1 class="font-bold text-3xl">Posts</h1>
13
13
  <div class="container">
14
14
  <ul class="flex flex-col">
src/pages/robots.txt.ts ADDED
@@ -0,0 +1,13 @@
1
+ import type { APIRoute } from 'astro';
2
+
3
+ const getRobotsTxt = (sitemapURL: URL) =>
4
+ `User-agent: *
5
+ Allow: /
6
+
7
+ Sitemap: ${sitemapURL.href}
8
+ `;
9
+
10
+ export const GET: APIRoute = ({ site }) => {
11
+ const sitemapURL = new URL('sitemap-index.xml', site);
12
+ return new Response(getRobotsTxt(sitemapURL));
13
+ };
src/pages/rss.xml.js DELETED
@@ -1,16 +0,0 @@
1
- import rss from '@astrojs/rss';
2
- import { getCollection } from 'astro:content';
3
- import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
4
-
5
- export async function GET(context) {
6
- const posts = await getCollection('blog');
7
- return rss({
8
- title: SITE_TITLE,
9
- description: SITE_DESCRIPTION,
10
- site: context.site,
11
- items: posts.map((post) => ({
12
- ...post.data,
13
- link: `/blog/${post.id}/`,
14
- })),
15
- });
16
- }
src/pages/rss.xml.ts ADDED
@@ -0,0 +1,17 @@
1
+ import type { APIRoute } from 'astro';
2
+ import { getCollection } from 'astro:content';
3
+ import rss from '@astrojs/rss';
4
+ import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
5
+
6
+ export const GET: APIRoute = async ({ site }) => {
7
+ const posts = await getCollection('blog');
8
+ return rss({
9
+ title: SITE_TITLE,
10
+ description: SITE_DESCRIPTION,
11
+ site: site,
12
+ items: posts.map((post) => ({
13
+ ...post.data,
14
+ link: `/posts/${post.id}/`,
15
+ })),
16
+ });
17
+ }
tests/{test.js → home.spec.ts} RENAMED
@@ -1,6 +1,6 @@
1
1
  import { expect, test } from '@playwright/test';
2
2
 
3
3
  test('index page has expected h1', async ({ page }) => {
4
- await page.goto('/');
4
+ await page.goto('/');
5
- await expect(page.getByRole('heading', { name: 'pyrossh' })).toBeVisible();
5
+ await expect(page.getByRole('heading', { name: 'Hello!' })).toBeVisible();
6
6
  });
tests/sitemap.spec.ts ADDED
@@ -0,0 +1,27 @@
1
+ import { expect, test } from '@playwright/test';
2
+
3
+ test('/sitemap.xml is valid', async ({ page }) => {
4
+ const response = await page.goto('/sitemap.xml');
5
+ expect(response.status()).toBe(200);
6
+
7
+ // Ensure XML is valid. Playwright parses the XML here and will error if it
8
+ // cannot be parsed.
9
+ const urls = await page.$$eval('url', (urls) =>
10
+ urls.map((url) => ({
11
+ loc: url.querySelector('loc').textContent,
12
+ // changefreq: url.querySelector('changefreq').textContent, // if you enabled in your sitemap
13
+ // priority: url.querySelector('priority').textContent,
14
+ })),
15
+ );
16
+
17
+ // Sanity check
18
+ expect(urls.length).toBeGreaterThanOrEqual(5);
19
+
20
+ // Ensure entries are in a valid format.
21
+ for (const url of urls) {
22
+ expect(url.loc).toBeTruthy();
23
+ expect(() => new URL(url.loc)).not.toThrow();
24
+ // expect(url.changefreq).toBe('daily');
25
+ // expect(url.priority).toBe('0.7');
26
+ }
27
+ });
tests/sitemap.test.js DELETED
@@ -1,27 +0,0 @@
1
- import { expect, test } from '@playwright/test';
2
-
3
- test('/sitemap.xml is valid', async ({ page }) => {
4
- const response = await page.goto('/sitemap.xml');
5
- expect(response.status()).toBe(200);
6
-
7
- // Ensure XML is valid. Playwright parses the XML here and will error if it
8
- // cannot be parsed.
9
- const urls = await page.$$eval('url', (urls) =>
10
- urls.map((url) => ({
11
- loc: url.querySelector('loc').textContent,
12
- // changefreq: url.querySelector('changefreq').textContent, // if you enabled in your sitemap
13
- // priority: url.querySelector('priority').textContent,
14
- })),
15
- );
16
-
17
- // Sanity check
18
- expect(urls.length).toBeGreaterThanOrEqual(5);
19
-
20
- // Ensure entries are in a valid format.
21
- for (const url of urls) {
22
- expect(url.loc).toBeTruthy();
23
- expect(() => new URL(url.loc)).not.toThrow();
24
- // expect(url.changefreq).toBe('daily');
25
- // expect(url.priority).toBe('0.7');
26
- }
27
- });