You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/arch_develop.md
+102-1Lines changed: 102 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -444,7 +444,7 @@ await tester.result(items[0].data) // Execute the actions, asserting the final r
444
444
445
445
Abstractly, a 'wizard' is a collection of discrete, linear steps (subroutines), where each step can potentially be dependent on prior steps, that results in some final state. Wizards are extremely common in top-level flows such as creating a new resource, deployments, or confirmation messages. For these kinds of flows, we have a shared `Wizard` class that handles the bulk of control flow and state management logic for us.
446
446
447
-
### Creating a Wizard (Quick Picks)
447
+
### 1. `Wizard` Class
448
448
449
449
Create a new wizard by extending the base `Wizard` class, using the template type to specify the
450
450
shape of the wizard state. All wizards have an internal `form` property that is used to assign
@@ -482,6 +482,41 @@ class ExampleWizard extends Wizard<ExampleState> {
482
482
}
483
483
```
484
484
485
+
### 2. `CompositeWizard` Class
486
+
487
+
`CompositeWizard` extends `Wizard` to create and manage a collection of nested/child wizards.
488
+
489
+
Extend this class to create a wizard that contains other wizards as part of a prompter flow.
490
+
Use `this.createWizardPrompter()` to use a wizard as a prompter in the `CompositeWizard`.
Wizards can be ran by calling the async `run` method:
@@ -495,6 +530,8 @@ Note that all wizards can potentially return `undefined` if the workflow was can
495
530
496
531
### Testing
497
532
533
+
#### Using `WizardTester`
534
+
498
535
Use `createWizardTester` on an instance of a wizard. Tests can then be constructed by asserting both the user-defined and internal state. Using the above `ExampleWizard`:
499
536
500
537
```ts
@@ -505,6 +542,70 @@ tester.foo.applyInput('Hello, world!') // Manipulate 'user' state
505
542
tester.bar.assertShow() // True since 'foo' has a defined value
506
543
```
507
544
545
+
#### Using `PrompterTester`
546
+
547
+
Use `PrompterTester` to simulate user behavior (click, input and selection) on prompters to test end-to-end flow of a wizard.
548
+
549
+
Example:
550
+
551
+
```ts
552
+
// 1. Register PrompterTester handlers
553
+
const prompterTester =PrompterTester.init()
554
+
.handleInputBox('Input Prompter title 1', (inputBox) => {
555
+
// Register Input Prompter handler
556
+
inputBox.acceptValue('my-source-bucket-name')
557
+
})
558
+
.handleQuickPick('Quick Pick Prompter title 2', (quickPick) => {
559
+
// Register Quick Pick Prompter handler
560
+
561
+
// Optional assertion can be added as part of the handler function
562
+
assert.strictEqual(quickPick.items.length, 2)
563
+
assert.strictEqual(quickPick.items[0].label, 'Specify required parameters and save as defaults')
'Quick Pick Prompter with various handler behavior title 3',
570
+
(() => {
571
+
// Register handler with dynamic behavior
572
+
const generator = (function* () {
573
+
// First call, choose '**'
574
+
yieldasync (picker:TestQuickPick) => {
575
+
awaitpicker.untilReady()
576
+
assert.strictEqual(picker.items[1].label, '**')
577
+
picker.acceptItem(picker.items[1])
578
+
}
579
+
// Second call, choose BACK button
580
+
yieldasync (picker:TestQuickPick) => {
581
+
awaitpicker.untilReady()
582
+
picker.pressButton(vscode.QuickInputButtons.Back)
583
+
}
584
+
// Third and subsequent call
585
+
while (true) {
586
+
yieldasync (picker:TestQuickPick) => {
587
+
awaitpicker.untilReady()
588
+
picker.acceptItem(picker.items[1])
589
+
}
590
+
}
591
+
})()
592
+
593
+
return (picker:TestQuickPick) => {
594
+
const next =generator.next().value
595
+
returnnext(picker)
596
+
}
597
+
})()
598
+
)
599
+
.build()
600
+
601
+
// 2. Run your wizard class
602
+
const result =awaitwizard.run()
603
+
604
+
// 3. Assert your tests
605
+
prompterTester.assertCallAll()
606
+
prompterTester.assertCallOrder('Input Prompter title 1', 1)
607
+
```
608
+
508
609
## Module path debugging
509
610
510
611
Node has an environment variable `NODE_DEBUG=module` that helps to debug module imports. This can be helpful on windows, which can load node modules into uppercase or lower case drive letters, depending on the drive letter of the parent module.
0 commit comments