Skip to content

Commit

Permalink
Sync develop and master branch (#99)
Browse files Browse the repository at this point in the history
* WRQ-8596: Adapt performanceMetrics app for Agate performance tests (#81)

* added performance tests for agate components

* code review fixes

* Adapted performanceMetrics app for Agate test results

* code review fixes

* fixed urls for performanceMetrics

* WRQ-11737: Added performance tests for agate overall view + fixes for other tests (#82)

* avoided unnecessary api call when the theme library is changed in poerformanceMetrics

* Added overallView for Agate
Fixed lint warnings for latest enact/cli
Fixed placeholder images link

* Added tests for agate/overallview
Solved lint warnings

* modified marquee test in order to fix the tests on jenkins

* revert for marquee test

* fix for marquee test

* fix for sandstone/marquee test

* fixed tests for agate/Slider, agate/IncrementSlider, sandstone/Slider and sandstone/Panels

* fixed tests for agate/Panels

* code review fixes

* WRQ-14123: Fixed performanceMetrics when same component is selected once more. Fixed tests where results were saved in the wrong file (#83)

* fixed performanceMetrics when same component is selected once more.
Fixed tests where the tests results were saved in the wrong file

* Fixed performance tests where the metric name was incorrect

* Added missing component options in performance metrics dropdown

* WRQ-16517: Updated dependencies to fix critical vulnerabilities (#84)

* updated dependencies to fix vulnerabilities

* fixed quickguidepanel test view

* WRQ-18593: Changed chart configuration to show all labels and lines (#86)

* updated configuration for chart xAxis

* reverted chart width

* changed xAxis interval and chart size

* fix enact link on sandstone (#87)

* Fix QuickGuidePanel import statement to Panel (#88)

Enact-DCO-1.0-Signed-off-by: Juwon Jeong ([email protected])

* WRQ-25865: Updated package dependencies to fix security vulnerabilities (#93)

* Update package dependencies to fix security vulnerabilities

* Updated `react-router-dom` dependency

* WRQ-31596: Fix Critical and High vulnerabilities in agate (#94)

* updated package-lock

* fixed package-lock

* updated package.json

---------

Co-authored-by: Daniel Stoian <[email protected]>

* WRR-1078: Added tests for INP web vital (#92)

* added support for reading interaction to next paint

* Added inp performance tests

* added performance tests for Agate ArcPicker --> IncrementSlider

* Added INP performance tests for agate components

* Added INP Metric for Performance Metrics charts

* import order fix

* removed commented code

* updated readme

* refactored inp tests to download webvitals library instead of using local code

* lint fixes

* adjustments for sandstone inp tests

* adjustments for agate inp tests

* reverse for commented tests

* adjustments for sandstone inp tests

* adjustments for agate inp tests

* adjustments for sandstone inp tests

* adjustments for sandstone inp tests

* adjustments for agate inp tests

* moved url of web vitals library to a global variable

* minor fixes

* updated views and tests for contextualpopup in order to support INP metric. fixed eslint warnings

* pinned web-vitals version

* WRR-2951: Removed tests for FID web-vital (#96)

* Removed tests for FID web-vital

* minor fixes

* WRR-626: Updated puppeteer and wait-on dependencies to latest version (#97)

* upgraded puppeteer to v22

* updated puppeteer to latest version

* updated wait-on to latest version

* Update jsdom-extended.js

* changed ws dependency to 7.5.10

---------

Co-authored-by: adrian-cocoara-lgp <[email protected]>
Co-authored-by: Juwon Jeong <[email protected]>
Co-authored-by: ion-andrusciac-lgp <[email protected]>
Co-authored-by: paul-beldean-lgp <[email protected]>
  • Loading branch information
5 people authored Oct 16, 2024
1 parent d337869 commit 1feea49
Show file tree
Hide file tree
Showing 83 changed files with 3,715 additions and 1,114 deletions.
54 changes: 40 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ To get LCP we use the `PageLoadingMetrics` function from `TraceModel`.
Frames per second (FPS) measures video quality (how many images are displayed consecutively each second). We use it to measure component animation performance.
FPS is read using the performance.now() method and Window.requestAnimationFrame() for the entire life span of the page. Just before the page is closed the average FPS is calculated.

### FID
### INP

First Input Delay (FID) measures "the time from when a user first interacts with a page (i.e. when they click a link, tap on a button, or use a custom, JavaScript-powered control) to the time when the browser is actually able to begin processing event handlers in response to that interaction" (see https://web.dev/fid/).
FID is calculated using the PerformanceObserver interface. Its observer() method specifies the set of entry types to observe (in this case first-input). The performance observer's callback function will be invoked when a performance entry is recorded for one of the specified entryTypes.
Interaction to Next Paint (INP) is a web performance metric that measures how quickly a website updates or shows changes after a user interacts with it. It specifically captures the delay between when a user interacts with your site—like clicking a link, pressing a key on the keyboard, or tapping a button—and when they see a visual response (see https://web.dev/articles/inp).
INP is calculated from the onINP() webVitals function. It logs the INP value in the console and we are monitoring the console in order to read the actual value.

### CLS

Expand All @@ -109,7 +109,8 @@ CLS is calculated using the PerformanceObserver interface. Its observer() method
### Example

Each component is tested repeatedly for both `click` and `keypress` events to measure average FPS.
FID and CLS are tested in the same test because they both typically require interactions. We can check the React Devtools to see which component is at the top of a specific component.
CLS is tested separately because requires interactions. We can check the React Devtools to see which component is at the top of a specific component.
CLS is tested separately because it is read from using the `web-vitals` library.
DCL, FCP and LCP are also tested together as they are measured at page load time.

Results can be found in `testResults` folder.
Expand All @@ -119,15 +120,15 @@ Test results are compared to the optimum values which are stored in global varia
**Metrics threshholds:**
- global.maxCLS = 0.1;
- global.maxDCL = 2000;
- global.maxFCP = 1800;
- global.maxFID = 100;
- global.maxFCP = 1800;
- global.maxINP = 200;
- global.minFPS = 20;
- global.maxLCP = 2500;

```javascript
const TestResults = require('../TestResults');
const {CLS, FID, FPS, getAverageFPS, PageLoadingMetrics} = require('../TraceModel');
const {clsValue, firstInputValue, getFileName, newPageMultiple} = require('../utils');
const {CLS, FPS, getAverageFPS, PageLoadingMetrics} = require('../TraceModel');
const {clsValue, getFileName, newPageMultiple} = require('../utils');

describe('Dropdown', () => {
const component = 'Dropdown';
Expand Down Expand Up @@ -186,24 +187,49 @@ describe('Dropdown', () => {
});
});

it('should have a good FID and CLS', async () => {
await page.evaluateOnNewDocument(FID);
it('should have a good CLS', async () => {
await page.evaluateOnNewDocument(CLS);
await page.goto(`http://${serverAddr}/dropdown`);
await page.waitForSelector('#dropdown');
await page.focus('#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 INP', async () => {
await page.goto(`http://${serverAddr}/dropdown`);
await page.addScriptTag({url: webVitalsURL});
await page.waitForSelector('#dropdown');
await page.focus('#dropdown');
await new Promise(r => setTimeout(r, 100));
await page.keyboard.down('Enter');
await new Promise(r => setTimeout(r, 100));

let inpValue;

page.on("console", (msg) => {
inpValue = Number(msg.text());
TestResults.addResult({component: component, type: 'INP', actualValue: Math.round((inpValue + Number.EPSILON) * 1000) / 1000});
expect(inpValue).toBeLessThan(maxINP);
});

await page.evaluateHandle(() => {
webVitals.onINP(function (inp) {
console.log(inp.value); // eslint-disable-line no-console
},
{
reportAllChanges: true
}
);
});
await new Promise(r => setTimeout(r, 1000));
});

it('should have a good DCL, FCP and LCP', async () => {
const filename = getFileName(component);

Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const base = themeEnvArg ? themeEnvArg.split('=')[1] : 'sandstone';

module.exports = {
setupFilesAfterEnv: ['./jest.setup.js', './puppeteer.setup.js'],
testEnvironment: 'jsdom',
testEnvironment: '<rootDir>/jsdom-extended.js',
testMatch: [
'<rootDir>/performance/tests/' + base + '/*.test.js'
]
Expand Down
23 changes: 23 additions & 0 deletions jsdom-extended.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const JSDOMEnvironment = require("jest-environment-jsdom").default; // or import JSDOMEnvironment from 'jest-environment-jsdom' if you are using ESM modules

class JSDOMEnvironmentExtended extends JSDOMEnvironment {
constructor(...args) {
super(...args);

this.global.ReadableStream = ReadableStream;
this.global.TextDecoder = TextDecoder;
this.global.TextEncoder = TextEncoder;

this.global.Blob = Blob;
this.global.Headers = Headers;
this.global.FormData = FormData;
this.global.Request = Request;
this.global.Response = Response;
this.global.Request = Request;
this.global.Response = Response;
this.global.fetch = fetch;
this.global.structuredClone = structuredClone;
}
}

module.exports = JSDOMEnvironmentExtended;
Loading

0 comments on commit 1feea49

Please sign in to comment.