@autometa/jest-executor 0.5.10 → 0.6.1

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.
@@ -1,15 +1,15 @@
1
1
 
2
- > @autometa/jest-executor@0.5.1 test /Users/ben.aherne/Documents/GitHub/autometa/packages/jest-executor
2
+ > @autometa/jest-executor@0.5.10 test /Users/ben.aherne/Documents/GitHub/autometa/packages/jest-executor
3
3
  > vitest run --passWithNoTests
4
4
 
5
5
 
6
6
  RUN v1.4.0 /Users/ben.aherne/Documents/GitHub/autometa/packages/jest-executor
7
7
 
8
- ✓ src/timeout-selector.spec.ts (2 tests) 2ms
9
- ✓ src/executor.spec.ts (15 tests) 9ms
8
+ ✓ src/timeout-selector.spec.ts (2 tests) 4ms
9
+ ✓ src/executor.spec.ts (15 tests) 6ms
10
10
 
11
11
  Test Files 2 passed (2)
12
12
  Tests 17 passed (17)
13
- Start at 18:24:28
14
- Duration 5.24s (transform 2.06s, setup 0ms, collect 4.93s, tests 11ms, environment 0ms, prepare 1.98s)
13
+ Start at 13:56:48
14
+ Duration 6.00s (transform 2.24s, setup 0ms, collect 7.66s, tests 10ms, environment 0ms, prepare 2.38s)
15
15
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @autometa/jest-executor
2
2
 
3
+ ## 0.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - da669a3: feat: disposable injectables
8
+ - Updated dependencies [da669a3]
9
+ - @autometa/injection@0.1.4
10
+ - @autometa/app@0.4.1
11
+ - @autometa/config@0.1.26
12
+ - @autometa/scopes@0.7.1
13
+ - @autometa/test-builder@0.4.1
14
+ - @autometa/gherkin@0.7.1
15
+ - @autometa/events@0.3.1
16
+
17
+ ## 0.6.0
18
+
19
+ ### Minor Changes
20
+
21
+ - 7440e9f: feat: new group based hooks for feature, rule, outline and examples
22
+
23
+ ### Patch Changes
24
+
25
+ - Updated dependencies [7440e9f]
26
+ - @autometa/test-builder@0.4.0
27
+ - @autometa/gherkin@0.7.0
28
+ - @autometa/events@0.3.0
29
+ - @autometa/scopes@0.7.0
30
+ - @autometa/app@0.4.0
31
+ - @autometa/config@0.1.25
32
+
3
33
  ## 0.5.10
4
34
 
5
35
  ### Patch Changes
package/dist/esm/index.js CHANGED
@@ -52,6 +52,10 @@ function chooseTimeout(timeout1, timeout2) {
52
52
  // src/executor.ts
53
53
  import { NullTimeout as NullTimeout2, Timeout as Timeout2 } from "@autometa/scopes";
54
54
  import { Container, defineContainerContext } from "@autometa/injection";
55
+ var outlineApps = /* @__PURE__ */ new Map();
56
+ var examplesApps = /* @__PURE__ */ new Map();
57
+ var featureApps = /* @__PURE__ */ new Map();
58
+ var ruleApps = /* @__PURE__ */ new Map();
55
59
  function execute({ app, world }, global, bridge, events, config) {
56
60
  const globalBridge = new GlobalBridge(global);
57
61
  const featureTitle = bridge.data.scope.title(bridge.data.gherkin);
@@ -97,6 +101,46 @@ function execute({ app, world }, global, bridge, events, config) {
97
101
  localApp = testContainer.get(app);
98
102
  localApp.world = testContainer.get(world);
99
103
  localApp.di = testContainer;
104
+ if (!featureApps.has(name)) {
105
+ featureApps.set(name, []);
106
+ }
107
+ featureApps.get(name)?.push(localApp);
108
+ });
109
+ bridge.data.scope.hooks.beforeFeatureHooks.forEach((hook) => {
110
+ const hookTimeout = chooseTimeout(
111
+ chosenTimeout,
112
+ hook.options.timeout
113
+ ).getTimeout(config).milliseconds;
114
+ beforeAll(async () => {
115
+ if (!hook.canExecute(...bridge.data.gherkin.tags)) {
116
+ return;
117
+ }
118
+ const tags2 = bridge?.data?.gherkin?.tags ?? [];
119
+ const report = await hook.execute(staticApp, ...tags2);
120
+ if (report.error) {
121
+ const message = `${hook.name}: ${hook.description} failed to execute.`;
122
+ throw new AutomationError(message, { cause: report.error });
123
+ }
124
+ }, hookTimeout);
125
+ });
126
+ bridge.data.scope.hooks.afterFeatureHooks.forEach((hook) => {
127
+ const hookTimeout = chooseTimeout(
128
+ chosenTimeout,
129
+ hook.options.timeout
130
+ ).getTimeout(config).milliseconds;
131
+ afterAll(async () => {
132
+ if (!hook.canExecute(...bridge.data.gherkin.tags)) {
133
+ return;
134
+ }
135
+ const testName = expect.getState().currentTestName;
136
+ const tags2 = bridge?.data?.gherkin?.tags ?? [];
137
+ const apps = featureApps.get(testName);
138
+ const report = await hook.execute(staticApp, apps, ...tags2);
139
+ if (report.error) {
140
+ const message = `${hook.name}: ${hook.description} failed to execute.`;
141
+ throw new AutomationError(message, { cause: report.error });
142
+ }
143
+ }, hookTimeout);
100
144
  });
101
145
  bootstrapSetupHooks(globalBridge, staticApp, events, [
102
146
  config,
@@ -136,6 +180,12 @@ function execute({ app, world }, global, bridge, events, config) {
136
180
  chosenTimeout
137
181
  ]);
138
182
  bootstrapTeardownHooks(bridge, staticApp, events, [config, chosenTimeout]);
183
+ afterEach(async () => {
184
+ await testContainer.disposeAll();
185
+ });
186
+ afterAll(async () => {
187
+ await globalContainer.disposeGlobal();
188
+ });
139
189
  });
