UNPKG

booletwa

Version:

Generate TWA projects from a Web Manifest

255 lines (247 loc) 10.6 kB
/* * Copyright 2019 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import {PwaValidator} from '../lib/PwaValidator'; import {PsiResult, LighthouseMetricAudit} from '../lib/psi'; const WEB_VITALS_SCORES = { firstContentfulPaint: 0, largestContentfulPaint: 0, maxPotentialFID: 0, cumulativeLayoutShift: 0, } as LighthouseMetricAudit; function mockPsiResult(performanceScore: number | null, pwaScore: number | null, webVitalsScores = WEB_VITALS_SCORES): PsiResult { return { lighthouseResult: { categories: { pwa: { score: pwaScore, }, performance: { score: performanceScore, }, accessibility: { score: 0, }, }, audits: { metrics: { details: { items: [webVitalsScores], }, }, }, }, } as PsiResult; }; function mockPwaValidator(result: PsiResult): PwaValidator { return new PwaValidator({ runPageSpeedInsights: async (): Promise<PsiResult> => { return result; }, }); } describe('PwaValidator', () => { describe('#validate', () => { it('pass is true when lighthouse score >= 0.8 and pwa >= 1.0', async () => { const psiResult = mockPsiResult(0.8, 1.0); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.status).toBe('PASS'); }); it('pass is false when lighthouse score < 0.8 and pwa >= 1.0', async () => { const psiResult = mockPsiResult(0.7, 1.0); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.status).toBe('FAIL'); }); it('pass is false when lighthouse score >= 0.8 and pwa < 1.0', async () => { const psiResult = mockPsiResult(1.0, 0.99); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.status).toBe('FAIL'); }); it('pass is false when lighthouse score < 0.8 and pwa < 1.0', async () => { const psiResult = mockPsiResult(0.0, 0.0); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.status).toBe('FAIL'); }); it('pass is false when lighthouse scores are negative', async () => { const psiResult = mockPsiResult(-100.0, -10.0); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.status).toBe('FAIL'); }); it('throws an Error if score values are NaN', async () => { const psiResult = mockPsiResult(NaN, NaN); const pwaValidator = mockPwaValidator(psiResult); await expectAsync(pwaValidator.validate(new URL('https://example.com'))) .toBeRejectedWithError(); }); it('throws an Error if score values are NaN', async () => { const psiResult = mockPsiResult(null, null); const pwaValidator = mockPwaValidator(psiResult); await expectAsync(pwaValidator.validate(new URL('https://example.com'))) .toBeRejectedWithError(); }); it('throws an Error for an empty PsiResult', async () => { const pwaValidator = mockPwaValidator({} as PsiResult); await expectAsync(pwaValidator.validate(new URL('https://example.com'))) .toBeRejectedWithError(); }); it('returns the correct PSI url', async () => { const psiResult = mockPsiResult(0.8, 1.0); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.psiWebUrl) .toBe('https://developers.google.com/speed/pagespeed/insights/' + '?url=https%3A%2F%2Fexample.com%2F'); }); // LCP Tests it('LCP is PASS when 2.5 s', async () => { const psiResult = mockPsiResult(0.8, 1.0, { ...WEB_VITALS_SCORES, largestContentfulPaint: 2500, }); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.scores.largestContentfulPaint.status).toBe('PASS'); expect(result.scores.largestContentfulPaint.printValue).toBe('2.5 s'); }); it('LCP is PASS when 2.549 s', async () => { const psiResult = mockPsiResult(0.8, 1.0, { ...WEB_VITALS_SCORES, largestContentfulPaint: 2549, }); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.scores.largestContentfulPaint.status).toBe('PASS'); expect(result.scores.largestContentfulPaint.printValue).toBe('2.5 s'); }); it('LCP is WARN when 2.550 s', async () => { const psiResult = mockPsiResult(0.8, 1.0, { ...WEB_VITALS_SCORES, largestContentfulPaint: 2550, }); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.scores.largestContentfulPaint.status).toBe('WARN'); expect(result.scores.largestContentfulPaint.printValue).toBe('2.6 s'); }); it('LCP is WARN when 4s', async () => { const psiResult = mockPsiResult(0.8, 1.0, { ...WEB_VITALS_SCORES, largestContentfulPaint: 4000, }); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.scores.largestContentfulPaint.status).toBe('WARN'); expect(result.scores.largestContentfulPaint.printValue).toBe('4.0 s'); }); it('LCP is WARN when 4.049s', async () => { const psiResult = mockPsiResult(0.8, 1.0, { ...WEB_VITALS_SCORES, largestContentfulPaint: 4049, }); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.scores.largestContentfulPaint.status).toBe('WARN'); expect(result.scores.largestContentfulPaint.printValue).toBe('4.0 s'); }); it('LCP is FAIL when 4.050s', async () => { const psiResult = mockPsiResult(0.8, 1.0, { ...WEB_VITALS_SCORES, largestContentfulPaint: 4050, }); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.scores.largestContentfulPaint.status).toBe('FAIL'); expect(result.scores.largestContentfulPaint.printValue).toBe('4.1 s'); }); it('LCP is FAIL when 10s', async () => { const psiResult = mockPsiResult(0.8, 1.0, { ...WEB_VITALS_SCORES, largestContentfulPaint: 10000, }); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.scores.largestContentfulPaint.status).toBe('FAIL'); expect(result.scores.largestContentfulPaint.printValue).toBe('10.0 s'); }); // FID Tests it('FID is PASS when 100 ms', async () => { const psiResult = mockPsiResult(0.8, 1.0, { ...WEB_VITALS_SCORES, maxPotentialFID: 100, }); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.scores.firstInputDelay.status).toBe('PASS'); expect(result.scores.firstInputDelay.printValue).toBe('100 ms'); }); it('FID is WARN when 300 ms', async () => { const psiResult = mockPsiResult(0.8, 1.0, { ...WEB_VITALS_SCORES, maxPotentialFID: 300, }); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.scores.firstInputDelay.status).toBe('WARN'); expect(result.scores.firstInputDelay.printValue).toBe('300 ms'); }); it('FID is FAIL when 500 ms', async () => { const psiResult = mockPsiResult(0.8, 1.0, { ...WEB_VITALS_SCORES, maxPotentialFID: 500, }); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.scores.firstInputDelay.status).toBe('FAIL'); expect(result.scores.firstInputDelay.printValue).toBe('500 ms'); }); // CLS Tests it('CLS is PASS when 0.1', async () => { const psiResult = mockPsiResult(0.8, 1.0, { ...WEB_VITALS_SCORES, cumulativeLayoutShift: 0.1, }); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.scores.cumulativeLayoutShift.status).toBe('PASS'); expect(result.scores.cumulativeLayoutShift.printValue).toBe('0.10'); }); it('CLS is WARN when 0.25', async () => { const psiResult = mockPsiResult(0.8, 1.0, { ...WEB_VITALS_SCORES, cumulativeLayoutShift: 0.25, }); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.scores.cumulativeLayoutShift.status).toBe('WARN'); expect(result.scores.cumulativeLayoutShift.printValue).toBe('0.25'); }); it('CLS is FAIL when 0.3', async () => { const psiResult = mockPsiResult(0.8, 1.0, { ...WEB_VITALS_SCORES, cumulativeLayoutShift: 0.3, }); const pwaValidator = mockPwaValidator(psiResult); const result = await pwaValidator.validate(new URL('https://example.com')); expect(result.scores.cumulativeLayoutShift.status).toBe('FAIL'); expect(result.scores.cumulativeLayoutShift.printValue).toBe('0.30'); }); }); });