-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathMessageCheckerService.ts
More file actions
127 lines (106 loc) · 3.71 KB
/
MessageCheckerService.ts
File metadata and controls
127 lines (106 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { BrowserContext, Locator, Page, expect } from "@playwright/test";
import {
EmailAddress,
EmailContent,
EmailHeader,
EmailService,
} from "./EmailService";
export class MessageCheckerService extends EmailService {
context: BrowserContext;
constructor(context: BrowserContext) {
super();
this.context = context;
}
generateEmailAddress(): EmailAddress {
const randomString = this.randomString(10);
return `test+${randomString}@message-checker.appspotmail.com`;
}
// Action functions
async getInbox(emailAddress: EmailAddress): Promise<EmailHeader[]> {
const messageCheckerURL = this.buildMessageCheckerURLToInbox(emailAddress);
const messageCheckerPage = await this.openNewPage(messageCheckerURL);
try {
const inboxEntries: EmailHeader[] = [];
// Get all rows excluding the table header row
const rows = (await messageCheckerPage.getByRole("row").all()).slice(1);
for (const row of rows) {
const emailHeader = await this.createEmailHeaderFromRow(
row,
emailAddress,
);
inboxEntries.push(emailHeader);
}
return inboxEntries;
} finally {
await messageCheckerPage.close();
}
}
async getEmailContent(emailHeader: EmailHeader): Promise<EmailContent> {
const directEmailURL = this.buildMessageCheckerURLToEmail(emailHeader);
const emailPage = await this.openNewPage(directEmailURL);
try {
const container = emailPage.getByRole("document");
const text = await container.innerText();
const html = await container.innerHTML();
return { text, html, emailHeader };
} finally {
await emailPage.close();
}
}
async waitForEmailWithSubject(
emailAddress: EmailAddress,
subjectSubstring: string,
): Promise<EmailContent> {
const inboxURL = this.buildMessageCheckerURLToInbox(emailAddress);
const inboxPage = await this.openNewPage(inboxURL);
try {
const matchingRow = inboxPage
.getByRole("row")
.filter({ hasText: subjectSubstring })
.first();
await matchingRow.waitFor();
const emailHeader = await this.createEmailHeaderFromRow(
matchingRow,
emailAddress,
);
return this.getEmailContent(emailHeader);
} finally {
await inboxPage.close();
}
}
private static readonly MESSAGE_CHECKER_BASE_URL =
"https://message-checker.appspot.com";
// Helpers
private buildMessageCheckerURLToEmail(emailHeader: EmailHeader): string {
return `${MessageCheckerService.MESSAGE_CHECKER_BASE_URL}/message-body/${emailHeader.id}`;
}
private async createEmailHeaderFromRow(
row: Locator,
emailAddress: EmailAddress,
): Promise<EmailHeader> {
const subjectLink = row.getByRole("cell").first().getByRole("link");
const subject = (await subjectLink.innerText()).trim();
// EmailLink format: /message-body/{email-id}
// Split by "/" and get item at index 2 to extract email-id
const emailLink = (await subjectLink.getAttribute("href")) ?? "";
const emailId = emailLink.split("/")[2];
return {
id: emailId,
to: emailAddress,
from: "", // No sender information in MessageChecker
subject,
};
}
private buildMessageCheckerURLToInbox(emailAddress: string): string {
const encodedEmailPrefix = this.getEncodedEmailPrefix(emailAddress);
return `${MessageCheckerService.MESSAGE_CHECKER_BASE_URL}/address/${encodedEmailPrefix}`;
}
private getEncodedEmailPrefix(emailAddress: string): string {
return encodeURIComponent(emailAddress.split("@")[0]);
}
private async openNewPage(url: string): Promise<Page> {
const page = await this.context.newPage();
await page.goto(url);
return page;
}
}