build-start-rebuild-perf 0.2.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,77 +15,44 @@ concurrency:
15
15
  cancel-in-progress: true
16
16
 
17
17
  jobs:
18
- is-this-a-release:
19
- name: "Is this a release?"
18
+ should-run-release-plan-prepare:
19
+ name: Should we run release-plan prepare?
20
20
  runs-on: ubuntu-latest
21
21
  outputs:
22
- command: ${{ steps.check-release.outputs.command }}
23
-
22
+ should-prepare: ${{ steps.should-prepare.outputs.should-prepare }}
24
23
  steps:
25
- - uses: actions/checkout@v4
24
+ - uses: release-plan/actions/should-prepare-release@v1
26
25
  with:
27
- fetch-depth: 2
28
26
  ref: 'main'
29
- # This will only cause the `is-this-a-release` job to have a "command" of `release`
30
- # when the .release-plan.json file was changed on the last commit.
31
- - id: check-release
32
- run: if git diff --name-only HEAD HEAD~1 | grep -w -q ".release-plan.json"; then echo "command=release"; fi >> $GITHUB_OUTPUT
27
+ id: should-prepare
33
28
 
34
29
  create-prepare-release-pr:
35
30
  name: Create Prepare Release PR
36
31
  runs-on: ubuntu-latest
37
32
  timeout-minutes: 5
38
- needs: is-this-a-release
33
+ needs: should-run-release-plan-prepare
39
34
  permissions:
40
35
  contents: write
41
36
  issues: read
42
37
  pull-requests: write
43
- # only run on push event or workflow dispatch if plan wasn't updated (don't create a release plan when we're releasing)
44
- # only run on labeled event if the PR has already been merged
45
- if: ((github.event_name == 'push' || github.event_name == 'workflow_dispatch') && needs.is-this-a-release.outputs.command != 'release') || (github.event_name == 'pull_request_target' && github.event.pull_request.merged == true)
46
-
38
+ if: needs.should-run-release-plan-prepare.outputs.should-prepare == 'true'
47
39
  steps:
48
- - uses: actions/checkout@v4
49
- # We need to download lots of history so that
50
- # github-changelog can discover what's changed since the last release
40
+ - uses: release-plan/actions/prepare@v1
41
+ name: Run release-plan prepare
51
42
  with:
52
- fetch-depth: 0
53
43
  ref: 'main'
54
- - uses: pnpm/action-setup@v4
55
- - uses: actions/setup-node@v4
56
- with:
57
- node-version: 18
58
- cache: pnpm
59
- - run: pnpm install --frozen-lockfile
60
- - name: "Generate Explanation and Prep Changelogs"
61
- id: explanation
62
- run: |
63
- set +e
64
- pnpm release-plan prepare 2> >(tee -a release-plan-stderr.txt >&2)
65
-
66
- if [ $? -ne 0 ]; then
67
- release_plan_output=$(cat release-plan-stderr.txt)
68
- else
69
- release_plan_output=$(jq .description .release-plan.json -r)
70
- rm release-plan-stderr.txt
71
-
72
- if [ $(jq '.solution | length' .release-plan.json) -eq 1 ]; then
73
- new_version=$(jq -r '.solution[].newVersion' .release-plan.json)
74
- echo "new_version=v$new_version" >> $GITHUB_OUTPUT
75
- fi
76
- fi
77
- echo 'text<<EOF' >> $GITHUB_OUTPUT
78
- echo "$release_plan_output" >> $GITHUB_OUTPUT
79
- echo 'EOF' >> $GITHUB_OUTPUT
80
44
  env:
81
45
  GITHUB_AUTH: ${{ secrets.GITHUB_TOKEN }}
46
+ id: explanation
82
47
 
83
- - uses: peter-evans/create-pull-request@v7
48
+ - uses: peter-evans/create-pull-request@v8
49
+ name: Create Prepare Release PR
84
50
  with:
85
- commit-message: "Prepare Release ${{ steps.explanation.outputs.new_version}} using 'release-plan'"
51
+ commit-message: "Prepare Release ${{ steps.explanation.outputs.new-version}} using 'release-plan'"
86
52
  labels: "internal"
