vita-playwright 1.0.7 → 1.1.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.
- package/README.md +33 -9
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/src/utils/lighhouse_utility.d.ts +12 -0
- package/dist/src/utils/lighhouse_utility.js +110 -0
- package/dist/src/utils/lighhouse_utility.js.map +1 -0
- package/index.ts +3 -1
- package/package.json +4 -2
- package/src/utils/lighhouse_utility.ts +92 -0
package/README.md
CHANGED
|
@@ -34,22 +34,46 @@ import { DocsReaderHelper } from '../../../helpers/docs-reader-helper';
|
|
|
34
34
|
console.log(csvData);
|
|
35
35
|
})
|
|
36
36
|
|
|
37
|
-
#### output(keys are specific to excel file)
|
|
38
|
-
{
|
|
39
|
-
Username: [ '***', '***'],
|
|
40
|
-
Identifier: ['***', '***'],
|
|
41
|
-
'First name': ['***', '***'],
|
|
42
|
-
'Last name': ['***', '***']
|
|
43
|
-
}
|
|
44
37
|
```
|
|
45
38
|
<br />
|
|
46
39
|
|
|
47
|
-
## Contribution
|
|
40
|
+
<!-- ## Contribution
|
|
48
41
|
|
|
49
42
|
Pull requests are welcome. For major changes, please open an issue first
|
|
50
43
|
to discuss what you would like to change.
|
|
51
44
|
|
|
52
|
-
Please make sure to update tests as appropriate.
|
|
45
|
+
Please make sure to update tests as appropriate. -->
|
|
46
|
+
</details>
|
|
47
|
+
|
|
48
|
+
<details>
|
|
49
|
+
<summary>excel utilities</summary><br/>
|
|
50
|
+
|
|
51
|
+
### Installation
|
|
52
|
+
|
|
53
|
+
Use the package manager [npm](https://www.npmjs.com/) to install xlsx.
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install xlsx
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Usage
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import path from 'node:path';
|
|
63
|
+
import { DocsReaderHelper } from '../../../helpers/docs-reader-helper';
|
|
64
|
+
|
|
65
|
+
test("read data from excel file", async ()=>{
|
|
66
|
+
const pathtoExcel =path.resolve(__dirname,"../../../../resources/**/**.xlsx");
|
|
67
|
+
const excelData = await DocsReaderHelper.readDataFromExcelorCSV(pathtoExcel);
|
|
68
|
+
console.log(excelData);
|
|
69
|
+
|
|
70
|
+
const pathtoExcel =path.resolve(__dirname,"../../../../resources/**/**.csv");
|
|
71
|
+
const csvData = await DocsReaderHelper.readDataFromExcelorCSV(pathtoExcel);
|
|
72
|
+
console.log(csvData);
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
<br />
|
|
53
77
|
</details>
|
|
54
78
|
|
|
55
79
|
</details>
|
package/dist/index.d.ts
CHANGED
|
@@ -7,4 +7,5 @@ import { DocumentUtility } from "./src/utils/document_utility";
|
|
|
7
7
|
import { KeyVaultMethods } from "./src/utils/keyvault_methods";
|
|
8
8
|
import { TestData } from "./src/utils/test_data";
|
|
9
9
|
import { XmlToJson } from "./src/utils/xmlToJson";
|
|
10
|
-
|
|
10
|
+
import { LightHouseUtility } from "./src/utils/lighhouse_utility";
|
|
11
|
+
export { UIHelper, ApiHelper, TokenGenerators, AzureStorageMethods, Comparisions, DocumentUtility, KeyVaultMethods, TestData, XmlToJson, LightHouseUtility };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.XmlToJson = exports.TestData = exports.KeyVaultMethods = exports.DocumentUtility = exports.Comparisions = exports.AzureStorageMethods = exports.TokenGenerators = exports.ApiHelper = exports.UIHelper = void 0;
|
|
3
|
+
exports.LightHouseUtility = exports.XmlToJson = exports.TestData = exports.KeyVaultMethods = exports.DocumentUtility = exports.Comparisions = exports.AzureStorageMethods = exports.TokenGenerators = exports.ApiHelper = exports.UIHelper = void 0;
|
|
4
4
|
const ui_helpers_1 = require("./src/helpers/ui-helpers");
|
|
5
5
|
Object.defineProperty(exports, "UIHelper", { enumerable: true, get: function () { return ui_helpers_1.UIHelper; } });
|
|
6
6
|
const api_helpers_1 = require("./src/helpers/api-helpers");
|
|
@@ -19,4 +19,6 @@ const test_data_1 = require("./src/utils/test_data");
|
|
|
19
19
|
Object.defineProperty(exports, "TestData", { enumerable: true, get: function () { return test_data_1.TestData; } });
|
|
20
20
|
const xmlToJson_1 = require("./src/utils/xmlToJson");
|
|
21
21
|
Object.defineProperty(exports, "XmlToJson", { enumerable: true, get: function () { return xmlToJson_1.XmlToJson; } });
|
|
22
|
+
const lighhouse_utility_1 = require("./src/utils/lighhouse_utility");
|
|
23
|
+
Object.defineProperty(exports, "LightHouseUtility", { enumerable: true, get: function () { return lighhouse_utility_1.LightHouseUtility; } });
|
|
22
24
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;AAAA,yDAAoD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;AAAA,yDAAoD;AAYhD,yFAZK,qBAAQ,OAYL;AAXZ,2DAAsD;AAYlD,0FAZK,uBAAS,OAYL;AAXb,qDAAwD;AAYpD,gGAZK,2BAAe,OAYL;AAXnB,6EAAwE;AAYpE,oGAZK,2CAAmB,OAYL;AAXvB,2DAAwD;AAYpD,6FAZK,2BAAY,OAYL;AAXhB,mEAA+D;AAY3D,gGAZK,kCAAe,OAYL;AAXnB,mEAA+D;AAY3D,gGAZK,kCAAe,OAYL;AAXnB,qDAAiD;AAY7C,yFAZK,oBAAQ,OAYL;AAXZ,qDAAkD;AAY9C,0FAZK,qBAAS,OAYL;AAXb,qEAAkE;AAY9D,kGAZK,qCAAiB,OAYL"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class LightHouseUtility {
|
|
2
|
+
static auditLightHouse(pageurl: string, deviceType: any, filename: any, customThresholds?: {
|
|
3
|
+
performance: number;
|
|
4
|
+
accessibility: number;
|
|
5
|
+
'best-practices': number;
|
|
6
|
+
seo: number;
|
|
7
|
+
pwa: number;
|
|
8
|
+
}, format?: {
|
|
9
|
+
html: boolean;
|
|
10
|
+
}): Promise<void>;
|
|
11
|
+
static createLightHouseReport(dirname: string, savefilepath: string, applicationName?: string): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.LightHouseUtility = void 0;
|
|
16
|
+
const lr_desktop_config_1 = __importDefault(require("lighthouse/lighthouse-core/config/lr-desktop-config"));
|
|
17
|
+
const lr_mobile_config_1 = __importDefault(require("lighthouse/lighthouse-core/config/lr-mobile-config"));
|
|
18
|
+
const playwright_lighthouse_1 = require("playwright-lighthouse");
|
|
19
|
+
const fs_1 = __importDefault(require("fs"));
|
|
20
|
+
class LightHouseUtility {
|
|
21
|
+
static auditLightHouse(pageurl, deviceType, filename, customThresholds = {
|
|
22
|
+
performance: 80,
|
|
23
|
+
accessibility: 70,
|
|
24
|
+
'best-practices': 70,
|
|
25
|
+
seo: 70,
|
|
26
|
+
pwa: 70,
|
|
27
|
+
}, format = { html: true }) {
|
|
28
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
deviceType = deviceType === "mobile" ? lr_mobile_config_1.default : lr_desktop_config_1.default;
|
|
30
|
+
const options = {
|
|
31
|
+
"loglevel": "info"
|
|
32
|
+
};
|
|
33
|
+
yield (0, playwright_lighthouse_1.playAudit)({
|
|
34
|
+
url: pageurl,
|
|
35
|
+
opts: options,
|
|
36
|
+
config: deviceType,
|
|
37
|
+
thresholds: customThresholds,
|
|
38
|
+
ignoreError: true,
|
|
39
|
+
port: 9222,
|
|
40
|
+
reports: {
|
|
41
|
+
formats: format,
|
|
42
|
+
name: filename,
|
|
43
|
+
directory: `${process.cwd()}/lighthouse/pages/`
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
static createLightHouseReport(dirname, savefilepath, applicationName = "My Trips") {
|
|
49
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
50
|
+
var str = ``;
|
|
51
|
+
var sno = 0;
|
|
52
|
+
fs_1.default.readdir(dirname, function (err, filenames) {
|
|
53
|
+
if (err) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
filenames.forEach(function (file) {
|
|
57
|
+
sno = sno + 1;
|
|
58
|
+
str = str + '<tr class="center"><td> ' + sno + ' </td><td>' + file.split('.')[0] + '</td><td>\n<iframe src="./' + dirname.split('/')[dirname.split('/').length - 1] + '/' + file + '" width="100%" height="300" scrolling="no"></iframe></td><td>\n<p> <a href="./' + dirname.split('/')[dirname.split('/').length - 1] + '/' + file + '" target="_blank">open in new tab</a></p></td></tr>';
|
|
59
|
+
});
|
|
60
|
+
str = `<html>
|
|
61
|
+
<head>
|
|
62
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
63
|
+
<style>
|
|
64
|
+
table, th, td {
|
|
65
|
+
border: 1px solid black;
|
|
66
|
+
border-collapse: collapse;
|
|
67
|
+
}
|
|
68
|
+
table {
|
|
69
|
+
width: 55%;
|
|
70
|
+
}
|
|
71
|
+
td, th {
|
|
72
|
+
text-align: center;
|
|
73
|
+
color: #080;
|
|
74
|
+
}
|
|
75
|
+
h1 {
|
|
76
|
+
text-align: center;
|
|
77
|
+
color: #fa3
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.center {
|
|
81
|
+
margin-left: auto;
|
|
82
|
+
margin-right: auto;
|
|
83
|
+
}
|
|
84
|
+
div{
|
|
85
|
+
overflow-x:auto;
|
|
86
|
+
}
|
|
87
|
+
</style>
|
|
88
|
+
</head>
|
|
89
|
+
<body>
|
|
90
|
+
|
|
91
|
+
<h1><u>` + applicationName + ` Performance Testing Status</u></h1>
|
|
92
|
+
<div>
|
|
93
|
+
<table class='center'>
|
|
94
|
+
<tr class='center'>
|
|
95
|
+
<th> Sno </th>
|
|
96
|
+
<th>Pagename</th>
|
|
97
|
+
<th>Status</th>
|
|
98
|
+
<th> Link </th>
|
|
99
|
+
</tr>` + str + `
|
|
100
|
+
</table>
|
|
101
|
+
</div>
|
|
102
|
+
</body>
|
|
103
|
+
</html>`;
|
|
104
|
+
fs_1.default.writeFileSync(savefilepath, str);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.LightHouseUtility = LightHouseUtility;
|
|
110
|
+
//# sourceMappingURL=lighhouse_utility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lighhouse_utility.js","sourceRoot":"","sources":["../../../src/utils/lighhouse_utility.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,4GAA0F;AAC1F,0GAAwF;AACxF,iEAAkD;AAClD,4CAAoB;AAEpB,MAAa,iBAAiB;IAE1B,MAAM,CAAO,eAAe,CAAC,OAAe,EAAE,UAAU,EAAE,QAAQ,EAAE,gBAAgB,GAAG;QACnF,WAAW,EAAE,EAAE;QACf,aAAa,EAAE,EAAE;QACjB,gBAAgB,EAAE,EAAE;QACpB,GAAG,EAAE,EAAE;QACP,GAAG,EAAE,EAAE;KACV,EAAE,MAAM,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE;;YACtB,UAAU,GAAG,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,0BAAsB,CAAC,CAAC,CAAC,2BAAuB,CAAC;YACxF,MAAM,OAAO,GAAG;gBACZ,UAAU,EAAE,MAAM;aACrB,CAAC;YACF,MAAM,IAAA,iCAAS,EAAC;gBACZ,GAAG,EAAE,OAAO;gBACZ,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,UAAU;gBAClB,UAAU,EAAE,gBAAgB;gBAC5B,WAAW,EAAE,IAAI;gBACjB,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE;oBACL,OAAO,EAAE,MAAM;oBACf,IAAI,EAAE,QAAQ;oBACd,SAAS,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,oBAAoB;iBAClD;aACJ,CAAC,CAAC;QACP,CAAC;KAAA;IAED,MAAM,CAAO,sBAAsB,CAAC,OAAe,EAAE,YAAoB,EAAE,eAAe,GAAE,UAAU;;YAClG,IAAI,GAAG,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,GAAG,CAAC,CAAC;YACZ,YAAE,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,EAAE,SAAS;gBACxC,IAAI,GAAG,EAAE;oBACL,OAAO;iBACV;gBACD,SAAS,CAAC,OAAO,CAAC,UAAU,IAAI;oBAC5B,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;oBACd,GAAG,GAAG,GAAG,GAAG,6BAA6B,GAAG,GAAG,GAAG,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,4BAA4B,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,GAAG,gFAAgF,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,GAAG,qDAAqD,CAAA;gBACtY,CAAC,CAAC,CAAC;gBACH,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA+BM,GAAC,eAAe,GAAC;;;;;;;;sBAQnB,GAAG,GAAG,GAAG;;;;wBAIP,CAAC;gBACb,YAAE,CAAC,aAAa,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;QACP,CAAC;KAAA;CACJ;AAtFD,8CAsFC"}
|
package/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { DocumentUtility } from "./src/utils/document_utility";
|
|
|
7
7
|
import { KeyVaultMethods } from "./src/utils/keyvault_methods";
|
|
8
8
|
import { TestData } from "./src/utils/test_data";
|
|
9
9
|
import { XmlToJson } from "./src/utils/xmlToJson";
|
|
10
|
+
import { LightHouseUtility } from "./src/utils/lighhouse_utility";
|
|
10
11
|
|
|
11
12
|
export {
|
|
12
13
|
UIHelper,
|
|
@@ -17,5 +18,6 @@ export {
|
|
|
17
18
|
DocumentUtility,
|
|
18
19
|
KeyVaultMethods,
|
|
19
20
|
TestData,
|
|
20
|
-
XmlToJson
|
|
21
|
+
XmlToJson,
|
|
22
|
+
LightHouseUtility
|
|
21
23
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vita-playwright",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"url": "https://github.com/Vialto/fbt-test-automation",
|
|
5
5
|
"email": "noreply_testautomation@vialto.com",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -41,7 +41,9 @@
|
|
|
41
41
|
"lodash": "^4.17.21",
|
|
42
42
|
"playwright": "^1.25.0",
|
|
43
43
|
"robotjs": "^0.6.0",
|
|
44
|
-
"xlsx": "^0.18.5"
|
|
44
|
+
"xlsx": "^0.18.5",
|
|
45
|
+
"playwright-lighthouse": "^2.2.2",
|
|
46
|
+
"lighthouse": "^9.6.8"
|
|
45
47
|
},
|
|
46
48
|
"author": "Vialto QE",
|
|
47
49
|
"license": "ISC",
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import lighthouseDesktopConfig from 'lighthouse/lighthouse-core/config/lr-desktop-config';
|
|
2
|
+
import lighthouseMobileConfig from 'lighthouse/lighthouse-core/config/lr-mobile-config';
|
|
3
|
+
import { playAudit } from 'playwright-lighthouse';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
|
|
6
|
+
export class LightHouseUtility {
|
|
7
|
+
|
|
8
|
+
static async auditLightHouse(pageurl: string, deviceType, filename, customThresholds = {
|
|
9
|
+
performance: 80,
|
|
10
|
+
accessibility: 70,
|
|
11
|
+
'best-practices': 70,
|
|
12
|
+
seo: 70,
|
|
13
|
+
pwa: 70,
|
|
14
|
+
}, format = { html: true }) {
|
|
15
|
+
deviceType = deviceType === "mobile" ? lighthouseMobileConfig : lighthouseDesktopConfig;
|
|
16
|
+
const options = {
|
|
17
|
+
"loglevel": "info"
|
|
18
|
+
};
|
|
19
|
+
await playAudit({
|
|
20
|
+
url: pageurl,
|
|
21
|
+
opts: options,
|
|
22
|
+
config: deviceType,
|
|
23
|
+
thresholds: customThresholds,
|
|
24
|
+
ignoreError: true,
|
|
25
|
+
port: 9222,
|
|
26
|
+
reports: {
|
|
27
|
+
formats: format,
|
|
28
|
+
name: filename,
|
|
29
|
+
directory: `${process.cwd()}/lighthouse/pages/`
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static async createLightHouseReport(dirname: string, savefilepath: string, applicationName ="My Trips") {
|
|
35
|
+
var str = ``;
|
|
36
|
+
var sno = 0;
|
|
37
|
+
fs.readdir(dirname, function (err, filenames) {
|
|
38
|
+
if (err) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
filenames.forEach(function (file) {
|
|
42
|
+
sno = sno + 1;
|
|
43
|
+
str = str + '<tr class="center"><td> ' + sno + ' </td><td>' + file.split('.')[0] + '</td><td>\n<iframe src="./' + dirname.split('/')[dirname.split('/').length - 1] + '/' + file + '" width="100%" height="300" scrolling="no"></iframe></td><td>\n<p> <a href="./' + dirname.split('/')[dirname.split('/').length - 1] + '/' + file + '" target="_blank">open in new tab</a></p></td></tr>'
|
|
44
|
+
});
|
|
45
|
+
str = `<html>
|
|
46
|
+
<head>
|
|
47
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
48
|
+
<style>
|
|
49
|
+
table, th, td {
|
|
50
|
+
border: 1px solid black;
|
|
51
|
+
border-collapse: collapse;
|
|
52
|
+
}
|
|
53
|
+
table {
|
|
54
|
+
width: 55%;
|
|
55
|
+
}
|
|
56
|
+
td, th {
|
|
57
|
+
text-align: center;
|
|
58
|
+
color: #080;
|
|
59
|
+
}
|
|
60
|
+
h1 {
|
|
61
|
+
text-align: center;
|
|
62
|
+
color: #fa3
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.center {
|
|
66
|
+
margin-left: auto;
|
|
67
|
+
margin-right: auto;
|
|
68
|
+
}
|
|
69
|
+
div{
|
|
70
|
+
overflow-x:auto;
|
|
71
|
+
}
|
|
72
|
+
</style>
|
|
73
|
+
</head>
|
|
74
|
+
<body>
|
|
75
|
+
|
|
76
|
+
<h1><u>`+applicationName+` Performance Testing Status</u></h1>
|
|
77
|
+
<div>
|
|
78
|
+
<table class='center'>
|
|
79
|
+
<tr class='center'>
|
|
80
|
+
<th> Sno </th>
|
|
81
|
+
<th>Pagename</th>
|
|
82
|
+
<th>Status</th>
|
|
83
|
+
<th> Link </th>
|
|
84
|
+
</tr>` + str + `
|
|
85
|
+
</table>
|
|
86
|
+
</div>
|
|
87
|
+
</body>
|
|
88
|
+
</html>`;
|
|
89
|
+
fs.writeFileSync(savefilepath, str);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|