monocart-reporter 1.7.3 → 1.7.5

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.
package/README.md CHANGED
@@ -30,13 +30,20 @@
30
30
  * [Metadata](#metadata)
31
31
  * [Trend Chart](#trend-chart)
32
32
  * [Attach Lighthouse Audit Report](#attach-lighthouse-audit-report)
33
- * [Attach Code Coverage Report](#attach-code-coverage-report)
33
+ * [Code Coverage Report](#code-coverage-report)
34
+ - [Coverage Options](#coverage-options)
35
+ - [Istanbul](#istanbul)
36
+ - [V8](#v8)
37
+ - [V8 to Istanbul](#v8-to-istanbul)
34
38
  - [Compare Istanbul, V8 and V8 to Istanbul](#compare-istanbul-v8-and-v8-to-istanbul)
35
39
  - [Global Coverage Report](#global-coverage-report) for Component Testing
36
40
  * [Attach Network Report](#attach-network-report)
37
41
  * [Global State Management](#global-state-management)
42
+ - [Setup Global State](#setup-global-state)
43
+ - [Get, Set, and Remove Global Data](#get-set-and-remove-global-data)
44
+ - [Send and Receive Messages between Processes](#send-and-receive-messages-between-processes)
38
45
  * [Merge Shard Reports](#merge-shard-reports)
39
- * [onEnd hook](#onend-hook)
46
+ * [onEnd Hook](#onend-hook)
40
47
  - [Send Email](#send-email)
41
48
  - [Testrail Integration](#testrail-integration)
42
49
  - [Jira + Zephyr Scale Integration](#jira--zephyr-scale-integration)
@@ -46,7 +53,7 @@
46
53
  - [Teams Integration](#teams-integration)
47
54
  - [Dingtalk/Weixin/Feishu Integration](#dingtalkweixinfeishu-integration)
48
55
  * [Contributing](#contributing)
49
- * [Changelog](#changelog)
56
+ * [Changelog](CHANGELOG.md)
50
57
  ## Preview
51
58
  [https://cenfun.github.io/monocart-reporter](https://cenfun.github.io/monocart-reporter)
52
59
 
@@ -625,23 +632,27 @@ test('attach lighthouse audit report', async () => {
625
632
  ```
626
633
  Preview [Audit HTML Report](https://cenfun.github.io/monocart-reporter/audit-78a0a1cc4420ee9da113/index.html)
627
634
 
628
- ## Attach Code Coverage Report
629
- Attach a code coverage report with API `attachCoverageReport(data, testInfo, options)`. Arguments:
630
- - `data` There are two supported data inputs `Istanbul` (Object) or `V8` (Array)
631
- - `testInfo` see [TestInfo](https://playwright.dev/docs/api/class-testinfo)
632
- - `options` (Object)
633
- - `title` (String) report title.
634
- - `toIstanbul` (Boolean) Whether to convert to Istanbul report from V8 list. Defaults to `html-spa` report | (String) or using `html` report. V8 only.
635
- - `entryFilter` (Function) A filter function to execute for each element in the V8 list. V8 only.
636
- - `sourceFilter` (Function) A filter function to execute for each element in the sources which unpacked from the source map. Sourcemap only.
637
- - `watermarks` (Object) Istanbul watermarks, see [here](https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-lib-report) | (Array) V8 watermarks, Defaults to `[50, 80]`.
638
- - `lcov` (Boolean) Whether to create `lcov.info`. (for Sonar coverage)
639
- - `sourcePath` (Function) source path handler, return a new source path. ([issue#53](https://github.com/cenfun/monocart-reporter/issues/53)).
640
- - `inline` (Boolean) Whether inline all scripts to the single HTML file. V8 only.
641
-
642
- (see example: [report-coverage.spec.js](https://github.com/cenfun/monocart-reporter/blob/main/tests/report-coverage/report-coverage.spec.js))
643
-
644
- - [Istanbul](https://github.com/istanbuljs) Requires your source code is instrumented. Usually we can use the tool [babel-plugin-istanbul](https://github.com/istanbuljs/babel-plugin-istanbul) to build instrumenting code. (see example: [webpack.config.js](https://github.com/cenfun/monocart-reporter-test/blob/main/packages/coverage/webpack.config.js)) The instrumented code will automatically generate coverage data and save it on `window.__coverage__`. The Istanbul HTML report will be generated and attached to the test report as an attachment.
635
+ ## Code Coverage Report
636
+ There are two APIs for coverage report:
637
+ - `attachCoverageReport(data, testInfo, options)`
638
+ Attach a coverage report to a test. Arguments:
639
+ - `data` There are two supported data inputs: [Istanbul](#istanbul) (Object) or [V8](#v8) (Array)
640
+ - `testInfo` see [TestInfo](https://playwright.dev/docs/api/class-testinfo)
641
+ - `options` (Object) see [Coverage Options](#coverage-options)
642
+ - `addCoverageReport(data, testInfo)` Add coverage to global coverage report from a test. see [Global Coverage Report](#global-coverage-report)
643
+
644
+ ### Coverage Options
645
+ - `title` (String) report title.
646
+ - `toIstanbul` (Boolean) Whether to convert to Istanbul report from V8 list. Defaults to `html-spa` report | (String) or using `html` report. V8 only.
647
+ - `entryFilter` (Function) A filter function to execute for each element in the V8 list. V8 only.
648
+ - `sourceFilter` (Function) A filter function to execute for each element in the sources which unpacked from the source map. Sourcemap only.
649
+ - `watermarks` (Object) Istanbul watermarks, see [here](https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-lib-report) | (Array) V8 watermarks, Defaults to `[50, 80]`.
650
+ - `lcov` (Boolean) Whether to create `lcov.info`. (for Sonar coverage)
651
+ - `sourcePath` (Function) source path handler, return a new source path. ([issue#53](https://github.com/cenfun/monocart-reporter/issues/53)).
652
+ - `inline` (Boolean) Whether inline all scripts to the single HTML file. V8 only.
653
+
654
+ ### [Istanbul](https://github.com/istanbuljs)
655
+ Requires your source code is instrumented. Usually we can use the tool [babel-plugin-istanbul](https://github.com/istanbuljs/babel-plugin-istanbul) to build instrumenting code. (see example: [webpack.config-istanbul.js](https://github.com/cenfun/monocart-reporter-test/blob/main/packages/coverage/webpack.config-istanbul.js)) The instrumented code will automatically generate coverage data and save it on `window.__coverage__`. The Istanbul HTML report will be generated and attached to the test report as an attachment.
645
656
  ```js
646
657
  import { test, expect } from '@playwright/test';
647
658
  import { attachCoverageReport } from 'monocart-reporter';
@@ -669,9 +680,8 @@ test('Take Istanbul coverage report', async ({ page }) => {
669
680
  });
670
681
  ```
671
682
 
672
- ![](/docs/istanbul.png)
673
-
674
- - [V8](https://v8.dev/blog/javascript-code-coverage) ([Chromium-based only](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#type-ScriptCoverage)) Simply take coverage data with [class-coverage](https://playwright.dev/docs/api/class-coverage) APIs, the V8 HTML report will be generated.
683
+ ### [V8](https://v8.dev/blog/javascript-code-coverage)
684
+ Simply take coverage data with [class-coverage](https://playwright.dev/docs/api/class-coverage) APIs, so it is [Chromium-based only](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#type-ScriptCoverage), the V8 HTML report will be generated.
675
685
  ```js
676
686
  import { test, expect } from '@playwright/test';
677
687
  import { attachCoverageReport } from 'monocart-reporter';
@@ -712,7 +722,8 @@ test('Take V8 and Istanbul coverage report', async ({ page }) => {
712
722
 
713
723
  ![](/docs/v8.gif)
714
724
 
715
- - `V8 to Istanbul` Take V8 coverage data with [class-coverage](https://playwright.dev/docs/api/class-coverage) APIs, then the V8 coverage format will be converted to Istanbul's coverage format. The Istanbul HTML report will be generated.
725
+ ### V8 to Istanbul
726
+ Take V8 coverage data and convert it to Istanbul's coverage format. The Istanbul HTML report will be generated.
716
727
  ```js
717
728
  const report = await attachCoverageReport(coverageList, test.info(), {
718
729
  toIstanbul: true
@@ -723,16 +734,17 @@ const report = await attachCoverageReport(coverageList, test.info(), {
723
734
  | | Istanbul | V8 | V8 to Istanbul |
724
735
  | :--------------| :------ | :------ | :---------------------- |
725
736
  | Input data format | Istanbul (Object) | V8 (Array) | V8 (Array) |
726
- | Options | `watermarks: {}` | `watermarks: [50, 80]` | `toIstanbul: true, watermarks: {}` |
727
- | Output report | [Istanbul HTML report](https://cenfun.github.io/monocart-reporter/coverage-6eaa280d68aea439a847/index.html) | [V8 HTML report](https://cenfun.github.io/monocart-reporter/coverage/index.html) | [Istanbul HTML report](https://cenfun.github.io/monocart-reporter/coverage-bbea6fd47b9c551582fe/index.html) |
728
- | Indicators | Covered Lines, Branches, Statements and Functions, Execution Counts | Covered Bytes, Lines (after formatted) Execution Counts | Covered Lines, Branches, Statements and Functions, Execution Counts |
737
+ | Output | [Istanbul HTML report](https://cenfun.github.io/monocart-reporter/coverage-77aa6f37601a97417803/index.html) | [V8 HTML report](https://cenfun.github.io/monocart-reporter/coverage/index.html) | [Istanbul HTML report](https://cenfun.github.io/monocart-reporter/coverage-01eebe0ebc796534d759-1/index.html) |
738
+ | Indicators | Covered Lines, Branches, Statements and Functions, Execution Counts | Covered Bytes, Lines❔, Execution Counts | Covered Lines, Branches❔, Statements and Functions, Execution Counts |
729
739
  | Source code without [instrumentation](https://github.com/istanbuljs/babel-plugin-istanbul) | ❌ | ✅ | ✅ |
730
- | CSS coverage | ❌ | ✅ | |
740
+ | CSS coverage | ❌ | ✅ | |
731
741
  | Minified code | N/A | ✅ | ❌ |
732
742
  | Code formatting | N/A | ✅ | ❌ |
733
743
 
744
+ ❔ - Partial or conditional support
734
745
  ### Global Coverage Report
735
- The global coverage report will not be attached to any test case, but will merge all coverages into one global report after all the tests are finished. The API is `addCoverageReport(v8list, testInfo)`, currently supported `V8` only. Here is an example for Playwright Component Testing [playwright-ct-vue](https://github.com/cenfun/playwright-ct-vue).
746
+ The global coverage report will not be attached to any test case, but will merge all coverages into one global report after all the tests are finished.
747
+ - The global coverage options see [Coverage Options](#coverage-options)
736
748
  ```js
737
749
  // playwright.config.js
738
750
  module.exports = {
@@ -749,6 +761,54 @@ module.exports = {
749
761
  ]
750
762
  };
751
763
  ```
764
+ - It is recommended to use [automatic fixtures](https://playwright.dev/docs/test-fixtures#automatic-fixtures) to add coverage for each test:
765
+ ```js
766
+ // fixtures.js for v8
767
+ import { test as testBase, expect } from '@playwright/test';
768
+ import { addCoverageReport } from 'monocart-reporter';
769
+
770
+ const test = testBase.extend({
771
+ autoTestFixture: [async ({ page }, use) => {
772
+
773
+ const isChromium = test.info().project.name === 'Desktop Chromium';
774
+
775
+ // console.log('autoTestFixture setup...');
776
+ // coverage API is chromium only
777
+ if (isChromium) {
778
+ await Promise.all([
779
+ page.coverage.startJSCoverage({
780
+ resetOnNavigation: false
781
+ }),
782
+ page.coverage.startCSSCoverage({
783
+ resetOnNavigation: false
784
+ })
785
+ ]);
786
+ }
787
+
788
+ await use('autoTestFixture');
789
+
790
+ // console.log('autoTestFixture teardown...');
791
+ if (isChromium) {
792
+ const [jsCoverage, cssCoverage] = await Promise.all([
793
+ page.coverage.stopJSCoverage(),
794
+ page.coverage.stopCSSCoverage()
795
+ ]);
796
+ const coverageList = [... jsCoverage, ... cssCoverage];
797
+ // console.log(coverageList.map((item) => item.url));
798
+ await addCoverageReport(coverageList, test.info());
799
+ }
800
+
801
+ }, {
802
+ scope: 'test',
803
+ auto: true
804
+ }]
805
+ });
806
+ export { test, expect };
807
+ ```
808
+ - The coverage examples for Playwright component testing:
809
+ - [playwright-ct-vue](https://github.com/cenfun/playwright-ct-vue)
810
+ - [playwright-ct-react](https://github.com/cenfun/playwright-ct-react)
811
+ - [playwright-ct-svelte](https://github.com/cenfun/playwright-ct-svelte)
752
812
 
753
813
  ## Attach Network Report
754
814
  Attach a network report with API `attachNetworkReport(har, testInfo)`. Arguments:
@@ -821,12 +881,11 @@ test('finally, attach HAR', async () => {
821
881
  await attachNetworkReport(harPath, test.info());
822
882
  });
823
883
  ```
824
- Preview [Network HTML Report](https://cenfun.github.io/monocart-reporter/network-38e613e8d93547bdb27f/index.html)
825
-
884
+ Preview [Network HTML Report](https://cenfun.github.io/monocart-reporter/network-da7f5b4cceb1e6280782/index.html)
826
885
 
827
886
  ## Global State Management
828
887
  When tests are executed in [isolation](https://playwright.dev/docs/browser-contexts) mode, the reporter and each test may run in a different process, they cannot share data with each other. we can start a local WebSocket server to serve the global data, and read/write the global data with `useState` API from a test.
829
- - setup global state
888
+ ### Setup Global State
830
889
  ```js
831
890
  module.exports = {
832
891
  reporter: [
@@ -850,7 +909,7 @@ module.exports = {
850
909
  ]
851
910
  };
852
911
  ```
853
- - get/set/remove global data
912
+ ### Get, Set, and Remove Global Data
854
913
  ```js
855
914
  const { test } = require('@playwright/test');
856
915
  const { useState } = require('monocart-reporter');
@@ -878,7 +937,23 @@ test('state test', async ({ browserName }) => {
878
937
  console.log(all);
879
938
  });
880
939
  ```
881
- - customize sending and receiving messages
940
+ ### Send and Receive Messages between Processes
941
+ - send message and receive response from a test (child process)
942
+ ```js
943
+ const { test } = require('@playwright/test');
944
+ const { useState } = require('monocart-reporter');
945
+ test('state test send message', async () => {
946
+ const state = useState({
947
+ // port: 8130
948
+ });
949
+ const response = await state.send({
950
+ testId: test.info().testId,
951
+ data: 'my test data'
952
+ });
953
+ console.log('receive response on client', response);
954
+ });
955
+ ```
956
+ - receive message and send response from global state (main process)
882
957
  ```js
883
958
  module.exports = {
884
959
  reporter: [
@@ -887,29 +962,22 @@ module.exports = {
887
962
  name: "My Test Report",
888
963
  outputFile: './test-results/report.html',
889
964
  state: {
890
- // receive messages and send back response
891
- onReceive: function(... args) {
892
- console.log('receive on server', args);
893
- return ['custom response', ... args];
965
+ onReceive: function(message) {
966
+ const test = this.getTest(message.testId);
967
+ if (test) {
968
+ // current test
969
+ }
970
+ console.log('receive message on server', message);
971
+ return {
972
+ data: 'my response data'
973
+ };
894
974
  }
895
975
  }
896
976
  }]
897
977
  ]
898
978
  };
899
979
  ```
900
- ```js
901
- const { test } = require('@playwright/test');
902
- const { useState } = require('monocart-reporter');
903
- test('state test', async ({ browserName }) => {
904
- const state = useState({
905
- // port: 8130
906
- });
907
- // send messages
908
- const res = await state.send('string data', {});
909
- console.log('receive on client', res);
910
- });
911
- ```
912
-
980
+ see example: [Allow specified test cases to run in sequence mode with lock/unlock state](https://github.com/cenfun/monocart-reporter-test/tree/main/tests/global-state)
913
981
 
914
982
  ## Merge Shard Reports
915
983
  There will be multiple reports to be generated if Playwright test executes in sharding mode. for example:
@@ -944,7 +1012,7 @@ await merge(reportDataList, {
944
1012
  ```
945
1013
  Preview [merged report](https://cenfun.github.io/monocart-reporter-test/merged)
946
1014
 
947
- ## onEnd hook
1015
+ ## onEnd Hook
948
1016
  The `onEnd` function will be executed after report generated. Arguments:
949
1017
  - `reportData` all report data, properties:
950
1018
  - `name` (String) report name
@@ -981,54 +1049,41 @@ module.exports = {
981
1049
  };
982
1050
  ```
983
1051
  ## Send Email
984
- Simply send email with [nodemailer](https://nodemailer.com), check example: [send-email](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/send-email)
985
-
986
- ![](/docs/email.png)
987
-
1052
+ - Simply send email with [nodemailer](https://nodemailer.com)
1053
+ - Example: [send-email](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/send-email)
988
1054
 
989
1055
  ## Testrail Integration
990
- Send test results to your Testrail, check example: [testrail](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/testrail)
991
-
992
- ![](/docs/testrail.png)
1056
+ - Send test results to your [Testrail](https://www.testrail.com/)
1057
+ - Example: [testrail](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/testrail)
993
1058
 
994
1059
  ## Jira + Zephyr Scale Integration
995
- Create test cycle and executions with [zephyr-scale-api](https://support.smartbear.com/zephyr-scale-cloud/api-docs/), check example: [zephyr-scale](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/zephyr-scale)
996
-
997
- ![](/docs/zephyr.png)
1060
+ - Create test cycle and executions with [zephyr-scale-api](https://support.smartbear.com/zephyr-scale-cloud/api-docs/)
1061
+ - Example: [zephyr-scale](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/zephyr-scale)
998
1062
 
999
1063
  ## Jira + Xray Integration
1000
1064
  - Import test execution results with [Xray REST API](https://docs.getxray.app/display/XRAYCLOUD/REST+API)
1001
1065
  - Update Jira issue status with [Jira Transition API](https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-transitions-post)
1002
- check example: [xray](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/xray)
1003
-
1004
- ![](/docs/xray.png)
1066
+ - Example: [xray](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/xray)
1005
1067
 
1006
1068
  ## Slack Integration
1007
- 1. Simply send message with [@slack/webhook](https://github.com/slackapi/node-slack-sdk), example: [slack-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/slack-webhook)
1008
- 2. Recommended: Post chat message and upload image with [@slack/web-api](https://github.com/slackapi/node-slack-sdk), example: [slack-web-api](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/slack-web-api)
1009
-
1010
- ![](/docs/slack.png)
1069
+ - Simply send message with [@slack/webhook](https://github.com/slackapi/node-slack-sdk)
1070
+ - Example: [slack-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/slack-webhook)
1071
+ - Post chat message and upload image with [@slack/web-api](https://github.com/slackapi/node-slack-sdk)
1072
+ - Example: [slack-web-api](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/slack-web-api)
1011
1073
 
1012
1074
  ## Discord Integration
1013
- Using [Discord webhooks](https://discord.com/developers/docs/resources/webhook) to post messages to channels. check example: [discord-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/discord-webhook)
1014
-
1015
- ![](/docs/discord.png)
1075
+ - Using [Discord webhooks](https://discord.com/developers/docs/resources/webhook) to post messages to channels.
1076
+ - Example: [discord-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/discord-webhook)
1016
1077
 
1017
1078
  ## Teams Integration
1018
- Please create an [Incoming Webhooks](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook) for the channel first. check example: [teams-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/teams-webhook)
1019
-
1020
- ![](/docs/teams.png)
1079
+ - Please create an [Incoming Webhooks](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook) for the channel first.
1080
+ - Example: [teams-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/teams-webhook)
1021
1081
 
1022
1082
  ## Dingtalk/Weixin/Feishu Integration
1023
1083
  - [dingtalk-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/dingtalk-webhook)
1024
1084
  - [weixin-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/weixin-webhook)
1025
1085
  - [feishu-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/feishu-webhook)
1026
1086
 
1027
- ## Dependencies
1028
- - UI Framework [Vue 3](https://github.com/vuejs/core)
1029
- - Lightweight UI Components [vine-ui](https://github.com/cenfun/vine-ui)
1030
- - High Performance Grid [turbogrid](https://github.com/cenfun/turbogrid)
1031
- - String compress/decompress [lz-utils](https://github.com/cenfun/lz-utils)
1032
1087
 
1033
1088
  ## Contributing
1034
1089
  ```sh
@@ -1038,5 +1093,8 @@ npm run test
1038
1093
  npm run build
1039
1094
  npm run dev
1040
1095
  ```
1041
- ## CHANGELOG
1042
- - [CHANGELOG.md](CHANGELOG.md)
1096
+ ## Dependencies
1097
+ - UI Framework [Vue 3](https://github.com/vuejs/core)
1098
+ - Lightweight UI Components [vine-ui](https://github.com/cenfun/vine-ui)
1099
+ - High Performance Grid [turbogrid](https://github.com/cenfun/turbogrid)
1100
+ - String compress/decompress [lz-utils](https://github.com/cenfun/lz-utils)
package/lib/index.js CHANGED
@@ -96,8 +96,11 @@ class Reporter {
96
96
 
97
97
  // ==========================================================================
98
98
 
99
+ // Whether this reporter uses stdio for reporting.
100
+ // When it does not, Playwright Test could add some output to enhance user experience.
101
+ // If your reporter does not print to the terminal, it is strongly recommended to return false.
99
102
  printsToStdio() {
100
- return false;
103
+ return true;
101
104
  }
102
105
 
103
106
  // root suite in the reporter.onBegin(config, suite) method.
@@ -1,6 +1,6 @@
1
1
  const fs = require('fs');
2
- const { parse } = require('../runtime/monocart-vendor.js');
3
2
  const Util = require('../utils/util.js');
3
+ const parseSource = require('../utils/parse-source.js');
4
4
 
5
5
  const cacheMap = new Map();
6
6
 
@@ -15,24 +15,25 @@ function getEmptyLines(lines) {
15
15
  return emptyLines;
16
16
  }
17
17
 
18
- const getFileComments = (filePath, parserOptions = {}) => {
18
+ const getFileComments = (sourcePath, options = {}) => {
19
19
 
20
20
  const map = new Map();
21
21
 
22
- if (!fs.existsSync(filePath)) {
22
+ if (!fs.existsSync(sourcePath)) {
23
23
  return map;
24
24
  }
25
25
 
26
- // console.log('babel parse file: ', filePath);
26
+ // console.log('babel parse file: ', sourcePath);
27
27
 
28
- const source = fs.readFileSync(filePath).toString('utf-8');
28
+ const source = fs.readFileSync(sourcePath).toString('utf-8');
29
29
 
30
- let ast;
31
- try {
32
- ast = parse(source, parserOptions);
33
- } catch (e) {
34
- Util.logError(e.message);
35
- Util.logError(`failed to collect comments from the file: ${Util.relativePath(filePath)}`);
30
+ const ast = parseSource({
31
+ source,
32
+ sourcePath,
33
+ options
34
+ });
35
+
36
+ if (!ast) {
36
37
  return map;
37
38
  }
38
39
 
@@ -1,11 +1,10 @@
1
1
  const path = require('path');
2
2
 
3
3
  const Util = require('../../../utils/util.js');
4
+ const decodeMappings = require('../../../utils/decode-mappings.js');
4
5
 
5
6
  // position mapping for conversion between offset and line/column
6
7
  const PositionMapping = require('./position-mapping.js');
7
-
8
- const decodeMappings = require('./decode-mappings.js');
9
8
  const findOriginalRange = require('./find-original-range.js');
10
9
 
11
10
  const { dedupeCountRanges } = require('./dedupe.js');
@@ -222,8 +221,6 @@ const getDistCoverage = (item, state) => {
222
221
  addJsCoverage(coverage, block, range, index, positionMapping);
223
222
  });
224
223
  });
225
- // only for js
226
- item.ranges = coverage.ranges;
227
224
  return coverage;
228
225
  }
229
226
 
@@ -238,10 +235,76 @@ const unpackDistSource = (item, state) => {
238
235
  const coverage = getDistCoverage(item, state);
239
236
  const sourcePath = item.sourcePath;
240
237
  state.coverageData[sourcePath] = getFileCoverage(sourcePath, coverage);
238
+ // after dedupe
239
+ item.ranges = coverage.ranges;
241
240
  };
242
241
 
243
242
  // ========================================================================================================
244
243
 
244
+ const decodeSourceMappings = async (sourceMap, generatedPositionMapping) => {
245
+
246
+ const decodedList = await decodeMappings(sourceMap.mappings);
247
+
248
+ const originalIndexMap = new Map();
249
+ sourceMap.sources.forEach((item, i) => {
250
+ originalIndexMap.set(i, []);
251
+ });
252
+
253
+ const allDecodedMappings = [];
254
+ let generatedIndex = 0;
255
+ decodedList.forEach((segments, generatedLine) => {
256
+ let item = null;
257
+ segments.forEach((segment) => {
258
+ const [generatedColumn, sourceIndex, originalLine, originalColumn] = segment;
259
+ const generatedOffset = generatedPositionMapping.locationToOffset({
260
+ // 1-base
261
+ line: generatedLine + 1,
262
+ column: generatedColumn
263
+ });
264
+
265
+ item = {
266
+ generatedOffset,
267
+ generatedLine,
268
+ generatedColumn,
269
+ generatedIndex,
270
+
271
+ sourceIndex,
272
+ originalLine,
273
+ originalColumn
274
+ };
275
+
276
+ allDecodedMappings.push(item);
277
+ generatedIndex += 1;
278
+
279
+ if (typeof sourceIndex === 'undefined') {
280
+ return;
281
+ }
282
+
283
+ originalIndexMap.get(sourceIndex).push(item);
284
+
285
+ });
286
+
287
+ // line last one
288
+ if (item) {
289
+ const line = generatedPositionMapping.getLine(item.generatedLine + 1);
290
+ // last column
291
+ item.generatedEndOffset = item.generatedOffset + (line.length - item.generatedColumn);
292
+ }
293
+
294
+ });
295
+
296
+ // defaults to sort by generated offset, not need sort
297
+ // allDecodedMappings.sort((a, b) => {
298
+ // return a.generatedOffset - b.generatedOffset;
299
+ // });
300
+
301
+ return {
302
+ allDecodedMappings,
303
+ originalIndexMap
304
+ };
305
+
306
+ };
307
+
245
308
  const getOriginalDecodedMappings = (originalIndexMap, sourceIndex, positionMapping) => {
246
309
  // all mappings for the original file sorted
247
310
  const decodedMappings = originalIndexMap.get(sourceIndex);
@@ -323,70 +386,6 @@ const initOriginalList = (sourceMap, originalIndexMap, fileSources, options) =>
323
386
  return map;
324
387
  };
325
388
 
326
- const decodeSourceMappings = async (sourceMap, generatedPositionMapping) => {
327
-
328
- const decodedList = await decodeMappings(sourceMap.mappings);
329
-
330
- const originalIndexMap = new Map();
331
- sourceMap.sources.forEach((item, i) => {
332
- originalIndexMap.set(i, []);
333
- });
334
-
335
- const allDecodedMappings = [];
336
- let generatedIndex = 0;
337
- decodedList.forEach((segments, generatedLine) => {
338
- let item = null;
339
- segments.forEach((segment) => {
340
- const [generatedColumn, sourceIndex, originalLine, originalColumn] = segment;
341
- const generatedOffset = generatedPositionMapping.locationToOffset({
342
- // 1-base
343
- line: generatedLine + 1,
344
- column: generatedColumn
345
- });
346
-
347
- item = {
348
- generatedOffset,
349
- generatedLine,
350
- generatedColumn,
351
- generatedIndex,
352
-
353
- sourceIndex,
354
- originalLine,
355
- originalColumn
356
- };
357
-
358
- allDecodedMappings.push(item);
359
- generatedIndex += 1;
360
-
361
- if (typeof sourceIndex === 'undefined') {
362
- return;
363
- }
364
-
365
- originalIndexMap.get(sourceIndex).push(item);
366
-
367
- });
368
-
369
- // line last one
370
- if (item) {
371
- const line = generatedPositionMapping.getLine(item.generatedLine + 1);
372
- // last column
373
- item.generatedEndOffset = item.generatedOffset + (line.length - item.generatedColumn);
374
- }
375
-
376
- });
377
-
378
- // defaults to sort by generated offset, not need sort
379
- // allDecodedMappings.sort((a, b) => {
380
- // return a.generatedOffset - b.generatedOffset;
381
- // });
382
-
383
- return {
384
- allDecodedMappings,
385
- originalIndexMap
386
- };
387
-
388
- };
389
-
390
389
  const unpackSourceMap = async (item, state, options) => {
391
390
  const sourceMap = item.sourceMap;
392
391
  const generatedPositionMapping = state.positionMapping;
@@ -28,6 +28,11 @@ const findOffsetMapping = (generatedState, offset) => {
28
28
 
29
29
  const decodedMappings = generatedState.decodedMappings;
30
30
 
31
+ // possible no length
32
+ if (!decodedMappings.length) {
33
+ return;
34
+ }
35
+
31
36
  const mapping = findMapping(decodedMappings, offset);
32
37
 
33
38
  const generatedOffset = mapping.generatedOffset;