File size: 3,035 Bytes
d1ceb73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
/*
 * Copyright (c) Jupyter Development Team.
 * Distributed under the terms of the Modified BSD License.
 */

const playwright = require('playwright');
const path = require('path');
const fs = require('fs');

// eslint-disable-next-line no-redeclare
const URL = process.argv[2];
const BROWSER_VAR = 'JLAB_BROWSER_TYPE';
const BROWSER = process.env[BROWSER_VAR] || 'chromium';
const OUTPUT_VAR = 'JLAB_BROWSER_CHECK_OUTPUT';
const OUTPUT = process.env[OUTPUT_VAR];

let nextScreenshot = 0;
const screenshotStem = `screenshot-${+new Date()}`;

if (OUTPUT) {
  console.log(`Screenshots will be saved in ${OUTPUT}...`);
  if (!fs.existsSync(OUTPUT)) {
    console.log(`Creating ${OUTPUT}...`);
    fs.mkdirSync(OUTPUT, { recursive: true });
  }
}

async function main() {
  /* eslint-disable no-console */
  console.info(`Starting headless ${BROWSER}...`);
  let testError = null;

  const pwBrowser = playwright[BROWSER];
  const browser = await pwBrowser.launch({
    logger: {
      isEnabled: () => !!OUTPUT,
      log: (name, severity, message, args) => console.log(name, message)
    }
  });

  const context = await browser.newContext();
  const page = await context.newPage();

  async function screenshot() {
    if (!OUTPUT) {
      return;
    }
    const screenshotPath = path.join(
      OUTPUT,
      `${screenshotStem}-${++nextScreenshot}.png`
    );
    console.log(`Capturing screenshot ${screenshotPath}...`);
    await page.screenshot({
      type: 'png',
      path: screenshotPath
    });
  }

  console.info('Navigating to page:', URL);
  await page.goto(URL);
  console.info('Waiting for page to load...');

  // Wait for the local file to redirect on notebook >= 6.0
  await page.waitForNavigation();

  console.log('Waiting for page content..');

  try {
    await page.locator('#jupyter-config-data').waitFor({ state: 'attached' });
  } catch (reason) {
    console.error('Error loading JupyterLab page:', reason);
    // Limit to 1000 characters
    console.error((await page.content()).substring(0, 1000));
    testError = reason;
  }

  console.log('Waiting for #main selector...');
  await page.waitForSelector('#main', { timeout: 100000 });

  console.log('Waiting for #browserTest selector...');
  const el = await page.waitForSelector('#browserTest', {
    timeout: 100000,
    state: 'attached'
  });
  console.log('Waiting for application to start...');

  try {
    await page.waitForSelector('.completed', { state: 'attached' });
  } catch (e) {
    testError = e;
  }

  await screenshot();

  const textContent = await el.getProperty('textContent');
  const errors = JSON.parse(await textContent.jsonValue());

  for (let error of errors) {
    console.error(`Parsed an error from text content: ${error.message}`, error);
    testError = true;
  }

  await browser.close();

  if (testError) {
    throw testError;
  }
  console.info('Browser test complete');
}

// Stop the process if an error is raised in the async function.
process.on('unhandledRejection', up => {
  throw up;
});

void main();