@nyaruka/temba-components 0.25.2 → 0.26.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.
@@ -1,23 +1,23 @@
1
1
  import { puppeteerLauncher } from '@web/test-runner-puppeteer';
2
- import fs from "fs";
3
- import * as path from "path";
4
- import * as pngs from "pngjs";
2
+ import fs from 'fs';
3
+ import * as path from 'path';
4
+ import * as pngs from 'pngjs';
5
5
  import dynamicpixelmatch from 'dynamicpixelmatch';
6
6
  import pixelmatch from 'pixelmatch';
7
7
  import sizeOf from 'image-size';
8
8
 
9
- import rimraf from "rimraf";
9
+ import rimraf from 'rimraf';
10
10
 
11
11
  const SCREENSHOTS = 'screenshots';
12
12
  const DIFF = 'diff';
13
- const TEST = "test";
14
- const TRUTH = "truth";
13
+ const TEST = 'test';
14
+ const TRUTH = 'truth';
15
15
 
16
16
  const PNG = pngs.PNG;
17
17
 
18
- const fileExists = (filename) => {
18
+ const fileExists = filename => {
19
19
  return new Promise((resolve, reject) => {
20
- fs.access(filename, fs.F_OK, (err) => {
20
+ fs.access(filename, fs.F_OK, err => {
21
21
  if (err) {
22
22
  resolve(false);
23
23
  }
@@ -28,35 +28,31 @@ const fileExists = (filename) => {
28
28
 
29
29
  const ensureExists = function (mydir) {
30
30
  return new Promise((resolve, reject) => {
31
- fs.mkdir(mydir, {recursive: true }, function (err) {
31
+ fs.mkdir(mydir, { recursive: true }, function (err) {
32
32
  if (err) {
33
- if (err.code == "EEXIST")
34
- resolve("ignore the error if the folder already exists");
33
+ if (err.code == 'EEXIST')
34
+ resolve('ignore the error if the folder already exists');
35
35
  else reject(err); // something else went wrong
36
36
  }
37
- resolve("path created");
37
+ resolve('path created');
38
38
  });
39
39
  });
40
40
  };
41
41
 
42
-
43
42
  const getPath = async (type, filename) => {
44
- const file = path.resolve(SCREENSHOTS, type, filename)
43
+ const file = path.resolve(SCREENSHOTS, type, filename);
45
44
 
46
45
  // make sure our directory exists
47
46
  const parts = filename.split(path.sep);
48
47
  let pngdir = parts.slice(0, parts.length - 1);
49
48
  await ensureExists(path.resolve(SCREENSHOTS, type, ...pngdir));
50
-
51
- return file;
52
- }
53
49
 
50
+ return file;
51
+ };
54
52
 
55
53
  const checkScreenshot = async (filename, excluded, threshold) => {
56
-
57
54
  return new Promise(async (resolve, reject) => {
58
55
  const doneReading = async () => {
59
-
60
56
  // Wait until both files are read.
61
57
  if (++filesRead < 2) return;
62
58
 
@@ -64,20 +60,25 @@ const checkScreenshot = async (filename, excluded, threshold) => {
64
60
  if (img1.width != img2.width || img1.height !== img2.height) {
65
61
  // resolve(`Screenshot was ${img2.width}x${img2.height} but should be ${img1.width}x${img1.height}:\n${testImg}`);
66
62
 
67
-
68
63
  reject({
69
64
  message: 'Screenshot was not the right size',
70
65
  expected: `${img1.width}x${img1.height}`,
71
66
  actual: `${img2.width}x${img2.height}`,
72
- files: [testImg, truthImg, path.resolve(SCREENSHOTS)]
67
+ files: [testImg, truthImg, path.resolve(SCREENSHOTS)],
73
68
  });
74
69
  return;
75
70
  }
76
71
 
77
72
  // Do the visual diff.
78
73
  const diff = new PNG({ width: img1.width, height: img2.height });
79
- const matchOptions = { threshold: threshold || 0.3 };
80
- const numDiffPixels = excluded != null && excluded.length != 0
74
+ const matchOptions = {
75
+ threshold: threshold || 0.3,
76
+ includeAA: false,
77
+ diffColor: [255, 0, 0],
78
+ aaColor: [0, 0, 255],
79
+ };
80
+ const numDiffPixels =
81
+ excluded != null && excluded.length != 0
81
82
  ? dynamicpixelmatch(
82
83
  img1.data,
83
84
  img2.data,
@@ -101,9 +102,12 @@ const checkScreenshot = async (filename, excluded, threshold) => {
101
102
  // console.error("number of different pixels are not 0");
102
103
  const diffImg = await getPath(DIFF, filename);
103
104
  diff.pack().pipe(fs.createWriteStream(diffImg));
104
- reject({message:"Pixel match failed", files: [diffImg, testImg, truthImg, path.resolve(SCREENSHOTS)]});
105
- }
106
- resolve("success");
105
+ reject({
106
+ message: 'Pixel match failed',
107
+ files: [diffImg, testImg, truthImg, path.resolve(SCREENSHOTS)],
108
+ });
109
+ }
110
+ resolve('success');
107
111
  };
108
112
 
109
113
  let filesRead = 0;
@@ -114,18 +118,16 @@ const checkScreenshot = async (filename, excluded, threshold) => {
114
118
  const img1 = fs
115
119
  .createReadStream(truthImg)
116
120
  .pipe(new PNG())
117
- .on("parsed", await doneReading);
118
-
121
+ .on('parsed', await doneReading);
122
+
119
123
  const img2 = fs
120
124
  .createReadStream(testImg)
121
125
  .pipe(new PNG())
122
- .on("parsed", await doneReading);
126
+ .on('parsed', await doneReading);
123
127
  });
124
128
  };
125
129
 
126
-
127
130
  const wireScreenshots = async (page, context) => {
128
-
129
131
  // clear out any past tests
130
132
  const diffs = path.resolve(SCREENSHOTS, DIFF);
131
133
  const tests = path.resolve(SCREENSHOTS, TEST);
@@ -133,111 +135,108 @@ const wireScreenshots = async (page, context) => {
133
135
  rimraf.sync(diffs);
134
136
  rimraf.sync(tests);
135
137
 
136
- await page.exposeFunction("matchPageSnapshot", (filename, clip, excluded, threshold) =>{
137
-
138
- return new Promise(async (resolve, reject) => {
139
-
140
- const testFile = await getPath(TEST, filename);
141
- const truthFile = await getPath(TRUTH, filename);
142
-
143
- if (!await fileExists(truthFile)) {
144
-
145
- // no truth yet, record it
146
- await page.screenshot({ path: truthFile, clip});
147
-
148
- } else {
149
-
150
- // if its close, force our file to be the same size as our truth for pixelmatch
151
- const dimensions = sizeOf(truthFile);
152
- let { width, height} = dimensions;
153
-
154
- // we should have a device ratio of 2
155
- width /= 2;
156
- height /= 2;
157
-
158
- const wDiff = Math.abs((clip.width - width) / width);
159
- const hDiff = Math.abs((clip.height - height) / height);
160
-
161
-
162
- if (wDiff < .15) {
163
- clip.width = width;
164
- }
138
+ await page.exposeFunction(
139
+ 'matchPageSnapshot',
140
+ (filename, clip, excluded, threshold) => {
141
+ return new Promise(async (resolve, reject) => {
142
+ const testFile = await getPath(TEST, filename);
143
+ const truthFile = await getPath(TRUTH, filename);
144
+
145
+ if (!(await fileExists(truthFile))) {
146
+ // no truth yet, record it
147
+ await page.screenshot({ path: truthFile, clip });
148
+ } else {
149
+ // if its close, force our file to be the same size as our truth for pixelmatch
150
+ const dimensions = sizeOf(truthFile);
151
+ let { width, height } = dimensions;
152
+
153
+ // we should have a device ratio of 2
154
+ width /= 2;
155
+ height /= 2;
156
+
157
+ const wDiff = Math.abs((clip.width - width) / width);
158
+ const hDiff = Math.abs((clip.height - height) / height);
159
+
160
+ if (wDiff < 0.15) {
161
+ clip.width = width;
162
+ }
165
163
 
166
- if(hDiff < .15) {
167
- clip.height = height;
168
- }
164
+ if (hDiff < 0.15) {
165
+ clip.height = height;
166
+ }
169
167
 
170
- if (!clip.width || !clip.height) {
171
- reject({message: "Couldn't take screenshot clip is empty"});
172
- return;
173
- }
168
+ if (!clip.width || !clip.height) {
169
+ reject({ message: "Couldn't take screenshot clip is empty" });
170
+ return;
171
+ }
174
172
 
175
- // create a test screenshot to compare with our truth
176
- await page.screenshot({ path: testFile, clip });
173
+ // create a test screenshot to compare with our truth
174
+ await page.screenshot({ path: testFile, clip });
177
175
 
178
- try {
179
- const result = await checkScreenshot(filename);
180
- resolve(result);
181
- } catch(error) {
182
- reject(error);
183
- return;
176
+ try {
177
+ const result = await checkScreenshot(filename);
178
+ resolve(result);
179
+ } catch (error) {
180
+ reject(error);
181
+ return;
182
+ }
184
183
  }
185
- }
186
-
187
- resolve(true);
188
-
189
- });
190
184
 
191
- });
185
+ resolve(true);
186
+ });
187
+ }
188
+ );
192
189
 
193
- await page.exposeFunction("setViewport", async (options) => {
190
+ await page.exposeFunction('setViewport', async options => {
194
191
  await page.setViewport(options);
195
192
  });
196
-
197
- await page.exposeFunction("waitFor", (millis)=>{
193
+
194
+ await page.exposeFunction('waitFor', millis => {
198
195
  return new Promise(async (resolve, reject) => {
199
196
  await page.waitForTimeout(millis);
200
197
  resolve();
201
198
  });
202
199
  });
203
200
 
204
- await page.exposeFunction("moveMouse", (x, y) => {
201
+ await page.exposeFunction('moveMouse', (x, y) => {
205
202
  return new Promise(async (resolve, reject) => {
206
- await page.mouse.move(x,y);
203
+ await page.mouse.move(x, y);
207
204
  resolve();
208
205
  });
209
206
  });
210
207
 
211
- await page.exposeFunction("click", async (element) => {
212
- const frame = await page.frames().find((f) => {
208
+ await page.exposeFunction('click', async element => {
209
+ const frame = await page.frames().find(f => {
213
210
  return true;
214
211
  });
215
212
  const ele = await frame.$(element);
216
213
  await ele.click({});
217
214
  });
218
215
 
219
- await page.exposeFunction("typeInto", async (selector, text, replace=false) => {
220
- // console.log("frames", page.frames().length);
221
- const frame = await page.frames().find((f) => {
222
- return true
223
- });
224
- const element = await frame.$(selector);
225
-
226
- await element.click({clickCount: replace ? 3 : 1});
227
- await page.keyboard.type(text);
228
- });
216
+ await page.exposeFunction(
217
+ 'typeInto',
218
+ async (selector, text, replace = false) => {
219
+ // console.log("frames", page.frames().length);
220
+ const frame = await page.frames().find(f => {
221
+ return true;
222
+ });
223
+ const element = await frame.$(selector);
224
+
225
+ await element.click({ clickCount: replace ? 3 : 1 });
226
+ await page.keyboard.type(text);
227
+ }
228
+ );
229
229
 
230
- await page.exposeFunction("pressKey", async (key, times, options) => {
231
- for (let i=0; i<times; i++) {
230
+ await page.exposeFunction('pressKey', async (key, times, options) => {
231
+ for (let i = 0; i < times; i++) {
232
232
  await page.keyboard.press(key, options);
233
233
  }
234
234
  });
235
235
 
236
- await page.exposeFunction("type", async (text) => {
236
+ await page.exposeFunction('type', async text => {
237
237
  await page.keyboard.type(text);
238
238
  });
239
- }
240
-
239
+ };
241
240
 
242
241
  export default {
243
242
  rootDir: './',
@@ -248,7 +247,12 @@ export default {
248
247
  name: 'add-style',
249
248
  transform(context) {
250
249
  if (context.response.is('html')) {
251
- return { body: context.body.replace(/<head>/, `<head><link rel="stylesheet" href="/test-assets/style.css">`) };
250
+ return {
251
+ body: context.body.replace(
252
+ /<head>/,
253
+ `<head><link rel="stylesheet" href="/test-assets/style.css">`
254
+ ),
255
+ };
252
256
  }
253
257
  },
254
258
  },
@@ -267,32 +271,38 @@ export default {
267
271
  browsers: [
268
272
  puppeteerLauncher({
269
273
  launchOptions: {
274
+ args: [
275
+ '--font-render-hinsting=none',
276
+ '--hide-scrollbars',
277
+ '--disable-web-security',
278
+ ],
270
279
  headless: true,
271
280
  },
272
- createBrowserContext: ( { browser, config }) => browser.defaultBrowserContext(),
281
+ createBrowserContext: ({ browser, config }) =>
282
+ browser.defaultBrowserContext(),
273
283
  createPage: async ({ context, config }) => {
274
284
  const page = await context.newPage();
275
- await page.exposeFunction("readStaticFile", (filename)=> {
285
+ await page.exposeFunction('readStaticFile', filename => {
276
286
  try {
277
- var content = fs.readFileSync("./" + filename, 'utf8');
287
+ var content = fs.readFileSync('./' + filename, 'utf8');
278
288
  return content;
279
- } catch(err) {
289
+ } catch (err) {
280
290
  console.log(err);
281
291
  }
282
- return "Not Found";
283
- })
284
-
292
+ return 'Not Found';
293
+ });
294
+
285
295
  await page.once('load', async () => {
286
- await page.addScriptTag(({content: `
296
+ await page.addScriptTag({
297
+ content: `
287
298
  window.watched = ${config.watch};
288
- `}));
299
+ `,
300
+ });
289
301
  await wireScreenshots(page, context);
290
302
  });
291
-
303
+
292
304
  return page;
293
305
  },
294
- }),
306
+ }),
295
307
  ],
296
308
  };
297
-
298
-