53
+ sign-commits: true
87
54
  branch: release-preview
88
- title: Prepare Release ${{ steps.explanation.outputs.new_version }}
55
+ title: Prepare Release ${{ steps.explanation.outputs.new-version }}
89
56
  body: |
90
57
  This PR is a preview of the release that [release-plan](https://github.com/embroider-build/release-plan) has prepared. To release you should just merge this PR 👍
91
58
 
@@ -22,17 +22,15 @@ jobs:
22
22
  runs-on: ubuntu-latest
23
23
  permissions:
24
24
  contents: write
25
- pull-requests: write
26
25
  id-token: write
27
26
  attestations: write
28
27
 
29
28
  steps:
30
- - uses: actions/checkout@v4
31
- - uses: pnpm/action-setup@v4
32
- - uses: actions/setup-node@v4
29
+ - uses: actions/checkout@v6
30
+ - uses: pnpm/action-setup@v5
31
+ - uses: actions/setup-node@v6
33
32
  with:
34
- node-version: 18
35
- # This creates an .npmrc that reads the NODE_AUTH_TOKEN environment variable
33
+ node-version: 24
36
34
  registry-url: 'https://registry.npmjs.org'
37
35
  cache: pnpm
38
36
  - run: pnpm install --frozen-lockfile
@@ -40,4 +38,3 @@ jobs:
40
38
  run: NPM_CONFIG_PROVENANCE=true pnpm release-plan publish
41
39
  env:
42
40
  GITHUB_AUTH: ${{ secrets.GITHUB_TOKEN }}
43
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -30,4 +30,5 @@ jobs:
30
30
  with:
31
31
  cache: pnpm
32
32
  - run: pnpm i --frozen-lockfile
33
+ - run: pnpm puppeteer browsers install chrome
33
34
  - run: pnpm run test
@@ -1,18 +1,26 @@
1
1
  {
2
2
  "solution": {
3
3
  "build-start-rebuild-perf": {
4
- "impact": "patch",
5
- "oldVersion": "0.2.2",
6
- "newVersion": "0.2.3",
4
+ "impact": "minor",
5
+ "oldVersion": "0.3.0",
6
+ "newVersion": "0.4.0",
7
7
  "tagName": "latest",
8
8
  "constraints": [
9
+ {
10
+ "impact": "minor",
11
+ "reason": "Appears in changelog section :rocket: Enhancement"
12
+ },
13
+ {
14
+ "impact": "patch",
15
+ "reason": "Appears in changelog section :bug: Bug Fix"
16
+ },
9
17
  {
10
18
  "impact": "patch",
11
- "reason": "Appears in changelog section :memo: Documentation"
19
+ "reason": "Appears in changelog section :house: Internal"
12
20
  }
13
21
  ],
14
22
  "pkgJSONPath": "./package.json"
15
23
  }
16
24
  },
17
- "description": "## Release (2025-08-13)\n\n* build-start-rebuild-perf 0.2.3 (patch)\n\n#### :memo: Documentation\n* `build-start-rebuild-perf`\n * [#34](https://github.com/mainmatter/build-start-rebuild-perf/pull/34) Fix typo in README.md ([@KevinBongart](https://github.com/KevinBongart))\n\n#### Committers: 1\n- Kevin Bongart ([@KevinBongart](https://github.com/KevinBongart))\n"
25
+ "description": "## Release (2026-07-13)\n\n* build-start-rebuild-perf 0.4.0 (minor)\n\n#### :rocket: Enhancement\n* `build-start-rebuild-perf`\n * [#53](https://github.com/mainmatter/build-start-rebuild-perf/pull/53) Fix waitForPageToLoad behavior ([@NullVoxPopuli](https://github.com/NullVoxPopuli))\n * [#49](https://github.com/mainmatter/build-start-rebuild-perf/pull/49) Disable thousands separator for clearness ([@BlueCutOfficial](https://github.com/BlueCutOfficial))\n * [#43](https://github.com/mainmatter/build-start-rebuild-perf/pull/43) use standard puppeteer ([@mansona](https://github.com/mansona))\n\n#### :bug: Bug Fix\n* `build-start-rebuild-perf`\n * [#54](https://github.com/mainmatter/build-start-rebuild-perf/pull/54) Upgrade puppeteer so that tests pass ([@NullVoxPopuli](https://github.com/NullVoxPopuli))\n\n#### :house: Internal\n* `build-start-rebuild-perf`\n * [#66](https://github.com/mainmatter/build-start-rebuild-perf/pull/66) chore: update release-plan ([@BobrImperator](https://github.com/BobrImperator))\n * [#57](https://github.com/mainmatter/build-start-rebuild-perf/pull/57) stop running renovate on unpublished test app ([@mansona](https://github.com/mansona))\n * [#55](https://github.com/mainmatter/build-start-rebuild-perf/pull/55) make package.json licence match project licence ([@mansona](https://github.com/mansona))\n * [#56](https://github.com/mainmatter/build-start-rebuild-perf/pull/56) prevent version mismatch for puppeteer chrome install on CI ([@mansona](https://github.com/mansona))\n * [#44](https://github.com/mainmatter/build-start-rebuild-perf/pull/44) update biome schema to avoid warning ([@mansona](https://github.com/mansona))\n\n#### Committers: 4\n- Bartlomiej Dudzik ([@BobrImperator](https://github.com/BobrImperator))\n- Chris Manson ([@mansona](https://github.com/mansona))\n- Marine Dunstetter ([@BlueCutOfficial](https://github.com/BlueCutOfficial))\n- [@NullVoxPopuli](https://github.com/NullVoxPopuli)\n"
18
26
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # Changelog
2
2
 
3
+ ## Release (2026-07-13)
4
+
5
+ * build-start-rebuild-perf 0.4.0 (minor)
6
+
7
+ #### :rocket: Enhancement
8
+ * `build-start-rebuild-perf`
9
+ * [#53](https://github.com/mainmatter/build-start-rebuild-perf/pull/53) Fix waitForPageToLoad behavior ([@NullVoxPopuli](https://github.com/NullVoxPopuli))
10
+ * [#49](https://github.com/mainmatter/build-start-rebuild-perf/pull/49) Disable thousands separator for clearness ([@BlueCutOfficial](https://github.com/BlueCutOfficial))
11
+ * [#43](https://github.com/mainmatter/build-start-rebuild-perf/pull/43) use standard puppeteer ([@mansona](https://github.com/mansona))
12
+
13
+ #### :bug: Bug Fix
14
+ * `build-start-rebuild-perf`
15
+ * [#54](https://github.com/mainmatter/build-start-rebuild-perf/pull/54) Upgrade puppeteer so that tests pass ([@NullVoxPopuli](https://github.com/NullVoxPopuli))
16
+
17
+ #### :house: Internal
18
+ * `build-start-rebuild-perf`
19
+ * [#66](https://github.com/mainmatter/build-start-rebuild-perf/pull/66) chore: update release-plan ([@BobrImperator](https://github.com/BobrImperator))
20
+ * [#57](https://github.com/mainmatter/build-start-rebuild-perf/pull/57) stop running renovate on unpublished test app ([@mansona](https://github.com/mansona))
21
+ * [#55](https://github.com/mainmatter/build-start-rebuild-perf/pull/55) make package.json licence match project licence ([@mansona](https://github.com/mansona))
22
+ * [#56](https://github.com/mainmatter/build-start-rebuild-perf/pull/56) prevent version mismatch for puppeteer chrome install on CI ([@mansona](https://github.com/mansona))
23
+ * [#44](https://github.com/mainmatter/build-start-rebuild-perf/pull/44) update biome schema to avoid warning ([@mansona](https://github.com/mansona))
24
+
25
+ #### Committers: 4
26
+ - Bartlomiej Dudzik ([@BobrImperator](https://github.com/BobrImperator))
27
+ - Chris Manson ([@mansona](https://github.com/mansona))
28
+ - Marine Dunstetter ([@BlueCutOfficial](https://github.com/BlueCutOfficial))
29
+ - [@NullVoxPopuli](https://github.com/NullVoxPopuli)
30
+
31
+ ## Release (2025-08-25)
32
+
33
+ * build-start-rebuild-perf 0.3.0 (minor)
34
+
35
+ #### :rocket: Enhancement
36
+ * `build-start-rebuild-perf`
37
+ * [#41](https://github.com/mainmatter/build-start-rebuild-perf/pull/41) add option to have a custom page-load-timeout ([@mansona](https://github.com/mansona))
38
+
39
+ #### Committers: 1
40
+ - Chris Manson ([@mansona](https://github.com/mansona))
41
+
3
42
  ## Release (2025-08-13)
4
43
 
5
44
  * build-start-rebuild-perf 0.2.3 (patch)
package/README.md CHANGED
@@ -24,12 +24,14 @@ pnpm dlx build-start-rebuild-perf --file "app/router.js" --wait-for ".logo"
24
24
  ## Options
25
25
 
26
26
  ```
27
- -u, --url <url> URL to load (default: "http://localhost:4200")
28
- -f, --file <path> File to touch to trigger a reload (no default, but app/router.js is an option)
29
- -c, --command <cmd> Command to start dev server (default: "pnpm start")
30
- -w, --wait-for <selector> Element selector to wait for (default: "body")
31
- -l, --log-level <level> Set the log level (choices: "log", "warn", "error")
32
- -h, --help display help for command
27
+ -u, --url <url> URL to load (default: "http://localhost:4200")
28
+ -f, --file <path> File to touch to trigger a reload (no default, but app/router.js is an option)
29
+ -c, --command <cmd> Command to start dev server (default: "pnpm start")
30
+ -w, --wait-for <selector> Element selector to wait for (default: "body")
31
+ -t, --timeout <timeout ms> number of ms to wait for the server to become ready (default: "120000")
32
+ --page-load-timeout <timeout ms> number of ms to wait in the browser for the pageload event (default: "60000")
33
+ -l, --log-level <level> Set the log level (choices: "log", "warn", "error")
34
+ -h, --help display help for command
33
35
  ```
34
36
 
35
37
  ## Example Output
@@ -39,7 +41,7 @@ pnpm dlx build-start-rebuild-perf --file "app/router.js" --wait-for ".logo"
39
41
 
40
42
  | Dev Server Ready | First Paint | App Loaded | Reload after change |
41
43
  | ---------------- | ----------- | ---------- | ------------------- |
42
- | 5,523 ms | 5,618 ms | 6,142 ms | 918 ms |
44
+ | 5523 ms | 5618 ms | 6142 ms | 918 ms |
43
45
  ```
44
46
 
45
47
  ## Share with us
package/biome.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.1.3/schema.json",
2
+ "$schema": "https://biomejs.dev/schemas/2.1.4/schema.json",
3
3
  "files": {
4
4
  "includes": ["bin/**", "lib/**", "src/**", "test/**", "*.js", "*.mjs", "*.json"],
5
5
  "ignoreUnknown": true
package/lib/browser.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { promises as fs } from "node:fs";
2
2
  import { resolve } from "node:path";
3
- import { Launcher } from "chrome-launcher";
4
- import puppeteer from "puppeteer-core";
3
+ import puppeteer from "puppeteer";
5
4
  import { error, log, warn } from "./log.js";
6
5
 
7
6
  export const VIEWPORT = {
@@ -14,7 +13,6 @@ let page = null;
14
13
 
15
14
  export async function initBrowser() {
16
15
  browser = await puppeteer.launch({
17
- executablePath: Launcher.getInstallations()[0],
18
16
  headless: process.env.SHOW_BROWSER !== "true",
19
17
  args: ["--no-sandbox"],
20
18
  });
@@ -49,11 +47,37 @@ export async function initBrowser() {
49
47
  }
50
48
  }
51
49
 
52
- export async function measurePageLoad(url, waitForSelector = "body") {
50
+ const HARD_CODED_NETWORK_IDLE_TIMEOUT = 30_000;
51
+ async function waitForNetworkIdle(page, pageLoadTimeout) {
52
+ let attempts = Math.max(pageLoadTimeout / HARD_CODED_NETWORK_IDLE_TIMEOUT, 1);
53
+
54
+ /**
55
+ * waitForNetworkIdle has no configurable timeout
56
+ * and always times out at 30s, if your app takes
57
+ * more than 30s to finish dependency discovery and optimization.
58
+ * (easily possible on 3 million line code bases)
59
+ */
60
+ for (let attempt = 0; attempt < attempts; attempt++) {
61
+ log(`waitForNetworkIdle: attempt ${attempt} of ${attempts}`);
62
+
63
+ try {
64
+ await page.waitForNetworkIdle();
65
+ return;
66
+ } catch (error) {
67
+ if (error.message.includes("Timed out after waiting 30000ms")) {
68
+ continue;
69
+ }
70
+
71
+ throw error;
72
+ }
73
+ }
74
+ }
75
+
76
+ export async function measurePageLoad(url, waitForSelector = "body", pageLoadTimeout = 60_000) {
53
77
  log(`Loading page: ${url}`);
54
78
 
55
79
  const response = await page.goto(url, {
56
- timeout: 60_000,
80
+ timeout: pageLoadTimeout,
57
81
  waitUntil: "load",
58
82
  });
59
83
 
@@ -64,7 +88,7 @@ export async function measurePageLoad(url, waitForSelector = "body") {
64
88
  const atFirstPaint = performance.now();
65
89
 
66
90
  log("Waiting for page to fully load...");
67
- await page.waitForNetworkIdle();
91
+ await waitForNetworkIdle(page, pageLoadTimeout);
68
92
 
69
93
  log(`Waiting for element: ${waitForSelector}`);
70
94
  await page.waitForSelector(waitForSelector, {
@@ -82,7 +106,7 @@ export async function measurePageLoad(url, waitForSelector = "body") {
82
106
  };
83
107
  }
84
108
 
85
- export async function measureFileReload(filePath) {
109
+ export async function measureFileReload(filePath, pageLoadTimeout = 60_000) {
86
110
  if (!filePath) {
87
111
  log("No file specified for reload test, skipping...");
88
112
  return 0;
@@ -108,7 +132,7 @@ export async function measureFileReload(filePath) {
108
132
  const atFileChanged = performance.now();
109
133
 
110
134
  log("Waiting for hot reload to complete...");
111
- await page.waitForNetworkIdle();
135
+ await waitForNetworkIdle(page, pageLoadTimeout);
112
136
 
113
137
  const atReloadComplete = performance.now();
114
138
 
package/lib/measure.js CHANGED
@@ -28,8 +28,12 @@ export async function measure(options) {
28
28
  const atStart = performance.now();
29
29
  const serverURL = await startServer(options);
30
30
  const atServerUp = performance.now();
31
- const pageLoadMetrics = await measurePageLoad(serverURL, options.waitFor);
32
- const reloadMetrics = await measureFileReload(options.file);
31
+ const pageLoadMetrics = await measurePageLoad(
32
+ serverURL,
33
+ options.waitFor,
34
+ options.pageLoadTimeout,
35
+ );
36
+ const reloadMetrics = await measureFileReload(options.file, options.pageLoadTimeout);
33
37
  await terminateServer();
34
38
 
35
39
  return {
package/lib/program.js CHANGED
@@ -14,6 +14,11 @@ program
14
14
  "number of ms to wait for the server to become ready",
15
15
  "120000",
16
16
  )
17
+ .option(
18
+ "--page-load-timeout <timeout ms>",
19
+ "number of ms to wait in the browser for the pageload event",
20
+ "60000",
21
+ )
17
22
  .addOption(
18
23
  new Option("-l, --log-level <level>", "Set the log level", "warn").choices([
19
24
  "log",
package/lib/utils.js CHANGED
@@ -38,6 +38,7 @@ export class PrefixedTransform extends Transform {
38
38
  const formatter = Intl.NumberFormat("en-US", {
39
39
  style: "unit",
40
40
  unit: "millisecond",
41
+ useGrouping: false,
41
42
  });
42
43
 
43
44
  export function formatMs(timeMs) {
package/package.json CHANGED
@@ -1,29 +1,28 @@
1
1
  {
2
2
  "name": "build-start-rebuild-perf",
3
- "version": "0.2.3",
3
+ "version": "0.4.0",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git@github.com:mainmatter/build-start-rebuild-perf.git"
9
9
  },
10
- "license": "ISC",
10
+ "license": "MIT",
11
11
  "author": "",
12
12
  "type": "module",
13
13
  "bin": {
14
14
  "build-start-rebuild-perf": "bin/cli.js"
15
15
  },
16
16
  "dependencies": {
17
- "chrome-launcher": "^1.2.0",
18
17
  "commander": "^14.0.0",
19
18
  "execa": "^9.6.0",
20
19
  "markdown-table": "^3.0.4",
21
- "puppeteer-core": "^24.16.0",
20
+ "puppeteer": "^24.36.1",
22
21
  "strip-ansi": "^7.1.0"
23
22
  },
24
23
  "devDependencies": {
25
24
  "@biomejs/biome": "^2.1.3",
26
- "release-plan": "^0.17.0",
25
+ "release-plan": "^0.18.0",
27
26
  "vitest": "^3.2.4"
28
27
  },
29
28
  "scripts": {
@@ -1,3 +1,6 @@
1
1
  packages:
2
- - '.'
3
- - 'test-ember-app'
2
+ - .
3
+ - test-ember-app
4
+
5
+ onlyBuiltDependencies:
6
+ - puppeteer
package/renovate.json CHANGED
@@ -1,4 +1,10 @@
1
1
  {
2
2
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
- "extends": ["config:recommended"]
3
+ "extends": ["config:recommended"],
4
+ "packageRules": [
5
+ {
6
+ "matchFiles": ["test-ember-app/package.json"],
7
+ "enabled": false
8
+ }
9
+ ]
4
10
  }
package/test/cli.test.js CHANGED
@@ -2,9 +2,23 @@ import { resolve } from "node:path";
2
2
  import { execa } from "execa";
3
3
  import { afterEach, beforeEach, describe, expect, it } from "vitest";
4
4
 
5
+ /**
6
+ *
7
+ * @param {string[]} extraArgs an array of args to pass to the script
8
+ * @returns
9
+ */
10
+ function runCommand(extraArgs) {
11
+ return execa("node", ["../bin/cli.js", "--command", "pnpm start", ...extraArgs], {
12
+ cwd: resolve(import.meta.dirname, "..", "test-ember-app"),
13
+ });
14
+ }
15
+
5
16
  describe("CLI Tests", () => {
6
17
  describe(
7
18
  "Returns result for an Ember CLI app",
19
+ {
20
+ timeout: 120000,
21
+ },
8
22
  () => {
9
23
  const killStrays = async () => {
10
24
  try {
@@ -17,21 +31,7 @@ describe("CLI Tests", () => {
17
31
  afterEach(killStrays);
18
32
 
19
33
  it("should return measurements", async () => {
20
- const cmd = await execa(
21
- "node",
22
- [
23
- "../bin/cli.js",
24
- "--command",
25
- "pnpm start",
26
- "--wait-for",
27
- "h1",
28
- "--file",
29
- "./app/router.js",
30
- ],
31
- {
32
- cwd: resolve(import.meta.dirname, "..", "test-ember-app"),
33
- },
34
- );
34
+ const cmd = await runCommand(["--wait-for", "h1", "--file", "./app/router.js"]);
35
35
 
36
36
  console.log(cmd.stdout);
37
37
  console.error(cmd.stderr);
@@ -42,9 +42,24 @@ describe("CLI Tests", () => {
42
42
  "| Dev Server Ready | First Paint | App Loaded | Reload after change |",
43
43
  );
44
44
  });
45
- },
46
- {
47
- timeout: 120000,
45
+
46
+ it("should throw an error if --page-load-timeout is passed as something very low", async () => {
47
+ let cmd;
48
+ try {
49
+ cmd = await runCommand([
50
+ "--wait-for",
51
+ "h1",
52
+ "--file",
53
+ "./app/router.js",
54
+ "--page-load-timeout",
55
+ "100",
56
+ ]);
57
+ } catch (err) {
58
+ expect(err.stderr).toContain(`TimeoutError: Navigation timeout of 100 ms exceeded`);
59
+ }
60
+ // we expect the runCommand to throw. This is to make sure that we go into the catch block and don't "accidentally succeed"
61
+ expect(cmd).to.be.undefined;
62
+ });
48
63
  },
49
64
  );
50
65
  });