From b0017339c4ba178b865a3116f3cba6a03832f68b Mon Sep 17 00:00:00 2001 From: Daniel Stoian <63335068+daniel-stoian-lgp@users.noreply.github.com> Date: Thu, 1 Feb 2024 10:01:55 +0200 Subject: [PATCH] WRQ-4709 : Added performance tests for agate components (#79) * added performance tests for agate components * code review fixes * Solved lint errors. Added fallback script for serve * minor update README --------- Co-authored-by: Seungho Park --- README.md | 22 ++- package.json | 1 + performance/TraceModel.js | 2 +- performance/tests/agate/ArcPicker.test.js | 139 +++++++++++++++ performance/tests/agate/ArcSlider.test.js | 139 +++++++++++++++ performance/tests/agate/BodyText.test.js | 81 +++++++++ performance/tests/agate/CheckboxItem.test.js | 134 +++++++++++++++ performance/tests/agate/ColorPicker.test.js | 135 +++++++++++++++ .../agate/ContextualPopupDecorator.test.js | 104 ++++++++++++ performance/tests/agate/DatePicker.test.js | 138 +++++++++++++++ .../tests/agate/DateTimePicker.test.js | 145 ++++++++++++++++ performance/tests/agate/Drawer.test.js | 145 ++++++++++++++++ performance/tests/agate/Dropdown.test.js | 137 +++++++++++++++ .../tests/agate/FanSpeedControl.test.js | 139 +++++++++++++++ performance/tests/agate/Header.test.js | 81 +++++++++ performance/tests/agate/Heading.test.js | 81 +++++++++ performance/tests/agate/Icon.test.js | 81 +++++++++ performance/tests/agate/Image.test.js | 81 +++++++++ performance/tests/agate/ImageItem.test.js | 80 +++++++++ .../tests/agate/IncrementSlider.test.js | 131 +++++++++++++++ performance/tests/agate/Input.test.js | 158 ++++++++++++++++++ performance/tests/agate/Item.test.js | 138 +++++++++++++++ performance/tests/agate/Keypad.test.js | 145 ++++++++++++++++ performance/tests/agate/LabeledIcon.test.js | 81 +++++++++ .../tests/agate/LabeledIconButton.test.js | 81 +++++++++ performance/tests/agate/ListItemsTests.js | 137 +++++++++++++++ performance/tests/agate/Marquee.test.js | 100 +++++++++++ performance/tests/agate/MediaPlayer.test.js | 126 ++++++++++++++ performance/tests/agate/Panels.test.js | 132 +++++++++++++++ performance/tests/agate/Picker.test.js | 143 ++++++++++++++++ performance/tests/agate/Popup.test.js | 124 ++++++++++++++ performance/tests/agate/PopupMenu.test.js | 124 ++++++++++++++ performance/tests/agate/ProgressBar.test.js | 81 +++++++++ performance/tests/agate/RadioItem.test.js | 138 +++++++++++++++ performance/tests/agate/RangePicker.test.js | 145 ++++++++++++++++ performance/tests/agate/Scroller.test.js | 124 ++++++++++++++ performance/tests/agate/Slider.test.js | 131 +++++++++++++++ performance/tests/agate/SliderButton.test.js | 120 +++++++++++++ performance/tests/agate/SwitchItem.test.js | 140 ++++++++++++++++ performance/tests/agate/TabGroup.test.js | 103 ++++++++++++ .../tests/agate/TemperatureControl.test.js | 139 +++++++++++++++ performance/tests/agate/ThumbnailItem.test.js | 79 +++++++++ performance/tests/agate/TimePicker.test.js | 117 +++++++++++++ performance/tests/agate/ToggleButton.test.js | 139 +++++++++++++++ .../tests/agate/TooltipDecorator.test.js | 99 +++++++++++ performance/tests/agate/VirtualList.test.js | 6 + .../tests/agate/WindDirectionControl.test.js | 139 +++++++++++++++ src/App/Agate-App.js | 86 ++++++++++ src/views/agate/ArcPicker.js | 15 ++ src/views/agate/ArcSlider.js | 15 ++ src/views/agate/BodyText.js | 14 ++ src/views/agate/CheckboxItem.js | 12 ++ src/views/agate/ColorPicker.js | 16 ++ src/views/agate/ContextualPopupDecorator.js | 17 ++ src/views/agate/DatePicker.js | 12 ++ src/views/agate/DateTimePicker.js | 12 ++ src/views/agate/Drawer.js | 23 +++ src/views/agate/Dropdown.js | 22 +++ src/views/agate/FanSpeedControl.js | 14 ++ src/views/agate/Header.js | 15 ++ src/views/agate/Heading.js | 14 ++ src/views/agate/Icon.js | 15 ++ src/views/agate/Image.js | 15 ++ src/views/agate/ImageItem.js | 19 +++ src/views/agate/IncrementSlider.js | 15 ++ src/views/agate/Input.js | 15 ++ src/views/agate/Item.js | 14 ++ src/views/agate/Keypad.js | 12 ++ src/views/agate/LabeledIcon.js | 17 ++ src/views/agate/LabeledIconButton.js | 17 ++ src/views/agate/Marquee.js | 17 ++ src/views/agate/MediaPlayer.js | 25 +++ src/views/agate/Panels.js | 70 ++++++++ src/views/agate/Picker.js | 19 +++ src/views/agate/Popup.js | 22 +++ src/views/agate/PopupMenu.js | 26 +++ src/views/agate/ProgressBar.js | 15 ++ src/views/agate/RadioItem.js | 14 ++ src/views/agate/RangePicker.js | 18 ++ src/views/agate/Scroller.js | 18 ++ src/views/agate/Slider.js | 15 ++ src/views/agate/SliderButton.js | 18 ++ src/views/agate/SwitchItem.js | 14 ++ src/views/agate/TabGroup.js | 20 +++ src/views/agate/TemperatureControl.js | 12 ++ src/views/agate/ThumbnailItem.js | 17 ++ src/views/agate/TimePicker.js | 12 ++ src/views/agate/ToggleButton.js | 16 ++ src/views/agate/TooltipDecorator.js | 20 +++ src/views/agate/VirtualList.js | 64 +++++++ src/views/agate/WindDirectionControl.js | 14 ++ 91 files changed, 6067 insertions(+), 10 deletions(-) create mode 100644 performance/tests/agate/ArcPicker.test.js create mode 100644 performance/tests/agate/ArcSlider.test.js create mode 100644 performance/tests/agate/BodyText.test.js create mode 100644 performance/tests/agate/CheckboxItem.test.js create mode 100644 performance/tests/agate/ColorPicker.test.js create mode 100644 performance/tests/agate/ContextualPopupDecorator.test.js create mode 100644 performance/tests/agate/DatePicker.test.js create mode 100644 performance/tests/agate/DateTimePicker.test.js create mode 100644 performance/tests/agate/Drawer.test.js create mode 100644 performance/tests/agate/Dropdown.test.js create mode 100644 performance/tests/agate/FanSpeedControl.test.js create mode 100644 performance/tests/agate/Header.test.js create mode 100644 performance/tests/agate/Heading.test.js create mode 100644 performance/tests/agate/Icon.test.js create mode 100644 performance/tests/agate/Image.test.js create mode 100644 performance/tests/agate/ImageItem.test.js create mode 100644 performance/tests/agate/IncrementSlider.test.js create mode 100644 performance/tests/agate/Input.test.js create mode 100644 performance/tests/agate/Item.test.js create mode 100644 performance/tests/agate/Keypad.test.js create mode 100644 performance/tests/agate/LabeledIcon.test.js create mode 100644 performance/tests/agate/LabeledIconButton.test.js create mode 100644 performance/tests/agate/ListItemsTests.js create mode 100644 performance/tests/agate/Marquee.test.js create mode 100644 performance/tests/agate/MediaPlayer.test.js create mode 100644 performance/tests/agate/Panels.test.js create mode 100644 performance/tests/agate/Picker.test.js create mode 100644 performance/tests/agate/Popup.test.js create mode 100644 performance/tests/agate/PopupMenu.test.js create mode 100644 performance/tests/agate/ProgressBar.test.js create mode 100644 performance/tests/agate/RadioItem.test.js create mode 100644 performance/tests/agate/RangePicker.test.js create mode 100644 performance/tests/agate/Scroller.test.js create mode 100644 performance/tests/agate/Slider.test.js create mode 100644 performance/tests/agate/SliderButton.test.js create mode 100644 performance/tests/agate/SwitchItem.test.js create mode 100644 performance/tests/agate/TabGroup.test.js create mode 100644 performance/tests/agate/TemperatureControl.test.js create mode 100644 performance/tests/agate/ThumbnailItem.test.js create mode 100644 performance/tests/agate/TimePicker.test.js create mode 100644 performance/tests/agate/ToggleButton.test.js create mode 100644 performance/tests/agate/TooltipDecorator.test.js create mode 100644 performance/tests/agate/VirtualList.test.js create mode 100644 performance/tests/agate/WindDirectionControl.test.js create mode 100644 src/views/agate/ArcPicker.js create mode 100644 src/views/agate/ArcSlider.js create mode 100644 src/views/agate/BodyText.js create mode 100644 src/views/agate/CheckboxItem.js create mode 100644 src/views/agate/ColorPicker.js create mode 100644 src/views/agate/ContextualPopupDecorator.js create mode 100644 src/views/agate/DatePicker.js create mode 100644 src/views/agate/DateTimePicker.js create mode 100644 src/views/agate/Drawer.js create mode 100644 src/views/agate/Dropdown.js create mode 100644 src/views/agate/FanSpeedControl.js create mode 100644 src/views/agate/Header.js create mode 100644 src/views/agate/Heading.js create mode 100644 src/views/agate/Icon.js create mode 100644 src/views/agate/Image.js create mode 100644 src/views/agate/ImageItem.js create mode 100644 src/views/agate/IncrementSlider.js create mode 100644 src/views/agate/Input.js create mode 100644 src/views/agate/Item.js create mode 100644 src/views/agate/Keypad.js create mode 100644 src/views/agate/LabeledIcon.js create mode 100644 src/views/agate/LabeledIconButton.js create mode 100644 src/views/agate/Marquee.js create mode 100644 src/views/agate/MediaPlayer.js create mode 100644 src/views/agate/Panels.js create mode 100644 src/views/agate/Picker.js create mode 100644 src/views/agate/Popup.js create mode 100644 src/views/agate/PopupMenu.js create mode 100644 src/views/agate/ProgressBar.js create mode 100644 src/views/agate/RadioItem.js create mode 100644 src/views/agate/RangePicker.js create mode 100644 src/views/agate/Scroller.js create mode 100644 src/views/agate/Slider.js create mode 100644 src/views/agate/SliderButton.js create mode 100644 src/views/agate/SwitchItem.js create mode 100644 src/views/agate/TabGroup.js create mode 100644 src/views/agate/TemperatureControl.js create mode 100644 src/views/agate/ThumbnailItem.js create mode 100644 src/views/agate/TimePicker.js create mode 100644 src/views/agate/ToggleButton.js create mode 100644 src/views/agate/TooltipDecorator.js create mode 100644 src/views/agate/VirtualList.js create mode 100644 src/views/agate/WindDirectionControl.js diff --git a/README.md b/README.md index c305b833..4866c0f2 100644 --- a/README.md +++ b/README.md @@ -8,27 +8,32 @@ We utilize puppeteer to get chrome performance traces. ### Testing Sandstone components -Start the server with Sandstone components and run the test suite on it. +You can start the server and run the test suite on it separately. Sandstone is the default theme, so you can simply use: + ``` -npm run test-all -- --theme=sandstone +npm run serve +npm run test ``` +Alternatively, you can use the test-all command to start the server and run the test suite together: + ``` -npm run serve-sandstone -npm run test -- --theme=sandstone +npm run test-all ``` ### Testing Agate components -Start the server with Agate components and run the test suite on it. -``` -npm run test-all -- --theme=agate -``` +Start the server with Agate components and run the test suite on it. You can specify the theme by adding --theme=agate at the end of the command: ``` npm run serve-agate npm run test -- --theme=agate ``` + +``` +npm run test-all -- --theme=agate +``` + On Windows OS you might need to install `cross-env` globally with `npm install -g cross-env`. ## Testing on TV @@ -47,7 +52,6 @@ TV_IP=10.0.1.1 npm run test -- --target=TV --theme=sandstone ## CPU Throttling You can simulate a low-end device with a CPU throttling option. 1 is no throttle, 2 is 2x slowdown. - See the [Puppeteer API docs](https://pptr.dev/api/puppeteer.page.emulatecputhrottling) for the detailed information. Available commands are: diff --git a/package.json b/package.json index 26c9ace7..dffc4f1c 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "author": "", "main": "src/index.js", "scripts": { + "serve": "cross-env REACT_APP_ENACT_THEME=sandstone enact serve", "serve-sandstone": "cross-env REACT_APP_ENACT_THEME=sandstone enact serve", "serve-agate": "cross-env REACT_APP_ENACT_THEME=agate enact serve", "pack": "enact pack", diff --git a/performance/TraceModel.js b/performance/TraceModel.js index 67d93838..d965ef28 100644 --- a/performance/TraceModel.js +++ b/performance/TraceModel.js @@ -1,4 +1,4 @@ -/* global requestAnimationFrame, PerformanceObserver */ +/* global requestAnimationFrame */ const fs = require('fs'); diff --git a/performance/tests/agate/ArcPicker.test.js b/performance/tests/agate/ArcPicker.test.js new file mode 100644 index 00000000..093af91c --- /dev/null +++ b/performance/tests/agate/ArcPicker.test.js @@ -0,0 +1,139 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('ArcPicker', () => { + const component = 'ArcPicker'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/arcPicker`); + await page.waitForSelector('#arcPicker'); + await page.click('#arcPicker'); // to move mouse on the button. + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/arcPicker`); + await page.waitForSelector('#arcPicker'); + await page.focus('#arcPicker'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowUp'); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowUp'); + await page.keyboard.down('ArrowDown'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowDown'); + await page.keyboard.down('ArrowDown'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowDown'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/arcPicker`); + await page.waitForSelector('#arcPicker'); + await page.focus('#arcPicker'); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 200)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const arcPickerPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await arcPickerPage.emulateCPUThrottling(CPUThrottling); + + await arcPickerPage.tracing.start({path: filename, screenshots: false}); + await arcPickerPage.goto(`http://${serverAddr}/arcPicker`); + await arcPickerPage.waitForSelector('#arcPicker'); + await new Promise(r => setTimeout(r, 200)); + + await arcPickerPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await arcPickerPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); + diff --git a/performance/tests/agate/ArcSlider.test.js b/performance/tests/agate/ArcSlider.test.js new file mode 100644 index 00000000..2ea002e2 --- /dev/null +++ b/performance/tests/agate/ArcSlider.test.js @@ -0,0 +1,139 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('ArcSlider', () => { + const component = 'ArcSlider'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/arcSlider`); + await page.waitForSelector('#arcSlider'); + await page.click('#arcSlider'); // to move mouse on the button. + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/arcSlider`); + await page.waitForSelector('#arcSlider'); + await page.focus('#arcSlider'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowUp'); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowUp'); + await page.keyboard.down('ArrowDown'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowDown'); + await page.keyboard.down('ArrowDown'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowDown'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/arcSlider`); + await page.waitForSelector('#arcSlider'); + await page.focus('#arcSlider'); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 200)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const buttonPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await buttonPage.emulateCPUThrottling(CPUThrottling); + + await buttonPage.tracing.start({path: filename, screenshots: false}); + await buttonPage.goto(`http://${serverAddr}/arcSlider`); + await buttonPage.waitForSelector('#arcSlider'); + await new Promise(r => setTimeout(r, 200)); + + await buttonPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await buttonPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); + diff --git a/performance/tests/agate/BodyText.test.js b/performance/tests/agate/BodyText.test.js new file mode 100644 index 00000000..90551720 --- /dev/null +++ b/performance/tests/agate/BodyText.test.js @@ -0,0 +1,81 @@ +/* global CPUThrottling, page, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('BodyText', () => { + const component = 'BodyText'; + TestResults.newFile(component); + + it('should have a good CLS', async () => { + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/bodyText`); + await page.waitForSelector('#bodyText'); + await page.focus('#bodyText'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const bodyTextPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await bodyTextPage.emulateCPUThrottling(CPUThrottling); + + await bodyTextPage.tracing.start({path: filename, screenshots: false}); + await bodyTextPage.goto(`http://${serverAddr}/bodyText`); + await bodyTextPage.waitForSelector('#bodyText'); + await new Promise(r => setTimeout(r, 200)); + + await bodyTextPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await bodyTextPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/CheckboxItem.test.js b/performance/tests/agate/CheckboxItem.test.js new file mode 100644 index 00000000..53cc4f9f --- /dev/null +++ b/performance/tests/agate/CheckboxItem.test.js @@ -0,0 +1,134 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('CheckboxItem', () => { + const component = 'CheckboxItem'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/checkboxItem`); + await new Promise(r => setTimeout(r, 500)); + await page.click('#agate-checkboxItem'); // to move mouse on the checkboxItem. + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/checkboxItem`); + await page.focus('#agate-checkboxItem'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/checkboxItem`); + await page.waitForSelector('#agate-checkboxItem'); + await page.focus('#agate-checkboxItem'); + await page.keyboard.down('Enter'); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const checkboxItemPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await checkboxItemPage.emulateCPUThrottling(CPUThrottling); + + await checkboxItemPage.tracing.start({path: filename, screenshots: false}); + await checkboxItemPage.goto(`http://${serverAddr}/checkboxItem`); + await checkboxItemPage.waitForSelector('#agate-checkboxItem'); + await new Promise(r => setTimeout(r, 200)); + + await checkboxItemPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await checkboxItemPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/ColorPicker.test.js b/performance/tests/agate/ColorPicker.test.js new file mode 100644 index 00000000..9e9695da --- /dev/null +++ b/performance/tests/agate/ColorPicker.test.js @@ -0,0 +1,135 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('ColorPicker', () => { + const component = 'ColorPicker'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/colorPicker`); + await page.click('#agate-colorPicker'); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 300)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 300)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 300)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 300)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/colorPicker`); + await page.focus('#agate-colorPicker'); + await new Promise(r => setTimeout(r, 300)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 300)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 300)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 300)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 300)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/colorPicker`); + await page.waitForSelector('#agate-colorPicker'); + await page.focus('#agate-colorPicker'); + await page.keyboard.down('Enter'); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const colorPickerPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await colorPickerPage.emulateCPUThrottling(CPUThrottling); + + await colorPickerPage.tracing.start({path: filename, screenshots: false}); + await colorPickerPage.goto(`http://${serverAddr}/colorPicker?open`); + await colorPickerPage.waitForSelector('#agate-colorPicker'); + await new Promise(r => setTimeout(r, 200)); + + await colorPickerPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await colorPickerPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/ContextualPopupDecorator.test.js b/performance/tests/agate/ContextualPopupDecorator.test.js new file mode 100644 index 00000000..a53929e5 --- /dev/null +++ b/performance/tests/agate/ContextualPopupDecorator.test.js @@ -0,0 +1,104 @@ +/* global CPUThrottling, page, minFPS, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('ContextualPopupDecorator', () => { + const component = 'ContextualPopupDecorator'; + TestResults.newFile(component); + + it('FPS', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/contextualPopupDecorator`); + await page.waitForSelector('#agate-contextualPopupDecorator'); + await page.click('#agate-contextualPopupDecorator'); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + + it('should have a good CLS', async () => { + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/contextualPopupDecorator`); + await new Promise(r => setTimeout(r, 200)); + await page.waitForSelector('#agate-contextualPopupDecorator'); + await page.click('#agate-contextualPopupDecorator'); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const contextualPopupDecoratorPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await contextualPopupDecoratorPage.emulateCPUThrottling(CPUThrottling); + + await contextualPopupDecoratorPage.tracing.start({path: filename, screenshots: false}); + await contextualPopupDecoratorPage.goto(`http://${serverAddr}/contextualPopupDecorator`); + await contextualPopupDecoratorPage.waitForSelector('#agate-contextualPopupDecorator'); + await new Promise(r => setTimeout(r, 200)); + + await contextualPopupDecoratorPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await contextualPopupDecoratorPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/DatePicker.test.js b/performance/tests/agate/DatePicker.test.js new file mode 100644 index 00000000..d29193d2 --- /dev/null +++ b/performance/tests/agate/DatePicker.test.js @@ -0,0 +1,138 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('DatePicker', () => { + const component = 'DatePicker'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/datePicker`); + await page.waitForSelector('[aria-label$="month decrease the value"]'); + await page.click('[aria-label$="month decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.click('[aria-label$="day decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.click('[aria-label$="year decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.click('[aria-label$="month increase the value"]'); + await new Promise(r => setTimeout(r, 200)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/datePicker`); + await page.waitForSelector('#agate-datePicker'); + await page.focus('[aria-label$="month decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.focus('[aria-label$="day decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.focus('[aria-label$="year decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.focus('[aria-label$="month increase the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/datePicker`); + await page.waitForSelector('#agate-datePicker'); + await page.focus('[aria-label$="month decrease the value"]'); + await page.keyboard.down('Enter'); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const datePickerPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await datePickerPage.emulateCPUThrottling(CPUThrottling); + + await datePickerPage.tracing.start({path: filename, screenshots: false}); + await datePickerPage.goto(`http://${serverAddr}/datePicker`); + await datePickerPage.waitForSelector('#agate-datePicker'); + await new Promise(r => setTimeout(r, 200)); + + await datePickerPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await datePickerPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/DateTimePicker.test.js b/performance/tests/agate/DateTimePicker.test.js new file mode 100644 index 00000000..4e4b7b65 --- /dev/null +++ b/performance/tests/agate/DateTimePicker.test.js @@ -0,0 +1,145 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('DateTimePicker', () => { + const component = 'DateTimePicker'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/dateTimePicker`); + await page.waitForSelector('#agate-dateTimePicker'); + await page.click('[aria-label$="hour previous item"]'); + await new Promise(r => setTimeout(r, 200)); + await page.click('[aria-label$="minute decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.click('[aria-label$="month decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.click('[aria-label$="day decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.click('[aria-label$="year decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/dateTimePicker`); + await page.waitForSelector('#agate-dateTimePicker'); + await page.focus('[aria-label$="hour previous item"]'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.click('[aria-label$="minute decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.click('[aria-label$="month decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.click('[aria-label$="day decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.click('[aria-label$="year decrease the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/dateTimePicker`); + await page.waitForSelector('#agate-dateTimePicker'); + await page.focus('[aria-label$="hour previous item"]'); + await page.keyboard.down('Enter'); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const dateTimePickerPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await dateTimePickerPage.emulateCPUThrottling(CPUThrottling); + + await dateTimePickerPage.tracing.start({path: filename, screenshots: false}); + await dateTimePickerPage.goto(`http://${serverAddr}/dateTimePicker`); + await dateTimePickerPage.waitForSelector('#agate-dateTimePicker'); + await new Promise(r => setTimeout(r, 200)); + + await dateTimePickerPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await dateTimePickerPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/Drawer.test.js b/performance/tests/agate/Drawer.test.js new file mode 100644 index 00000000..b5f4f100 --- /dev/null +++ b/performance/tests/agate/Drawer.test.js @@ -0,0 +1,145 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('Drawer', () => { + const component = 'Drawer'; + const open = '#button-open'; + const close = '#button-close'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/drawer`); + await page.waitForSelector('#agate-drawer'); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/drawer`); + await page.waitForSelector('#agate-drawer'); + await page.focus('#button-close'); + await page.keyboard.down('Enter'); + await page.keyboard.up('Enter'); + await new Promise(r => setTimeout(r, 500)); + await page.keyboard.down('Enter'); + await page.keyboard.up('Enter'); + await new Promise(r => setTimeout(r, 500)); + await page.keyboard.down('Enter'); + await page.keyboard.up('Enter'); + await new Promise(r => setTimeout(r, 500)); + await page.keyboard.down('Enter'); + await page.keyboard.up('Enter'); + await new Promise(r => setTimeout(r, 500)); + await page.keyboard.down('Enter'); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/drawer`); + await page.waitForSelector('#agate-drawer'); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const DrawerPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await DrawerPage.emulateCPUThrottling(CPUThrottling); + + await DrawerPage.tracing.start({path: filename, screenshots: false}); + await DrawerPage.goto(`http://${serverAddr}/drawer`); + await DrawerPage.waitForSelector('#agate-drawer'); + await new Promise(r => setTimeout(r, 200)); + + await DrawerPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await DrawerPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/Dropdown.test.js b/performance/tests/agate/Dropdown.test.js new file mode 100644 index 00000000..ce805749 --- /dev/null +++ b/performance/tests/agate/Dropdown.test.js @@ -0,0 +1,137 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('Dropdown', () => { + const component = 'Dropdown'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/dropdown`); + await page.waitForSelector('#agate-dropdown'); + await page.click('#agate-dropdown'); // to move mouse on dropdown + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/dropdown`); + await page.waitForSelector('#agate-dropdown'); + await page.focus('#agate-dropdown'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/dropdown`); + await page.waitForSelector('#agate-dropdown'); + await page.focus('#agate-dropdown'); + await page.keyboard.down('Enter'); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const dropdownPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await dropdownPage.emulateCPUThrottling(CPUThrottling); + + await dropdownPage.tracing.start({path: filename, screenshots: false}); + await dropdownPage.goto(`http://${serverAddr}/dropdown`); + await dropdownPage.waitForSelector('#agate-dropdown'); + await new Promise(r => setTimeout(r, 200)); + + await dropdownPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await dropdownPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/FanSpeedControl.test.js b/performance/tests/agate/FanSpeedControl.test.js new file mode 100644 index 00000000..046c648f --- /dev/null +++ b/performance/tests/agate/FanSpeedControl.test.js @@ -0,0 +1,139 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('FanSpeedControl', () => { + const component = 'FanSpeedControl'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/fanSpeedControl`); + await page.waitForSelector('#fanSpeedControl'); + await page.click('#fanSpeedControl'); // to move mouse on the button. + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/fanSpeedControl`); + await page.waitForSelector('#fanSpeedControl'); + await page.focus('#fanSpeedControl'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowUp'); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowUp'); + await page.keyboard.down('ArrowDown'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowDown'); + await page.keyboard.down('ArrowDown'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowDown'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/fanSpeedControl`); + await page.waitForSelector('#fanSpeedControl'); + await page.focus('#fanSpeedControl'); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 200)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const fanSpeedControlPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await fanSpeedControlPage.emulateCPUThrottling(CPUThrottling); + + await fanSpeedControlPage.tracing.start({path: filename, screenshots: false}); + await fanSpeedControlPage.goto(`http://${serverAddr}/fanSpeedControl`); + await fanSpeedControlPage.waitForSelector('#fanSpeedControl'); + await new Promise(r => setTimeout(r, 200)); + + await fanSpeedControlPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await fanSpeedControlPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); + diff --git a/performance/tests/agate/Header.test.js b/performance/tests/agate/Header.test.js new file mode 100644 index 00000000..d423afa3 --- /dev/null +++ b/performance/tests/agate/Header.test.js @@ -0,0 +1,81 @@ +/* global CPUThrottling, page, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('Header', () => { + const component = 'Header'; + TestResults.newFile(component); + + it('should have a good CLS', async () => { + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/header`); + await page.waitForSelector('#header'); + await page.focus('#header'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const headerPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await headerPage.emulateCPUThrottling(CPUThrottling); + + await headerPage.tracing.start({path: filename, screenshots: false}); + await headerPage.goto(`http://${serverAddr}/header`); + await headerPage.waitForSelector('#header'); + await new Promise(r => setTimeout(r, 200)); + + await headerPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await headerPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/Heading.test.js b/performance/tests/agate/Heading.test.js new file mode 100644 index 00000000..58fd1eab --- /dev/null +++ b/performance/tests/agate/Heading.test.js @@ -0,0 +1,81 @@ +/* global CPUThrottling, page, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('Heading', () => { + const component = 'Heading'; + TestResults.newFile(component); + + it('should have a good CLS', async () => { + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/heading`); + await page.waitForSelector('#heading'); + await page.focus('#heading'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const headingPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await headingPage.emulateCPUThrottling(CPUThrottling); + + await headingPage.tracing.start({path: filename, screenshots: false}); + await headingPage.goto(`http://${serverAddr}/heading`); + await headingPage.waitForSelector('#heading'); + await new Promise(r => setTimeout(r, 200)); + + await headingPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await headingPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/Icon.test.js b/performance/tests/agate/Icon.test.js new file mode 100644 index 00000000..af3751f3 --- /dev/null +++ b/performance/tests/agate/Icon.test.js @@ -0,0 +1,81 @@ +/* global CPUThrottling, page, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('Icon', () => { + const component = 'Icon'; + TestResults.newFile(component); + + it('should have a good CLS', async () => { + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/icon`); + await page.waitForSelector('#icon'); + await page.focus('#icon'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const iconPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await iconPage.emulateCPUThrottling(CPUThrottling); + + await iconPage.tracing.start({path: filename, screenshots: false}); + await iconPage.goto(`http://${serverAddr}/icon`); + await iconPage.waitForSelector('#icon'); + await new Promise(r => setTimeout(r, 200)); + + await iconPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await iconPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/Image.test.js b/performance/tests/agate/Image.test.js new file mode 100644 index 00000000..001a2f9c --- /dev/null +++ b/performance/tests/agate/Image.test.js @@ -0,0 +1,81 @@ +/* global CPUThrottling, page, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('Image', () => { + const component = 'Image'; + TestResults.newFile(component); + + it('should have a good CLS', async () => { + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/Image`); + await page.waitForSelector('#image'); + await page.focus('#image'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const imagePage = targetEnv === 'TV' ? page : await newPageMultiple(); + await imagePage.emulateCPUThrottling(CPUThrottling); + + await imagePage.tracing.start({path: filename, screenshots: false}); + await imagePage.goto(`http://${serverAddr}/image`); + await imagePage.waitForSelector('#image'); + await new Promise(r => setTimeout(r, 200)); + + await imagePage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await imagePage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/ImageItem.test.js b/performance/tests/agate/ImageItem.test.js new file mode 100644 index 00000000..759a5d62 --- /dev/null +++ b/performance/tests/agate/ImageItem.test.js @@ -0,0 +1,80 @@ +/* global CPUThrottling, page, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('ImageItem', () => { + const component = 'ImageItem'; + TestResults.newFile(component); + + it('should have a good CLS', async () => { + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/imageItem`); + await page.waitForSelector('#imageItem'); + await page.focus('#imageItem'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const imageItemPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await imageItemPage.emulateCPUThrottling(CPUThrottling); + + await imageItemPage.tracing.start({path: filename, screenshots: false}); + await imageItemPage.goto(`http://${serverAddr}/imageItem`); + await imageItemPage.waitForSelector('#imageItem'); + await new Promise(r => setTimeout(r, 200)); + await imageItemPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await imageItemPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/IncrementSlider.test.js b/performance/tests/agate/IncrementSlider.test.js new file mode 100644 index 00000000..7e710522 --- /dev/null +++ b/performance/tests/agate/IncrementSlider.test.js @@ -0,0 +1,131 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); +const TestResults = require('../../TestResults'); + +describe('IncrementSlider', () => { + const component = 'IncrementSlider'; + TestResults.newFile(component); + + describe('drag', () => { + it('increment', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/incrementSlider`); + await page.waitForSelector('#incrementSlider'); + const {x: posX, y: posY} = await page.evaluate(() => { + const knobElement = document.querySelector('[class$="Slider_knob"]'); + const {x, y} = knobElement.getBoundingClientRect(); + return {x, y}; + }); + + await page.mouse.move(posX, posY); + await page.mouse.down(); + + for (let i = 0; i < 100; i++) { + await page.mouse.move(posX + (i * 10), posY); + } + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keyboard', () => { + it('increment', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/incrementSlider`); + await page.waitForSelector('#incrementSlider'); + await page.focus('#incrementSlider'); + + await page.keyboard.press('Enter'); + + for (let i = 0; i < 100; i++) { + await page.keyboard.down('ArrowRight'); + } + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/incrementSlider`); + await page.waitForSelector('#incrementSlider'); + await page.focus('#incrementSlider'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const incrementSliderPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await incrementSliderPage.emulateCPUThrottling(CPUThrottling); + + await incrementSliderPage.tracing.start({path: filename, screenshots: false}); + await incrementSliderPage.goto(`http://${serverAddr}/incrementSlider`); + await incrementSliderPage.waitForSelector('#incrementSlider'); + await new Promise(r => setTimeout(r, 200)); + + await incrementSliderPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await incrementSliderPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); + diff --git a/performance/tests/agate/Input.test.js b/performance/tests/agate/Input.test.js new file mode 100644 index 00000000..cd328f25 --- /dev/null +++ b/performance/tests/agate/Input.test.js @@ -0,0 +1,158 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('Input', () => { + const component = 'Input'; + TestResults.newFile(component); + + it('FPS', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/input`); + await page.waitForSelector('#input'); + await page.focus('#input'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('A'); + await page.keyboard.up('A'); + await page.keyboard.down('B'); + await page.keyboard.up('B'); + await page.keyboard.down('B'); + await page.keyboard.up('B'); + await page.keyboard.down('A'); + await page.keyboard.up('A'); + await page.keyboard.down('Backspace'); + await page.keyboard.up('Backspace'); + await page.keyboard.down('Backspace'); + await page.keyboard.up('Backspace'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('A'); + await page.keyboard.up('A'); + await page.keyboard.down('B'); + await page.keyboard.up('B'); + await page.keyboard.down('B'); + await page.keyboard.up('B'); + await page.keyboard.down('A'); + await page.keyboard.up('A'); + await page.keyboard.down('Backspace'); + await page.keyboard.up('Backspace'); + await page.keyboard.down('Backspace'); + await page.keyboard.up('Backspace'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('A'); + await page.keyboard.up('A'); + await page.keyboard.down('B'); + await page.keyboard.up('B'); + await page.keyboard.down('B'); + await page.keyboard.up('B'); + await page.keyboard.down('A'); + await page.keyboard.up('A'); + await page.keyboard.down('Backspace'); + await page.keyboard.up('Backspace'); + await page.keyboard.down('Backspace'); + await page.keyboard.up('Backspace'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/input`); + await page.waitForSelector('#input'); + await new Promise(r => setTimeout(r, 100)); + await page.click('#input'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.down('A'); + await page.keyboard.up('A'); + await page.keyboard.down('B'); + await page.keyboard.up('B'); + await page.keyboard.down('B'); + await page.keyboard.up('B'); + await page.keyboard.down('A'); + await page.keyboard.up('A'); + await page.keyboard.down('Backspace'); + await page.keyboard.up('Backspace'); + await page.keyboard.down('Backspace'); + await page.keyboard.up('Backspace'); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const inputPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await inputPage.emulateCPUThrottling(CPUThrottling); + + await inputPage.tracing.start({path: filename, screenshots: false}); + await inputPage.goto(`http://${serverAddr}/input`); + await inputPage.waitForSelector('#input'); + await new Promise(r => setTimeout(r, 200)); + + await inputPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await inputPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/Item.test.js b/performance/tests/agate/Item.test.js new file mode 100644 index 00000000..4b233d60 --- /dev/null +++ b/performance/tests/agate/Item.test.js @@ -0,0 +1,138 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('Item', () => { + const component = 'Item'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/item`); + await page.waitForSelector('#item'); + await page.click('#item'); // to move mouse on the item. + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/item`); + await page.waitForSelector('#item'); + await page.focus('#item'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/item`); + await page.waitForSelector('#item'); + await new Promise(r => setTimeout(r, 100)); + await page.click('#item'); + await new Promise(r => setTimeout(r, 100)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const itemPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await itemPage.emulateCPUThrottling(CPUThrottling); + + await itemPage.tracing.start({path: filename, screenshots: false}); + await itemPage.goto(`http://${serverAddr}/item`); + await itemPage.waitForSelector('#item'); + await new Promise(r => setTimeout(r, 200)); + + await itemPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await itemPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/Keypad.test.js b/performance/tests/agate/Keypad.test.js new file mode 100644 index 00000000..ab21f7d0 --- /dev/null +++ b/performance/tests/agate/Keypad.test.js @@ -0,0 +1,145 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('Keypad', () => { + const component = 'Keypad'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/keypad`); + await page.waitForSelector('#keypad'); + await page.click('[aria-label$="1"]'); // to move mouse on the keypad. + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/keypad`); + await page.waitForSelector('#keypad'); + await page.focus('[aria-label$="1"]'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('ArrowRight'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('ArrowRight'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/keypad`); + await page.waitForSelector('#keypad'); + await new Promise(r => setTimeout(r, 100)); + await page.click('[aria-label$="1"]'); + await new Promise(r => setTimeout(r, 100)); + + let actualFirstInput = await page.evaluate(() => { + return window.fid; + }); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const keypadPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await keypadPage.emulateCPUThrottling(CPUThrottling); + + await keypadPage.tracing.start({path: filename, screenshots: false}); + await keypadPage.goto(`http://${serverAddr}/keypad`); + await keypadPage.waitForSelector('#keypad'); + await new Promise(r => setTimeout(r, 200)); + + await keypadPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await keypadPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/LabeledIcon.test.js b/performance/tests/agate/LabeledIcon.test.js new file mode 100644 index 00000000..56f4a9fd --- /dev/null +++ b/performance/tests/agate/LabeledIcon.test.js @@ -0,0 +1,81 @@ +/* global CPUThrottling, page, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('LabeledIcon', () => { + const component = 'LabeledIcon'; + TestResults.newFile(component); + + it('should have a good CLS', async () => { + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/labeledIcon`); + await page.waitForSelector('#labeledIcon'); + await page.focus('#labeledIcon'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const labeledIconPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await labeledIconPage.emulateCPUThrottling(CPUThrottling); + + await labeledIconPage.tracing.start({path: filename, screenshots: false}); + await labeledIconPage.goto(`http://${serverAddr}/labeledIcon`); + await labeledIconPage.waitForSelector('#labeledIcon'); + await new Promise(r => setTimeout(r, 200)); + + await labeledIconPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await labeledIconPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/LabeledIconButton.test.js b/performance/tests/agate/LabeledIconButton.test.js new file mode 100644 index 00000000..ca342cb3 --- /dev/null +++ b/performance/tests/agate/LabeledIconButton.test.js @@ -0,0 +1,81 @@ +/* global CPUThrottling, page, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('LabeledIconButton', () => { + const component = 'LabeledIconButton'; + TestResults.newFile(component); + + it('should have a good CLS', async () => { + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/labeledIconButton`); + await page.waitForSelector('#labeledIconButton'); + await page.focus('#labeledIconButton'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const labeledIconButtonPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await labeledIconButtonPage.emulateCPUThrottling(CPUThrottling); + + await labeledIconButtonPage.tracing.start({path: filename, screenshots: false}); + await labeledIconButtonPage.goto(`http://${serverAddr}/labeledIconButton`); + await labeledIconButtonPage.waitForSelector('#labeledIconButton'); + await new Promise(r => setTimeout(r, 200)); + + await labeledIconButtonPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await labeledIconButtonPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/ListItemsTests.js b/performance/tests/agate/ListItemsTests.js new file mode 100644 index 00000000..5823692e --- /dev/null +++ b/performance/tests/agate/ListItemsTests.js @@ -0,0 +1,137 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ +/* eslint-disable*/ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple, scrollAtPoint} = require('../../utils'); + +const listItemTests = (componentName, dataSize) => describe(componentName, () => { + jest.setTimeout(100000); + + const component = componentName + (dataSize ? dataSize : ''); + TestResults.newFile(component); + const pageURL = dataSize ? `http://${serverAddr}/${componentName}?dataSize=${dataSize}` : `http://${serverAddr}/${componentName}`; + + describe('ScrollButton', () => { + it('scrolls down', async () => { + await FPS(); + await page.goto(pageURL); + await page.waitForSelector(`#${componentName}`); + await page.focus('[aria-label="scroll down"]'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 2000)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('mousewheel', () => { + it('scrolls down', async () => { + await FPS(); + const List = `#${componentName}`; + + await page.goto(pageURL); + await page.waitForSelector(List); + await scrollAtPoint(page, List, 1000); + await new Promise(r => setTimeout(r, 200)); + await scrollAtPoint(page, List, 1000); + await new Promise(r => setTimeout(r, 200)); + await scrollAtPoint(page, List, 1000); + await new Promise(r => setTimeout(r, 200)); + await scrollAtPoint(page, List, 1000); + await new Promise(r => setTimeout(r, 200)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Mousewheel', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(pageURL); + await page.waitForSelector(`#${componentName}`); + await page.focus(`#${componentName}`); + await page.keyboard.down('Enter'); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const ListPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await ListPage.emulateCPUThrottling(CPUThrottling); + + await ListPage.tracing.start({path: filename, screenshots: false}); + await ListPage.goto(pageURL); + await ListPage.waitForSelector(`#${componentName}`); + await new Promise(r => setTimeout(r, 200)); + + await ListPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await ListPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); + +exports.listItemTests = listItemTests; + +/* eslint-enable*/ diff --git a/performance/tests/agate/Marquee.test.js b/performance/tests/agate/Marquee.test.js new file mode 100644 index 00000000..c7dd2721 --- /dev/null +++ b/performance/tests/agate/Marquee.test.js @@ -0,0 +1,100 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +const component = 'Marquee'; +const MarqueeText = '[class$="Marquee_marquee"]'; + +describe('Marquee', () => { + TestResults.newFile(component); + + it('FPS on hover', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/marquee`); + await page.waitForSelector('#marquee'); + await page.hover(MarqueeText); + await new Promise(r => setTimeout(r, 500)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/marquee`); + await page.waitForSelector('#marquee'); + await page.hover(MarqueeText); + await new Promise(r => setTimeout(r, 500)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const marqueePage = targetEnv === 'TV' ? page : await newPageMultiple(); + await marqueePage.emulateCPUThrottling(CPUThrottling); + + await marqueePage.tracing.start({path: filename, screenshots: false}); + await marqueePage.goto(`http://${serverAddr}/marquee`); + await marqueePage.waitForSelector('#marquee'); + await new Promise(r => setTimeout(r, 200)); + + await marqueePage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await marqueePage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); + diff --git a/performance/tests/agate/MediaPlayer.test.js b/performance/tests/agate/MediaPlayer.test.js new file mode 100644 index 00000000..2d64d273 --- /dev/null +++ b/performance/tests/agate/MediaPlayer.test.js @@ -0,0 +1,126 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('CheckboxItem', () => { + const component = 'CheckboxItem'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/mediaPlayer`); + await page.waitForSelector('#agate-mediaPlayer'); + await page.click('[aria-label=Play]'); // to move mouse on the checkboxItem. + await new Promise(r => setTimeout(r, 600)); + await page.mouse.up(); + await page.focus('[aria-label=Next]'); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/mediaPlayer`); + await page.waitForSelector('#agate-mediaPlayer'); + await page.focus('[aria-label=Play]'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 600)); + await page.keyboard.up('Enter'); + await page.focus('[aria-label=Next]'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/mediaPlayer`); + await page.waitForSelector('#agate-mediaPlayer'); + await page.focus('#agate-mediaPlayer'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const mediaPlayerPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await mediaPlayerPage.emulateCPUThrottling(CPUThrottling); + + await mediaPlayerPage.tracing.start({path: filename, screenshots: false}); + await mediaPlayerPage.goto(`http://${serverAddr}/mediaPlayer`); + await mediaPlayerPage.waitForSelector('#agate-mediaPlayer'); + await new Promise(r => setTimeout(r, 200)); + + await mediaPlayerPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await mediaPlayerPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/Panels.test.js b/performance/tests/agate/Panels.test.js new file mode 100644 index 00000000..eccd2e9f --- /dev/null +++ b/performance/tests/agate/Panels.test.js @@ -0,0 +1,132 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {FPS, getAverageFPS, PageLoadingMetrics, FID, CLS} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('Panels', () => { + const component = 'Panels'; + const panel1 = '#panel-1'; + const nextPanelButton = '#goToNextPanel'; + const previousPanelButton = '#goToPreviousPanel'; + TestResults.newFile(component); + + it('FPS', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/panels`); + await page.waitForSelector(nextPanelButton); + await page.click(nextPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(previousPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(nextPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(previousPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(nextPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(previousPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(nextPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(previousPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(nextPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(previousPanelButton); + await new Promise(r => setTimeout(r, 500)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({ + component: component, + type: 'FPS', + actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000 + }); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/panels`); + await page.waitForSelector(nextPanelButton); + await page.click(nextPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(previousPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(nextPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(previousPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(nextPanelButton); + await new Promise(r => setTimeout(r, 500)); + await page.click(previousPanelButton); + await new Promise(r => setTimeout(r, 500)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const panelsPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await panelsPage.emulateCPUThrottling(CPUThrottling); + + await panelsPage.tracing.start({path: filename, screenshots: false}); + await panelsPage.goto(`http://${serverAddr}/panels`); + await panelsPage.waitForSelector(panel1); + await new Promise(r => setTimeout(r, 200)); + + await panelsPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await panelsPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/Picker.test.js b/performance/tests/agate/Picker.test.js new file mode 100644 index 00000000..6979c1f9 --- /dev/null +++ b/performance/tests/agate/Picker.test.js @@ -0,0 +1,143 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('Picker', () => { + const component = 'Picker'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/picker`); + await page.waitForSelector('#picker'); + await page.click('[aria-label$="next item"]'); // to move mouse on the picker. + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/picker`); + await page.waitForSelector('#picker'); + await page.focus('[aria-label$="next item"]'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/picker`); + await page.waitForSelector('#picker'); + await new Promise(r => setTimeout(r, 100)); + await page.click('[aria-label$="next item"]'); + await new Promise(r => setTimeout(r, 100)); + + let actualFirstInput = await page.evaluate(() => { + return window.fid; + }); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const pickerPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await pickerPage.emulateCPUThrottling(CPUThrottling); + + await pickerPage.tracing.start({path: filename, screenshots: false}); + await pickerPage.goto(`http://${serverAddr}/picker`); + await pickerPage.waitForSelector('#picker'); + await new Promise(r => setTimeout(r, 200)); + + await pickerPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await pickerPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/Popup.test.js b/performance/tests/agate/Popup.test.js new file mode 100644 index 00000000..cced32c6 --- /dev/null +++ b/performance/tests/agate/Popup.test.js @@ -0,0 +1,124 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {FPS, getAverageFPS, PageLoadingMetrics, FID, CLS} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('Popup', () => { + const component = 'Popup'; + const open = '#button-open'; + const close = '#button-close'; + TestResults.newFile(component); + + it('FPS', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/popup`); + await page.waitForSelector('#popup'); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/popup`); + await page.waitForSelector('#popup'); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const popupPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await popupPage.emulateCPUThrottling(CPUThrottling); + + await popupPage.tracing.start({path: filename, screenshots: false}); + await popupPage.goto(`http://${serverAddr}/popup`); + await popupPage.waitForSelector('#popup'); + await new Promise(r => setTimeout(r, 200)); + + await popupPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await popupPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); + diff --git a/performance/tests/agate/PopupMenu.test.js b/performance/tests/agate/PopupMenu.test.js new file mode 100644 index 00000000..aef9d80c --- /dev/null +++ b/performance/tests/agate/PopupMenu.test.js @@ -0,0 +1,124 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {FPS, getAverageFPS, PageLoadingMetrics, FID, CLS} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('PopupMenu', () => { + const component = 'PopupMenu'; + const open = '#button-open'; + const close = '#button-close'; + TestResults.newFile(component); + + it('FPS', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/popupMenu`); + await page.waitForSelector('#popupMenu'); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/popupMenu`); + await page.waitForSelector('#popupMenu'); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + await page.click(open); + await new Promise(r => setTimeout(r, 500)); + await page.click(close); + await new Promise(r => setTimeout(r, 500)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const popupMenuPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await popupMenuPage.emulateCPUThrottling(CPUThrottling); + + await popupMenuPage.tracing.start({path: filename, screenshots: false}); + await popupMenuPage.goto(`http://${serverAddr}/popupMenu`); + await popupMenuPage.waitForSelector('#popupMenu'); + await new Promise(r => setTimeout(r, 200)); + + await popupMenuPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await popupMenuPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); + diff --git a/performance/tests/agate/ProgressBar.test.js b/performance/tests/agate/ProgressBar.test.js new file mode 100644 index 00000000..cacd215d --- /dev/null +++ b/performance/tests/agate/ProgressBar.test.js @@ -0,0 +1,81 @@ +/* global CPUThrottling, page, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('ProgressBar', () => { + const component = 'ProgressBar'; + TestResults.newFile(component); + + it('should have a good CLS', async () => { + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/progressBar`); + await page.waitForSelector('#progressBar'); + await page.focus('#progressBar'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const progressBarPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await progressBarPage.emulateCPUThrottling(CPUThrottling); + + await progressBarPage.tracing.start({path: filename, screenshots: false}); + await progressBarPage.goto(`http://${serverAddr}/progressBar`); + await progressBarPage.waitForSelector('#progressBar'); + await new Promise(r => setTimeout(r, 200)); + + await progressBarPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await progressBarPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/RadioItem.test.js b/performance/tests/agate/RadioItem.test.js new file mode 100644 index 00000000..07688f1a --- /dev/null +++ b/performance/tests/agate/RadioItem.test.js @@ -0,0 +1,138 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('RadioItem', () => { + const component = 'RadioItem'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/radioItem`); + await page.waitForSelector('#radioItem'); + await page.click('#radioItem'); // to move mouse on the radioItem. + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/radioItem`); + await page.waitForSelector('#radioItem'); + await page.focus('#radioItem'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/radioItem`); + await page.waitForSelector('#radioItem'); + await new Promise(r => setTimeout(r, 100)); + await page.click('#radioItem'); + await new Promise(r => setTimeout(r, 100)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const radioItemPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await radioItemPage.emulateCPUThrottling(CPUThrottling); + + await radioItemPage.tracing.start({path: filename, screenshots: false}); + await radioItemPage.goto(`http://${serverAddr}/radioItem`); + await radioItemPage.waitForSelector('#radioItem'); + await new Promise(r => setTimeout(r, 200)); + + await radioItemPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await radioItemPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/RangePicker.test.js b/performance/tests/agate/RangePicker.test.js new file mode 100644 index 00000000..4cb800ba --- /dev/null +++ b/performance/tests/agate/RangePicker.test.js @@ -0,0 +1,145 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('RangePicker', () => { + const component = 'RangePicker'; + TestResults.newFile(component); + + describe('RangePicker', () => { + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/rangePicker`); + await page.waitForSelector('#rangePicker'); + await page.click('[aria-label$="increase the value"]'); // to move mouse on the rangePicker. + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 200)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/rangePicker`); + await page.waitForSelector('#rangePicker'); + await page.focus('[aria-label$="increase the value"]'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/rangePicker`); + await page.waitForSelector('#rangePicker'); + await new Promise(r => setTimeout(r, 100)); + await page.click('[aria-label$="increase the value"]'); + await new Promise(r => setTimeout(r, 100)); + + let actualFirstInput = await page.evaluate(() => { + return window.fid; + }); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const rangePickerPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await rangePickerPage.emulateCPUThrottling(CPUThrottling); + + await rangePickerPage.tracing.start({path: filename, screenshots: false}); + await rangePickerPage.goto(`http://${serverAddr}/rangePicker`); + await rangePickerPage.waitForSelector('#rangePicker'); + await new Promise(r => setTimeout(r, 200)); + + await rangePickerPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await rangePickerPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); + }); +}); diff --git a/performance/tests/agate/Scroller.test.js b/performance/tests/agate/Scroller.test.js new file mode 100644 index 00000000..cbb5ba49 --- /dev/null +++ b/performance/tests/agate/Scroller.test.js @@ -0,0 +1,124 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple, scrollAtPoint} = require('../../utils'); + +describe( 'Scroller', () => { + const component = 'Scroller'; + TestResults.newFile(component); + + describe('keypress', () => { + it('scrolls down', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/scroller`); + await page.focus('[aria-label="scroll down"]'); + await page.keyboard.down('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 2000)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('mouse wheel', () => { + it('scrolls down', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/scroller`); + const scroller = '#scroller'; + + await scrollAtPoint(page, scroller, 1000); + await new Promise(r => setTimeout(r, 200)); + await scrollAtPoint(page, scroller, 1000); + await new Promise(r => setTimeout(r, 200)); + await scrollAtPoint(page, scroller, 1000); + await new Promise(r => setTimeout(r, 200)); + await scrollAtPoint(page, scroller, 1000); + await new Promise(r => setTimeout(r, 200)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/scroller`); + await page.waitForSelector('#scroller'); + await page.focus('[aria-label="scroll down"]'); + await page.keyboard.down('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 2000)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const scrollerPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await scrollerPage.emulateCPUThrottling(CPUThrottling); + + await scrollerPage.tracing.start({path: filename, screenshots: false}); + await scrollerPage.goto(`http://${serverAddr}/scroller`); + await scrollerPage.waitForSelector('#scroller'); + await new Promise(r => setTimeout(r, 200)); + + await scrollerPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await scrollerPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/Slider.test.js b/performance/tests/agate/Slider.test.js new file mode 100644 index 00000000..6284d629 --- /dev/null +++ b/performance/tests/agate/Slider.test.js @@ -0,0 +1,131 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); +const TestResults = require('../../TestResults'); + +describe('Slider', () => { + const component = 'Slider'; + TestResults.newFile(component); + + describe('drag', () => { + it('increment', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/slider`); + await page.waitForSelector('#slider'); + const {x: posX, y: posY} = await page.evaluate(() => { + const knobElement = document.querySelector('[class$="Slider_knob"]'); + const {x, y} = knobElement.getBoundingClientRect(); + return {x, y}; + }); + + await page.mouse.move(posX, posY); + await page.mouse.down(); + + for (let i = 0; i < 100; i++) { + await page.mouse.move(posX + (i * 10), posY); + } + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keyboard', () => { + it('increment', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/slider`); + await page.waitForSelector('#slider'); + await page.focus('#slider'); + + await page.keyboard.press('Enter'); + + for (let i = 0; i < 100; i++) { + await page.keyboard.down('ArrowRight'); + } + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/slider`); + await page.waitForSelector('#slider'); + await page.focus('#slider'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const sliderPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await sliderPage.emulateCPUThrottling(CPUThrottling); + + await sliderPage.tracing.start({path: filename, screenshots: false}); + await sliderPage.goto(`http://${serverAddr}/slider`); + await sliderPage.waitForSelector('#slider'); + await new Promise(r => setTimeout(r, 200)); + + await sliderPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await sliderPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); + diff --git a/performance/tests/agate/SliderButton.test.js b/performance/tests/agate/SliderButton.test.js new file mode 100644 index 00000000..d7e85ce7 --- /dev/null +++ b/performance/tests/agate/SliderButton.test.js @@ -0,0 +1,120 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('SliderButton', () => { + const component = 'SliderButton'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/sliderButton`); + await page.waitForSelector('#sliderButton'); + await page.click('#sliderButton'); // to move mouse on the button. + await page.mouse.down(); + await new Promise(r => setTimeout(r, 300)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/sliderButton`); + await page.waitForSelector('#sliderButton'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('ArrowRight'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('ArrowRight'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('ArrowRight'); + await new Promise(r => setTimeout(r, 200)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/sliderButton`); + await page.waitForSelector('#sliderButton'); + await page.keyboard.down('ArrowRight'); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const sliderButtonPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await sliderButtonPage.emulateCPUThrottling(CPUThrottling); + + await sliderButtonPage.tracing.start({path: filename, screenshots: false}); + await sliderButtonPage.goto(`http://${serverAddr}/sliderButton`); + await sliderButtonPage.waitForSelector('#sliderButton'); + await new Promise(r => setTimeout(r, 200)); + + await sliderButtonPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await sliderButtonPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/SwitchItem.test.js b/performance/tests/agate/SwitchItem.test.js new file mode 100644 index 00000000..035d06f5 --- /dev/null +++ b/performance/tests/agate/SwitchItem.test.js @@ -0,0 +1,140 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('SwitchItem', () => { + const component = 'SwitchItem'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/switchItem`); + await page.waitForSelector('#switchItem'); + await new Promise(r => setTimeout(r, 200)); + await page.click('#switchItem'); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/switchItem`); + await page.waitForSelector('#switchItem'); + await new Promise(r => setTimeout(r, 200)); + await page.focus('#switchItem'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/switchItem`); + await page.waitForSelector('#switchItem'); + await new Promise(r => setTimeout(r, 100)); + await page.click('#switchItem'); + await new Promise(r => setTimeout(r, 100)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const switchItemPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await switchItemPage.emulateCPUThrottling(CPUThrottling); + + await switchItemPage.tracing.start({path: filename, screenshots: false}); + await switchItemPage.goto(`http://${serverAddr}/switchItem`); + await switchItemPage.waitForSelector('#switchItem'); + await new Promise(r => setTimeout(r, 200)); + + await switchItemPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await switchItemPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/TabGroup.test.js b/performance/tests/agate/TabGroup.test.js new file mode 100644 index 00000000..e334f4b5 --- /dev/null +++ b/performance/tests/agate/TabGroup.test.js @@ -0,0 +1,103 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('TabGroup', () => { + const component = 'TabGroup'; + TestResults.newFile(component); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/tabGroup`); + await page.waitForSelector('#tabGroup'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('ArrowRight'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('ArrowRight'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('ArrowRight'); + await new Promise(r => setTimeout(r, 200)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/tabGroup`); + await page.waitForSelector('#tabGroup'); + await page.keyboard.down('ArrowRight'); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const tabGroupPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await tabGroupPage.emulateCPUThrottling(CPUThrottling); + + await tabGroupPage.tracing.start({path: filename, screenshots: false}); + await tabGroupPage.goto(`http://${serverAddr}/tabGroup`); + await tabGroupPage.waitForSelector('#tabGroup'); + await new Promise(r => setTimeout(r, 200)); + + await tabGroupPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await tabGroupPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/TemperatureControl.test.js b/performance/tests/agate/TemperatureControl.test.js new file mode 100644 index 00000000..56de3f8f --- /dev/null +++ b/performance/tests/agate/TemperatureControl.test.js @@ -0,0 +1,139 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('TemperatureControl', () => { + const component = 'TemperatureControl'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/temperatureControl`); + await page.waitForSelector('#agate-temperatureControl'); + await page.click('#agate-temperatureControl'); // to move mouse on the button. + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/temperatureControl`); + await page.waitForSelector('#agate-temperatureControl'); + await page.focus('#agate-temperatureControl'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowUp'); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowUp'); + await page.keyboard.down('ArrowDown'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowDown'); + await page.keyboard.down('ArrowDown'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowDown'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/temperatureControl`); + await page.waitForSelector('#agate-temperatureControl'); + await page.focus('#agate-temperatureControl'); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 200)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const buttonPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await buttonPage.emulateCPUThrottling(CPUThrottling); + + await buttonPage.tracing.start({path: filename, screenshots: false}); + await buttonPage.goto(`http://${serverAddr}/temperatureControl`); + await buttonPage.waitForSelector('#agate-temperatureControl'); + await new Promise(r => setTimeout(r, 200)); + + await buttonPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await buttonPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); + diff --git a/performance/tests/agate/ThumbnailItem.test.js b/performance/tests/agate/ThumbnailItem.test.js new file mode 100644 index 00000000..29c8765b --- /dev/null +++ b/performance/tests/agate/ThumbnailItem.test.js @@ -0,0 +1,79 @@ +/* global CPUThrottling, page, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('ThumbnailItem', () => { + const component = 'ThumbnailItem'; + TestResults.newFile(component); + + it('should have a good CLS', async () => { + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/thumbnailItem`); + await page.waitForSelector('#thumbnailItem'); + await page.focus('#thumbnailItem'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const thumbnailItemPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await thumbnailItemPage.emulateCPUThrottling(CPUThrottling); + + await thumbnailItemPage.tracing.start({path: filename, screenshots: false}); + await thumbnailItemPage.goto(`http://${serverAddr}/thumbnailItem`); + await thumbnailItemPage.waitForSelector('#thumbnailItem'); + await new Promise(r => setTimeout(r, 200)); + await thumbnailItemPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await thumbnailItemPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/TimePicker.test.js b/performance/tests/agate/TimePicker.test.js new file mode 100644 index 00000000..df9151e0 --- /dev/null +++ b/performance/tests/agate/TimePicker.test.js @@ -0,0 +1,117 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('TimePicker', () => { + const component = 'TimePicker'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/timePicker`); + await page.waitForSelector('#timePicker'); + await new Promise(r => setTimeout(r, 200)); + await page.click('[aria-label$="hour next item"]'); + await new Promise(r => setTimeout(r, 1000)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/timePicker`); + await page.waitForSelector('#timePicker'); + await page.focus('[aria-label$="hour next item"]'); + await new Promise(r => setTimeout(r, 200)); + await page.keyboard.down('ArrowDown'); + await new Promise(r => setTimeout(r, 200)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/timePicker`); + await page.waitForSelector('#timePicker'); + await page.focus('[aria-label$="hour next item"]'); + await page.keyboard.down('ArrowDown'); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const timePickerPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await timePickerPage.emulateCPUThrottling(CPUThrottling); + + await timePickerPage.tracing.start({path: filename, screenshots: false}); + await timePickerPage.goto(`http://${serverAddr}/timePicker`); + await timePickerPage.waitForSelector('#timePicker'); + await new Promise(r => setTimeout(r, 200)); + + await timePickerPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await timePickerPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/ToggleButton.test.js b/performance/tests/agate/ToggleButton.test.js new file mode 100644 index 00000000..d7749fa7 --- /dev/null +++ b/performance/tests/agate/ToggleButton.test.js @@ -0,0 +1,139 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('Button', () => { + const component = 'Button'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/toggleButton`); + await page.waitForSelector('#agate-togglebutton'); + await page.click('#agate-togglebutton'); // to move mouse on the togglebutton. + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/toggleButton`); + await page.waitForSelector('#agate-togglebutton'); + await page.focus('#agate-togglebutton'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('Enter'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('Enter'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/toggleButton`); + await page.waitForSelector('#agate-togglebutton'); + await page.focus('#agate-togglebutton'); + await page.keyboard.down('Enter'); + await new Promise(r => setTimeout(r, 200)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const toggleButtonPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await toggleButtonPage.emulateCPUThrottling(CPUThrottling); + + await toggleButtonPage.tracing.start({path: filename, screenshots: false}); + await toggleButtonPage.goto(`http://${serverAddr}/toggleButton`); + await toggleButtonPage.waitForSelector('#agate-togglebutton'); + await new Promise(r => setTimeout(r, 200)); + + await toggleButtonPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await toggleButtonPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); + diff --git a/performance/tests/agate/TooltipDecorator.test.js b/performance/tests/agate/TooltipDecorator.test.js new file mode 100644 index 00000000..e631eb7e --- /dev/null +++ b/performance/tests/agate/TooltipDecorator.test.js @@ -0,0 +1,99 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('TooltipDecorator', () => { + const component = 'TooltipDecorator'; + TestResults.newFile(component); + + describe('focus', () => { + it('should have a good FPS', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/tooltipDecorator`); + await page.waitForSelector('#tooltipDecorator'); + await page.focus('#tooltipDecorator'); + await new Promise(r => setTimeout(r, 200)); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/tooltipDecorator`); + await page.waitForSelector('#tooltipDecorator'); + await page.focus('#tooltipDecorator'); + await page.keyboard.down('Enter'); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const tooltipDecoratorPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await tooltipDecoratorPage.emulateCPUThrottling(CPUThrottling); + + await tooltipDecoratorPage.tracing.start({path: filename, screenshots: false}); + await tooltipDecoratorPage.goto(`http://${serverAddr}/tooltipDecorator`); + await tooltipDecoratorPage.waitForSelector('#tooltipDecorator'); + await new Promise(r => setTimeout(r, 200)); + + await tooltipDecoratorPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await tooltipDecoratorPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); diff --git a/performance/tests/agate/VirtualList.test.js b/performance/tests/agate/VirtualList.test.js new file mode 100644 index 00000000..75afc2b6 --- /dev/null +++ b/performance/tests/agate/VirtualList.test.js @@ -0,0 +1,6 @@ +const {listItemTests} = require("./ListItemsTests"); + +const componentName = 'VirtualList'; + +listItemTests(componentName); +listItemTests(componentName, 12); diff --git a/performance/tests/agate/WindDirectionControl.test.js b/performance/tests/agate/WindDirectionControl.test.js new file mode 100644 index 00000000..db074207 --- /dev/null +++ b/performance/tests/agate/WindDirectionControl.test.js @@ -0,0 +1,139 @@ +/* global CPUThrottling, page, minFPS, maxFID, maxCLS, stepNumber, maxDCL, maxFCP, maxLCP, passRatio, serverAddr, targetEnv */ + +const TestResults = require('../../TestResults'); +const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../../TraceModel'); +const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../../utils'); + +describe('WindDirectionControl', () => { + const component = 'WindDirectionControl'; + TestResults.newFile(component); + + describe('click', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/windDirectionControl`); + await page.waitForSelector('#agate-windDirectionControl'); + await page.click('#agate-windDirectionControl'); // to move mouse on the button. + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + await page.mouse.down(); + await new Promise(r => setTimeout(r, 100)); + await page.mouse.up(); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Click', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + describe('keypress', () => { + it('animates', async () => { + await FPS(); + await page.goto(`http://${serverAddr}/windDirectionControl`); + await page.waitForSelector('#agate-windDirectionControl'); + await page.focus('#agate-windDirectionControl'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowUp'); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowUp'); + await page.keyboard.down('ArrowDown'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowDown'); + await page.keyboard.down('ArrowDown'); + await new Promise(r => setTimeout(r, 100)); + await page.keyboard.up('ArrowDown'); + + const averageFPS = await getAverageFPS(); + TestResults.addResult({component: component, type: 'FPS Keypress', actualValue: Math.round((averageFPS + Number.EPSILON) * 1000) / 1000}); + + expect(averageFPS).toBeGreaterThan(minFPS); + }); + }); + + it('should have a good FID and CLS', async () => { + await page.evaluateOnNewDocument(FID); + await page.evaluateOnNewDocument(CLS); + await page.goto(`http://${serverAddr}/windDirectionControl`); + await page.waitForSelector('#agate-windDirectionControl'); + await page.focus('#agate-windDirectionControl'); + await page.keyboard.down('ArrowUp'); + await new Promise(r => setTimeout(r, 200)); + + let actualFirstInput = await firstInputValue(); + let actualCLS = await clsValue(); + + TestResults.addResult({component: component, type: 'FID', actualValue: Math.round((actualFirstInput + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'CLS', actualValue: Math.round((actualCLS + Number.EPSILON) * 1000) / 1000}); + + expect(actualFirstInput).toBeLessThan(maxFID); + expect(actualCLS).toBeLessThan(maxCLS); + }); + + it('should have a good DCL, FCP and LCP', async () => { + const filename = getFileName(component); + + let passContDCL = 0; + let passContFCP = 0; + let passContLCP = 0; + let avgDCL = 0; + let avgFCP = 0; + let avgLCP = 0; + for (let step = 0; step < stepNumber; step++) { + const windDirectionControlPage = targetEnv === 'TV' ? page : await newPageMultiple(); + await windDirectionControlPage.emulateCPUThrottling(CPUThrottling); + + await windDirectionControlPage.tracing.start({path: filename, screenshots: false}); + await windDirectionControlPage.goto(`http://${serverAddr}/windDirectionControl`); + await windDirectionControlPage.waitForSelector('#agate-windDirectionControl'); + await new Promise(r => setTimeout(r, 200)); + + await windDirectionControlPage.tracing.stop(); + + const {actualDCL, actualFCP, actualLCP} = PageLoadingMetrics(filename); + avgDCL = avgDCL + actualDCL; + if (actualDCL < maxDCL) { + passContDCL += 1; + } + + avgFCP = avgFCP + actualFCP; + if (actualFCP < maxFCP) { + passContFCP += 1; + } + + avgLCP = avgLCP + actualLCP; + if (actualLCP < maxLCP) { + passContLCP += 1; + } + + if (targetEnv === 'PC') await windDirectionControlPage.close(); + } + avgDCL = avgDCL / stepNumber; + avgFCP = avgFCP / stepNumber; + avgLCP = avgLCP / stepNumber; + + TestResults.addResult({component: component, type: 'DCL', actualValue: Math.round((avgDCL + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'FCP', actualValue: Math.round((avgFCP + Number.EPSILON) * 1000) / 1000}); + TestResults.addResult({component: component, type: 'LCP', actualValue: Math.round((avgLCP + Number.EPSILON) * 1000) / 1000}); + + expect(passContDCL).toBeGreaterThan(passRatio * stepNumber); + expect(avgDCL).toBeLessThan(maxDCL); + + expect(passContFCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgFCP).toBeLessThan(maxFCP); + + expect(passContLCP).toBeGreaterThan(passRatio * stepNumber); + expect(avgLCP).toBeLessThan(maxLCP); + }); +}); + diff --git a/src/App/Agate-App.js b/src/App/Agate-App.js index 9ff740fe..9f72f340 100644 --- a/src/App/Agate-App.js +++ b/src/App/Agate-App.js @@ -1,8 +1,51 @@ import kind from '@enact/core/kind'; import ThemeDecorator from '@enact/agate/ThemeDecorator'; +import ArcPicker from '../views/agate/ArcPicker'; +import ArcSlider from '../views/agate/ArcSlider'; +import BodyText from '../views/agate/BodyText'; import Button from '../views/agate/Button'; import Checkbox from '../views/agate/Checkbox'; +import CheckboxItem from '../views/agate/CheckboxItem'; +import ColorPicker from '../views/agate/ColorPicker'; +import ContextualPopupDecorator from '../views/agate/ContextualPopupDecorator'; +import DatePicker from '../views/agate/DatePicker'; +import DateTimePicker from '../views/agate/DateTimePicker'; +import Drawer from '../views/agate/Drawer'; +import Dropdown from '../views/agate/Dropdown'; +import FanSpeedControl from "../views/agate/FanSpeedControl"; +import Header from "../views/agate/Header"; +import Heading from "../views/agate/Heading"; +import Icon from "../views/agate/Icon"; +import Image from "../views/agate/Image"; +import ImageItem from "../views/agate/ImageItem"; +import IncrementSlider from '../views/agate/IncrementSlider'; +import Input from '../views/agate/Input'; +import Item from '../views/agate/Item'; +import Keypad from '../views/agate/Keypad'; +import LabeledIcon from '../views/agate/LabeledIcon'; +import LabeledIconButton from '../views/agate/LabeledIconButton'; +import Marquee from '../views/agate/Marquee'; +import MediaPlayer from '../views/agate/MediaPlayer'; +import Panels from '../views/agate/Panels'; +import Picker from '../views/agate/Picker'; +import Popup from "../views/agate/Popup"; +import PopupMenu from "../views/agate/PopupMenu"; +import ProgressBar from '../views/agate/ProgressBar'; +import RadioItem from '../views/agate/RadioItem'; +import RangePicker from '../views/agate/RangePicker'; +import Scroller from '../views/agate/Scroller'; +import Slider from '../views/agate/Slider'; +import SliderButton from '../views/agate/SliderButton'; +import SwitchItem from '../views/agate/SwitchItem'; +import TabGroup from '../views/agate/TabGroup'; +import TemperatureControl from '../views/agate/TemperatureControl'; +import TimePicker from '../views/agate/TimePicker'; +import ThumbnailItem from '../views/agate/ThumbnailItem'; +import ToggleButton from '../views/agate/ToggleButton'; +import TooltipDecorator from '../views/agate/TooltipDecorator'; +import VirtualList from '../views/agate/VirtualList'; +import WindDirectionControl from '../views/agate/WindDirectionControl'; import css from './App.less'; @@ -20,8 +63,51 @@ const AgateApp = kind({
+ } /> + } /> + } /> } /> } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } />
diff --git a/src/views/agate/ArcPicker.js b/src/views/agate/ArcPicker.js new file mode 100644 index 00000000..733bb48c --- /dev/null +++ b/src/views/agate/ArcPicker.js @@ -0,0 +1,15 @@ +import ArcPicker from '@enact/agate/ArcPicker'; +import kind from '@enact/core/kind'; + +const ArcPickerView = kind({ + name: 'ArcPickerView', + + render: () => ( + <> + ArcPicker + {[1, 2, 3, 4]} + + ) +}); + +export default ArcPickerView; diff --git a/src/views/agate/ArcSlider.js b/src/views/agate/ArcSlider.js new file mode 100644 index 00000000..dcc01ca9 --- /dev/null +++ b/src/views/agate/ArcSlider.js @@ -0,0 +1,15 @@ +import ArcSlider from '@enact/agate/ArcSlider'; +import kind from '@enact/core/kind'; + +const ArcSliderView = kind({ + name: 'ArcSliderView', + + render: () => ( + <> + ArcSlider + + + ) +}); + +export default ArcSliderView; diff --git a/src/views/agate/BodyText.js b/src/views/agate/BodyText.js new file mode 100644 index 00000000..44723a7e --- /dev/null +++ b/src/views/agate/BodyText.js @@ -0,0 +1,14 @@ +import BodyText from '@enact/agate/BodyText'; +import kind from '@enact/core/kind'; + +const BodyTextView = kind({ + name: 'BodyTextView', + + render: () => ( + + This is a text on the screen! + + ) +}); + +export default BodyTextView; diff --git a/src/views/agate/CheckboxItem.js b/src/views/agate/CheckboxItem.js new file mode 100644 index 00000000..6dd54cc1 --- /dev/null +++ b/src/views/agate/CheckboxItem.js @@ -0,0 +1,12 @@ +import CheckboxItem from '@enact/agate/CheckboxItem'; +import kind from '@enact/core/kind'; + +const CheckboxItemView = kind({ + name: 'CheckboxItemView', + + render: () => ( + Checkbox Item + ) +}); + +export default CheckboxItemView; diff --git a/src/views/agate/ColorPicker.js b/src/views/agate/ColorPicker.js new file mode 100644 index 00000000..8e92b1ec --- /dev/null +++ b/src/views/agate/ColorPicker.js @@ -0,0 +1,16 @@ +import ColorPicker from '@enact/agate/ColorPicker'; +import kind from '@enact/core/kind'; + +const colors = ['green', 'yellow', 'orange', 'red', 'black', 'gray', 'white', '#cc5500', 'maroon', 'brown']; + +const isOpen = window.location.search.startsWith("?open"); + +const ColorPickerView = kind({ + name: 'ColorPickerView', + + render: () => ( + {colors} + ) +}); + +export default ColorPickerView; diff --git a/src/views/agate/ContextualPopupDecorator.js b/src/views/agate/ContextualPopupDecorator.js new file mode 100644 index 00000000..2a2febb9 --- /dev/null +++ b/src/views/agate/ContextualPopupDecorator.js @@ -0,0 +1,17 @@ +import kind from '@enact/core/kind'; +import Button from '@enact/agate/Button'; +import ContextualPopupDecorator from '@enact/agate/ContextualPopupDecorator'; + +const ContextualPopupButton = ContextualPopupDecorator(Button); + +const popup = () =>

