neetob 0.5.69 → 0.5.77
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.
- checksums.yaml +4 -4
- data/.env +2 -1
- data/.neetoci/default.yml +1 -1
- data/.ruby-version +1 -1
- data/Gemfile.lock +44 -21
- data/README.md +11 -0
- data/bookmarks.md +113 -113
- data/data/github-labels.json +80 -45
- data/data/repo-team-leads.json +82 -0
- data/exe/neetob +1 -1
- data/lib/neetob/cli/base.rb +35 -5
- data/lib/neetob/cli/cloudflare/automatic_https_rewrites.rb +34 -0
- data/lib/neetob/cli/cloudflare/base.rb +2 -2
- data/lib/neetob/cli/cloudflare/commands.rb +7 -0
- data/lib/neetob/cli/github/active_record_doctor.rb +1 -1
- data/lib/neetob/cli/github/brakeman.rb +1 -1
- data/lib/neetob/cli/github/bundle_audit.rb +1 -1
- data/lib/neetob/cli/github/issues/helpers.rb +17 -4
- data/lib/neetob/cli/github/make_pr/base.rb +1 -1
- data/lib/neetob/cli/github/repositories/pull_requests.rb +19 -0
- data/lib/neetob/cli/github/repositories/team_leads.rb +34 -0
- data/lib/neetob/cli/github/unused_assets_audit.rb +5 -1
- data/lib/neetob/cli/monthly_audit/github_issue_creation.rb +57 -17
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/{bot_protection_enabled.rb → automatic_https_rewrites_is_enabled.rb} +11 -9
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cloudflare/main.rb +2 -2
- data/lib/neetob/cli/monthly_audit/instances_and_addons/cronitor/setup_correctly_for_landing_pages.rb +3 -2
- data/lib/neetob/cli/monthly_audit/instances_and_addons/honeybadger/setup_correctly_for_apps.rb +28 -29
- data/lib/neetob/cli/monthly_audit/instances_and_addons/main.rb +5 -5
- data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy_or_heroku/cloudfront_cdn_enabled.rb +0 -17
- data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy_or_heroku/essential_environment_variables_set.rb +0 -15
- data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy_or_heroku/main.rb +0 -3
- data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy_or_heroku/scheduled_exports_enabled.rb +2 -4
- data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy_or_heroku/ssl_certificates_over_thirty_days_from_expiry.rb +67 -34
- data/lib/neetob/cli/monthly_audit/misc/main.rb +1 -1
- data/lib/neetob/cli/monthly_audit/misc/sparkpost_sub_account_used_for_all_apps.rb +24 -18
- data/lib/neetob/cli/monthly_audit/security/code/active_record_doctor.rb +2 -2
- data/lib/neetob/cli/monthly_audit/security/code/brakeman.rb +7 -4
- data/lib/neetob/cli/monthly_audit/security/code/bundle_audit.rb +13 -4
- data/lib/neetob/cli/monthly_audit/security/code/fasterer.rb +2 -2
- data/lib/neetob/cli/monthly_audit/security/code/yarn_audit.rb +1 -1
- data/lib/neetob/cli/monthly_audit/security/github/dependabot_prs_merged.rb +20 -5
- data/lib/neetob/cli/monthly_audit/security/github/dependabot_turned_on.rb +25 -21
- data/lib/neetob/cli/neeto_deploy/autoscaling_config.rb +1 -1
- data/lib/neetob/cli/neeto_deploy/certificates.rb +1 -1
- data/lib/neetob/cli/neeto_deploy/commands.rb +7 -0
- data/lib/neetob/cli/neeto_deploy/config_vars/list.rb +1 -1
- data/lib/neetob/cli/neeto_deploy/config_vars/remove.rb +1 -1
- data/lib/neetob/cli/neeto_deploy/config_vars/upsert.rb +1 -1
- data/lib/neetob/cli/neeto_deploy/scheduled_exports.rb +1 -1
- data/lib/neetob/cli/neeto_deploy/unique_email_domains.rb +165 -0
- data/lib/neetob/cli/sre/base.rb +13 -13
- data/lib/neetob/cli/sre/check_essential_env.rb +7 -2
- data/lib/neetob/cli/sre/checklist.rb +2 -2
- data/lib/neetob/version.rb +1 -1
- data/neetob.gemspec +1 -1
- data/package.json +30 -0
- data/playwright.config.ts +39 -0
- data/scripts/config/.env.local +17 -0
- data/scripts/constants/auditData.ts +402 -0
- data/scripts/constants/routes.ts +30 -0
- data/scripts/constants/selectors.ts +4 -0
- data/scripts/constants/table.ts +30 -0
- data/scripts/constants/texts.ts +46 -0
- data/scripts/constants/userAgents.ts +14 -0
- data/scripts/utils/markdown.ts +23 -0
- data/scripts/workflows/dependabot.ts +104 -0
- data/scripts/workflows/honeybadger.ts +169 -0
- data/scripts/workflows/sparkpost.ts +204 -0
- data/tsconfig.json +35 -0
- data/yarn.lock +2216 -0
- metadata +24 -6
- data/lib/neetob/cli/monthly_audit/instances_and_addons/neeto_deploy_or_heroku/auto_scaling_enabled.rb +0 -67
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { NEETO_HEALTH_WORKSPACE, PRODUCTION_APPS } from "@auditData";
|
|
2
|
+
import { ROUTES } from "@routes";
|
|
3
|
+
import { HONEYBADGER_TEXTS } from "@texts";
|
|
4
|
+
import { faker } from "@faker-js/faker";
|
|
5
|
+
import test, { expect } from "@playwright/test";
|
|
6
|
+
import { addRow } from "@utils/markdown";
|
|
7
|
+
import { HONEYBADGER_TABLE } from "@constants/table";
|
|
8
|
+
|
|
9
|
+
const { honeybadger } = ROUTES;
|
|
10
|
+
const randomUserAgent = faker.internet.userAgent();
|
|
11
|
+
const randomTimezone = faker.location.timeZone();
|
|
12
|
+
test.use({ userAgent: randomUserAgent, timezoneId: randomTimezone });
|
|
13
|
+
|
|
14
|
+
test.describe("Honeybadger", () => {
|
|
15
|
+
test.beforeEach(async ({ page }) => {
|
|
16
|
+
await page.goto(honeybadger.signIn);
|
|
17
|
+
await page.waitForLoadState();
|
|
18
|
+
await page
|
|
19
|
+
.getByLabel(HONEYBADGER_TEXTS.email)
|
|
20
|
+
.fill(process.env.HONEYBADGER_EMAIL);
|
|
21
|
+
|
|
22
|
+
await page
|
|
23
|
+
.getByLabel(HONEYBADGER_TEXTS.password)
|
|
24
|
+
.fill(process.env.HONEYBADGER_PASSWORD);
|
|
25
|
+
|
|
26
|
+
await page
|
|
27
|
+
.getByRole("button", { name: HONEYBADGER_TEXTS.signIn, exact: true })
|
|
28
|
+
.click();
|
|
29
|
+
|
|
30
|
+
await expect(
|
|
31
|
+
page.getByRole("link", { name: HONEYBADGER_TEXTS.addProject })
|
|
32
|
+
).toBeVisible();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("Check whether honeybadger is configured for apps", async ({ page }) => {
|
|
36
|
+
for (const [i, app] of PRODUCTION_APPS.entries()) {
|
|
37
|
+
const { name, honebadgerId, channelId, integrationName } = app;
|
|
38
|
+
const prodName = `neeto-${name}-web-production`;
|
|
39
|
+
const row = [prodName];
|
|
40
|
+
const comments: string[] = [];
|
|
41
|
+
|
|
42
|
+
const errorPage = page.getByRole("heading", {
|
|
43
|
+
name: HONEYBADGER_TEXTS.pageNotFound,
|
|
44
|
+
});
|
|
45
|
+
const projectsHeading = page.getByRole("link", {
|
|
46
|
+
name: HONEYBADGER_TEXTS.projects,
|
|
47
|
+
exact: true,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
await test.step(`Step ${
|
|
51
|
+
i + 1
|
|
52
|
+
}: Check whether honeybadger is configured for neeto-${name}-web`, async () => {
|
|
53
|
+
await page.goto(honeybadger.settings.general(honebadgerId));
|
|
54
|
+
await page.waitForLoadState();
|
|
55
|
+
await expect(errorPage.or(projectsHeading)).toBeVisible({
|
|
56
|
+
timeout: 30_000,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if (await errorPage.isVisible()) {
|
|
60
|
+
const comment = `HoneyBadger is not configured for ${prodName}`;
|
|
61
|
+
const rowData = [prodName, "No", "No", "No", "No", comment, "No"];
|
|
62
|
+
addRow(HONEYBADGER_TABLE, rowData);
|
|
63
|
+
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const notificationsCheckbox = page.getByLabel(
|
|
68
|
+
HONEYBADGER_TEXTS.enableNotifications
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const [isHidden, isChecked] = await Promise.all([
|
|
72
|
+
notificationsCheckbox.isHidden(),
|
|
73
|
+
notificationsCheckbox.isChecked(),
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
const isNotificationsEnabled = isHidden || !isChecked ? "No" : "Yes";
|
|
77
|
+
row.push(isNotificationsEnabled);
|
|
78
|
+
|
|
79
|
+
if (isNotificationsEnabled === "No") {
|
|
80
|
+
comments.push("Notifications are not turned on");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
await page.goto(
|
|
84
|
+
ROUTES.honeybadger.settings.integrations.channels(honebadgerId)
|
|
85
|
+
);
|
|
86
|
+
await page.waitForLoadState();
|
|
87
|
+
|
|
88
|
+
const githubIntegration = page
|
|
89
|
+
.getByRole("cell", {
|
|
90
|
+
name: HONEYBADGER_TEXTS.githubIntegration(name),
|
|
91
|
+
})
|
|
92
|
+
.or(
|
|
93
|
+
page.getByRole("cell", {
|
|
94
|
+
name: HONEYBADGER_TEXTS.githubIntegration(integrationName),
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
const slackIntegration = page.getByRole("cell", {
|
|
99
|
+
name: HONEYBADGER_TEXTS.slackIntegration(name),
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const [isGithubVisible, isSlackVisible] = await Promise.all([
|
|
103
|
+
githubIntegration.isVisible(),
|
|
104
|
+
slackIntegration.isVisible(),
|
|
105
|
+
]);
|
|
106
|
+
|
|
107
|
+
const gitHubIntegrationStatus = isGithubVisible ? "Yes" : "No";
|
|
108
|
+
row.push(gitHubIntegrationStatus);
|
|
109
|
+
|
|
110
|
+
if (gitHubIntegrationStatus === "No") {
|
|
111
|
+
comments.push(`GitHub is not integrated`);
|
|
112
|
+
row.push(gitHubIntegrationStatus);
|
|
113
|
+
} else {
|
|
114
|
+
await page
|
|
115
|
+
.getByRole("row")
|
|
116
|
+
.filter({ has: githubIntegration })
|
|
117
|
+
.getByRole("link")
|
|
118
|
+
.click();
|
|
119
|
+
|
|
120
|
+
const [isCreateIssueChecked, isReopenIssueChecked] =
|
|
121
|
+
await Promise.all([
|
|
122
|
+
page.getByLabel(HONEYBADGER_TEXTS.createIssue).isChecked(),
|
|
123
|
+
page.getByLabel(HONEYBADGER_TEXTS.reOpenIssue).isChecked(),
|
|
124
|
+
]);
|
|
125
|
+
|
|
126
|
+
const isGitHubIssueEnabled =
|
|
127
|
+
isCreateIssueChecked && isReopenIssueChecked ? "Yes" : "No";
|
|
128
|
+
|
|
129
|
+
row.push(isGitHubIssueEnabled);
|
|
130
|
+
|
|
131
|
+
if (isGitHubIssueEnabled === "No") {
|
|
132
|
+
comments.push(
|
|
133
|
+
"`Automatically create GitHub issue` or `Automatically re-open issue` options are not enabled"
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const slackIntegrationStatus = isSlackVisible ? "Yes" : "No";
|
|
139
|
+
|
|
140
|
+
if (slackIntegrationStatus === "No") {
|
|
141
|
+
comments.push("Slack is not integrated");
|
|
142
|
+
row.push(slackIntegrationStatus);
|
|
143
|
+
} else {
|
|
144
|
+
await page.goto(
|
|
145
|
+
honeybadger.settings.integrations.slack(honebadgerId, channelId)
|
|
146
|
+
);
|
|
147
|
+
await page.waitForLoadState();
|
|
148
|
+
|
|
149
|
+
const isNeetoHealthVisible = await page
|
|
150
|
+
.getByText(NEETO_HEALTH_WORKSPACE)
|
|
151
|
+
.isVisible();
|
|
152
|
+
|
|
153
|
+
row.push(isNeetoHealthVisible ? "Yes" : "No");
|
|
154
|
+
|
|
155
|
+
if (!isNeetoHealthVisible) {
|
|
156
|
+
comments.push("Slack is not configured in neeto-health workspace");
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
row.push(comments.join(","));
|
|
161
|
+
row.push(row.includes("No") ? "No" : "Yes");
|
|
162
|
+
|
|
163
|
+
addRow(HONEYBADGER_TABLE, row);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
console.log(JSON.stringify(HONEYBADGER_TABLE, null, 2));
|
|
168
|
+
});
|
|
169
|
+
});
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { ROUTES } from "@routes";
|
|
2
|
+
import { faker } from "@faker-js/faker";
|
|
3
|
+
import test, { BrowserContext, expect, Page } from "@playwright/test";
|
|
4
|
+
import { addRow } from "@utils/markdown";
|
|
5
|
+
import {
|
|
6
|
+
CHAT_WIDGET_SELECTORS,
|
|
7
|
+
CustomCommands,
|
|
8
|
+
EMPTY_STORAGE_STATE,
|
|
9
|
+
LOGIN_SELECTORS,
|
|
10
|
+
MailerUtils,
|
|
11
|
+
SIGNUP_SELECTORS,
|
|
12
|
+
simulateClickWithDelay,
|
|
13
|
+
simulateTypingWithDelay,
|
|
14
|
+
} from "@neetoplaywright";
|
|
15
|
+
import { NEETO_DEPLOY_TEXTS, SPARKPOST_TEXTS } from "@texts";
|
|
16
|
+
import { NEETO_DEPLOY_SELECTORS } from "@selectors";
|
|
17
|
+
import { SPARKPOST_TABLE } from "@constants/table";
|
|
18
|
+
import { randomPick } from "@bigbinary/neeto-cist";
|
|
19
|
+
import { USER_AGENTS } from "@constants/userAgents";
|
|
20
|
+
import { initI18n } from "playwright-i18next-fixture";
|
|
21
|
+
import {
|
|
22
|
+
DEPLOY_APPS,
|
|
23
|
+
DEPLOY_PASSWORD_PATTERN,
|
|
24
|
+
SPARKPOST_KEY_PATTERN,
|
|
25
|
+
} from "@constants/auditData";
|
|
26
|
+
|
|
27
|
+
const timezone = faker.location.timeZone();
|
|
28
|
+
const userAgent = randomPick(...USER_AGENTS);
|
|
29
|
+
test.use({ timezoneId: timezone, userAgent });
|
|
30
|
+
test.slow();
|
|
31
|
+
|
|
32
|
+
test.describe("Sparkpost", () => {
|
|
33
|
+
let stepNumber = 3,
|
|
34
|
+
otp: string,
|
|
35
|
+
deployPage: Page,
|
|
36
|
+
receivedAfter: Date,
|
|
37
|
+
context: BrowserContext,
|
|
38
|
+
mailerUtils: MailerUtils,
|
|
39
|
+
playwrightUtils: CustomCommands;
|
|
40
|
+
|
|
41
|
+
test.beforeEach(async ({ page: sparkPostPage }) => {
|
|
42
|
+
await test.step("1: Login to sparkPost", async () => {
|
|
43
|
+
await sparkPostPage.goto(ROUTES.sparkPost.login);
|
|
44
|
+
await sparkPostPage.waitForLoadState();
|
|
45
|
+
|
|
46
|
+
await simulateTypingWithDelay({
|
|
47
|
+
value: process.env.SPARKPOST_EMAIL,
|
|
48
|
+
field: sparkPostPage.getByRole("textbox", {
|
|
49
|
+
name: SPARKPOST_TEXTS.emailAddress,
|
|
50
|
+
}),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
await simulateTypingWithDelay({
|
|
54
|
+
value: process.env.SPARKPOST_PASSWORD,
|
|
55
|
+
field: sparkPostPage.getByRole("textbox", {
|
|
56
|
+
name: SPARKPOST_TEXTS.password,
|
|
57
|
+
}),
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
await simulateClickWithDelay({
|
|
61
|
+
page: sparkPostPage,
|
|
62
|
+
element: sparkPostPage.getByRole("button", {
|
|
63
|
+
name: SPARKPOST_TEXTS.continue,
|
|
64
|
+
}),
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
await expect(
|
|
68
|
+
sparkPostPage.getByRole("heading", { name: SPARKPOST_TEXTS.welcome })
|
|
69
|
+
).toBeVisible({ timeout: 20_000 });
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
await test.step("2: Navigate to SparkPost API keys section", async () => {
|
|
73
|
+
await sparkPostPage.goto(ROUTES.sparkPost.apiKeys);
|
|
74
|
+
await sparkPostPage.waitForLoadState();
|
|
75
|
+
await expect(
|
|
76
|
+
sparkPostPage.getByRole("heading", { name: SPARKPOST_TEXTS.apiKeys })
|
|
77
|
+
).toBeVisible({ timeout: 20_000 });
|
|
78
|
+
|
|
79
|
+
await sparkPostPage
|
|
80
|
+
.getByRole("button", { name: SPARKPOST_TEXTS.hundredPerPage })
|
|
81
|
+
.click();
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test("Check whether sparkPost sub-accounts are configured", async ({
|
|
86
|
+
page: sparkPostPage,
|
|
87
|
+
browser,
|
|
88
|
+
}) => {
|
|
89
|
+
for (const [i, app] of DEPLOY_APPS.entries()) {
|
|
90
|
+
const { appName, sparkPostName, workspace } = app;
|
|
91
|
+
const comment = `SparkPost sub-account is not set for ${appName}`;
|
|
92
|
+
const row = [appName];
|
|
93
|
+
|
|
94
|
+
await test.step(`${stepNumber++}: Login to ${workspace} workspace`, async () => {
|
|
95
|
+
context = await browser.newContext(EMPTY_STORAGE_STATE);
|
|
96
|
+
deployPage = await context.newPage();
|
|
97
|
+
|
|
98
|
+
// To avoid "No i18n instance initialized" error
|
|
99
|
+
await initI18n({ plugins: [], options: {}, cache: true });
|
|
100
|
+
|
|
101
|
+
playwrightUtils = new CustomCommands(deployPage, deployPage.request);
|
|
102
|
+
mailerUtils = new MailerUtils(playwrightUtils);
|
|
103
|
+
|
|
104
|
+
await expect(async () => {
|
|
105
|
+
await deployPage.goto(
|
|
106
|
+
ROUTES.neetoDeploy.configure(workspace, appName)
|
|
107
|
+
);
|
|
108
|
+
await playwrightUtils.waitForPageLoad();
|
|
109
|
+
}).toPass({ timeout: 2 * 6 * 10_000 });
|
|
110
|
+
|
|
111
|
+
await deployPage
|
|
112
|
+
.getByTestId(LOGIN_SELECTORS.emailTextField)
|
|
113
|
+
.fill(process.env.NEETO_DEPLOY_EMAIL);
|
|
114
|
+
|
|
115
|
+
receivedAfter = new Date();
|
|
116
|
+
await deployPage.getByTestId(LOGIN_SELECTORS.submitButton).click();
|
|
117
|
+
await expect(async () => {
|
|
118
|
+
await deployPage.reload({ waitUntil: "domcontentloaded" });
|
|
119
|
+
await playwrightUtils.waitForPageLoad();
|
|
120
|
+
}).toPass({ timeout: 2 * 6 * 10_000 });
|
|
121
|
+
|
|
122
|
+
let retryCount = 0;
|
|
123
|
+
await expect(async () => {
|
|
124
|
+
if (retryCount > 0) {
|
|
125
|
+
receivedAfter = new Date();
|
|
126
|
+
await deployPage
|
|
127
|
+
.getByTestId(NEETO_DEPLOY_SELECTORS.resendOtpButton)
|
|
128
|
+
.click();
|
|
129
|
+
|
|
130
|
+
await deployPage
|
|
131
|
+
.getByTestId(CHAT_WIDGET_SELECTORS.closeChat)
|
|
132
|
+
.click();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
retryCount++;
|
|
136
|
+
|
|
137
|
+
otp = await mailerUtils.findOtpFromEmail({
|
|
138
|
+
email: process.env.NEETO_DEPLOY_EMAIL,
|
|
139
|
+
timeout: 45_000,
|
|
140
|
+
receivedAfter,
|
|
141
|
+
});
|
|
142
|
+
}).toPass({ timeout: 3 * 6 * 10_000 });
|
|
143
|
+
|
|
144
|
+
await deployPage.getByTestId(SIGNUP_SELECTORS.otpTextBox).fill(otp);
|
|
145
|
+
await playwrightUtils.waitForPageLoad();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
await test.step(`${stepNumber++}: Check whether SparkPost sub-account is configured for ${appName}`, async () => {
|
|
149
|
+
const errorImage = deployPage.getByTestId(
|
|
150
|
+
NEETO_DEPLOY_SELECTORS.errorImage
|
|
151
|
+
);
|
|
152
|
+
const clickToShowButton = deployPage.getByRole("button", {
|
|
153
|
+
name: NEETO_DEPLOY_TEXTS.envVariable,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
await expect(errorImage.or(clickToShowButton)).toBeVisible({
|
|
157
|
+
timeout: 25_000,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const sparkPostCell = sparkPostPage.getByRole("cell", {
|
|
161
|
+
name: SPARKPOST_TEXTS.subaccount(sparkPostName),
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
const [errorImageVisible, sparkPostCellHidden] = await Promise.all([
|
|
165
|
+
errorImage.isVisible(),
|
|
166
|
+
sparkPostCell.isHidden(),
|
|
167
|
+
]);
|
|
168
|
+
|
|
169
|
+
if (errorImageVisible || sparkPostCellHidden) {
|
|
170
|
+
row.push("No", comment, "No");
|
|
171
|
+
addRow(SPARKPOST_TABLE, row);
|
|
172
|
+
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const [password, key] = await Promise.all([
|
|
177
|
+
deployPage
|
|
178
|
+
.getByRole("row")
|
|
179
|
+
.filter({ hasText: NEETO_DEPLOY_TEXTS.sparkPostPassword })
|
|
180
|
+
.getByRole("cell", { name: DEPLOY_PASSWORD_PATTERN })
|
|
181
|
+
.innerText(),
|
|
182
|
+
|
|
183
|
+
sparkPostPage
|
|
184
|
+
.getByRole("row")
|
|
185
|
+
.filter({ hasText: SPARKPOST_TEXTS.subaccount(sparkPostName) })
|
|
186
|
+
.getByRole("cell", { name: SPARKPOST_KEY_PATTERN })
|
|
187
|
+
.innerText(),
|
|
188
|
+
]);
|
|
189
|
+
|
|
190
|
+
const passwordPrefix = password.slice(0, 3);
|
|
191
|
+
const keyPrefix = key.slice(0, 3);
|
|
192
|
+
const status = passwordPrefix === keyPrefix ? "Yes" : "No";
|
|
193
|
+
|
|
194
|
+
row.push(status, status === "No" ? comment : "", status);
|
|
195
|
+
|
|
196
|
+
addRow(SPARKPOST_TABLE, row);
|
|
197
|
+
|
|
198
|
+
await context.close();
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
console.log(JSON.stringify(SPARKPOST_TABLE, null, 2));
|
|
203
|
+
});
|
|
204
|
+
});
|
data/tsconfig.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"esModuleInterop": true,
|
|
4
|
+
"resolveJsonModule": true,
|
|
5
|
+
"target": "ES2019",
|
|
6
|
+
"moduleResolution": "Node",
|
|
7
|
+
"lib": ["ES2021", "dom"],
|
|
8
|
+
"baseUrl": "scripts",
|
|
9
|
+
"noEmit": true,
|
|
10
|
+
"paths": {
|
|
11
|
+
"@auth/*": ["auth/*"],
|
|
12
|
+
"@config/*": ["config/*"],
|
|
13
|
+
"@selectors": ["constants/selectors"],
|
|
14
|
+
"@selectors/*": ["constants/selectors/*"],
|
|
15
|
+
"@constants/*": ["constants/*"],
|
|
16
|
+
"@texts": ["constants/texts"],
|
|
17
|
+
"@texts/*": ["constants/texts/*"],
|
|
18
|
+
"@routes": ["constants/routes.ts"],
|
|
19
|
+
"@fixtures/*": ["fixtures/*"],
|
|
20
|
+
"@fixtures": ["fixtures"],
|
|
21
|
+
"@poms/*": ["poms/*"],
|
|
22
|
+
"@poms": ["poms"],
|
|
23
|
+
"@tests/*": ["tests/*"],
|
|
24
|
+
"@utils/*": ["utils/*"],
|
|
25
|
+
"@auditData": ["constants/auditData.ts"],
|
|
26
|
+
"@neetoplaywright": [
|
|
27
|
+
"../node_modules/@bigbinary/neeto-playwright-commons"
|
|
28
|
+
],
|
|
29
|
+
"@neetoplaywright/*": [
|
|
30
|
+
"../node_modules/@bigbinary/neeto-playwright-commons/*"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
"skipLibCheck": true
|
|
34
|
+
}
|
|
35
|
+
}
|