140
190
  afterAll(async () => {
141
191
  const failures = Query.find.failed(bridge);
@@ -153,6 +203,10 @@ function execute({ app, world }, global, bridge, events, config) {
153
203
  const message = `${count} asynchronous Test Events were rejected.`;
154
204
  console.warn(message);
155
205
  }
206
+ featureApps.clear();
207
+ outlineApps.clear();
208
+ examplesApps.clear();
209
+ ruleApps.clear();
156
210
  });
157
211
  }
158
212
  function bootstrapBackground(root, bridge, localApp, events, [config, timeout]) {
@@ -329,6 +383,7 @@ function bootstrapScenarioOutline(root, bridge, localApp, staticApp, events, [co
329
383
  } = bridge;
330
384
  const title = scope.title(gherkin);
331
385
  const retry = [...gherkin.tags].find((tag) => tag.startsWith("@retries="));
386
+ const { beforeScenarioOutlineHooks, afterScenarioOutlineHooks } = scope.hooks;
332
387
  const [group, modifier] = getGroupOrModifier(
333
388
  bridge,
334
389
  config.current.test?.tagFilter
@@ -337,7 +392,58 @@ function bootstrapScenarioOutline(root, bridge, localApp, staticApp, events, [co
337
392
  timeout,
338
393
  bridge.data.scope.timeout
339
394
  ).getTimeout(config).milliseconds;
395
+ const original = localApp;
396
+ localApp = () => {
397
+ const testName = expect.getState().currentTestName;
398
+ if (!outlineApps.has(testName)) {
399
+ outlineApps.set(testName, []);
400
+ }
401
+ const apps = outlineApps.get(testName);
402
+ const app = original();
403
+ apps.push(app);
404
+ return app;
405
+ };
340
406
  group(title, () => {
407
+ beforeScenarioOutlineHooks.forEach((hook) => {
408
+ const hookTimeout = chooseTimeout(
409
+ timeout,
410
+ hook.options.timeout
411
+ ).getTimeout(config).milliseconds;
412
+ beforeAll(async () => {
413
+ if (!hook.canExecute(...gherkin.tags)) {
414
+ return;
415
+ }
416
+ events.beforeScenarioOutline.emitStart({
417
+ title,
418
+ modifier,
419
+ tags: [...gherkin.tags]
420
+ });
421
+ const tags = gherkin.tags ?? [];
422
+ events.beforeScenarioOutline.emitStart({
423
+ title,
424
+ modifier,
425
+ tags: [...gherkin.tags]
426
+ });
427
+ const report = await hook.execute(staticApp, ...tags);
428
+ if (report.error) {
429
+ const message = `${hook.name}: ${hook.description} failed to execute.`;
430
+ events.beforeScenarioOutline.emitEnd({
431
+ title,
432
+ modifier,
433
+ error: report.error,
434
+ tags: [...gherkin.tags],
435
+ status: "FAILED"
436
+ });
437
+ throw new AutomationError(message, { cause: report.error });
438
+ }
439
+ events.beforeScenarioOutline.emitEnd({
440
+ title,
441
+ modifier,
442
+ tags: [...gherkin.tags],
443
+ status: "PASSED"
444
+ });
445
+ }, hookTimeout);
446
+ });
341
447
  beforeAll(() => {
342
448
  if (retry) {
343
449
  const count = parseInt(retry.split("=")[1]);
@@ -359,6 +465,43 @@ function bootstrapScenarioOutline(root, bridge, localApp, staticApp, events, [co
359
465
  });
360
466
  bootstrapAfterHooks(root, bridge, localApp, events, [config, timeout]);
361
467
  bootstrapTeardownHooks(bridge, staticApp, events, [config, timeout]);
468
+ afterScenarioOutlineHooks.forEach((hook) => {
469
+ const hookTimeout = chooseTimeout(
470
+ timeout,
471
+ hook.options.timeout
472
+ ).getTimeout(config).milliseconds;
473
+ afterAll(async () => {
474
+ if (!hook.canExecute(...gherkin.tags)) {
475
+ return;
476
+ }
477
+ const testName = expect.getState().currentTestName;
478
+ const tags = gherkin.tags ?? [];
479
+ const apps = outlineApps.get(testName);
480
+ events.afterScenarioOutline.emitStart({
481
+ title,
482
+ modifier,
483
+ tags: [...gherkin.tags]
484
+ });
485
+ const report = await hook.execute(staticApp, apps, ...tags);
486
+ if (report.error) {
487
+ const message = `${hook.name}: ${hook.description} failed to execute.`;
488
+ events.scenarioOutline.emitEnd({
489
+ title,
490
+ modifier,
491
+ error: report.error,
492
+ tags: [...gherkin.tags],
493
+ status: "FAILED"
494
+ });
495
+ throw new AutomationError(message, { cause: report.error });
496
+ }
497
+ events.afterScenarioOutline.emitEnd({
498
+ title,
499
+ modifier,
500
+ tags: [...gherkin.tags],
501
+ status: "PASSED"
502
+ });
503
+ }, hookTimeout);
504
+ });
362
505
  afterAll(() => {
363
506
  const failures = Query.find.failed(bridge);
364
507
  const status = getStatus(modifier, failures);
@@ -368,6 +511,8 @@ function bootstrapScenarioOutline(root, bridge, localApp, staticApp, events, [co
368
511
  tags: [...gherkin.tags],
369
512
  status
370
513
  });
514
+ outlineApps.clear();
515
+ examplesApps.clear();
371
516
  }, chosenTimeout);
372
517
  });
373
518
  }
@@ -377,6 +522,17 @@ function bootstrapExamples(root, example, localApp, staticApp, events, timeout)
377
522
  const retry = [...example.data.gherkin.tags].find(
378
523
  (tag) => tag.startsWith("@retries=")
379
524
  );
525
+ const original = localApp;
526
+ localApp = () => {
527
+ const testName = expect.getState().currentTestName ?? "unnamed test";
528
+ if (!examplesApps.has(testName)) {
529
+ examplesApps.set(testName, []);
530
+ }
531
+ const apps = examplesApps.get(testName);
532
+ const app = original();
533
+ apps.push(app);
534
+ return app;
535
+ };
380
536
  const [group] = getGroupOrModifier(
381
537
  example,
382
538
  timeout[0].current.test?.tagFilter
@@ -388,7 +544,62 @@ function bootstrapExamples(root, example, localApp, staticApp, events, timeout)
388
544
  jest.retryTimes(count);
389
545
  }
390
546
  });
547
+ example.data.scope.hooks.beforeExamplesHooks.forEach((hook) => {
548
+ const hookTimeout = chooseTimeout(
549
+ timeout[1],
550
+ hook.options.timeout
551
+ ).getTimeout(timeout[0]).milliseconds;
552
+ beforeAll(async () => {
553
+ if (!hook.canExecute(...example.data.gherkin.tags)) {
554
+ return;
555
+ }
556
+ const tags = example?.data?.gherkin?.tags ?? [];
557
+ events.beforeExamples.emitStart({
558
+ title,
559
+ tags: [...tags]
560
+ });
561
+ const report = await hook.execute(staticApp, ...tags);
562
+ if (report.error) {
563
+ const message = `${hook.name}: ${hook.description} failed to execute.`;
564
+ events.beforeExamples.emitEnd({
565
+ title,
566
+ error: report.error,
567
+ tags: [...tags],
568
+ status: "FAILED"
569
+ });
570
+ throw new AutomationError(message, { cause: report.error });
571
+ }
572
+ events.beforeExamples.emitEnd({
573
+ title,
574
+ tags: [...tags],
575
+ status: "PASSED"
576
+ });
577
+ }, hookTimeout);
578
+ });
391
579
  bootstrapScenarios(root, example, localApp, staticApp, events, timeout);
580
+ example.data.scope.hooks.afterExamplesHooks.forEach((hook) => {
581
+ const hookTimeout = chooseTimeout(
582
+ timeout[1],
583
+ hook.options.timeout
584
+ ).getTimeout(timeout[0]).milliseconds;
585
+ afterAll(async () => {
586
+ const testName = expect.getState().currentTestName;
587
+ if (!hook.canExecute(...example.data.gherkin.tags)) {
588
+ return;
589
+ }
590
+ const tags = example?.data?.gherkin?.tags ?? [];
591
+ const apps = examplesApps.get(testName);
592
+ const report = await hook.execute(staticApp, apps, ...tags);
593
+ if (report.error) {
594
+ const message = `${hook.name}: ${hook.description} failed to execute.`;
595
+ throw new AutomationError(message, { cause: report.error });
596
+ }
597
+ }, hookTimeout);
598
+ });
599
+ afterAll(() => {
600
+ const testName = expect.getState().currentTestName;
601
+ examplesApps.delete(testName);
602
+ });
392
603
  });
393
604
  }
394
605
  function bootstrapRules(bridge, localApp, staticApp, events, [config, timeout]) {
@@ -421,6 +632,83 @@ function bootstrapRules(bridge, localApp, staticApp, events, [config, timeout])
421
632
  const count = parseInt(retry.split("=")[1]);
422
633
  jest.retryTimes(count);
423
634
  }
635
+ const original = localApp;
636
+ localApp = () => {
637
+ const testName = expect.getState().currentTestName;
638
+ if (!ruleApps.has(testName)) {
639
+ ruleApps.set(testName, []);
640
+ }
641
+ const apps = ruleApps.get(testName);
642
+ const app = original();
643
+ apps.push(app);
644
+ return app;
645
+ };
646
+ });
647
+ bridge.data.scope.hooks.beforeRuleHooks.forEach((hook) => {
648
+ const hookTimeout = chooseTimeout(
649
+ ruleTimeout,
650
+ hook.options.timeout
651
+ ).getTimeout(config).milliseconds;
652
+ beforeAll(async () => {
653
+ if (!hook.canExecute(...data.gherkin.tags)) {
654
+ return;
655
+ }
656
+ const tags2 = data.gherkin.tags ?? [];
657
+ events.beforeRule.emitStart({
658
+ title: `${hook.name}: ${hook.description}`,
659
+ tags: [...tags2]
660
+ });
661
+ const report = await hook.execute(staticApp, ...tags2);
662
+ if (report.error) {
663
+ const message = `${hook.name}: ${hook.description} failed to execute.`;
664
+ events.beforeRule.emitEnd({
665
+ title: `${hook.name}: ${hook.description}`,
666
+ tags: [...tags2],
667
+ status: "FAILED",
668
+ error: report.error
669
+ });
670
+ throw new AutomationError(message, { cause: report.error });
671
+ }
672
+ events.beforeRule.emitEnd({
673
+ title: `${hook.name}: ${hook.description}`,
674
+ tags: [...tags2],
675
+ status: "PASSED"
676
+ });
677
+ }, hookTimeout);
678
+ });
679
+ bridge.data.scope.hooks.afterRuleHooks.forEach((hook) => {
680
+ const hookTimeout = chooseTimeout(
681
+ ruleTimeout,
682
+ hook.options.timeout
683
+ ).getTimeout(config).milliseconds;
684
+ afterAll(async () => {
685
+ const testName = expect.getState().currentTestName;
686
+ if (!hook.canExecute(...data.gherkin.tags)) {
687
+ return;
688
+ }
689
+ const tags2 = data.gherkin.tags ?? [];
690
+ const apps = ruleApps.get(testName);
691
+ events.afterRule.emitStart({
692
+ title: `${hook.name}: ${hook.description}`,
693
+ tags: [...tags2]
694
+ });
695
+ const report = await hook.execute(staticApp, apps, ...tags2);
696
+ if (report.error) {
697
+ const message = `${hook.name}: ${hook.description} failed to execute.`;
698
+ events.afterRule.emitEnd({
699
+ title: `${hook.name}: ${hook.description}`,
700
+ tags: [...tags2],
701
+ status: "FAILED",
702
+ error: report.error
703
+ });
704
+ throw new AutomationError(message, { cause: report.error });
705
+ }
706
+ events.afterRule.emitEnd({
707
+ title: `${hook.name}: ${hook.description}`,
708
+ tags: [...tags2],
709
+ status: "PASSED"
710
+ });
711
+ }, hookTimeout);
424
712
  });
