• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

get-set-fetch / scraper / 4403974148

pending completion
4403974148

push

github

Andrei Sabau
dependencies update

655 of 852 branches covered (76.88%)

Branch coverage included in aggregate %.

1574 of 1796 relevant lines covered (87.64%)

1266.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

64.06
/src/browserclient/PlaywrightClient.ts
1
// @ts-ignore
2
// eslint-disable-next-line import/no-unresolved
3
import { BrowserType, Browser, LaunchOptions, Page, ChromiumBrowser, Response, FirefoxBrowser, WebKitBrowser, chromium, firefox, webkit, Request } from 'playwright-core';
4✔
4
import { getLogger } from '../logger/Logger';
4✔
5
import BrowserClient from './BrowserClient';
4✔
6

7
type ArgumentsType<T> = T extends (...args: infer U) => any ? U : never;
8
type DirectNavigationOptions = ArgumentsType<Page['goto']>[1];
9

10
type ExtendedLaunchOptions = LaunchOptions & {
11
  browser: string;
12
}
13

14
/** Playwright Client.  */
15
export default class PlaywrightClient extends BrowserClient {
4✔
16
  logger = getLogger('PlaywrightClient');
3✔
17

18
  browserType: BrowserType<WebKitBrowser> | BrowserType<ChromiumBrowser> | BrowserType<FirefoxBrowser>;
19
  browser: Browser;
20
  page: Page;
21
  opts: LaunchOptions;
22

23
  constructor(opts:Partial<ExtendedLaunchOptions> = {}) {
×
24
    super({ headlesss: true, ...opts });
3✔
25

26
    this.browserType = this.getBrowserType(opts.browser);
3✔
27
  }
28

29
  getBrowserType(browser:string): BrowserType<WebKitBrowser> | BrowserType<ChromiumBrowser> | BrowserType<FirefoxBrowser> {
30
    switch (browser) {
3✔
31
      case 'firefox':
3!
32
        return firefox;
×
33
      case 'webkit':
34
        return webkit;
×
35
      default:
36
        return chromium;
3✔
37
    }
38
  }
39

40
  /*
41
  playwright does not yet implement downloadBrowserIfNeeded
42
  https://github.com/microsoft/playwright/issues/823
43

44
  async download() {
45
    // browser present, no download required
46
    if (existsSync(this.browserType.executablePath())) return;
47

48
    console.log(`Downloading ${this.browserType.name()}`);
49
    await this.browserType.downloadBrowserIfNeeded();
50
  }
51
  */
52

53
  async launch():Promise<void> {
54
    this.browser = await this.browserType.launch(this.opts);
93✔
55
    this.page = await this.browser.newPage();
93✔
56

57
    this.isLaunched = true;
93✔
58
  }
59

60
  async close():Promise<void> {
61
    this.page = null;
93✔
62
    await this.browser.close();
93✔
63
    this.isLaunched = false;
93✔
64
  }
65

66
  goto(url: string, opts: DirectNavigationOptions):Promise<Response> {
67
    return this.page.goto(url, opts);
156✔
68
  }
69

70
  async getRedirectResponse(req:Request):Promise<Response|null> {
71
    let redirectReq:Request = req.redirectedFrom();
141✔
72
    while (redirectReq && redirectReq.redirectedFrom()) {
141✔
73
      redirectReq = redirectReq.redirectedFrom();
×
74
    }
75
    return redirectReq ? redirectReq.response() : null;
141✔
76
  }
77

78
  getUrl() {
79
    return this.page.url();
48✔
80
  }
81

82
  async closePage() {
83
    if (this.page) {
×
84
      await this.page.close();
×
85
      this.page = null;
×
86
    }
87
  }
88

89
  async evaluate(pageFunction, argObj?) {
90
    // if there's an error in the async fnc to be evaluated the page.evaluate return promise may never resolve
91
    // listen to page errors and reject accordingly
92
    return new Promise(async (resolve, reject) => {
582✔
93
      const logConsole = this.logger.logger.level === 'trace' || this.logger.logger.level === 'debug';
582✔
94
      const consoleHandler = msg => {
582✔
95
        for (let i = 0; i < msg.args().length; i += 1) {
×
96
          this.logger.debug(`DOM console: ${msg.args()[i]}`);
×
97
        }
98
      };
99

100
      if (logConsole) {
582!
101
        this.page.on('console', consoleHandler);
×
102
      }
103

104
      const errorHandler = err => {
582✔
105
        this.logger.error(err);
×
106
        reject(err);
×
107
        this.page.off('pageerror', errorHandler);
×
108
        this.page.off('crash', errorHandler);
×
109
        if (logConsole) {
×
110
          this.page.off('console', consoleHandler);
×
111
        }
112
      };
113
      this.page.on('pageerror', errorHandler);
582✔
114
      this.page.on('crash', errorHandler);
582✔
115

116
      this.logger.trace({ pageFunction: pageFunction.toString(), argObj }, 'evaluate call');
582✔
117
      const result = await this.page.evaluate(pageFunction, argObj);
582✔
118
      resolve(result);
582✔
119
      this.page.off('pageerror', errorHandler);
582✔
120
      this.page.off('crash', errorHandler);
582✔
121
      this.page.off('console', consoleHandler);
582✔
122
    });
123
  }
124
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc