@thinkwise/testwise 0.1.97 → 0.2.0-beta.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/Testwise.ts +8 -13
- package/artifact-builder/ArtifactManager.ts +34 -0
- package/artifact-builder/InterfaceGenerator.ts +183 -0
- package/artifact-builder/ModelDataBuilder.ts +177 -0
- package/artifact-builder/ModelDataRefiner.ts +38 -0
- package/artifact-builder/SchemaGenerator.ts +134 -0
- package/artifact-builder/ScreenInterfaceRefiner.ts +159 -0
- package/artifact-builder/SelectorBuilder.ts +82 -0
- package/artifact-builder/SubjectComponentGenerator.ts +186 -0
- package/artifact-builder/SubjectGenerator.ts +332 -0
- package/artifact-builder/SubjectRegistration.ts +136 -0
- package/artifact-builder/helpers/DataRetriever.ts +64 -0
- package/artifact-builder/helpers/NamingHandler.ts +180 -0
- package/artifact-builder/helpers/index.ts +2 -0
- package/artifact-builder/index.ts +9 -0
- package/components/{actionbar/Actionbar.ts → action-bar/ActionBar.ts} +12 -12
- package/components/{actionbar/ActionbarObjects.ts → action-bar/ActionBarObjects.ts} +4 -4
- package/components/{actionbar → action-bar}/CustomActionBar.ts +2 -2
- package/components/index.ts +3 -4
- package/components/tab/DetailTabPage.ts +20 -0
- package/components/tab/{DetailTabObjects.ts → DetailTabPageObjects.ts} +1 -1
- package/components/tab/Tab.ts +31 -5
- package/components/tab/TabObjects.ts +15 -3
- package/dist/Testwise.d.ts +0 -1
- package/dist/Testwise.js +7 -14
- package/dist/Testwise.js.map +1 -1
- package/dist/artifact-builder/ArtifactManager.d.ts +8 -0
- package/dist/artifact-builder/ArtifactManager.js +27 -0
- package/dist/artifact-builder/ArtifactManager.js.map +1 -0
- package/dist/artifact-builder/InterfaceGenerator.d.ts +16 -0
- package/dist/artifact-builder/InterfaceGenerator.js +134 -0
- package/dist/artifact-builder/InterfaceGenerator.js.map +1 -0
- package/dist/artifact-builder/ModelDataBuilder.d.ts +2 -0
- package/dist/artifact-builder/ModelDataBuilder.js +128 -0
- package/dist/artifact-builder/ModelDataBuilder.js.map +1 -0
- package/dist/artifact-builder/ModelDataRefiner.d.ts +4 -0
- package/dist/artifact-builder/ModelDataRefiner.js +28 -0
- package/dist/artifact-builder/ModelDataRefiner.js.map +1 -0
- package/dist/artifact-builder/SchemaGenerator.d.ts +12 -0
- package/dist/artifact-builder/SchemaGenerator.js +104 -0
- package/dist/artifact-builder/SchemaGenerator.js.map +1 -0
- package/dist/artifact-builder/ScreenInterfaceRefiner.d.ts +15 -0
- package/dist/artifact-builder/ScreenInterfaceRefiner.js +125 -0
- package/dist/artifact-builder/ScreenInterfaceRefiner.js.map +1 -0
- package/dist/artifact-builder/SelectorBuilder.d.ts +13 -0
- package/dist/artifact-builder/SelectorBuilder.js +69 -0
- package/dist/artifact-builder/SelectorBuilder.js.map +1 -0
- package/dist/artifact-builder/SubjectComponentGenerator.d.ts +23 -0
- package/dist/artifact-builder/SubjectComponentGenerator.js +136 -0
- package/dist/artifact-builder/SubjectComponentGenerator.js.map +1 -0
- package/dist/artifact-builder/SubjectGenerator.d.ts +27 -0
- package/dist/artifact-builder/SubjectGenerator.js +235 -0
- package/dist/artifact-builder/SubjectGenerator.js.map +1 -0
- package/dist/artifact-builder/SubjectRegistration.d.ts +22 -0
- package/dist/artifact-builder/SubjectRegistration.js +96 -0
- package/dist/artifact-builder/SubjectRegistration.js.map +1 -0
- package/dist/artifact-builder/helpers/DataRetriever.d.ts +12 -0
- package/dist/artifact-builder/helpers/DataRetriever.js +52 -0
- package/dist/artifact-builder/helpers/DataRetriever.js.map +1 -0
- package/dist/artifact-builder/helpers/NamingHandler.d.ts +24 -0
- package/dist/artifact-builder/helpers/NamingHandler.js +145 -0
- package/dist/artifact-builder/helpers/NamingHandler.js.map +1 -0
- package/dist/artifact-builder/helpers/index.d.ts +2 -0
- package/dist/artifact-builder/helpers/index.js +3 -0
- package/dist/artifact-builder/helpers/index.js.map +1 -0
- package/dist/artifact-builder/index.d.ts +9 -0
- package/dist/artifact-builder/index.js +10 -0
- package/dist/artifact-builder/index.js.map +1 -0
- package/dist/components/{actionbar/Actionbar.d.ts → action-bar/ActionBar.d.ts} +4 -4
- package/dist/components/{actionbar/Actionbar.js → action-bar/ActionBar.js} +9 -9
- package/dist/components/action-bar/ActionBar.js.map +1 -0
- package/dist/components/{actionbar/ActionbarObjects.d.ts → action-bar/ActionBarObjects.d.ts} +2 -2
- package/dist/components/{actionbar/ActionbarObjects.js → action-bar/ActionBarObjects.js} +5 -5
- package/dist/components/action-bar/ActionBarObjects.js.map +1 -0
- package/dist/components/{actionbar → action-bar}/CustomActionBar.d.ts +2 -2
- package/dist/components/action-bar/CustomActionBar.js +7 -0
- package/dist/components/action-bar/CustomActionBar.js.map +1 -0
- package/dist/components/index.d.ts +3 -4
- package/dist/components/index.js +3 -4
- package/dist/components/index.js.map +1 -1
- package/dist/components/tab/DetailTabPage.d.ts +9 -0
- package/dist/components/tab/DetailTabPage.js +15 -0
- package/dist/components/tab/DetailTabPage.js.map +1 -0
- package/dist/components/tab/{DetailTabObjects.d.ts → DetailTabPageObjects.d.ts} +1 -1
- package/dist/components/tab/{DetailTabObjects.js → DetailTabPageObjects.js} +2 -2
- package/dist/components/tab/DetailTabPageObjects.js.map +1 -0
- package/dist/components/tab/Tab.d.ts +8 -3
- package/dist/components/tab/Tab.js +25 -4
- package/dist/components/tab/Tab.js.map +1 -1
- package/dist/components/tab/TabObjects.d.ts +7 -2
- package/dist/components/tab/TabObjects.js +9 -2
- package/dist/components/tab/TabObjects.js.map +1 -1
- package/dist/enums/ElementTypes.d.ts +8 -0
- package/dist/enums/ElementTypes.js +10 -0
- package/dist/enums/ElementTypes.js.map +1 -0
- package/dist/helpers/PathResolver.d.ts +3 -0
- package/dist/helpers/PathResolver.js +26 -0
- package/dist/helpers/PathResolver.js.map +1 -0
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.js +1 -0
- package/dist/helpers/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/IProperty.d.ts +4 -0
- package/dist/interfaces/IProperty.js +2 -0
- package/dist/interfaces/IProperty.js.map +1 -0
- package/dist/interfaces/IRegisteredSubjects.d.ts +5 -0
- package/dist/interfaces/IRegisteredSubjects.js +2 -0
- package/dist/interfaces/IRegisteredSubjects.js.map +1 -0
- package/dist/interfaces/ISubject.d.ts +8 -0
- package/dist/interfaces/ISubject.js +2 -0
- package/dist/interfaces/ISubject.js.map +1 -0
- package/dist/page-extensions/SubjectProvider.d.ts +11 -0
- package/dist/page-extensions/SubjectProvider.js +24 -0
- package/dist/page-extensions/SubjectProvider.js.map +1 -0
- package/dist/page-extensions/SubjectRegistry.d.ts +14 -0
- package/dist/page-extensions/SubjectRegistry.js +14 -0
- package/dist/page-extensions/SubjectRegistry.js.map +1 -0
- package/dist/page-extensions/index.d.ts +3 -0
- package/dist/page-extensions/index.js +3 -0
- package/dist/page-extensions/index.js.map +1 -1
- package/dist/services/ConfigBuilder.d.ts +1 -0
- package/dist/services/ConfigBuilder.js +20 -1
- package/dist/services/ConfigBuilder.js.map +1 -1
- package/dist/test-artifacts/SubjectPageBase.d.ts +5 -0
- package/dist/test-artifacts/SubjectPageBase.js +6 -0
- package/dist/test-artifacts/SubjectPageBase.js.map +1 -0
- package/dist/test-artifacts/index.d.ts +3 -0
- package/dist/test-artifacts/index.js +4 -0
- package/dist/test-artifacts/index.js.map +1 -0
- package/dist/test-artifacts/screens/index.d.ts +1 -0
- package/dist/test-artifacts/screens/index.js +2 -0
- package/dist/test-artifacts/screens/index.js.map +1 -0
- package/dist/test-artifacts/subjects/index.d.ts +1 -0
- package/dist/test-artifacts/subjects/index.js +2 -0
- package/dist/test-artifacts/subjects/index.js.map +1 -0
- package/dist/types/Components.d.ts +7 -0
- package/dist/types/Components.js +28 -0
- package/dist/types/Components.js.map +1 -0
- package/enums/ElementTypes.ts +8 -0
- package/helpers/PathResolver.ts +30 -0
- package/helpers/index.ts +1 -0
- package/index.ts +1 -0
- package/interfaces/IProperty.ts +4 -0
- package/interfaces/IRegisteredSubjects.ts +5 -0
- package/interfaces/ISubject.ts +9 -0
- package/package.json +26 -9
- package/page-extensions/SubjectProvider.ts +41 -0
- package/page-extensions/SubjectRegistry.ts +30 -0
- package/page-extensions/index.ts +3 -0
- package/promptCredentials.js +124 -124
- package/scripts/Testwise.template.json +4 -1
- package/scripts/main.js +75 -4
- package/scripts/postinstall.js +42 -0
- package/scripts/setup.js +17 -14
- package/scripts/sync.js +69 -0
- package/scripts/tsconfig.template.json +1 -1
- package/services/ConfigBuilder.ts +25 -2
- package/test-artifacts/SubjectPageBase.ts +9 -0
- package/test-artifacts/index.ts +3 -0
- package/test-artifacts/screens/index.ts +0 -0
- package/test-artifacts/subjects/index.ts +0 -0
- package/tsconfig.json +1 -1
- package/types/Components.ts +55 -0
- package/components/tab/ComponentTab.ts +0 -40
- package/components/tab/ComponentTabObjects.ts +0 -17
- package/components/tab/DetailTab.ts +0 -20
- package/dist/Testwise.json +0 -25
- package/dist/bdd.d.ts +0 -6
- package/dist/bdd.js +0 -9
- package/dist/bdd.js.map +0 -1
- package/dist/biome.json +0 -52
- package/dist/components/actionbar/Actionbar.js.map +0 -1
- package/dist/components/actionbar/ActionbarObjects.js.map +0 -1
- package/dist/components/actionbar/CustomActionBar.js +0 -7
- package/dist/components/actionbar/CustomActionBar.js.map +0 -1
- package/dist/components/tab/ComponentTab.d.ts +0 -12
- package/dist/components/tab/ComponentTab.js +0 -31
- package/dist/components/tab/ComponentTab.js.map +0 -1
- package/dist/components/tab/ComponentTabObjects.d.ts +0 -8
- package/dist/components/tab/ComponentTabObjects.js +0 -11
- package/dist/components/tab/ComponentTabObjects.js.map +0 -1
- package/dist/components/tab/DetailTab.d.ts +0 -9
- package/dist/components/tab/DetailTab.js +0 -15
- package/dist/components/tab/DetailTab.js.map +0 -1
- package/dist/components/tab/DetailTabObjects.js.map +0 -1
- package/dist/helpers/TestExtensions.d.ts +0 -8
- package/dist/helpers/TestExtensions.js +0 -21
- package/dist/helpers/TestExtensions.js.map +0 -1
- package/dist/package-lock.json +0 -3852
- package/dist/package.json +0 -59
- package/dist/scripts/Testwise.template.json +0 -25
- package/dist/scripts/tsconfig.template.json +0 -12
- package/dist/services/ReportingService.d.ts +0 -8
- package/dist/services/ReportingService.js +0 -29
- package/dist/services/ReportingService.js.map +0 -1
- package/dist/tsconfig.json +0 -20
- package/services/ReportingService.ts +0 -37
package/promptCredentials.js
CHANGED
|
@@ -1,124 +1,124 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { spawnSync } from 'node:child_process';
|
|
3
|
-
import { readFileSync } from 'node:fs';
|
|
4
|
-
import process from 'node:process';
|
|
5
|
-
import chalk from 'chalk';
|
|
6
|
-
import prompts from 'prompts';
|
|
7
|
-
|
|
8
|
-
const packageScripts = JSON.parse(readFileSync('./package.json')).scripts;
|
|
9
|
-
|
|
10
|
-
function exitWithError(error) {
|
|
11
|
-
console.log(chalk.red(error));
|
|
12
|
-
process.exit(1);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function startTestSolution() {
|
|
16
|
-
console.log('Now starting test solution...');
|
|
17
|
-
spawnSync(`yarn --cwd ../ ${args.join(' ')}`, {
|
|
18
|
-
shell: true,
|
|
19
|
-
stdio: 'inherit'
|
|
20
|
-
});
|
|
21
|
-
process.exit();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const args = process.argv.slice(2);
|
|
25
|
-
|
|
26
|
-
if (!args.length) {
|
|
27
|
-
exitWithError('Error: Got too few parameters. Usage: yarn test:credentials test');
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const yarnScriptToExec = args[0];
|
|
31
|
-
|
|
32
|
-
if (!packageScripts[yarnScriptToExec]) {
|
|
33
|
-
exitWithError(`Error: Given script "${yarnScriptToExec}" doesn't exist in package.json.`);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// INCOMING HACK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
37
|
-
// temp fix to be reworked when converting this file to TS
|
|
38
|
-
import fs from 'node:fs';
|
|
39
|
-
import path from 'node:path';
|
|
40
|
-
|
|
41
|
-
const indiciumURL = (() => {
|
|
42
|
-
try {
|
|
43
|
-
const configPath = path.resolve(process.cwd(), './Testwise.json');
|
|
44
|
-
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
45
|
-
return config.environmentSettings?.serviceUrl || '';
|
|
46
|
-
} catch (error) {
|
|
47
|
-
console.error('Error reading Testwise.json:', error);
|
|
48
|
-
return '';
|
|
49
|
-
}
|
|
50
|
-
})();
|
|
51
|
-
|
|
52
|
-
// END OF HACK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
53
|
-
|
|
54
|
-
if (process.env.SF_TEST_USERNAME && process.env.SF_TEST_PASSWORD) {
|
|
55
|
-
console.log('Using SF_TEST_USERNAME and SF_TEST_PASSWORD environment variables.');
|
|
56
|
-
startTestSolution();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const questions = [
|
|
60
|
-
{
|
|
61
|
-
type: 'text',
|
|
62
|
-
name: 'username',
|
|
63
|
-
message: 'Username:',
|
|
64
|
-
validate: (value) => {
|
|
65
|
-
if (!value?.length) {
|
|
66
|
-
return 'Username is required';
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (value.toLowerCase() === 'demo') {
|
|
70
|
-
return 'Running tests locally with demo is forbidden as it results in dataset concurrency problems';
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
type: 'invisible',
|
|
78
|
-
name: 'password',
|
|
79
|
-
message: 'Password:',
|
|
80
|
-
validate: (value) => (!value?.length ? 'Password is required' : true)
|
|
81
|
-
}
|
|
82
|
-
];
|
|
83
|
-
|
|
84
|
-
(async () => {
|
|
85
|
-
const credentialsResponse = await prompts(questions);
|
|
86
|
-
|
|
87
|
-
if (!credentialsResponse || !credentialsResponse.username || !credentialsResponse.password) {
|
|
88
|
-
exitWithError('Username or password was not given');
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const { password, username } = credentialsResponse;
|
|
92
|
-
const params = new URLSearchParams();
|
|
93
|
-
|
|
94
|
-
params.append('UserName', username);
|
|
95
|
-
params.append('Password', password);
|
|
96
|
-
|
|
97
|
-
const fetch = (await import('node-fetch')).default;
|
|
98
|
-
const authResponse = await fetch(`${indiciumURL}/account/api/login`, {
|
|
99
|
-
method: 'POST',
|
|
100
|
-
body: params
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
if (authResponse.status === 204) {
|
|
104
|
-
console.log('Confirmed credentials work @', indiciumURL);
|
|
105
|
-
} else {
|
|
106
|
-
const confirmResponse = await prompts([
|
|
107
|
-
{
|
|
108
|
-
type: 'confirm',
|
|
109
|
-
name: 'value',
|
|
110
|
-
message: `Can't login to ${indiciumURL} with the given credentials. Continue anyways?`,
|
|
111
|
-
initial: true
|
|
112
|
-
}
|
|
113
|
-
]);
|
|
114
|
-
|
|
115
|
-
if (!confirmResponse.value) {
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
process.env.SF_TEST_USERNAME = username;
|
|
121
|
-
process.env.SF_TEST_PASSWORD = password;
|
|
122
|
-
|
|
123
|
-
startTestSolution();
|
|
124
|
-
})();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import process from 'node:process';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import prompts from 'prompts';
|
|
7
|
+
|
|
8
|
+
const packageScripts = JSON.parse(readFileSync('./package.json')).scripts;
|
|
9
|
+
|
|
10
|
+
function exitWithError(error) {
|
|
11
|
+
console.log(chalk.red(error));
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function startTestSolution() {
|
|
16
|
+
console.log('Now starting test solution...');
|
|
17
|
+
spawnSync(`yarn --cwd ../ ${args.join(' ')}`, {
|
|
18
|
+
shell: true,
|
|
19
|
+
stdio: 'inherit'
|
|
20
|
+
});
|
|
21
|
+
process.exit();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const args = process.argv.slice(2);
|
|
25
|
+
|
|
26
|
+
if (!args.length) {
|
|
27
|
+
exitWithError('Error: Got too few parameters. Usage: yarn test:credentials test');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const yarnScriptToExec = args[0];
|
|
31
|
+
|
|
32
|
+
if (!packageScripts[yarnScriptToExec]) {
|
|
33
|
+
exitWithError(`Error: Given script "${yarnScriptToExec}" doesn't exist in package.json.`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// INCOMING HACK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
37
|
+
// temp fix to be reworked when converting this file to TS
|
|
38
|
+
import fs from 'node:fs';
|
|
39
|
+
import path from 'node:path';
|
|
40
|
+
|
|
41
|
+
const indiciumURL = (() => {
|
|
42
|
+
try {
|
|
43
|
+
const configPath = path.resolve(process.cwd(), './Testwise.json');
|
|
44
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
45
|
+
return config.environmentSettings?.serviceUrl || '';
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.error('Error reading Testwise.json:', error);
|
|
48
|
+
return '';
|
|
49
|
+
}
|
|
50
|
+
})();
|
|
51
|
+
|
|
52
|
+
// END OF HACK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
53
|
+
|
|
54
|
+
if (process.env.SF_TEST_USERNAME && process.env.SF_TEST_PASSWORD) {
|
|
55
|
+
console.log('Using SF_TEST_USERNAME and SF_TEST_PASSWORD environment variables.');
|
|
56
|
+
startTestSolution();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const questions = [
|
|
60
|
+
{
|
|
61
|
+
type: 'text',
|
|
62
|
+
name: 'username',
|
|
63
|
+
message: 'Username:',
|
|
64
|
+
validate: (value) => {
|
|
65
|
+
if (!value?.length) {
|
|
66
|
+
return 'Username is required';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (value.toLowerCase() === 'demo') {
|
|
70
|
+
return 'Running tests locally with demo is forbidden as it results in dataset concurrency problems';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
type: 'invisible',
|
|
78
|
+
name: 'password',
|
|
79
|
+
message: 'Password:',
|
|
80
|
+
validate: (value) => (!value?.length ? 'Password is required' : true)
|
|
81
|
+
}
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
(async () => {
|
|
85
|
+
const credentialsResponse = await prompts(questions);
|
|
86
|
+
|
|
87
|
+
if (!credentialsResponse || !credentialsResponse.username || !credentialsResponse.password) {
|
|
88
|
+
exitWithError('Username or password was not given');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const { password, username } = credentialsResponse;
|
|
92
|
+
const params = new URLSearchParams();
|
|
93
|
+
|
|
94
|
+
params.append('UserName', username);
|
|
95
|
+
params.append('Password', password);
|
|
96
|
+
|
|
97
|
+
const fetch = (await import('node-fetch')).default;
|
|
98
|
+
const authResponse = await fetch(`${indiciumURL}/account/api/login`, {
|
|
99
|
+
method: 'POST',
|
|
100
|
+
body: params
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
if (authResponse.status === 204) {
|
|
104
|
+
console.log('Confirmed credentials work @', indiciumURL);
|
|
105
|
+
} else {
|
|
106
|
+
const confirmResponse = await prompts([
|
|
107
|
+
{
|
|
108
|
+
type: 'confirm',
|
|
109
|
+
name: 'value',
|
|
110
|
+
message: `Can't login to ${indiciumURL} with the given credentials. Continue anyways?`,
|
|
111
|
+
initial: true
|
|
112
|
+
}
|
|
113
|
+
]);
|
|
114
|
+
|
|
115
|
+
if (!confirmResponse.value) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
process.env.SF_TEST_USERNAME = username;
|
|
121
|
+
process.env.SF_TEST_PASSWORD = password;
|
|
122
|
+
|
|
123
|
+
startTestSolution();
|
|
124
|
+
})();
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
"environmentSettings" :{
|
|
3
3
|
"baseUrl" : "https://develop.example.app",
|
|
4
4
|
"serviceUrl" : "https://develop.example.app/service",
|
|
5
|
-
"metaEndpoint" : "iam"
|
|
5
|
+
"metaEndpoint" : "iam",
|
|
6
|
+
"authUser" : "ExampleUser",
|
|
7
|
+
"authUserPassword" : "ExamplePassword@1",
|
|
8
|
+
"guiApplAlias" : "ExampleName"
|
|
6
9
|
},
|
|
7
10
|
"featureSettings" :{
|
|
8
11
|
"logger" : {
|
package/scripts/main.js
CHANGED
|
@@ -1,11 +1,82 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
2
4
|
import process from 'node:process';
|
|
5
|
+
import { PathResolver } from '../dist/helpers/index.js';
|
|
6
|
+
import { postinstall } from './postinstall.js';
|
|
3
7
|
import { setup } from './setup.js';
|
|
8
|
+
import { sync } from './sync.js';
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
|
|
10
|
+
await setup();
|
|
11
|
+
const { testwiseConfig } = await import('../dist/services/index.js');
|
|
12
|
+
const config = testwiseConfig();
|
|
13
|
+
const configBuilder = await config.load();
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
if (process.argv[2] === 'postinstall') {
|
|
17
|
+
if (!await verifiedSeedData()) process.exit(0);
|
|
18
|
+
|
|
19
|
+
postinstall();
|
|
7
20
|
} else if (process.argv[2] === 'sync') {
|
|
8
|
-
|
|
21
|
+
if (!await verifiedSeedData()) process.exit(0);
|
|
22
|
+
|
|
23
|
+
sync();
|
|
9
24
|
} else {
|
|
10
|
-
console.warn('Command unknown.
|
|
25
|
+
console.warn('Command unknown.');
|
|
11
26
|
}
|
|
27
|
+
|
|
28
|
+
async function verifiedSeedData() {
|
|
29
|
+
const consumerRoot = new PathResolver().getConsumerRootDirectory();
|
|
30
|
+
const seedDataDir = path.join(consumerRoot, 'seed-data');
|
|
31
|
+
const subjectsJson = path.join(seedDataDir, 'subjects.json');
|
|
32
|
+
const screensDir = path.join(seedDataDir, 'screen-schemas');
|
|
33
|
+
const projectIsConfigured = await isConfigured();
|
|
34
|
+
|
|
35
|
+
if (!fs.existsSync(seedDataDir)) {
|
|
36
|
+
if (projectIsConfigured) {
|
|
37
|
+
fs.mkdirSync(seedDataDir);
|
|
38
|
+
fs.mkdirSync(screensDir);
|
|
39
|
+
|
|
40
|
+
console.log('Created seed-data directory structure.');
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
console.info('No seed-data directory found.');
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!fs.existsSync(subjectsJson) && !projectIsConfigured) {
|
|
49
|
+
console.info('No subjects.json');
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!fs.existsSync(screensDir)) {
|
|
54
|
+
if (projectIsConfigured) {
|
|
55
|
+
fs.mkdirSync(screensDir);
|
|
56
|
+
console.log('Created screen-schemas directory.');
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
console.info('No screen-schemas directory found.');
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const screenFiles = fs.readdirSync(screensDir).filter((f) => f.endsWith('.json'));
|
|
65
|
+
if (screenFiles.length === 0 && !projectIsConfigured) {
|
|
66
|
+
console.info('No screen JSON files found in seed-data/screen-schemas');
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function isConfigured() {
|
|
73
|
+
const user = configBuilder.get('environmentSettings.authUser');
|
|
74
|
+
const password = configBuilder.get('environmentSettings.authUserPassword');
|
|
75
|
+
const guiApplAlias = configBuilder.get('environmentSettings.guiApplAlias');
|
|
76
|
+
|
|
77
|
+
return Boolean(
|
|
78
|
+
user && user !== 'ExampleUser' &&
|
|
79
|
+
password && password !== 'ExamplePassword@1' &&
|
|
80
|
+
guiApplAlias && guiApplAlias !== 'ExampleName'
|
|
81
|
+
);
|
|
82
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import { execSync } from 'node:child_process';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import process from 'node:process';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { ArtifactManager } from '../dist/artifact-builder/index.js';
|
|
8
|
+
import { testwiseConfig } from '../dist/services/ConfigBuilder.js';
|
|
9
|
+
import { sync } from './sync.js';
|
|
10
|
+
|
|
11
|
+
const _filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const _dirname = path.dirname(_filename);
|
|
13
|
+
|
|
14
|
+
export async function postinstall() {
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const autoSync = testwiseConfig().get('featureSettings.other.autoSync') ?? true;
|
|
18
|
+
if (!autoSync) return;
|
|
19
|
+
|
|
20
|
+
const rootDir = path.resolve(_dirname, '..');
|
|
21
|
+
const artifactManager = new ArtifactManager();
|
|
22
|
+
|
|
23
|
+
if (artifactManager.backupExists()) {
|
|
24
|
+
artifactManager.restoreBackup();
|
|
25
|
+
console.info('Restored artifacts from backup.');
|
|
26
|
+
|
|
27
|
+
// const { SubjectRegistration } = await import('../dist/artifact-builder/index.js');
|
|
28
|
+
// new SubjectRegistration().run(); - do not remove: future feature
|
|
29
|
+
|
|
30
|
+
execSync('npx tsc', { cwd: rootDir, stdio: 'inherit' });
|
|
31
|
+
|
|
32
|
+
console.info('Postinstall restore process completed successfully.');
|
|
33
|
+
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
await sync();
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.error('Postinstall process failed:', error.message);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
}
|
package/scripts/setup.js
CHANGED
|
@@ -1,34 +1,37 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/naming-convention */
|
|
2
1
|
import fs from 'node:fs';
|
|
3
2
|
import path from 'node:path';
|
|
4
|
-
import process from 'node:process';
|
|
5
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { PathResolver } from '../dist/helpers/index.js';
|
|
6
5
|
|
|
7
|
-
const
|
|
8
|
-
const
|
|
6
|
+
const _filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const _dirname = path.dirname(_filename);
|
|
9
8
|
|
|
10
|
-
export function setup() {
|
|
9
|
+
export async function setup() {
|
|
11
10
|
try {
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
11
|
+
const consumerRoot = new PathResolver().getConsumerRootDirectory();
|
|
12
|
+
const testwiseConfigFile = path.resolve(consumerRoot, 'Testwise.json');
|
|
13
|
+
const testwiseConfigTemplateFile = path.join(_dirname, 'Testwise.template.json');
|
|
14
|
+
const tsConfigFile = path.resolve(consumerRoot, 'tsconfig.json');
|
|
15
|
+
const tsConfigTemplateFile = path.join(_dirname, 'tsconfig.template.json');
|
|
16
|
+
|
|
17
|
+
let filesCreated = false;
|
|
16
18
|
|
|
17
19
|
if (!fs.existsSync(testwiseConfigFile)) {
|
|
18
20
|
fs.copyFileSync(testwiseConfigTemplateFile, testwiseConfigFile);
|
|
19
21
|
console.info('Testwise.json config file created.');
|
|
20
|
-
|
|
21
|
-
console.info('Testwise.json already exists, skipping creation.');
|
|
22
|
+
filesCreated = true;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
if (!fs.existsSync(tsConfigFile)) {
|
|
25
26
|
fs.copyFileSync(tsConfigTemplateFile, tsConfigFile);
|
|
26
27
|
console.info('tsconfig.json config file created.');
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
filesCreated = true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!filesCreated) {
|
|
32
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
29
33
|
}
|
|
30
34
|
} catch (error) {
|
|
31
35
|
console.error('Error during installation:', error.message);
|
|
32
|
-
process.exit(1); // Exit with an error code if something goes wrong
|
|
33
36
|
}
|
|
34
37
|
}
|
package/scripts/sync.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
|
|
2
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
3
|
+
|
|
4
|
+
import { execSync } from 'node:child_process';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import process from 'node:process';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { ArtifactManager } from '../dist/artifact-builder/index.js';
|
|
9
|
+
|
|
10
|
+
const _filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const _dirname = path.dirname(_filename);
|
|
12
|
+
|
|
13
|
+
export async function sync() {
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const rootDir = path.resolve(_dirname, '..');
|
|
17
|
+
|
|
18
|
+
const { rimrafSync } = await import('rimraf');
|
|
19
|
+
|
|
20
|
+
// Remove dist folder synchronously
|
|
21
|
+
rimrafSync(path.join(rootDir, 'dist'));
|
|
22
|
+
|
|
23
|
+
// Compile TypeScript
|
|
24
|
+
execSync('npx tsc', { cwd: rootDir, stdio: 'inherit' });
|
|
25
|
+
|
|
26
|
+
// Lazy import post recompilation
|
|
27
|
+
const { InterfaceGenerator } = await import('../dist/artifact-builder/index.js');
|
|
28
|
+
const { ScreenInterfaceRefiner } = await import('../dist/artifact-builder/index.js');
|
|
29
|
+
const { SchemaGenerator } = await import('../dist/artifact-builder/index.js');
|
|
30
|
+
const { SubjectComponentGenerator } = await import('../dist/artifact-builder/index.js');
|
|
31
|
+
const { SubjectGenerator } = await import('../dist/artifact-builder/index.js');
|
|
32
|
+
const { ModelDataRefiner } = await import('../dist/artifact-builder/index.js');
|
|
33
|
+
const { buildSubjects, buildScreens } = await import('../dist/artifact-builder/ModelDataBuilder.js');
|
|
34
|
+
// const { SubjectRegistration } = await import('../dist/artifact-builder/index.js'); - do not remove: future feature
|
|
35
|
+
|
|
36
|
+
// Build Seed Data Axios Instance
|
|
37
|
+
await buildSubjects();
|
|
38
|
+
await buildScreens();
|
|
39
|
+
|
|
40
|
+
// Seed data refinement pre-processing
|
|
41
|
+
await new ModelDataRefiner().run();
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
// Generate artifacts
|
|
45
|
+
const interfaceGenerator = new InterfaceGenerator();
|
|
46
|
+
|
|
47
|
+
await interfaceGenerator.generateScreenInterfacesFromSchemas();
|
|
48
|
+
|
|
49
|
+
new ScreenInterfaceRefiner().refine();
|
|
50
|
+
new SchemaGenerator().generateSchema();
|
|
51
|
+
|
|
52
|
+
await interfaceGenerator.generateSubjectInterfacesFromSchemas();
|
|
53
|
+
|
|
54
|
+
new SubjectComponentGenerator().run();
|
|
55
|
+
new SubjectGenerator().run();
|
|
56
|
+
// new SubjectRegistration().run(); - do not remove: future feature
|
|
57
|
+
|
|
58
|
+
// Compile TypeScript again
|
|
59
|
+
execSync('npx tsc', { cwd: rootDir, stdio: 'inherit' });
|
|
60
|
+
|
|
61
|
+
console.info('Sync process completed successfully.');
|
|
62
|
+
} catch (error) {
|
|
63
|
+
// reinstate the backup -- simulate this to see what happens first
|
|
64
|
+
console.error('Sync process failed:', error.message);
|
|
65
|
+
process.exit(1); // Will npm do an automatic rollback here?
|
|
66
|
+
} finally {
|
|
67
|
+
new ArtifactManager().performBackup();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -3,7 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import dotenv from 'dotenv';
|
|
4
4
|
|
|
5
5
|
class ConfigBuilder {
|
|
6
|
-
private config: Record<string, unknown
|
|
6
|
+
private config: Record<string, unknown> | null = null;
|
|
7
7
|
|
|
8
8
|
constructor() {
|
|
9
9
|
const baseDir = process.env.INIT_CWD || process.cwd();
|
|
@@ -18,19 +18,42 @@ class ConfigBuilder {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
if (!fs.existsSync(configFilePath)) {
|
|
21
|
-
|
|
21
|
+
console.warn(`Config file not found at path: ${configFilePath}`);
|
|
22
|
+
return;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
const fileContent = fs.readFileSync(configFilePath, 'utf-8');
|
|
25
26
|
this.config = JSON.parse(fileContent);
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
public async load() {
|
|
30
|
+
const baseDir = process.env.INIT_CWD || process.cwd();
|
|
31
|
+
const configFilePath = path.resolve(baseDir, 'Testwise.json');
|
|
32
|
+
|
|
33
|
+
if (!fs.existsSync(configFilePath)) {
|
|
34
|
+
console.warn(`Config file not found at path: ${configFilePath}`);
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const fileContent = fs.readFileSync(configFilePath, 'utf-8');
|
|
39
|
+
this.config = JSON.parse(fileContent);
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
|
|
28
43
|
/**
|
|
29
44
|
* Retrieves a value from the config using a dot-separated key.
|
|
30
45
|
* @param key - The dot-separated key to retrieve the value.
|
|
31
46
|
* @returns The value associated with the key, or undefined if not found.
|
|
32
47
|
*/
|
|
33
48
|
public get<T>(key: string): T | undefined {
|
|
49
|
+
if (!key || typeof key !== 'string') {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!this.config) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
34
57
|
const result = key
|
|
35
58
|
.split('.')
|
|
36
59
|
.reduce(
|
|
File without changes
|
|
File without changes
|
package/tsconfig.json
CHANGED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type SubjectAgnosticComponents =
|
|
2
|
+
| 'Chart'
|
|
3
|
+
| 'PivotGridFieldList'
|
|
4
|
+
| 'Splitter'
|
|
5
|
+
| 'ActionBar'
|
|
6
|
+
| 'CombinedFilter'
|
|
7
|
+
| 'CustomActionBar'
|
|
8
|
+
| 'DetailTabPage'
|
|
9
|
+
| 'Tab'
|
|
10
|
+
| 'Tab'
|
|
11
|
+
| 'TaskTiles'
|
|
12
|
+
| 'FilterForm'
|
|
13
|
+
| 'PrefilterList'
|
|
14
|
+
| 'TaskBar'
|
|
15
|
+
| 'Cardlist'
|
|
16
|
+
| 'TreeView'
|
|
17
|
+
| 'CubeViewBar'
|
|
18
|
+
| 'PivotGrid'
|
|
19
|
+
| 'Maps'
|
|
20
|
+
| 'ReportBar'
|
|
21
|
+
| 'ReportTiles'
|
|
22
|
+
| 'Scheduler'
|
|
23
|
+
| 'Preview';
|
|
24
|
+
|
|
25
|
+
export const coreComponents: SubjectAgnosticComponents[] = [
|
|
26
|
+
'ActionBar',
|
|
27
|
+
'CombinedFilter',
|
|
28
|
+
'CustomActionBar',
|
|
29
|
+
'Splitter',
|
|
30
|
+
'Tab',
|
|
31
|
+
'DetailTabPage',
|
|
32
|
+
'TaskBar',
|
|
33
|
+
'Tab',
|
|
34
|
+
'Cardlist',
|
|
35
|
+
'FilterForm',
|
|
36
|
+
'TaskTiles',
|
|
37
|
+
'PrefilterList',
|
|
38
|
+
'Chart',
|
|
39
|
+
'TreeView',
|
|
40
|
+
'CubeViewBar',
|
|
41
|
+
'PivotGrid',
|
|
42
|
+
'PivotGridFieldList',
|
|
43
|
+
'Maps',
|
|
44
|
+
'ReportBar',
|
|
45
|
+
'ReportTiles',
|
|
46
|
+
'Scheduler',
|
|
47
|
+
'Preview'
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
export type SubjectComponents = 'Form' | 'Grid';
|
|
51
|
+
export const subjectComponents: SubjectComponents[] = ['Form', 'Grid'];
|
|
52
|
+
|
|
53
|
+
export type ScreenComponents = SubjectComponents | SubjectAgnosticComponents;
|
|
54
|
+
export const screenComponents: ScreenComponents[] = [...coreComponents, ...subjectComponents];
|
|
55
|
+
export const disabledScreenComponents: ScreenComponents[] = ['Splitter'];
|