proxymail-qa 0.2.0 → 0.4.0

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.
package/README.md CHANGED
@@ -86,6 +86,9 @@ cy.task('createAddress').then(({ address }) => {
86
86
  // A persona with a date of birth for an age band, and a country.
87
87
  await qa.createAddress({ persona: true, age: 'under13', country: 'GB' });
88
88
 
89
+ // Find a test account made earlier: an under-18 in GB with a saved password.
90
+ const [teen] = await qa.listAddresses({ tags: ['age-gate'], country: 'GB', maxAge: 17, hasPassword: true });
91
+
89
92
  // The link that opens a mobile app (myapp://…) when the email also has a web one.
90
93
  const { value: appLink } = await qa.waitForLink(address, { app: true });
91
94
 
@@ -97,6 +100,11 @@ const { delivered, invalid } = await qa.variants(address);
97
100
 
98
101
  // After the app changes the test account's password, keep the saved one in step.
99
102
  await qa.setPassword(address, { password: 'the-new-test-password' });
103
+
104
+ // Check the email that arrived: SPF, DKIM, DMARC, local or http links, where
105
+ // its link goes, a stated expiry and more. Verdicts only, never its content.
106
+ const result = await qa.checkEmail(address, { type: 'link', expectHost: 'staging.example.com' });
107
+ expect(result.failed).toEqual([]);
100
108
  ```
101
109
 
102
110
  When a wait comes back empty, the error says why as far as Proxy Mail QA can
package/dist/index.d.ts CHANGED
@@ -57,6 +57,16 @@ export interface CreateAddressInput {
57
57
  dateOfBirth?: string;
58
58
  country?: string;
59
59
  }
60
+ export interface ListAddressesOptions {
61
+ limit?: number;
62
+ before?: string;
63
+ tags?: string[];
64
+ country?: string;
65
+ minAge?: number;
66
+ maxAge?: number;
67
+ hasPassword?: boolean;
68
+ search?: string;
69
+ }
60
70
  export interface AddressPatch {
61
71
  label?: string | null;
62
72
  notes?: string | null;
@@ -122,6 +132,31 @@ export interface CountOptions {
122
132
  subtype?: CountSubtype | CountSubtype[];
123
133
  }
124
134
  export type CountSubtype = 'otp' | 'coupon' | 'verify' | 'magic_signin' | 'invite' | 'reset' | 'other' | 'any';
135
+ export type CheckId = 'spf' | 'dkim' | 'dmarc' | 'local_links' | 'plain_http' | 'expected_host' | 'expiry' | 'plain_text' | 'size' | 'images_only';
136
+ export interface EmailCheck {
137
+ check: CheckId;
138
+ status: 'pass' | 'fail' | 'warn' | 'skip';
139
+ detail: string;
140
+ }
141
+ export interface EmailChecks {
142
+ address: string;
143
+ email: {
144
+ id: string;
145
+ received_at: string;
146
+ service: string | null;
147
+ service_domain: string | null;
148
+ type: 'code' | 'link' | null;
149
+ subtype: string | null;
150
+ };
151
+ passed: boolean;
152
+ failed: CheckId[];
153
+ warnings: CheckId[];
154
+ checks: EmailCheck[];
155
+ }
156
+ export interface CheckOptions extends CountOptions {
157
+ emailId?: string;
158
+ expectHost?: string;
159
+ }
125
160
  export interface NoEmail {
126
161
  address: string;
127
162
  since: string;
@@ -146,10 +181,7 @@ export declare class ProxyMailQA {
146
181
  password: true;
147
182
  }): Promise<CreatedAddressWithPassword>;
148
183
  createAddress(input?: CreateAddressInput): Promise<CreatedAddress>;
149
- listAddresses(options?: {
150
- limit?: number;
151
- before?: string;
152
- }): Promise<Address[]>;
184
+ listAddresses(options?: ListAddressesOptions): Promise<Address[]>;
153
185
  getAddress(address: string): Promise<Address>;
154
186
  updateAddress(address: string, patch: AddressPatch): Promise<Address>;
155
187
  deleteAddress(address: string): Promise<void>;
@@ -164,6 +196,7 @@ export declare class ProxyMailQA {
164
196
  limit?: number;
165
197
  }): Promise<Record<string, unknown>[]>;
166
198
  countEmails(address: string, options?: CountOptions): Promise<EmailCount>;
199
+ checkEmail(address: string, options?: CheckOptions): Promise<EmailChecks>;
167
200
  expectNoEmail(address: string, options?: CountOptions & {
168
201
  timeout?: number;
169
202
  }): Promise<NoEmail>;
package/dist/index.js CHANGED
@@ -79,12 +79,26 @@ export class ProxyMailQA {
79
79
  country: input.country,
80
80
  });
81
81
  }
82
+ // Newest first. With filters, finds test accounts made earlier, such as
83
+ // an under-18 in GB with a saved password: every filter given must match.
82
84
  listAddresses(options = {}) {
83
85
  const query = new URLSearchParams();
84
86
  if (options.limit)
85
87
  query.set('limit', String(options.limit));
86
88
  if (options.before)
87
89
  query.set('before', options.before);
90
+ for (const tag of options.tags ?? [])
91
+ query.append('tag', tag);
92
+ if (options.country)
93
+ query.set('country', options.country);
94
+ if (options.minAge !== undefined)
95
+ query.set('min_age', String(options.minAge));
96
+ if (options.maxAge !== undefined)
97
+ query.set('max_age', String(options.maxAge));
98
+ if (options.hasPassword !== undefined)
99
+ query.set('has_password', String(options.hasPassword));
100
+ if (options.search)
101
+ query.set('search', options.search);
88
102
  return this.request('GET', `/addresses${query.size ? `?${query}` : ''}`);
89
103
  }
90
104
  getAddress(address) {
@@ -127,6 +141,18 @@ export class ProxyMailQA {
127
141
  countEmails(address, options = {}) {
128
142
  return this.request('GET', `/addresses/${encodeURIComponent(address)}/count${countQuery(options)}`);
129
143
  }
144
+ // Checks one email the address received: SPF, DKIM and DMARC, links to
145
+ // localhost or plain http, where its link goes (expectHost), a stated
146
+ // expiry, a plain-text part, size and image-only emails. Doesn't wait: wait
147
+ // for the email first. Throws ProxyMailQAError (404) when none matches.
148
+ checkEmail(address, options = {}) {
149
+ const extra = {};
150
+ if (options.emailId)
151
+ extra.email_id = options.emailId;
152
+ if (options.expectHost)
153
+ extra.expect_host = options.expectHost;
154
+ return this.request('GET', `/addresses/${encodeURIComponent(address)}/checks${countQuery(options, extra)}`);
155
+ }
130
156
  // Resolves when no matching email arrives within timeout seconds (default
131
157
  // 30; longer repeats the request), for checks such as "an unsubscribed user
132
158
  // gets nothing". Throws ProxyMailQAError (status 409, code email_arrived)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "proxymail-qa",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Disposable test inboxes for Playwright, Cypress and scripts: create an address, then wait for its verification code or link.",
5
5
  "license": "MIT",
6
6
  "author": "Proxy Mail QA <hello@proxymail.qa> (https://proxymail.qa)",