-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Quinn Hanam <hanquinn@amazon.com>
- Loading branch information
Showing
17 changed files
with
1,068 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>RUM Integ Test</title> | ||
<script src="./loader_time_to_interactive_event.js"></script> | ||
<link | ||
rel="icon" | ||
type="image/png" | ||
href="https://awsmedia.s3.amazonaws.com/favicon.ico" | ||
/> | ||
|
||
<script> | ||
// Common to all test pages | ||
function dispatch() { | ||
cwr('dispatch'); | ||
} | ||
|
||
function clearRequestResponse() { | ||
document.getElementById('request_url').innerText = ''; | ||
document.getElementById('request_header').innerText = ''; | ||
document.getElementById('request_body').innerText = ''; | ||
|
||
document.getElementById('response_status').innerText = ''; | ||
document.getElementById('response_header').innerText = ''; | ||
document.getElementById('response_body').innerText = ''; | ||
} | ||
|
||
function disable() { | ||
cwr('disable'); | ||
} | ||
|
||
function enable() { | ||
cwr('enable'); | ||
} | ||
</script> | ||
|
||
<style> | ||
table { | ||
border-collapse: collapse; | ||
margin-top: 10px; | ||
margin-bottom: 10px; | ||
} | ||
|
||
td, | ||
th { | ||
border: 1px solid black; | ||
text-align: left; | ||
padding: 8px; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<p id="welcome">This application is used for RUM integ testing.</p> | ||
|
||
<button id="disable" onclick="disable()">Disable</button> | ||
<button id="enable" onclick="enable()">Enable</button> | ||
<hr /> | ||
<button id="dispatch" onclick="dispatch()">Dispatch</button> | ||
<button id="testButton">Test Button</button> | ||
|
||
<hr /> | ||
<span id="request"></span> | ||
<span id="response"></span> | ||
<table> | ||
<tr> | ||
<td>Request URL</td> | ||
<td id="request_url"></td> | ||
</tr> | ||
<tr> | ||
<td>Request Header</td> | ||
<td id="request_header"></td> | ||
</tr> | ||
<tr> | ||
<td>Request Body</td> | ||
<td id="request_body"></td> | ||
</tr> | ||
</table> | ||
<table> | ||
<tr> | ||
<td>Response Status Code</td> | ||
<td id="response_status"></td> | ||
</tr> | ||
<tr> | ||
<td>Response Header</td> | ||
<td id="response_header"></td> | ||
</tr> | ||
<tr> | ||
<td>Response Body</td> | ||
<td id="response_body"></td> | ||
</tr> | ||
</table> | ||
<img src="blank.png" alt="sample" /> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"$id": "com.amazon.rum.time_to_interactive_event", | ||
"$schema": "https://json-schema.org/draft/2020-12/schema", | ||
"title": "TimeToInteractiveEvent", | ||
"type": "object", | ||
"properties": { | ||
"version": { | ||
"const": "1.0.0", | ||
"type": "string", | ||
"description": "Schema version." | ||
}, | ||
"value": { | ||
"type": "number", | ||
"description": "Time to interactive value" | ||
} | ||
}, | ||
"additionalProperties": false, | ||
"required": ["version", "value"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { loader } from './loader'; | ||
import { showRequestClientBuilder } from '../test-utils/mock-http-handler'; | ||
import { TTIPlugin } from '../plugins/event-plugins/TTIPlugin'; | ||
loader('cwr', 'abc123', '1.0', 'us-west-2', './rum_javascript_telemetry.js', { | ||
dispatchInterval: 0, | ||
metaDataPluginsToLoad: [], | ||
eventPluginsToLoad: [new TTIPlugin()], | ||
telemetries: [], | ||
clientBuilder: showRequestClientBuilder | ||
}); | ||
window.cwr('setAwsCredentials', { | ||
accessKeyId: 'a', | ||
secretAccessKey: 'b', | ||
sessionToken: 'c' | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { TTIMetric, onTTI } from '../../time-to-interactive/TimeToInteractive'; | ||
import { TimeToInteractiveEvent } from '../../events/time-to-interactive-event'; | ||
import { TIME_TO_INTERACTIVE_EVENT_TYPE } from '../utils/constant'; | ||
import { PluginContext } from 'plugins/types'; | ||
import { InternalPlugin } from '../InternalPlugin'; | ||
|
||
export const TTI_EVENT_PLUGIN_ID = 'time-to-interactive'; | ||
|
||
export class TTIPlugin extends InternalPlugin { | ||
protected fpsEnabled; | ||
|
||
constructor(fpsMeasurementEnabled = false) { | ||
super(TTI_EVENT_PLUGIN_ID); | ||
this.fpsEnabled = fpsMeasurementEnabled; | ||
} | ||
|
||
protected context!: PluginContext; | ||
|
||
enable(): void { | ||
/* Nothing to do. */ | ||
} | ||
|
||
disable(): void { | ||
/* Nothing to do. */ | ||
} | ||
|
||
configure(): void { | ||
/* Nothing to do. */ | ||
} | ||
|
||
onload(): void { | ||
onTTI(this.handleTTI, { fpsEnabled: this.fpsEnabled }); | ||
} | ||
|
||
private handleTTI = (metric: TTIMetric): void => { | ||
const ttiEvent: TimeToInteractiveEvent = { | ||
version: '1.0.0', | ||
value: Math.round(metric.value) | ||
}; | ||
this.context.record(TIME_TO_INTERACTIVE_EVENT_TYPE, ttiEvent); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { | ||
STATUS_202, | ||
REQUEST_BODY, | ||
RESPONSE_STATUS | ||
} from '../../../test-utils/integ-test-utils'; | ||
import { Selector } from 'testcafe'; | ||
import { TIME_TO_INTERACTIVE_EVENT_TYPE } from '../../utils/constant'; | ||
|
||
const testButton: Selector = Selector(`#testButton`); | ||
const dispatch: Selector = Selector(`#dispatch`); | ||
|
||
fixture('TTI Plugin').page( | ||
'http://localhost:8080/time_to_interactive_event.html' | ||
); | ||
|
||
test('when TTI is recorded, a TTI event is recorded', async (t: TestController) => { | ||
const browser = t.browser.name; | ||
// Skip firefox, till Firefox supports longtasks | ||
if (browser === 'Firefox') { | ||
return 'Test is skipped'; | ||
} | ||
|
||
await t | ||
.click(testButton) | ||
.wait(100) | ||
.click(dispatch) | ||
.wait(3000) | ||
.click(dispatch) | ||
.expect(RESPONSE_STATUS.textContent) | ||
.eql(STATUS_202.toString()) | ||
.expect(REQUEST_BODY.textContent) | ||
.contains('BatchId'); | ||
|
||
const events = JSON.parse(await REQUEST_BODY.textContent).RumEvents.filter( | ||
(e) => e.type === TIME_TO_INTERACTIVE_EVENT_TYPE | ||
); | ||
await t.expect(events.length).eql(1); | ||
|
||
const ttiEvent = JSON.parse(events[0].details); | ||
|
||
await t.expect(ttiEvent.value).typeOf('number'); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { mockLongTaskPerformanceObserver } from '../../../test-utils/mock-data'; | ||
import { TTIPlugin } from '../TTIPlugin'; | ||
import { context, record } from '../../../test-utils/test-utils'; | ||
import { TIME_TO_INTERACTIVE_EVENT_TYPE } from '../../../plugins/utils/constant'; | ||
|
||
const mockTTIData = { | ||
name: 'TTI', | ||
value: 201.2 | ||
}; | ||
|
||
jest.mock('../../../time-to-interactive/TimeToInteractive', () => { | ||
return { | ||
onTTI: jest.fn().mockImplementation((callback) => { | ||
callback(mockTTIData); | ||
}) | ||
}; | ||
}); | ||
|
||
describe('Time to Interactive - Plugin Tests', () => { | ||
beforeEach(() => { | ||
// setup | ||
mockLongTaskPerformanceObserver(); | ||
record.mockClear(); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
test('When TTI resolves successfully, an event is recorded by plugin', async () => { | ||
const plugin: TTIPlugin = new TTIPlugin(); | ||
|
||
// Run Plugin | ||
plugin.load(context); | ||
|
||
// eslint-disable-next-line @typescript-eslint/unbound-method | ||
await new Promise(process.nextTick); | ||
|
||
// Assert | ||
expect(record).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
test('When TTI resolves successfully, TTI event with resolved value is recorded by plugin', async () => { | ||
const plugin: TTIPlugin = new TTIPlugin(); | ||
|
||
// Run Plugin | ||
plugin.load(context); | ||
|
||
// eslint-disable-next-line @typescript-eslint/unbound-method | ||
await new Promise(process.nextTick); | ||
|
||
// Assert | ||
expect(record).toHaveBeenCalledTimes(1); | ||
expect(record.mock.calls[0][0]).toEqual(TIME_TO_INTERACTIVE_EVENT_TYPE); | ||
expect(record.mock.calls[0][1]).toEqual({ | ||
value: 201, | ||
version: '1.0.0' | ||
}); | ||
}); | ||
test('When TTI with frames per second enabled resolves successfully, TTI event with resolved value is recorded by plugin', async () => { | ||
const plugin: TTIPlugin = new TTIPlugin(true); | ||
|
||
// Run Plugin | ||
plugin.load(context); | ||
|
||
// eslint-disable-next-line @typescript-eslint/unbound-method | ||
await new Promise(process.nextTick); | ||
|
||
// Assert | ||
expect(record).toHaveBeenCalledTimes(1); | ||
expect(record.mock.calls[0][0]).toEqual(TIME_TO_INTERACTIVE_EVENT_TYPE); | ||
expect(record.mock.calls[0][1]).toEqual({ | ||
value: 201, | ||
version: '1.0.0' | ||
}); | ||
}); | ||
test('Disable and enable does not have effect on the plugin behavior', async () => { | ||
const plugin: TTIPlugin = new TTIPlugin(); | ||
|
||
plugin.load(context); | ||
|
||
// eslint-disable-next-line @typescript-eslint/unbound-method | ||
await new Promise(process.nextTick); | ||
plugin.disable(); | ||
plugin.enable(); | ||
|
||
// Assert | ||
expect(record).toHaveBeenCalled(); | ||
}); | ||
|
||
test('Disable does not have effect on the plugin behavior', async () => { | ||
const plugin: TTIPlugin = new TTIPlugin(); | ||
|
||
plugin.load(context); | ||
|
||
// eslint-disable-next-line @typescript-eslint/unbound-method | ||
await new Promise(process.nextTick); | ||
plugin.disable(); | ||
|
||
// Assert | ||
expect(record).toHaveBeenCalled(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.