Repository: elastic/synthetics
Pull request #668 (2022-11-29 20:03:08)

chore: fix flaky cache res timing test
+ This fixes the flaky test with the cached resource timing data. Using a CSS resource and also adjusted the page to wait for the response since the old test did not ensure the timing data was available. 

apmmachine: 
## :green_heart: Build Succeeded


<!-- BUILD BADGES-->
> _the below badges are clickable and redirect to their specific view in the CI or DOCS_
[![Pipeline View](https://img.shields.io/badge/pipeline-pipeline%20-green)](https://apm-ci.elastic.co/blue/organizations/jenkins/apm-agent-rum%2Felastic-synthetics%2FPR-668/detail/PR-668/1//pipeline) [![Test View](https://img.shields.io/badge/test-test-green)](https://apm-ci.elastic.co/blue/organizations/jenkins/apm-agent-rum%2Felastic-synthetics%2FPR-668/detail/PR-668/1//tests) [![Changes](https://img.shields.io/badge/changes-changes-green)](https://apm-ci.elastic.co/blue/organizations/jenkins/apm-agent-rum%2Felastic-synthetics%2FPR-668/detail/PR-668/1//changes) [![Artifacts](https://img.shields.io/badge/artifacts-artifacts-yellow)](https://apm-ci.elastic.co/blue/organizations/jenkins/apm-agent-rum%2Felastic-synthetics%2FPR-668/detail/PR-668/1//artifacts) [![preview](https://img.shields.io/badge/docs-preview-yellowgreen)](http://synthetics_668.docs-preview.app.elstc.co/diff)  [![preview](https://img.shields.io/badge/elastic-observability-blue)](https://ci-stats.elastic.co/app/apm/services/apm-ci/transactions/view?rangeFrom=2022-11-29T19:53:22.748Z&rangeTo=2022-11-29T20:13:22.748Z&transactionName=BUILD+apm-agent-rum%2Felastic-synthetics%2FPR-%7Bnumber%7D&transactionType=job&latencyAggregationType=avg&traceId=73efb648ee1cb30d073e70a658761393&transactionId=f1e41d8f6a40154c)

<!-- BUILD SUMMARY-->
<details><summary>Expand to view the summary</summary>
<p>

#### Build stats




* Start Time: 2022-11-29T20:03:22.748+0000


* Duration: 14 min 25 sec




#### Test stats :test_tube:

| Test         | Results                         |
| ------------ | :-----------------------------: |
| Failed       | 0  |
| Passed       | 204  |
| Skipped      | 2 |
| Total        | 206   |


</p>
</details>

<!-- TEST RESULTS IF ANY-->


<!-- STEPS ERRORS IF ANY -->














## :robot: GitHub comments

<details><summary>Expand to view the GitHub comments</summary>
<p>

To re-run your PR in the CI, just comment with:



- `/test` : Re-trigger the build.




</p>
</details>

<!--COMMENT_GENERATED_WITH_ID_comment.id-->

Patch:
diff --git a/src/helpers.ts b/src/helpers.ts
index 4d3f33d..c4d4dfc 100644
--- a/src/helpers.ts
+++ b/src/helpers.ts
@@ -370,3 +370,11 @@ export function removeTrailingSlash(url: string) {
 export function getMonitorManagementURL(url) {
   return removeTrailingSlash(url) + '/app/uptime/manage-monitors/all';
 }
+
+export function getArrayChunks<T>(arr: T[], chunkSize: number): T[][] {
+  const chunks = [];
+  for (let i = 0; i < arr.length; i += chunkSize) {
+    chunks.push(arr.slice(i, i + chunkSize));
+  }
+  return chunks;
+}
diff --git a/src/push/index.ts b/src/push/index.ts
index 18831d6..5e143c7 100644
--- a/src/push/index.ts
+++ b/src/push/index.ts
@@ -45,6 +45,7 @@ import {
   safeNDJSONParse,
   done,
   getMonitorManagementURL,
+  getArrayChunks,
 } from '../helpers';
 import type { PushOptions, ProjectSettings } from '../common_types';
 import { findSyntheticsConfig, readConfig } from '../config';
@@ -61,8 +62,9 @@ export async function push(monitors: Monitor[], options: PushOptions) {
     schemas = await buildMonitorSchema(monitors);
 
     progress(`creating all monitors`);
-    for (const schema of schemas) {
-      await pushMonitors({ schemas: [schema], keepStale: true, options });
+    const chunks = getArrayChunks(schemas, 10);
+    for (const chunk of chunks) {
+      await pushMonitors({ schemas: chunk, keepStale: true, options });
     }
   } else {
     write('');


Test patch:
diff --git a/__tests__/plugins/network.test.ts b/__tests__/plugins/network.test.ts
index fc70543..74f4326 100644
--- a/__tests__/plugins/network.test.ts
+++ b/__tests__/plugins/network.test.ts
@@ -243,39 +243,43 @@ describe('network', () => {
     const driver = await Gatherer.setupDriver({
       wsEndpoint,
     });
-
     const network = new NetworkManager(driver);
     await network.start();
-
     const delayTime = 5;
-    server.route('/test.js', async (req, res) => {
+
+    server.route('/test.css', async (req, res) => {
       res.writeHead(200, {
-        'content-type': 'application/javascript',
-        'cache-control': 'public; max-age=600',
+        'Content-Type': 'text/css',
+        'Cache-Control': 'public, max-age=10000',
       });
       await delay(delayTime + 1);
-      res.end('var a=10');
+      res.end(`body { background: green }`);
     });
     server.route('/index', async (_, res) => {
       res.setHeader('content-type', 'text/html');
-      res.end(`<script src=${server.PREFIX}/test.js />`);
+      res.end(`<link rel="stylesheet" href=${server.PREFIX}/test.css />`);
     });
 
-    await driver.page.goto(server.PREFIX + '/index', {
-      waitUntil: 'networkidle',
-    });
-    await driver.page.reload({ waitUntil: 'networkidle' });
-    await delay(delayTime + 1);
+    await driver.page.goto(server.PREFIX + '/index');
+    const [response] = await Promise.all([
+      driver.page.waitForResponse('**/test.css'),
+      driver.page.reload(),
+    ]);
+    await response.finished();
+
     const netinfo = await network.stop();
     await Gatherer.stop();
     const resources = netinfo.filter(req =>
-      req.url.includes(`${server.PREFIX}/test.js`)
+      req.url.includes(`${server.PREFIX}/test.css`)
     );
     expect(resources.length).toBe(2);
+
+    const [uncached, cached] = resources;
+    expect(uncached.timings.wait).toBeGreaterThan(delayTime);
+    expect(cached.timings.wait).toBeLessThan(delayTime); // served from cache
     resources.forEach(res => {
       const timing = res.timings;
-      expect(timing.wait).toBeGreaterThan(delayTime);
-      expect(timing.total).toBeGreaterThan(timing.wait + timing.receive);
+      expect(timing.total).toBeGreaterThanOrEqual(timing.wait + timing.receive);
       // Check with absolute value to make sure we are not crossing absurd values
       expect(timing.total).toBeLessThan(50);
     });
diff --git a/__tests__/push/__snapshots__/index.test.ts.snap b/__tests__/push/__snapshots__/index.test.ts.snap
index 6cd55d7..727591a 100644
--- a/__tests__/push/__snapshots__/index.test.ts.snap
+++ b/__tests__/push/__snapshots__/index.test.ts.snap
@@ -3,8 +3,8 @@
 exports[`Push API handle streamed response 1`] = `
 "> preparing all monitors
 > creating all monitors
-> journey 1
-> journey 2
+> 2 monitors created successfully
+> journey 2 monitor updated successfully
 > deleting all stale monitors
 ✓ Pushed: http://localhost:54455/stream/app/uptime/manage-monitors/all
 "
diff --git a/__tests__/push/index.test.ts b/__tests__/push/index.test.ts
index 36218ce..85787b6 100644
--- a/__tests__/push/index.test.ts
+++ b/__tests__/push/index.test.ts
@@ -262,7 +262,16 @@ heartbeat.monitors:
           await new Promise(r => setTimeout(r, 20));
           req.on('data', chunks => {
             const schema = JSON.parse(chunks.toString()) as APISchema;
-            res.write(JSON.stringify(schema.monitors[0].name) + '\n');
+            res.write(
+              JSON.stringify(
+                schema.monitors.length + ' monitors created successfully'
+              ) + '\n'
+            );
+            res.write(
+              JSON.stringify(
+                `${schema.monitors[1].name} monitor updated successfully`
+              ) + '\n'
+            );
             if (!schema.keep_stale) {
               // write more than the stream buffer to check the broken NDJSON data
               res.write(