425
713
  bootstrapSetupHooks(rule, staticApp, events, transferTimeout);
426
714
  bootstrapBeforeHooks(bridge, rule, localApp, events, transferTimeout);
@@ -444,6 +732,8 @@ function bootstrapRules(bridge, localApp, staticApp, events, [config, timeout])
444
732
  tags: [...data.gherkin.tags],
445
733
  status
446
734
  });
735
+ const testName = expect.getState().currentTestName;
736
+ ruleApps.delete(testName);
447
737
  }, ruleTimeout.milliseconds);
448
738
  });
449
739
  });
@@ -496,9 +786,10 @@ function bootstrapBeforeHooks(root, bridge, localApp, events, [config, timeout])
496
786
  bridge.data.scope.timeout
497
787
  ).getTimeout(config);
498
788
  bridge.data.scope.hooks.before.forEach((hook) => {
499
- const hookTimeout = chooseTimeout(chosenTimeout, hook.timeout).getTimeout(
500
- config
501
- ).milliseconds;
789
+ const hookTimeout = chooseTimeout(
790
+ chosenTimeout,
791
+ hook.options.timeout
792
+ ).getTimeout(config).milliseconds;
502
793
  beforeEach(async () => {
503
794
  const testName = expect.getState().currentTestName;
504
795
  if (!testName)
@@ -541,7 +832,7 @@ function bootstrapSetupHooks(bridge, staticApp, events, [config, timeout]) {
541
832
  setups.forEach((hook) => {
542
833
  const hookTimeout = chooseTimeout(
543
834
  Timeout2.from(chosenTimeout),
544
- hook.timeout
835
+ hook.options.timeout
545
836
  ).getTimeout(config).milliseconds;
546
837
  const tags = gherkin.tags ?? [];
547
838
  beforeAll(async () => {
@@ -572,7 +863,7 @@ function bootstrapAfterHooks(root, bridge, localApp, events, [config, timeout])
572
863
  scope.hooks.after.forEach((hook) => {
573
864
  const hookTimeout = chooseTimeout(
574
865
  Timeout2.from(chosenTimeout),
575
- hook.timeout
866
+ hook.options.timeout
576
867
  ).getTimeout(config).milliseconds;
577
868
  afterEach(async () => {
578
869
  const testName = expect.getState().currentTestName;
@@ -607,15 +898,16 @@ function bootstrapAfterHooks(root, bridge, localApp, events, [config, timeout])
607
898
  });
608
899
  }
609
900
  function bootstrapTeardownHooks(bridge, staticApp, event, [config, timeout]) {
610
- const tags = bridge.data.gherkin.tags ?? [];
901
+ const tags = [...bridge.data.gherkin.tags];
611
902
  const { scope } = bridge.data;
612
903
  const chosenTimeout = chooseTimeout(timeout, scope.timeout).getTimeout(
613
904
  config
614
905
  );
615
906
  scope.hooks.teardown.forEach((hook) => {
616
- const hookTimeout = chooseTimeout(chosenTimeout, hook.timeout).getTimeout(
617
- config
618
- ).milliseconds;
907
+ const hookTimeout = chooseTimeout(
908
+ chosenTimeout,
909
+ hook.options.timeout
910
+ ).getTimeout(config).milliseconds;
619
911
  afterAll(async () => {
620
912
  if (!hook.canExecute(...tags)) {
621
913
  return;
@@ -624,7 +916,7 @@ function bootstrapTeardownHooks(bridge, staticApp, event, [config, timeout]) {
624
916
  title: `${hook.name}: ${hook.description}`,
625
917
  tags: [...tags]
626
918
  });
627
- const report = await hook.execute(staticApp, ...tags);
919
+ const report = await hook.execute(staticApp, tags);
628
920
  event.teardown.emitEnd({
629
921
  title: `${hook.name}: ${hook.description}`,
630
922
  tags: [...tags],