Popup

; + +const ContextualPopupDecoratorView = kind({ + name: 'ContextualPopupDecoratorView', + + render: () => ( + Button + ) +}); + +export default ContextualPopupDecoratorView; diff --git a/src/views/agate/DatePicker.js b/src/views/agate/DatePicker.js new file mode 100644 index 00000000..606a9590 --- /dev/null +++ b/src/views/agate/DatePicker.js @@ -0,0 +1,12 @@ +import DatePicker from '@enact/agate/DatePicker'; +import kind from '@enact/core/kind'; + +const DatePickerView = kind({ + name: 'DatePickerView', + + render: () => ( + + ) +}); + +export default DatePickerView; diff --git a/src/views/agate/DateTimePicker.js b/src/views/agate/DateTimePicker.js new file mode 100644 index 00000000..6ee6ed53 --- /dev/null +++ b/src/views/agate/DateTimePicker.js @@ -0,0 +1,12 @@ +import DateTimePicker from '@enact/agate/DateTimePicker'; +import kind from '@enact/core/kind'; + +const DateTimePickerView = kind({ + name: 'DateTimePickerView', + + render: () => ( + + ) +}); + +export default DateTimePickerView; diff --git a/src/views/agate/Drawer.js b/src/views/agate/Drawer.js new file mode 100644 index 00000000..20e3266d --- /dev/null +++ b/src/views/agate/Drawer.js @@ -0,0 +1,23 @@ +import Button from '@enact/agate/Button'; +import Drawer from '@enact/agate/Drawer'; +import {useCallback, useState} from "react"; + +const DrawerView = () => { + const [open, setOpen] = useState(true); + + const handleToggle = useCallback(() => { + setOpen(!open); + }, [open]); + + return ( + <> + + + Drawer + + + + ); +}; + +export default DrawerView; diff --git a/src/views/agate/Dropdown.js b/src/views/agate/Dropdown.js new file mode 100644 index 00000000..aed61a94 --- /dev/null +++ b/src/views/agate/Dropdown.js @@ -0,0 +1,22 @@ +import Dropdown from '@enact/agate/Dropdown'; +import kind from '@enact/core/kind'; + +const items = [ + 'Option 1', + 'Option 2', + 'Option 3', + 'Option 4', + 'Option 5' +]; + +const DropdownView = kind({ + name: 'DropdownView', + + render: () => ( + + {items} + + ) +}); + +export default DropdownView; diff --git a/src/views/agate/FanSpeedControl.js b/src/views/agate/FanSpeedControl.js new file mode 100644 index 00000000..0b0c683d --- /dev/null +++ b/src/views/agate/FanSpeedControl.js @@ -0,0 +1,14 @@ +import FanSpeedControl from '@enact/agate/FanSpeedControl'; +import kind from '@enact/core/kind'; + +const FanSpeedControlView = kind({ + name: 'FanSpeedControlView', + + render: () => ( + + ) +}); + +export default FanSpeedControlView; diff --git a/src/views/agate/Header.js b/src/views/agate/Header.js new file mode 100644 index 00000000..81bd4086 --- /dev/null +++ b/src/views/agate/Header.js @@ -0,0 +1,15 @@ +import Button from '@enact/agate/Button'; +import Header from '@enact/agate/Header'; +import kind from '@enact/core/kind'; + +const HeaderView = kind({ + name: 'HeaderView', + + render: () => ( + + ) +}); + +export default HeaderView; diff --git a/src/views/agate/Heading.js b/src/views/agate/Heading.js new file mode 100644 index 00000000..24cd96a8 --- /dev/null +++ b/src/views/agate/Heading.js @@ -0,0 +1,14 @@ +import Heading from '@enact/agate/Heading'; +import kind from '@enact/core/kind'; + +const HeadingView = kind({ + name: 'HeadingView', + + render: () => ( + + This is a heading! + + ) +}); + +export default HeadingView; diff --git a/src/views/agate/Icon.js b/src/views/agate/Icon.js new file mode 100644 index 00000000..6d323c59 --- /dev/null +++ b/src/views/agate/Icon.js @@ -0,0 +1,15 @@ +import Icon from '@enact/agate/Icon'; +import kind from '@enact/core/kind'; + +const IconView = kind({ + name: 'IconView', + + render: () => ( + <> +
Icon
+ plus + + ) +}); + +export default IconView; diff --git a/src/views/agate/Image.js b/src/views/agate/Image.js new file mode 100644 index 00000000..f4674ae3 --- /dev/null +++ b/src/views/agate/Image.js @@ -0,0 +1,15 @@ +import Image from '@enact/agate/Image'; +import kind from '@enact/core/kind'; + +const ImageView = kind({ + name: 'ImageView', + + render: () => ( + <> +

Image

+ + + ) +}); + +export default ImageView; diff --git a/src/views/agate/ImageItem.js b/src/views/agate/ImageItem.js new file mode 100644 index 00000000..f2feed3e --- /dev/null +++ b/src/views/agate/ImageItem.js @@ -0,0 +1,19 @@ +import ImageItem from '@enact/agate/ImageItem'; +import kind from '@enact/core/kind'; +import ri from '@enact/ui/resolution'; + +const ImageItemView = kind({ + name: 'ImageItemView', + + render: () => ( + + Image Item caption + + ) +}); + +export default ImageItemView; diff --git a/src/views/agate/IncrementSlider.js b/src/views/agate/IncrementSlider.js new file mode 100644 index 00000000..5d604b78 --- /dev/null +++ b/src/views/agate/IncrementSlider.js @@ -0,0 +1,15 @@ +import IncrementSlider from '@enact/agate/IncrementSlider'; +import kind from '@enact/core/kind'; + +const IncrementSliderView = kind({ + name: 'IncrementSliderView', + + render: () => ( + <> + IncrementSlider + + + ) +}); + +export default IncrementSliderView; diff --git a/src/views/agate/Input.js b/src/views/agate/Input.js new file mode 100644 index 00000000..96fdd85c --- /dev/null +++ b/src/views/agate/Input.js @@ -0,0 +1,15 @@ +import Input from '@enact/agate/Input'; +import kind from '@enact/core/kind'; + +const InputView = kind({ + name: 'InputView', + + render: () => ( + + ) +}); + +export default InputView; diff --git a/src/views/agate/Item.js b/src/views/agate/Item.js new file mode 100644 index 00000000..694a49c1 --- /dev/null +++ b/src/views/agate/Item.js @@ -0,0 +1,14 @@ +import Item from '@enact/agate/Item'; +import kind from '@enact/core/kind'; + +const ItemView = kind({ + name: 'ItemView', + + render: () => ( + + Hello Item + + ) +}); + +export default ItemView; diff --git a/src/views/agate/Keypad.js b/src/views/agate/Keypad.js new file mode 100644 index 00000000..97687173 --- /dev/null +++ b/src/views/agate/Keypad.js @@ -0,0 +1,12 @@ +import Keypad from '@enact/agate/Keypad'; +import kind from '@enact/core/kind'; + +const KeypadView = kind({ + name: 'KeypadView', + + render: () => ( + + ) +}); + +export default KeypadView; diff --git a/src/views/agate/LabeledIcon.js b/src/views/agate/LabeledIcon.js new file mode 100644 index 00000000..6f64a580 --- /dev/null +++ b/src/views/agate/LabeledIcon.js @@ -0,0 +1,17 @@ +import LabeledIcon from '@enact/agate/LabeledIcon'; +import kind from '@enact/core/kind'; + +const LabeledIconView = kind({ + name: 'LabeledIconView', + + render: () => ( + + LabeledIcon + + ) +}); + +export default LabeledIconView; diff --git a/src/views/agate/LabeledIconButton.js b/src/views/agate/LabeledIconButton.js new file mode 100644 index 00000000..0433994e --- /dev/null +++ b/src/views/agate/LabeledIconButton.js @@ -0,0 +1,17 @@ +import LabeledIconButton from '@enact/agate/LabeledIconButton'; +import kind from '@enact/core/kind'; + +const LabeledIconButtonView = kind({ + name: 'LabeledIconButtonView', + + render: () => ( + + LabeledIconButton + + ) +}); + +export default LabeledIconButtonView; diff --git a/src/views/agate/Marquee.js b/src/views/agate/Marquee.js new file mode 100644 index 00000000..9f126f5f --- /dev/null +++ b/src/views/agate/Marquee.js @@ -0,0 +1,17 @@ +import Marquee from '@enact/agate/Marquee'; +import kind from '@enact/core/kind'; + +const MarqueeView = kind({ + name: 'MarqueeView', + + render: () => ( + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + + ) +}); + +export default MarqueeView; diff --git a/src/views/agate/MediaPlayer.js b/src/views/agate/MediaPlayer.js new file mode 100644 index 00000000..38f0481b --- /dev/null +++ b/src/views/agate/MediaPlayer.js @@ -0,0 +1,25 @@ +import MediaPlayer from '@enact/agate/MediaPlayer'; +import kind from '@enact/core/kind'; + +const audioFiles = [ + 'https://sampleswap.org/mp3/artist/254731/BossPlayer_Your-Right-Here-160.mp3', + 'https://sampleswap.org/mp3/artist/78152/HiatusManJBanner_Show-Stopper-160.mp3', + 'https://sampleswap.org/mp3/artist/47067/DJ-Masque_Oceanic-Dawn-160.mp3', + 'https://sampleswap.org/mp3/artist/26546/benzoul_lovevoodoo-160.mp3', + 'https://sampleswap.org/mp3/artist/19139/MarkNine_In-my-Place-160.mp3', + 'https://sampleswap.org/mp3/artist/47067/DJ-Masque_Dont-Forget-To-Be-Yourself-160.mp3' +]; + +const MediaPlayerView = kind({ + name: 'MediaPlayerView', + + render: () => ( + + { + audioFiles.map((audioFile, index) => ()) + } + + ) +}); + +export default MediaPlayerView; diff --git a/src/views/agate/Panels.js b/src/views/agate/Panels.js new file mode 100644 index 00000000..0ad2ce8f --- /dev/null +++ b/src/views/agate/Panels.js @@ -0,0 +1,70 @@ +import Button from '@enact/agate/Button'; +import Header from '@enact/agate/Header'; +import Item from '@enact/agate/Item'; +import {Panel, Panels} from '@enact/agate/Panels'; +import TabGroup from '@enact/agate/TabGroup'; +import {useCallback, useState} from 'react'; + +const PanelsView = () => { + const [index, setPanelIndex] = useState(0); + + const handleClick = useCallback(() => { + return index === 0 ? setPanelIndex(1) : setPanelIndex(0); + }, [index]); + + return ( + + +
+
+ + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt + ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation + ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur + sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id + est laborum. + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt + ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation + ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur + sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id + est laborum. + +
+ +
+
+ +
+
+ ); +}; + +export default PanelsView; diff --git a/src/views/agate/Picker.js b/src/views/agate/Picker.js new file mode 100644 index 00000000..faca776c --- /dev/null +++ b/src/views/agate/Picker.js @@ -0,0 +1,19 @@ +import Picker from '@enact/agate/Picker'; +import kind from '@enact/core/kind'; + +const pickerList = [ + 'Apple', + 'Banana', + 'Clementine', + 'Durian' +]; + +const PickerView = kind({ + name: 'PickerView', + + render: () => ( + {pickerList} + ) +}); + +export default PickerView; diff --git a/src/views/agate/Popup.js b/src/views/agate/Popup.js new file mode 100644 index 00000000..d7b3da64 --- /dev/null +++ b/src/views/agate/Popup.js @@ -0,0 +1,22 @@ +import Button from '@enact/agate/Button'; +import Popup from '@enact/agate/Popup'; +import {useCallback, useState} from 'react'; + +const PopupView = () => { + const [open, setOpen] = useState(true); + + const handleToggle = useCallback(() => { + setOpen(!open); + }, [open]); + + return ( + <> + + + + + + ); +}; + +export default PopupView; diff --git a/src/views/agate/PopupMenu.js b/src/views/agate/PopupMenu.js new file mode 100644 index 00000000..d5f0216f --- /dev/null +++ b/src/views/agate/PopupMenu.js @@ -0,0 +1,26 @@ +import Button from '@enact/agate/Button'; +import PopupMenu from '@enact/agate/PopupMenu'; +import {useCallback, useState} from 'react'; + +const PopupMenuView = () => { + const [open, setOpen] = useState(true); + + const handleToggle = useCallback(() => { + setOpen(!open); + }, [open]); + + return ( + <> + + + + + + ); +}; + +export default PopupMenuView; diff --git a/src/views/agate/ProgressBar.js b/src/views/agate/ProgressBar.js new file mode 100644 index 00000000..b7f1f6a7 --- /dev/null +++ b/src/views/agate/ProgressBar.js @@ -0,0 +1,15 @@ +import ProgressBar from '@enact/agate/ProgressBar'; +import kind from '@enact/core/kind'; + +const ProgressBarView = kind({ + name: 'ProgressBar', + + render: () => ( + <> +
+ + + ) +}); + +export default ProgressBarView; diff --git a/src/views/agate/RadioItem.js b/src/views/agate/RadioItem.js new file mode 100644 index 00000000..7a67a500 --- /dev/null +++ b/src/views/agate/RadioItem.js @@ -0,0 +1,14 @@ +import RadioItem from '@enact/agate/RadioItem'; +import kind from '@enact/core/kind'; + +const RadioItemView = kind({ + name: 'RadioItemView', + + render: () => ( + + Hello RadioItem + + ) +}); + +export default RadioItemView; diff --git a/src/views/agate/RangePicker.js b/src/views/agate/RangePicker.js new file mode 100644 index 00000000..bbece891 --- /dev/null +++ b/src/views/agate/RangePicker.js @@ -0,0 +1,18 @@ +import RangePicker from '@enact/agate/RangePicker'; +import kind from '@enact/core/kind'; + +const RangePickerView = kind({ + name: 'RangePickerView', + + render: () => ( + + ) +}); + +export default RangePickerView; diff --git a/src/views/agate/Scroller.js b/src/views/agate/Scroller.js new file mode 100644 index 00000000..ef635497 --- /dev/null +++ b/src/views/agate/Scroller.js @@ -0,0 +1,18 @@ +import Scroller from '@enact/agate/Scroller'; +import kind from '@enact/core/kind'; + +const ScrollerView = kind({ + name: 'ScrollerView', + + render: () => ( +
+ +
+ Content +
+
+
+ ) +}); + +export default ScrollerView; diff --git a/src/views/agate/Slider.js b/src/views/agate/Slider.js new file mode 100644 index 00000000..ed8a4663 --- /dev/null +++ b/src/views/agate/Slider.js @@ -0,0 +1,15 @@ +import Slider from '@enact/agate/Slider'; +import kind from '@enact/core/kind'; + +const SliderView = kind({ + name: 'SliderView', + + render: () => ( + <> + Slider + + + ) +}); + +export default SliderView; diff --git a/src/views/agate/SliderButton.js b/src/views/agate/SliderButton.js new file mode 100644 index 00000000..1a23060e --- /dev/null +++ b/src/views/agate/SliderButton.js @@ -0,0 +1,18 @@ +import SliderButton from '@enact/agate/SliderButton'; +import kind from '@enact/core/kind'; + +const threeItems = ['Light Speed', 'Ridiculous Speed', 'Ludicrous Speed']; + +const SliderButtonView = kind({ + name: 'SliderButtonView', + + render: () => ( + + {threeItems} + + ) +}); + +export default SliderButtonView; diff --git a/src/views/agate/SwitchItem.js b/src/views/agate/SwitchItem.js new file mode 100644 index 00000000..d63135c1 --- /dev/null +++ b/src/views/agate/SwitchItem.js @@ -0,0 +1,14 @@ +import SwitchItem from '@enact/agate/SwitchItem'; +import kind from '@enact/core/kind'; + +const SwitchItemView = kind({ + name: 'SwitchItemView', + + render: () => ( + + Hello SwitchItem + + ) +}); + +export default SwitchItemView; diff --git a/src/views/agate/TabGroup.js b/src/views/agate/TabGroup.js new file mode 100644 index 00000000..6bd3af1a --- /dev/null +++ b/src/views/agate/TabGroup.js @@ -0,0 +1,20 @@ +import TabGroup from '@enact/agate/TabGroup'; +import kind from '@enact/core/kind'; + +const TabGroupView = kind({ + name: 'TabGroupView', + + render: () => ( + + ) +}); + +export default TabGroupView; diff --git a/src/views/agate/TemperatureControl.js b/src/views/agate/TemperatureControl.js new file mode 100644 index 00000000..3ffa37e0 --- /dev/null +++ b/src/views/agate/TemperatureControl.js @@ -0,0 +1,12 @@ +import TemperatureControl from '@enact/agate/TemperatureControl'; +import kind from '@enact/core/kind'; + +const TemperatureControlView = kind({ + name: 'TemperatureControlView', + + render: () => ( + + ) +}); + +export default TemperatureControlView; diff --git a/src/views/agate/ThumbnailItem.js b/src/views/agate/ThumbnailItem.js new file mode 100644 index 00000000..a63212be --- /dev/null +++ b/src/views/agate/ThumbnailItem.js @@ -0,0 +1,17 @@ +import ThumbnailItem from '@enact/agate/ThumbnailItem'; +import kind from '@enact/core/kind'; + +const ThumbnailItemView = kind({ + name: 'ThumbnailItemView', + + render: () => ( + + Thumbnail Item default + + ) +}); + +export default ThumbnailItemView; diff --git a/src/views/agate/TimePicker.js b/src/views/agate/TimePicker.js new file mode 100644 index 00000000..a62b6581 --- /dev/null +++ b/src/views/agate/TimePicker.js @@ -0,0 +1,12 @@ +import TimePicker from '@enact/agate/TimePicker'; +import kind from '@enact/core/kind'; + +const TimePickerView = kind({ + name: 'TimePickerView', + + render: () => ( + + ) +}); + +export default TimePickerView; diff --git a/src/views/agate/ToggleButton.js b/src/views/agate/ToggleButton.js new file mode 100644 index 00000000..9c5db051 --- /dev/null +++ b/src/views/agate/ToggleButton.js @@ -0,0 +1,16 @@ +import ToggleButton from '@enact/agate/ToggleButton'; +import kind from '@enact/core/kind'; + +const ToggleButtonView = kind({ + name: 'ToggleButtonView', + + render: () => ( + + ) +}); + +export default ToggleButtonView; diff --git a/src/views/agate/TooltipDecorator.js b/src/views/agate/TooltipDecorator.js new file mode 100644 index 00000000..c3739692 --- /dev/null +++ b/src/views/agate/TooltipDecorator.js @@ -0,0 +1,20 @@ +import Button from '@enact/agate/Button'; +import TooltipDecorator from '@enact/agate/TooltipDecorator'; +import kind from '@enact/core/kind'; + +const TooltipButton = TooltipDecorator({tooltipDestinationProp: 'decoration'}, Button); + +const TooltipDecoratorView = kind({ + name: 'TooltipDecoratorView', + + render: () => ( + + Click me + + ) +}); + +export default TooltipDecoratorView; diff --git a/src/views/agate/VirtualList.js b/src/views/agate/VirtualList.js new file mode 100644 index 00000000..ff82c861 --- /dev/null +++ b/src/views/agate/VirtualList.js @@ -0,0 +1,64 @@ +import Item from '@enact/agate/Item'; +import VirtualList from '@enact/agate/VirtualList'; +import kind from '@enact/core/kind'; +import PropTypes from 'prop-types'; + +const items = []; +const itemSize = 93; +const url = new URL(window.location.href); + +const populateItemsArray = (dataSize) => { + for (let i = 0; i < dataSize; i++) { + items.push({item: 'Item ' + ('00' + i).slice(-3)}); + } +}; + +// eslint-disable-next-line enact/prop-types +const renderItem = ({index, ...rest}) => { + return ( + + {items[index].item} + + ); +}; + + +const VirtualListView = kind({ + name: 'VirtualListView', + + propTypes: { + /** + * Number of items in the VirtualList + */ + dataSize: PropTypes.number + }, + + defaultProps: { + dataSize: 100 + }, + + render: ({dataSize}) => { + let dataSizeProp = dataSize; + const urlDataSize = parseInt(url.searchParams.get('dataSize')); + + if (!isNaN(urlDataSize)) { + dataSizeProp = parseInt(urlDataSize); + } + + populateItemsArray(dataSizeProp); + + return ( +
+ +
+ ); + } +}); + +export default VirtualListView; diff --git a/src/views/agate/WindDirectionControl.js b/src/views/agate/WindDirectionControl.js new file mode 100644 index 00000000..2be08a50 --- /dev/null +++ b/src/views/agate/WindDirectionControl.js @@ -0,0 +1,14 @@ +import WindDirectionControl from '@enact/agate/WindDirectionControl'; +import kind from '@enact/core/kind'; + +const WindDirectionControlView = kind({ + name: 'WindDirectionControlView', + + render: () => ( + + ) +}); + +export default WindDirectionControlView;