@seleniumhq/code-export-javascript-mocha 4.0.13 → 4.1.0-beta.2
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/__test__/src/__snapshots__/command.spec.js.snap +52 -37
- package/__test__/src/__snapshots__/index.spec.js.snap +46 -18
- package/__test__/src/__snapshots__/location.spec.js.snap +1 -1
- package/__test__/src/command.spec.js +45 -58
- package/__test__/src/index.spec.js +65 -59
- package/dist/command.d.ts.map +1 -1
- package/dist/command.js +59 -43
- package/dist/command.js.map +1 -1
- package/dist/hook.d.ts +1 -1
- package/dist/location.js +1 -2
- package/dist/location.js.map +1 -1
- package/dist/selection.js +1 -2
- package/dist/selection.js.map +1 -1
- package/jest.config.js +14 -0
- package/package.json +4 -3
- package/src/command.ts +99 -43
- package/src/hook.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -16,12 +16,10 @@
|
|
|
16
16
|
// under the License.
|
|
17
17
|
|
|
18
18
|
import Command from '../../src/command'
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
ControlFlowCommandNames,
|
|
22
|
-
} from '../../../selenium-ide/src/neo/models/Command'
|
|
19
|
+
import { Commands } from '@seleniumhq/side-model'
|
|
20
|
+
import { ControlFlowCommandNames } from '@seleniumhq/side-runtime/dist/playback-tree/commands'
|
|
23
21
|
import { opts } from '../../src/index'
|
|
24
|
-
import { codeExport as exporter } from '
|
|
22
|
+
import { codeExport as exporter } from 'side-code-export'
|
|
25
23
|
|
|
26
24
|
const commandPrefixPadding = opts.commandPrefixPadding
|
|
27
25
|
|
|
@@ -34,22 +32,11 @@ async function prettify(command, { fullPayload } = {}) {
|
|
|
34
32
|
}
|
|
35
33
|
|
|
36
34
|
describe('command code emitter', () => {
|
|
37
|
-
it('should
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
})
|
|
44
|
-
expect(() => {
|
|
45
|
-
if (result.length) {
|
|
46
|
-
if (result.length === 1) {
|
|
47
|
-
throw new Error(`${result[0]} has no emitter, write one!`)
|
|
48
|
-
} else {
|
|
49
|
-
throw new Error(`No emitters for ${result.join(', ')}. Write them!`)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}).not.toThrow()
|
|
35
|
+
it('should have an emitter for every command', () => {
|
|
36
|
+
const missing = Object.keys(Commands).filter(
|
|
37
|
+
(command) => !Command.emitters[command]
|
|
38
|
+
)
|
|
39
|
+
expect(missing).toEqual([])
|
|
53
40
|
})
|
|
54
41
|
it('should emit `add selection` command', () => {
|
|
55
42
|
const command = {
|
|
@@ -375,14 +362,6 @@ describe('command code emitter', () => {
|
|
|
375
362
|
}
|
|
376
363
|
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
377
364
|
})
|
|
378
|
-
it.skip('should emit `mouse move` event', () => {
|
|
379
|
-
const command = {
|
|
380
|
-
command: 'mouseMove',
|
|
381
|
-
target: 'id=button',
|
|
382
|
-
value: '',
|
|
383
|
-
}
|
|
384
|
-
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
385
|
-
})
|
|
386
365
|
it('should emit `mouse move at` event', () => {
|
|
387
366
|
const command = {
|
|
388
367
|
command: 'mouseMoveAt',
|
|
@@ -463,6 +442,14 @@ describe('command code emitter', () => {
|
|
|
463
442
|
}
|
|
464
443
|
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
465
444
|
})
|
|
445
|
+
it('should emit `run` command for a test with a capitalized name', () => {
|
|
446
|
+
const command = { command: 'run', target: 'Some Test Case', value: '' }
|
|
447
|
+
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
448
|
+
})
|
|
449
|
+
it('should emit a comment for `run` with a test name from a variable', async () => {
|
|
450
|
+
const command = { command: 'run', target: '${testName}', value: '' }
|
|
451
|
+
expect(await Command.emit(command, opts)).toMatchSnapshot()
|
|
452
|
+
})
|
|
466
453
|
it('should emit `run script` command', () => {
|
|
467
454
|
const command = {
|
|
468
455
|
command: 'runScript',
|
|
@@ -566,22 +553,6 @@ describe('command code emitter', () => {
|
|
|
566
553
|
}
|
|
567
554
|
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
568
555
|
})
|
|
569
|
-
it('should skip playback supported commands, that are not supported in webdriver', () => {
|
|
570
|
-
return Promise.all([
|
|
571
|
-
expect(
|
|
572
|
-
prettify({ command: 'answerOnNextPrompt', target: 'blah' })
|
|
573
|
-
).resolves.toBe(undefined),
|
|
574
|
-
expect(
|
|
575
|
-
prettify({ command: 'chooseCancelOnNextConfirmation' })
|
|
576
|
-
).resolves.toBe(undefined),
|
|
577
|
-
expect(prettify({ command: 'chooseCancelOnNextPrompt' })).resolves.toBe(
|
|
578
|
-
undefined
|
|
579
|
-
),
|
|
580
|
-
expect(prettify({ command: 'chooseOkOnNextConfirmation' })).resolves.toBe(
|
|
581
|
-
undefined
|
|
582
|
-
),
|
|
583
|
-
])
|
|
584
|
-
})
|
|
585
556
|
it('should emit `store` command', () => {
|
|
586
557
|
const command = {
|
|
587
558
|
command: 'store',
|
|
@@ -638,26 +609,26 @@ describe('command code emitter', () => {
|
|
|
638
609
|
}
|
|
639
610
|
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
640
611
|
})
|
|
641
|
-
it('should emit `store
|
|
612
|
+
it('should emit `store element count` command', () => {
|
|
642
613
|
const command = {
|
|
643
|
-
command: '
|
|
614
|
+
command: 'storeElementCount',
|
|
644
615
|
target: 'xpath=button',
|
|
645
616
|
value: 'myVar',
|
|
646
617
|
}
|
|
647
618
|
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
648
619
|
})
|
|
649
|
-
it('should emit `
|
|
620
|
+
it('should emit `times` command', () => {
|
|
650
621
|
const command = {
|
|
651
|
-
command:
|
|
652
|
-
target: '
|
|
622
|
+
command: ControlFlowCommandNames.times,
|
|
623
|
+
target: '5',
|
|
653
624
|
value: '',
|
|
654
625
|
}
|
|
655
626
|
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
656
627
|
})
|
|
657
|
-
it('should emit `times` command', () => {
|
|
628
|
+
it('should emit `times` command with a variable count', () => {
|
|
658
629
|
const command = {
|
|
659
630
|
command: ControlFlowCommandNames.times,
|
|
660
|
-
target: '
|
|
631
|
+
target: '${count}',
|
|
661
632
|
value: '',
|
|
662
633
|
}
|
|
663
634
|
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
@@ -846,25 +817,41 @@ describe('command code emitter', () => {
|
|
|
846
817
|
}
|
|
847
818
|
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
848
819
|
})
|
|
849
|
-
it('should emit `answer
|
|
820
|
+
it('should emit `answer prompt` command', () => {
|
|
850
821
|
const command = {
|
|
851
|
-
command: '
|
|
822
|
+
command: 'answerPrompt',
|
|
852
823
|
target: 'an answer',
|
|
853
824
|
value: '',
|
|
854
825
|
}
|
|
855
826
|
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
856
827
|
})
|
|
857
|
-
it('should emit `
|
|
828
|
+
it('should emit `dismiss prompt` command', () => {
|
|
829
|
+
const command = {
|
|
830
|
+
command: 'dismissPrompt',
|
|
831
|
+
target: '',
|
|
832
|
+
value: '',
|
|
833
|
+
}
|
|
834
|
+
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
835
|
+
})
|
|
836
|
+
it('should emit `accept confirmation` command', () => {
|
|
837
|
+
const command = {
|
|
838
|
+
command: 'acceptConfirmation',
|
|
839
|
+
target: '',
|
|
840
|
+
value: '',
|
|
841
|
+
}
|
|
842
|
+
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
843
|
+
})
|
|
844
|
+
it('should emit `accept alert` command', () => {
|
|
858
845
|
const command = {
|
|
859
|
-
command: '
|
|
846
|
+
command: 'acceptAlert',
|
|
860
847
|
target: '',
|
|
861
848
|
value: '',
|
|
862
849
|
}
|
|
863
850
|
return expect(prettify(command)).resolves.toMatchSnapshot()
|
|
864
851
|
})
|
|
865
|
-
it('should emit `
|
|
852
|
+
it('should emit `dismiss confirmation` command', () => {
|
|
866
853
|
const command = {
|
|
867
|
-
command: '
|
|
854
|
+
command: 'dismissConfirmation',
|
|
868
855
|
target: '',
|
|
869
856
|
value: '',
|
|
870
857
|
}
|
|
@@ -16,15 +16,11 @@
|
|
|
16
16
|
// under the License.
|
|
17
17
|
|
|
18
18
|
import fs from 'fs'
|
|
19
|
+
import { spawnSync } from 'child_process'
|
|
20
|
+
import os from 'os'
|
|
19
21
|
import path from 'path'
|
|
20
|
-
import
|
|
21
|
-
emitTest,
|
|
22
|
-
emitSuite,
|
|
23
|
-
_emitMethod,
|
|
24
|
-
_findTestByName,
|
|
25
|
-
} from '../../src'
|
|
22
|
+
import languageExport from '../../src'
|
|
26
23
|
import Command from '../../src/command'
|
|
27
|
-
import { project as projectProcessor } from '@seleniumhq/side-code-export'
|
|
28
24
|
|
|
29
25
|
function readFile(filename) {
|
|
30
26
|
return JSON.parse(
|
|
@@ -43,110 +39,120 @@ function readFile(filename) {
|
|
|
43
39
|
)
|
|
44
40
|
}
|
|
45
41
|
|
|
42
|
+
const options = (project) => ({
|
|
43
|
+
project,
|
|
44
|
+
tests: project.tests,
|
|
45
|
+
enableOriginTracing: false,
|
|
46
|
+
enableDescriptionAsComment: false,
|
|
47
|
+
beforeEachOptions: {},
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
// Checks that the exported code compiles, with the first checker installed
|
|
51
|
+
const checkers = [[process.execPath, '--check']]
|
|
52
|
+
function expectValidSyntax(body) {
|
|
53
|
+
const file = path.join(
|
|
54
|
+
fs.mkdtempSync(path.join(os.tmpdir(), 'side-export-')),
|
|
55
|
+
'test.js'
|
|
56
|
+
)
|
|
57
|
+
fs.writeFileSync(file, body)
|
|
58
|
+
for (const [command, ...args] of checkers) {
|
|
59
|
+
const result = spawnSync(command, [...args, file], { encoding: 'utf8' })
|
|
60
|
+
// Skip a checker that isn't installed, and fail on any other error
|
|
61
|
+
if (result.error?.code === 'ENOENT') continue
|
|
62
|
+
if (result.error) throw result.error
|
|
63
|
+
expect(result.stderr).toBe('')
|
|
64
|
+
expect(result.status).toBe(0)
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
46
69
|
describe('Code Export JavaScript Mocha', () => {
|
|
47
70
|
it('should export a test', async () => {
|
|
48
71
|
const project = readFile('single-test.side')
|
|
49
|
-
const results = await
|
|
50
|
-
|
|
72
|
+
const results = await languageExport.emit.test({
|
|
73
|
+
...options(project),
|
|
51
74
|
test: project.tests[0],
|
|
52
|
-
tests: project.tests,
|
|
53
75
|
})
|
|
54
|
-
expect(results.body).toBeDefined()
|
|
55
76
|
expect(results.body).toMatchSnapshot()
|
|
77
|
+
expectValidSyntax(results.body)
|
|
56
78
|
})
|
|
57
79
|
it('should export a test with grid execution', async () => {
|
|
58
80
|
const project = readFile('single-test.side')
|
|
59
|
-
const results = await
|
|
60
|
-
|
|
81
|
+
const results = await languageExport.emit.test({
|
|
82
|
+
...options(project),
|
|
61
83
|
test: project.tests[0],
|
|
62
|
-
tests: project.tests,
|
|
63
84
|
beforeEachOptions: {
|
|
64
85
|
browserName: 'Firefox',
|
|
65
86
|
gridUrl: 'http://localhost:4444/wd/hub',
|
|
66
87
|
},
|
|
67
88
|
})
|
|
68
|
-
expect(results.body).toBeDefined()
|
|
69
89
|
expect(results.body).toMatchSnapshot()
|
|
90
|
+
expectValidSyntax(results.body)
|
|
70
91
|
})
|
|
71
92
|
it('should export a suite', async () => {
|
|
72
|
-
const project =
|
|
73
|
-
const results = await
|
|
74
|
-
|
|
93
|
+
const project = readFile('single-suite.side')
|
|
94
|
+
const results = await languageExport.emit.suite({
|
|
95
|
+
...options(project),
|
|
75
96
|
suite: project.suites[0],
|
|
76
|
-
tests: project.tests,
|
|
77
97
|
})
|
|
78
|
-
expect(results.body).toBeDefined()
|
|
79
98
|
expect(results.body).toMatchSnapshot()
|
|
99
|
+
expectValidSyntax(results.body)
|
|
80
100
|
})
|
|
81
101
|
it('should export a test with a reused test method', async () => {
|
|
82
|
-
const project =
|
|
83
|
-
const results = await
|
|
84
|
-
|
|
102
|
+
const project = readFile('test-case-reuse.side')
|
|
103
|
+
const results = await languageExport.emit.test({
|
|
104
|
+
...options(project),
|
|
85
105
|
test: project.tests[1],
|
|
86
|
-
tests: project.tests,
|
|
87
106
|
})
|
|
88
|
-
expect(results.body).toBeDefined()
|
|
89
107
|
expect(results.body).toMatchSnapshot()
|
|
108
|
+
expectValidSyntax(results.body)
|
|
90
109
|
})
|
|
91
110
|
it('should export a suite with a reused test method', async () => {
|
|
92
|
-
const project =
|
|
93
|
-
const results = await
|
|
94
|
-
|
|
111
|
+
const project = readFile('test-case-reuse.side')
|
|
112
|
+
const results = await languageExport.emit.suite({
|
|
113
|
+
...options(project),
|
|
95
114
|
suite: project.suites[0],
|
|
96
|
-
tests: project.tests,
|
|
97
115
|
})
|
|
98
|
-
expect(results.body).toBeDefined()
|
|
99
116
|
expect(results.body).toMatchSnapshot()
|
|
117
|
+
expectValidSyntax(results.body)
|
|
100
118
|
})
|
|
101
119
|
it('should export a suite that uses control flow commands', async () => {
|
|
102
|
-
const project =
|
|
103
|
-
const results = await
|
|
104
|
-
|
|
120
|
+
const project = readFile('control-flow-suite.side')
|
|
121
|
+
const results = await languageExport.emit.suite({
|
|
122
|
+
...options(project),
|
|
105
123
|
suite: project.suites[0],
|
|
106
|
-
tests: project.tests,
|
|
107
124
|
})
|
|
108
|
-
expect(results.body).toBeDefined()
|
|
109
125
|
expect(results.body).toMatchSnapshot()
|
|
126
|
+
expectValidSyntax(results.body)
|
|
110
127
|
})
|
|
111
128
|
it('should export a test with commands that open a new window', async () => {
|
|
112
|
-
const project =
|
|
113
|
-
const results = await
|
|
114
|
-
|
|
129
|
+
const project = readFile('select-window.side')
|
|
130
|
+
const results = await languageExport.emit.test({
|
|
131
|
+
...options(project),
|
|
115
132
|
test: project.tests[0],
|
|
116
|
-
tests: project.tests,
|
|
117
133
|
})
|
|
118
|
-
expect(results.body).toBeDefined()
|
|
119
134
|
expect(results.body).toMatchSnapshot()
|
|
135
|
+
expectValidSyntax(results.body)
|
|
120
136
|
})
|
|
121
137
|
it('should export a suite with commands that open a new window inside of a reused test method', async () => {
|
|
122
|
-
const project =
|
|
123
|
-
const results = await
|
|
124
|
-
|
|
138
|
+
const project = readFile('nested-select-window.side')
|
|
139
|
+
const results = await languageExport.emit.suite({
|
|
140
|
+
...options(project),
|
|
125
141
|
suite: project.suites[0],
|
|
126
|
-
tests: project.tests,
|
|
127
142
|
})
|
|
128
|
-
expect(results.body).toBeDefined()
|
|
129
143
|
expect(results.body).toMatchSnapshot()
|
|
144
|
+
expectValidSyntax(results.body)
|
|
130
145
|
})
|
|
131
146
|
it('should export a suite with just one new window util method when there are multiple commands that open a new window', async () => {
|
|
132
|
-
const project =
|
|
133
|
-
const results = await
|
|
134
|
-
|
|
147
|
+
const project = readFile('nested-select-window-v2.side')
|
|
148
|
+
const results = await languageExport.emit.suite({
|
|
149
|
+
...options(project),
|
|
135
150
|
suite: project.suites[0],
|
|
136
|
-
tests: project.tests,
|
|
137
151
|
})
|
|
138
|
-
expect(results.body).toBeDefined()
|
|
139
152
|
expect(results.body).toMatchSnapshot()
|
|
153
|
+
expectValidSyntax(results.body)
|
|
140
154
|
})
|
|
141
155
|
it('should export the command emitter', () => {
|
|
142
|
-
expect(
|
|
156
|
+
expect(languageExport.emit.command).toBe(Command.emit)
|
|
143
157
|
})
|
|
144
158
|
})
|
|
145
|
-
|
|
146
|
-
function normalizeProject(project) {
|
|
147
|
-
let _project = { ...project }
|
|
148
|
-
_project.suites.forEach(suite => {
|
|
149
|
-
projectProcessor.normalizeTestsInSuite({ suite, tests: _project.tests })
|
|
150
|
-
})
|
|
151
|
-
return _project
|
|
152
|
-
}
|
package/dist/command.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAiBA,OAAO,EACL,cAAc,EAEd,sBAAsB,EACtB,eAAe,EACf,uBAAuB,
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAiBA,OAAO,EACL,cAAc,EAEd,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EAGxB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAIrD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CA8F5D,CAAA;AAID,iBAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,QAE1D;AAED,iBAAS,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,mCAO3D;AAgBD,iBAAS,iBAAiB;;;;;;sCACiB,MAAM;;;;GA8BhD;AAED,iBAAe,qBAAqB,CAClC,OAAO,EAAE,YAAY,EACrB,cAAc,EAAE,sBAAsB,mBAOvC;;;;;;;;;;AA+1BD,wBAKC"}
|
package/dist/command.js
CHANGED
|
@@ -25,7 +25,6 @@ const location_1 = __importDefault(require("./location"));
|
|
|
25
25
|
const selection_1 = __importDefault(require("./selection"));
|
|
26
26
|
exports.emitters = {
|
|
27
27
|
addSelection: emitSelect,
|
|
28
|
-
answerOnNextPrompt: skip,
|
|
29
28
|
assert: emitAssert,
|
|
30
29
|
assertAlert: emitAssertAlert,
|
|
31
30
|
assertChecked: emitVerifyChecked,
|
|
@@ -44,9 +43,6 @@ exports.emitters = {
|
|
|
44
43
|
assertText: emitVerifyText,
|
|
45
44
|
assertTitle: emitVerifyTitle,
|
|
46
45
|
check: emitCheck,
|
|
47
|
-
chooseCancelOnNextConfirmation: skip,
|
|
48
|
-
chooseCancelOnNextPrompt: skip,
|
|
49
|
-
chooseOkOnNextConfirmation: skip,
|
|
50
46
|
click: emitClick,
|
|
51
47
|
clickAt: emitClick,
|
|
52
48
|
close: emitClose,
|
|
@@ -66,7 +62,6 @@ exports.emitters = {
|
|
|
66
62
|
if: emitControlFlowIf,
|
|
67
63
|
mouseDown: emitMouseDown,
|
|
68
64
|
mouseDownAt: emitMouseDown,
|
|
69
|
-
mouseMove: emitMouseMove,
|
|
70
65
|
mouseMoveAt: emitMouseMove,
|
|
71
66
|
mouseOver: emitMouseMove,
|
|
72
67
|
mouseOut: emitMouseOut,
|
|
@@ -91,8 +86,7 @@ exports.emitters = {
|
|
|
91
86
|
storeTitle: emitStoreTitle,
|
|
92
87
|
storeValue: emitStoreValue,
|
|
93
88
|
storeWindowHandle: emitStoreWindowHandle,
|
|
94
|
-
|
|
95
|
-
submit: emitSubmit,
|
|
89
|
+
storeElementCount: emitStoreXpathCount,
|
|
96
90
|
times: emitControlFlowTimes,
|
|
97
91
|
type: emitType,
|
|
98
92
|
uncheck: emitUncheck,
|
|
@@ -116,11 +110,12 @@ exports.emitters = {
|
|
|
116
110
|
waitForElementNotEditable: emitWaitForElementNotEditable,
|
|
117
111
|
waitForElementNotPresent: emitWaitForElementNotPresent,
|
|
118
112
|
waitForElementNotVisible: emitWaitForElementNotVisible,
|
|
119
|
-
|
|
113
|
+
answerPrompt: emitAnswerOnNextPrompt,
|
|
120
114
|
waitForText: emitWaitForText,
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
115
|
+
dismissConfirmation: emitChooseCancelOnNextConfirmation,
|
|
116
|
+
dismissPrompt: emitChooseCancelOnNextConfirmation,
|
|
117
|
+
acceptConfirmation: emitChooseOkOnNextConfirmation,
|
|
118
|
+
acceptAlert: emitChooseOkOnNextConfirmation,
|
|
124
119
|
while: emitControlFlowWhile,
|
|
125
120
|
};
|
|
126
121
|
side_code_export_1.codeExport.register.preprocessors(exports.emitters);
|
|
@@ -131,9 +126,15 @@ function emit(command, context) {
|
|
|
131
126
|
return side_code_export_1.codeExport.emit.command(command, exports.emitters[command.command], {
|
|
132
127
|
context,
|
|
133
128
|
variableLookup,
|
|
129
|
+
variableInString,
|
|
134
130
|
emitNewWindowHandling,
|
|
135
131
|
});
|
|
136
132
|
}
|
|
133
|
+
// How a variable is joined with a string literal, e.g. "Hi " + name
|
|
134
|
+
const variableInString = {
|
|
135
|
+
quotes: ['"', "'", '`'],
|
|
136
|
+
toString: (lookup) => `String(${lookup})`,
|
|
137
|
+
};
|
|
137
138
|
function variableLookup(varName) {
|
|
138
139
|
return `vars["${varName}"]`;
|
|
139
140
|
}
|
|
@@ -231,9 +232,14 @@ function generateScriptArguments(script) {
|
|
|
231
232
|
.map((varName) => `vars["${varName}"]`)
|
|
232
233
|
.join(',')}`;
|
|
233
234
|
}
|
|
234
|
-
|
|
235
|
+
// The name of the counter of a loop, unique in a test
|
|
236
|
+
const loopCounter = (context) => `loop${context?.loopId ?? 1}`;
|
|
237
|
+
function emitControlFlowDo(_target, _value, context) {
|
|
235
238
|
return Promise.resolve({
|
|
236
|
-
commands: [
|
|
239
|
+
commands: [
|
|
240
|
+
{ level: 0, statement: `let ${loopCounter(context)} = 0` },
|
|
241
|
+
{ level: 0, statement: 'do {' },
|
|
242
|
+
],
|
|
237
243
|
endingLevelAdjustment: 1,
|
|
238
244
|
});
|
|
239
245
|
}
|
|
@@ -288,36 +294,49 @@ function emitControlFlowForEach(collectionVarName, iteratorVarName) {
|
|
|
288
294
|
],
|
|
289
295
|
});
|
|
290
296
|
}
|
|
291
|
-
function emitControlFlowRepeatIf(script) {
|
|
297
|
+
function emitControlFlowRepeatIf(script, value, context) {
|
|
292
298
|
return Promise.resolve({
|
|
293
299
|
commands: [
|
|
294
300
|
{
|
|
295
|
-
level:
|
|
296
|
-
statement: `
|
|
301
|
+
level: 1,
|
|
302
|
+
statement: `if (++${loopCounter(context)} > ${side_code_export_1.codeExport.parsers.loopLimit(value)}) throw new Error('${side_code_export_1.codeExport.parsers.loopLimitMessage}')`,
|
|
297
303
|
},
|
|
304
|
+
{ level: 0, statement: `} while(!!${generateExpressionScript(script)})` },
|
|
298
305
|
],
|
|
299
306
|
startingLevelAdjustment: -1,
|
|
300
307
|
});
|
|
301
308
|
}
|
|
302
|
-
function emitControlFlowTimes(target) {
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
{
|
|
309
|
+
function emitControlFlowTimes(target, value, context) {
|
|
310
|
+
const loop = loopCounter(context);
|
|
311
|
+
const times = `times${context?.loopId ?? 1}`;
|
|
312
|
+
const count = side_code_export_1.codeExport.parsers.loopCount(target, (count) => `Math.floor(Number(${count}))`);
|
|
313
|
+
const commands = [{ level: 0, statement: `const ${times} = ${count}` }];
|
|
314
|
+
if (count !== target) {
|
|
315
|
+
commands.push({
|
|
309
316
|
level: 0,
|
|
310
|
-
statement: `
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
|
|
317
|
+
statement: `if (isNaN(${times})) throw new Error('Invalid number provided as a target.')`,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
commands.push({
|
|
321
|
+
level: 0,
|
|
322
|
+
statement: `for (let ${loop} = 0; ${loop} < ${times}; ${loop}++) {`,
|
|
323
|
+
}, {
|
|
324
|
+
level: 1,
|
|
325
|
+
statement: `if (${loop} >= ${side_code_export_1.codeExport.parsers.loopLimit(value)}) throw new Error('${side_code_export_1.codeExport.parsers.loopLimitMessage}')`,
|
|
326
|
+
});
|
|
327
|
+
return Promise.resolve({ commands });
|
|
314
328
|
}
|
|
315
|
-
function emitControlFlowWhile(script) {
|
|
329
|
+
function emitControlFlowWhile(script, value, context) {
|
|
330
|
+
const loop = loopCounter(context);
|
|
316
331
|
return Promise.resolve({
|
|
317
332
|
commands: [
|
|
333
|
+
{ level: 0, statement: `let ${loop} = 0` },
|
|
318
334
|
{ level: 0, statement: `while(!!${generateExpressionScript(script)}) {` },
|
|
335
|
+
{
|
|
336
|
+
level: 1,
|
|
337
|
+
statement: `if (++${loop} > ${side_code_export_1.codeExport.parsers.loopLimit(value)}) throw new Error('${side_code_export_1.codeExport.parsers.loopLimitMessage}')`,
|
|
338
|
+
},
|
|
319
339
|
],
|
|
320
|
-
endingLevelAdjustment: 1,
|
|
321
340
|
});
|
|
322
341
|
}
|
|
323
342
|
async function emitDoubleClick(target) {
|
|
@@ -355,8 +374,7 @@ async function emitDragAndDrop(dragged, dropped) {
|
|
|
355
374
|
return Promise.resolve({ commands });
|
|
356
375
|
}
|
|
357
376
|
async function emitEcho(message) {
|
|
358
|
-
|
|
359
|
-
return Promise.resolve(`console.log(${_message})`);
|
|
377
|
+
return Promise.resolve(`console.log("${message}")`);
|
|
360
378
|
}
|
|
361
379
|
async function emitEditContent(locator, content) {
|
|
362
380
|
const commands = [
|
|
@@ -452,8 +470,12 @@ async function emitPause(time) {
|
|
|
452
470
|
const commands = [{ level: 0, statement: `await driver.sleep(${time})` }];
|
|
453
471
|
return Promise.resolve({ commands });
|
|
454
472
|
}
|
|
455
|
-
async function emitRun(testName) {
|
|
456
|
-
|
|
473
|
+
async function emitRun(testName, _value, context) {
|
|
474
|
+
// The test to run is only known during playback
|
|
475
|
+
if ((0, side_code_export_1.hasVariable)(testName)) {
|
|
476
|
+
return Promise.resolve(`${context.commentPrefix} Cannot export run with a test name from a variable: ${testName}`);
|
|
477
|
+
}
|
|
478
|
+
return Promise.resolve(`await ${side_code_export_1.codeExport.parsers.uncapitalize(side_code_export_1.codeExport.parsers.sanitizeName(testName))}()`);
|
|
457
479
|
}
|
|
458
480
|
async function emitRunScript(script) {
|
|
459
481
|
return Promise.resolve(`await driver.executeScript("${script.script}${generateScriptArguments(script)}")`);
|
|
@@ -536,10 +558,7 @@ function generateSendKeysInput(value) {
|
|
|
536
558
|
if (typeof value === 'object') {
|
|
537
559
|
return value
|
|
538
560
|
.map((s) => {
|
|
539
|
-
if (s.startsWith('
|
|
540
|
-
return s;
|
|
541
|
-
}
|
|
542
|
-
else if (s.startsWith('Key[')) {
|
|
561
|
+
if (s.startsWith('Key[')) {
|
|
543
562
|
const key = s.match(/\['(.*)'\]/)?.[1];
|
|
544
563
|
return `Key.${key}`;
|
|
545
564
|
}
|
|
@@ -603,9 +622,6 @@ async function emitStoreXpathCount(locator, varName) {
|
|
|
603
622
|
const result = `await driver.findElements(${await location_1.default.emit(locator)}).length`;
|
|
604
623
|
return Promise.resolve(variableSetter(varName, result));
|
|
605
624
|
}
|
|
606
|
-
async function emitSubmit(_locator) {
|
|
607
|
-
return Promise.resolve(`raise Exception("\`submit\` is not a supported command in Selenium Webdriver. Please re-record the step in the IDE.")`);
|
|
608
|
-
}
|
|
609
625
|
async function emitType(target, value) {
|
|
610
626
|
return Promise.resolve(`await driver.findElement(${await location_1.default.emit(target)}).sendKeys(${generateSendKeysInput(value)})`);
|
|
611
627
|
}
|
|
@@ -687,7 +703,7 @@ async function emitVerifyNotSelectedValue(locator, expectedValue) {
|
|
|
687
703
|
},
|
|
688
704
|
{
|
|
689
705
|
level: 1,
|
|
690
|
-
statement: `assert.equal(value, "${
|
|
706
|
+
statement: `assert.equal(value, "${expectedValue}")`,
|
|
691
707
|
},
|
|
692
708
|
{ level: 0, statement: `}` },
|
|
693
709
|
];
|
|
@@ -702,7 +718,7 @@ async function emitVerifyNotText(locator, text) {
|
|
|
702
718
|
},
|
|
703
719
|
{
|
|
704
720
|
level: 1,
|
|
705
|
-
statement: `assert.notEqual(text, "${
|
|
721
|
+
statement: `assert.notEqual(text, "${text}")`,
|
|
706
722
|
},
|
|
707
723
|
{ level: 0, statement: `}` },
|
|
708
724
|
];
|
|
@@ -734,7 +750,7 @@ async function emitVerifyText(locator, text) {
|
|
|
734
750
|
const commands = [
|
|
735
751
|
{
|
|
736
752
|
level: 0,
|
|
737
|
-
statement: `assert.equal(await driver.findElement(${await location_1.default.emit(locator)}).getText(), "${
|
|
753
|
+
statement: `assert.equal(await driver.findElement(${await location_1.default.emit(locator)}).getText(), "${text}")`,
|
|
738
754
|
},
|
|
739
755
|
];
|
|
740
756
|
return Promise.resolve({ commands });
|