diff --git a/docs/api.md b/docs/api.md
index f961e5d4..6542e5eb 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -53,6 +53,7 @@ Chromeless provides TypeScript typings.
- [`setCookies(cookie: Cookie)`](#api-setcookies-one)
- [`setCookies(cookies: Cookie[])`](#api-setcookies-many)
- [`deleteCookies(name: string)`](#api-deletecookies)
+- [`authenticate(username: string, password: string, patterns?: RequestPattern[])`](#api-authenticate)
- [`clearCookies()`](#api-clearcookies)
@@ -770,3 +771,22 @@ __Example__
```js
await chromeless.setFileInput('.uploader', '/User/Me/Documents/img.jpg')
```
+---------------------------------------
+
+
+
+### authenticate(username: string, password: string, patterns?: RequestPattern[]): Chromeless
+
+provide authenticate for pop up dialog
+
+RequestPattern is defined as [here](https://chromedevtools.github.io/devtools-protocol/tot/Network#type-RequestPattern)
+
+
+__Example__
+
+```js
+await chromeless
+ .authenticate('username', 'Passw0Rd',[{urlPattern: '*'}])
+ .goto('https://github.com')
+ .screenshot()
+```
diff --git a/src/api.ts b/src/api.ts
index cb05faa2..6fd535d3 100644
--- a/src/api.ts
+++ b/src/api.ts
@@ -9,6 +9,7 @@ import {
PdfOptions,
DeviceMetrics,
ScreenshotOptions,
+ RequestPattern,
} from './types'
import { getDebugOption } from './util'
import { isArray } from 'util'
@@ -198,6 +199,16 @@ export default class Chromeless implements Promise {
return this
}
+ authenticate(
+ username: string,
+ password: string,
+ patterns?: RequestPattern[],
+ ): Chromeless {
+ this.queue.enqueue({ type: 'authenticate', username, password, patterns })
+
+ return this
+ }
+
setExtraHTTPHeaders(headers: Headers): Chromeless {
this.queue.enqueue({ type: 'setExtraHTTPHeaders', headers })
diff --git a/src/chrome/local-runtime.ts b/src/chrome/local-runtime.ts
index b376cf1c..56701b56 100644
--- a/src/chrome/local-runtime.ts
+++ b/src/chrome/local-runtime.ts
@@ -7,6 +7,7 @@ import {
CookieQuery,
PdfOptions,
ScreenshotOptions,
+ RequestPattern,
} from '../types'
import {
nodeExists,
@@ -123,6 +124,12 @@ export default class LocalRuntime {
return this.clearInput(command.selector)
case 'setFileInput':
return this.setFileInput(command.selector, command.files)
+ case 'authenticate':
+ return this.authenticate(
+ command.username,
+ command.password,
+ command.patterns,
+ )
default:
throw new Error(`No such command: ${JSON.stringify(command)}`)
}
@@ -173,6 +180,42 @@ export default class LocalRuntime {
await this.log(`Set useragent to ${this.userAgentValue}`)
}
+ private async authenticate(
+ username: string,
+ password: string,
+ pattens?: RequestPattern[],
+ ): Promise {
+ const { Network } = this.client
+ await Network.setRequestInterception({
+ patterns: pattens ? pattens : [{ urlPattern: '*' }],
+ })
+
+ Network.requestIntercepted(
+ async ({ interceptionId, request, authChallenge }) => {
+ // perform a test against the intercepted request
+ this.log(
+ `${interceptionId} ${request.url} ${
+ authChallenge ? authChallenge.origin : 'undefined'
+ } ${authChallenge ? authChallenge.scheme : 'undefined'}`,
+ )
+ if (authChallenge) {
+ await Network.continueInterceptedRequest({
+ interceptionId: interceptionId,
+ authChallengeResponse: {
+ response: 'ProvideCredentials',
+ username: username,
+ password: password,
+ },
+ })
+ } else {
+ await Network.continueInterceptedRequest({
+ interceptionId: interceptionId,
+ })
+ }
+ },
+ )
+ }
+
private async waitTimeout(timeout: number): Promise {
this.log(`Waiting for ${timeout}ms`)
await wait(timeout)
diff --git a/src/types.ts b/src/types.ts
index 4d50687c..15370f24 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -196,6 +196,12 @@ export type Command =
selector: string
files: string[]
}
+ | {
+ type: 'authenticate'
+ username: string
+ password: string
+ patterns?: RequestPattern[]
+ }
export type Headers = Record
@@ -269,3 +275,9 @@ export interface Viewport {
height: number
scale: number
}
+
+export interface RequestPattern {
+ urlPattern?: string
+ resourceType?: string
+ interceptionStage?: string
+}