@lynxwall/cucumber-tsflow 4.0.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 +284 -0
- package/dist/behave-json-formatter.d.ts +19 -0
- package/dist/behave-json-formatter.d.ts.map +1 -0
- package/dist/behave-json-formatter.js +62 -0
- package/dist/behave-json-formatter.js.map +1 -0
- package/dist/binding-decorator.d.ts +11 -0
- package/dist/binding-decorator.d.ts.map +1 -0
- package/dist/binding-decorator.js +189 -0
- package/dist/binding-decorator.js.map +1 -0
- package/dist/binding-registry.d.ts +75 -0
- package/dist/binding-registry.d.ts.map +1 -0
- package/dist/binding-registry.js +177 -0
- package/dist/binding-registry.js.map +1 -0
- package/dist/hook-decorators.d.ts +29 -0
- package/dist/hook-decorators.d.ts.map +1 -0
- package/dist/hook-decorators.js +82 -0
- package/dist/hook-decorators.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +4 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +17 -0
- package/dist/logger.js.map +1 -0
- package/dist/managed-scenario-context.d.ts +22 -0
- package/dist/managed-scenario-context.d.ts.map +1 -0
- package/dist/managed-scenario-context.js +98 -0
- package/dist/managed-scenario-context.js.map +1 -0
- package/dist/our-callsite.d.ts +26 -0
- package/dist/our-callsite.d.ts.map +1 -0
- package/dist/our-callsite.js +49 -0
- package/dist/our-callsite.js.map +1 -0
- package/dist/scenario-context.d.ts +17 -0
- package/dist/scenario-context.d.ts.map +1 -0
- package/dist/scenario-context.js +24 -0
- package/dist/scenario-context.js.map +1 -0
- package/dist/scenario-info.d.ts +17 -0
- package/dist/scenario-info.d.ts.map +1 -0
- package/dist/scenario-info.js +31 -0
- package/dist/scenario-info.js.map +1 -0
- package/dist/step-binding-flags.d.ts +46 -0
- package/dist/step-binding-flags.d.ts.map +1 -0
- package/dist/step-binding-flags.js +61 -0
- package/dist/step-binding-flags.js.map +1 -0
- package/dist/step-binding.d.ts +45 -0
- package/dist/step-binding.d.ts.map +1 -0
- package/dist/step-binding.js +24 -0
- package/dist/step-binding.js.map +1 -0
- package/dist/step-definition-decorators.d.ts +25 -0
- package/dist/step-definition-decorators.d.ts.map +1 -0
- package/dist/step-definition-decorators.js +95 -0
- package/dist/step-definition-decorators.js.map +1 -0
- package/dist/tsflow-snippet-syntax.d.ts +10 -0
- package/dist/tsflow-snippet-syntax.d.ts.map +1 -0
- package/dist/tsflow-snippet-syntax.js +73 -0
- package/dist/tsflow-snippet-syntax.js.map +1 -0
- package/dist/types.d.ts +22 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- package/package.json +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
# cucumber-tsflow
|
|
4
|
+
|
|
5
|
+
Provides 'specflow' like bindings for CucumberJS in TypeScript 1.7+.
|
|
6
|
+
|
|
7
|
+
This is a fork of the original cucumber-tsflow found here: [cucumber-tsflow](https://github.com/timjroberts/cucumber-js-tsflow)
|
|
8
|
+
|
|
9
|
+
This fork contains the following updates:
|
|
10
|
+
|
|
11
|
+
- Updated to use latest version of Cucumber (@cucumber/cucumber).
|
|
12
|
+
- Bug fixes related to tags.
|
|
13
|
+
- Added Timeout in step definition and hooks.
|
|
14
|
+
- Added WrapperOptions in step definitions.
|
|
15
|
+
- Added BeforeAll and AfterAll Hooks.
|
|
16
|
+
- Added a behave-json-formatter that fixes json so it can be used with Behave Pro.
|
|
17
|
+
- Added tsflow-snippet-syntax used to format snippet examples.
|
|
18
|
+
- examples use the [Cucumber Syntax](https://github.com/cucumber/cucumber-expressions#readme) for parameters.
|
|
19
|
+
|
|
20
|
+
### Quick Start
|
|
21
|
+
|
|
22
|
+
cucumber-tsflow uses TypeScript Decorators to create SpecFlow like bindings for TypeScript classes and methods that allow those classes and methods to be used in your CucumberJS support files. As such, cucumber-tsflow has a peer dependency on CucumberJS, and you still run your specifications using the cucumber command line tool.
|
|
23
|
+
|
|
24
|
+
##### Install @cucumber/cucumber and @lynxwall/cucumber-tsflow
|
|
25
|
+
|
|
26
|
+
###### npm
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @cucumber/cucumber @lynxwall/cucumber-tsflow --save-dev
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
###### yarn
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
yarn add --dev @cucumber/cucumber @lynxwall/cucumber-tsflow
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
###### Create .feature files to describe your specifications
|
|
39
|
+
|
|
40
|
+
By default, CucumberJS looks for .feature files in a folder called 'features', so create that folder and then create a new file called 'my_feature.feature':
|
|
41
|
+
|
|
42
|
+
```gherkin
|
|
43
|
+
# features/my_feature.feature
|
|
44
|
+
|
|
45
|
+
Feature: Example Feature
|
|
46
|
+
This is an example feature
|
|
47
|
+
|
|
48
|
+
Scenario: Adding two numbers
|
|
49
|
+
Given I enter "2" and "8"
|
|
50
|
+
Then I receive the result "10"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
###### Create the Support Files to support the Feature
|
|
54
|
+
|
|
55
|
+
By default, CucumberJS looks for support files beneath the 'features' folder. You can override this on the cucumber command line by specifying the '-r' option. However, let's work with the default and create our code in the default location. We need to write step definitions to support the two steps that we created above.
|
|
56
|
+
|
|
57
|
+
Create a new 'ArithmeticSteps.ts' file:
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
// features/ArithmeticSteps.ts
|
|
61
|
+
|
|
62
|
+
import { binding, given, then } from "@lynxwall/cucumber-tsflow";
|
|
63
|
+
|
|
64
|
+
@binding()
|
|
65
|
+
class ArithmeticSteps {
|
|
66
|
+
private computedResult: number;
|
|
67
|
+
|
|
68
|
+
@given('I enter {string} and {string}')
|
|
69
|
+
iEnterstringAndstring(num1: string, num2: string): any {
|
|
70
|
+
this.computedResult = parseInt(num1) + parseInt(num2);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@then('I receive the result {string}')
|
|
74
|
+
iReceiveTheResultstring(expectedResult: string): any {
|
|
75
|
+
if (parseInt(expectedResult) !== this.computedResult) {
|
|
76
|
+
throw new Error('Arithmetic Error');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export = ArithmeticSteps;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Note how the cucumber-tsflow Decorators are being used to bind the methods in the class. During runtime, these Decorators simply call the Cucumber code on your behalf in order to register callbacks with Given(), When(), Then(), etc. The callbacks that are being registered with Cucumber are wrappers around your bound class.
|
|
85
|
+
|
|
86
|
+
###### Compiling your TypeScript Support Code
|
|
87
|
+
|
|
88
|
+
You'll also need a `tsconfig.json` file to compile your code. You'll also need to ensure that the `"moduleResolution": "node"` compiler option is set in order to bring in the typings that are shipped with cucumber-tsflow.
|
|
89
|
+
|
|
90
|
+
Once compiled, running the cucumber command line should execute your features along with the support code that you've created in the class.
|
|
91
|
+
|
|
92
|
+
In this quick example test state is encapsulated directly in the class. As your test suite grows larger and step definitions get shared between multiple classes, you can begin using 'Context Injection' to share state between running step definitions (see below).
|
|
93
|
+
|
|
94
|
+
### Bindings
|
|
95
|
+
|
|
96
|
+
Bindings provide the automation that connects a specification step in a Gherkin feature file to some code that
|
|
97
|
+
executes for that step. When using Cucumber with TypeScript you can define this automation using a 'binding' class:
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
import { binding } from "@lynxwall/cucumber-tsflow";
|
|
101
|
+
|
|
102
|
+
@binding()
|
|
103
|
+
class MySteps {
|
|
104
|
+
...
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export = MySteps;
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
*Note*: You must use the `export = <type>;` because Cucumber expects exports in this manner.
|
|
111
|
+
|
|
112
|
+
### Step Definitions
|
|
113
|
+
|
|
114
|
+
Step definitions can be bound to automation code in a 'binding' class by implementing a public function that is
|
|
115
|
+
bound with a 'given', 'when' or 'then' binding decorator:
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
import { binding, given, when, then } from "@lynxwall/cucumber-tsflow";
|
|
119
|
+
|
|
120
|
+
@binding()
|
|
121
|
+
class MySteps {
|
|
122
|
+
...
|
|
123
|
+
@given(/I perform a search using the value "([^"]*)"/)
|
|
124
|
+
public givenAValueBasedSearch(searchValue: string): void {
|
|
125
|
+
...
|
|
126
|
+
}
|
|
127
|
+
...
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export = MySteps;
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The function follows the same requirements of functions you would normally supply to Cucumber which means that the
|
|
134
|
+
functions may be synchronous by returning nothing, use the callback, or return a `Promise<T>`. Additionally, the
|
|
135
|
+
function may also be `async` following the TypeScript async semantics.
|
|
136
|
+
|
|
137
|
+
Step definitions may also be scoped at a tag level by supplying an optional tag name when using the binding
|
|
138
|
+
decorators:
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
@given('I perform a search using the value {string}')
|
|
142
|
+
public givenAValueBasedSearch(searchValue: string): void {
|
|
143
|
+
...
|
|
144
|
+
// The default step definition
|
|
145
|
+
...
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@given('I perform a search using the value {string}', "@tagName")
|
|
149
|
+
public givenAValueBasedSearch(searchValue: string): void {
|
|
150
|
+
...
|
|
151
|
+
// The step definition that will execute if the feature or
|
|
152
|
+
// scenario has the @tagName defined on it
|
|
153
|
+
...
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### Hooks
|
|
158
|
+
|
|
159
|
+
Hooks can be used to perform additional automation on specific events such as before or after scenario execution.
|
|
160
|
+
Hooks can be restricted to run for only features or scenarios with a specific tag:
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
import { binding, before, after } from "@lynxwall/cucumber-tsflow";
|
|
164
|
+
|
|
165
|
+
@binding()
|
|
166
|
+
class MySteps {
|
|
167
|
+
...
|
|
168
|
+
@before()
|
|
169
|
+
public beforeAllScenarios(): void {
|
|
170
|
+
...
|
|
171
|
+
}
|
|
172
|
+
...
|
|
173
|
+
|
|
174
|
+
@before("@requireTempDir")
|
|
175
|
+
public async beforeAllScenariosRequiringTempDirectory(): Promise<void> {
|
|
176
|
+
let tempDirInfo = await this.createTemporaryDirectory();
|
|
177
|
+
|
|
178
|
+
...
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@after()
|
|
182
|
+
public afterAllScenarios(): void {
|
|
183
|
+
...
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@after("@requireTmpDir")
|
|
187
|
+
public afterAllScenarios(): void {
|
|
188
|
+
...
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export = MySteps;
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
#### Timeout in step definition and hooks
|
|
196
|
+
|
|
197
|
+
In step definition and hooks, we can set timeout. For example, to set the timeout for a step to be 20000ms, we can do:
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
|
|
201
|
+
@given('I perform a search using the value {string}', undefined, 20000)
|
|
202
|
+
public givenAValueBasedSearch(searchValue: string): void {
|
|
203
|
+
...
|
|
204
|
+
// this step will time tou in 20000ms.
|
|
205
|
+
...
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
tsflow currently doesn't have a way to define a global default step timeout,
|
|
211
|
+
|
|
212
|
+
but it can be easily done through cucumber.js ```setDefaultTimeout``` function.
|
|
213
|
+
|
|
214
|
+
#### Passing WrapperOptions
|
|
215
|
+
|
|
216
|
+
In step definition, we can pass additional wrapper options to cucumber js. For example:
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
|
|
220
|
+
@given('I perform a search using the value {string}', undefined, undefined, {retry: 2})
|
|
221
|
+
public givenAValueBasedSearch(searchValue: string): void {
|
|
222
|
+
...
|
|
223
|
+
// this step will be retried by cucumber js
|
|
224
|
+
...
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
#### Using behave-json-formatter and tsflow-snippet-syntax
|
|
230
|
+
|
|
231
|
+
Changing the formatter used for generating json along with changing the Snippet Syntax can be done through the cucumber.js configuration file.
|
|
232
|
+
|
|
233
|
+
If it doesn't already exist, create a file named cucumber.js at the root of your project. This is where we can configure different options for cucumber.js.
|
|
234
|
+
|
|
235
|
+
The following example shows how to configure the formatter and snippet syntax:
|
|
236
|
+
|
|
237
|
+
```javascript
|
|
238
|
+
module.exports = {
|
|
239
|
+
default: [
|
|
240
|
+
'--format node_modules/@lynxwall/cucumber-tsflow/dist/behave-json-formatter:cucumber_report.json',
|
|
241
|
+
'--format-options \'{"snippetSyntax": "node_modules/@lynxwall/cucumber-tsflow/dist/tsflow-snippet-syntax"}\'',
|
|
242
|
+
'--publish-quiet'
|
|
243
|
+
].join(' ')
|
|
244
|
+
};
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
The first line tells cucumber to generate a report using the behave-json-formatter.
|
|
248
|
+
|
|
249
|
+
The next line tells cucumber to generate example snippets using the tsflow-snippet-syntax.
|
|
250
|
+
|
|
251
|
+
### Sharing Data between Bindings
|
|
252
|
+
|
|
253
|
+
#### Context Injection
|
|
254
|
+
|
|
255
|
+
Like 'specflow', cucumber-tsflow supports a simple dependency injection framework that will instantitate and inject
|
|
256
|
+
class instances into 'binding' classes for each execuing scenario.
|
|
257
|
+
|
|
258
|
+
To use context injection:
|
|
259
|
+
|
|
260
|
+
- Create simple classes representing the shared data (they *must* have default constructors)
|
|
261
|
+
- Define a constructor on the 'binding' classes that will require the shared data that accepts the context objects
|
|
262
|
+
as parameters
|
|
263
|
+
- Update the `@binding()` decorator to indicate the types of context objects that are required by the 'binding'
|
|
264
|
+
class
|
|
265
|
+
|
|
266
|
+
```javascript
|
|
267
|
+
import { binding, before, after } from "@lynxwall/cucumber-tsflow";
|
|
268
|
+
import { Workspace } from "./Workspace";
|
|
269
|
+
|
|
270
|
+
@binding([Workspace])
|
|
271
|
+
class MySteps {
|
|
272
|
+
constructor(protected workspace: Workspace)
|
|
273
|
+
{ }
|
|
274
|
+
|
|
275
|
+
@before("requireTempDir")
|
|
276
|
+
public async beforeAllScenariosRequiringTempDirectory(): Promise<void> {
|
|
277
|
+
let tempDirInfo = await this.createTemporaryDirectory();
|
|
278
|
+
|
|
279
|
+
this.workspace.updateFolder(tempDirInfo);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export = MySteps;
|
|
284
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import JsonFormatter, { IJsonStep } from '@cucumber/cucumber/lib/formatter/json_formatter';
|
|
2
|
+
import * as messages from '@cucumber/messages';
|
|
3
|
+
interface IBuildJsonStepOptions {
|
|
4
|
+
isBeforeHook: boolean;
|
|
5
|
+
gherkinStepMap: Record<string, messages.Step>;
|
|
6
|
+
pickleStepMap: Record<string, messages.PickleStep>;
|
|
7
|
+
testStep: messages.TestStep;
|
|
8
|
+
testStepAttachments: messages.Attachment[];
|
|
9
|
+
testStepResult: messages.TestStepResult;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Extending JsonFormatter.getStepData to add a name field to before
|
|
13
|
+
* and After steps so that json can be exported to Behave Pro (name on steps required)
|
|
14
|
+
*/
|
|
15
|
+
export default class BehaveJsonFormatter extends JsonFormatter {
|
|
16
|
+
getStepData({ isBeforeHook, gherkinStepMap, pickleStepMap, testStep, testStepAttachments, testStepResult }: IBuildJsonStepOptions): IJsonStep;
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=behave-json-formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behave-json-formatter.d.ts","sourceRoot":"","sources":["../src/behave-json-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,EAAE,EAAE,SAAS,EAAE,MAAM,iDAAiD,CAAC;AAC3F,OAAO,KAAK,QAAQ,MAAM,oBAAoB,CAAC;AAO/C,UAAU,qBAAqB;IAC9B,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9C,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IACnD,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC;IAC5B,mBAAmB,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;IAC3C,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,aAAa;IAC7D,WAAW,CAAC,EACX,YAAY,EACZ,cAAc,EACd,aAAa,EACb,QAAQ,EACR,mBAAmB,EACnB,cAAc,EACd,EAAE,qBAAqB,GAAG,SAAS;CAwCpC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
(function (factory) {
|
|
2
|
+
if (typeof module === "object" && typeof module.exports === "object") {
|
|
3
|
+
var v = factory(require, exports);
|
|
4
|
+
if (v !== undefined) module.exports = v;
|
|
5
|
+
}
|
|
6
|
+
else if (typeof define === "function" && define.amd) {
|
|
7
|
+
define(["require", "exports", "@cucumber/cucumber/lib/formatter/json_formatter", "@cucumber/messages", "@cucumber/cucumber/lib/value_checker", "@cucumber/cucumber/lib/formatter/helpers"], factory);
|
|
8
|
+
}
|
|
9
|
+
})(function (require, exports) {
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const json_formatter_1 = require("@cucumber/cucumber/lib/formatter/json_formatter");
|
|
13
|
+
const messages = require("@cucumber/messages");
|
|
14
|
+
const value_checker_1 = require("@cucumber/cucumber/lib/value_checker");
|
|
15
|
+
const helpers_1 = require("@cucumber/cucumber/lib/formatter/helpers");
|
|
16
|
+
const { getStepKeyword } = helpers_1.PickleParser;
|
|
17
|
+
/**
|
|
18
|
+
* Extending JsonFormatter.getStepData to add a name field to before
|
|
19
|
+
* and After steps so that json can be exported to Behave Pro (name on steps required)
|
|
20
|
+
*/
|
|
21
|
+
class BehaveJsonFormatter extends json_formatter_1.default {
|
|
22
|
+
getStepData({ isBeforeHook, gherkinStepMap, pickleStepMap, testStep, testStepAttachments, testStepResult }) {
|
|
23
|
+
var _a;
|
|
24
|
+
const data = {};
|
|
25
|
+
if ((0, value_checker_1.doesHaveValue)(testStep.pickleStepId)) {
|
|
26
|
+
const pickleStep = pickleStepMap[testStep.pickleStepId];
|
|
27
|
+
data.arguments = this.formatStepArgument(pickleStep.argument, gherkinStepMap[pickleStep.astNodeIds[0]]);
|
|
28
|
+
data.keyword = getStepKeyword({ pickleStep, gherkinStepMap });
|
|
29
|
+
data.line = gherkinStepMap[pickleStep.astNodeIds[0]].location.line;
|
|
30
|
+
data.name = pickleStep.text;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
data.keyword = isBeforeHook ? 'Before' : 'After';
|
|
34
|
+
data.hidden = true;
|
|
35
|
+
data.name = '';
|
|
36
|
+
}
|
|
37
|
+
if ((0, value_checker_1.doesHaveValue)(testStep.stepDefinitionIds) && ((_a = testStep.stepDefinitionIds) === null || _a === void 0 ? void 0 : _a.length) === 1) {
|
|
38
|
+
const stepDefinition = this.supportCodeLibrary.stepDefinitions.find(s => s.id === testStep.stepDefinitionIds[0]);
|
|
39
|
+
data.match = { location: (0, helpers_1.formatLocation)(stepDefinition) };
|
|
40
|
+
}
|
|
41
|
+
const { message, status } = testStepResult;
|
|
42
|
+
data.result = {
|
|
43
|
+
status: messages.TestStepResultStatus[status].toLowerCase()
|
|
44
|
+
};
|
|
45
|
+
if ((0, value_checker_1.doesHaveValue)(testStepResult.duration)) {
|
|
46
|
+
data.result.duration = messages.TimeConversion.durationToMilliseconds(testStepResult.duration) * 1000000;
|
|
47
|
+
}
|
|
48
|
+
if (status === messages.TestStepResultStatus.FAILED && (0, value_checker_1.doesHaveValue)(message)) {
|
|
49
|
+
data.result.error_message = message;
|
|
50
|
+
}
|
|
51
|
+
if ((testStepAttachments === null || testStepAttachments === void 0 ? void 0 : testStepAttachments.length) > 0) {
|
|
52
|
+
data.embeddings = testStepAttachments.map(attachment => ({
|
|
53
|
+
data: attachment.body,
|
|
54
|
+
mime_type: attachment.mediaType
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
return data;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.default = BehaveJsonFormatter;
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=behave-json-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behave-json-formatter.js","sourceRoot":"","sources":["../src/behave-json-formatter.ts"],"names":[],"mappings":";;;;;;;;;;;IAAA,oFAA2F;IAC3F,+CAA+C;IAC/C,wEAAqE;IACrE,sEAAwF;IAGxF,MAAM,EAAE,cAAc,EAAE,GAAG,sBAAY,CAAC;IAWxC;;;OAGG;IACH,MAAqB,mBAAoB,SAAQ,wBAAa;QAC7D,WAAW,CAAC,EACX,YAAY,EACZ,cAAc,EACd,aAAa,EACb,QAAQ,EACR,mBAAmB,EACnB,cAAc,EACS;;YACvB,MAAM,IAAI,GAAc,EAAE,CAAC;YAC3B,IAAI,IAAA,6BAAa,EAAC,QAAQ,CAAC,YAAY,CAAC,EAAE;gBACzC,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,YAAsB,CAAC,CAAC;gBAClE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,kBAAkB,CACvC,UAAU,CAAC,QAA8B,EACzC,cAAc,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CACxC,CAAC;gBACF,IAAI,CAAC,OAAO,GAAG,cAAc,CAAC,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC;gBAC9D,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACnE,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;aAC5B;iBAAM;gBACN,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;gBACjD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACnB,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;aACf;YACD,IAAI,IAAA,6BAAa,EAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAA,MAAA,QAAQ,CAAC,iBAAiB,0CAAE,MAAM,MAAK,CAAC,EAAE;gBAC1F,MAAM,cAAc,GAAG,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,IAAI,CAClE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAM,QAAQ,CAAC,iBAA8B,CAAC,CAAC,CAAC,CACzD,CAAC;gBACF,IAAI,CAAC,KAAK,GAAG,EAAE,QAAQ,EAAE,IAAA,wBAAc,EAAC,cAA6B,CAAC,EAAE,CAAC;aACzE;YACD,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC;YAC3C,IAAI,CAAC,MAAM,GAAG;gBACb,MAAM,EAAE,QAAQ,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE;aAC3D,CAAC;YACF,IAAI,IAAA,6BAAa,EAAC,cAAc,CAAC,QAAQ,CAAC,EAAE;gBAC3C,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,sBAAsB,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;aACzG;YACD,IAAI,MAAM,KAAK,QAAQ,CAAC,oBAAoB,CAAC,MAAM,IAAI,IAAA,6BAAa,EAAC,OAAO,CAAC,EAAE;gBAC9E,IAAI,CAAC,MAAM,CAAC,aAAa,GAAG,OAAO,CAAC;aACpC;YACD,IAAI,CAAA,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,MAAM,IAAG,CAAC,EAAE;gBACpC,IAAI,CAAC,UAAU,GAAG,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBACxD,IAAI,EAAE,UAAU,CAAC,IAAI;oBACrB,SAAS,EAAE,UAAU,CAAC,SAAS;iBAC/B,CAAC,CAAC,CAAC;aACJ;YACD,OAAO,IAAI,CAAC;QACb,CAAC;KACD;IAhDD,sCAgDC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ContextType, TypeDecorator } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* A class decorator that marks the associated class as a CucumberJS binding.
|
|
4
|
+
*
|
|
5
|
+
* @param requiredContextTypes An optional array of Types that will be created and passed into the created
|
|
6
|
+
* object for each scenario.
|
|
7
|
+
*
|
|
8
|
+
* An instance of the decorated class will be created for each scenario.
|
|
9
|
+
*/
|
|
10
|
+
export declare function binding(requiredContextTypes?: ContextType[]): TypeDecorator;
|
|
11
|
+
//# sourceMappingURL=binding-decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding-decorator.d.ts","sourceRoot":"","sources":["../src/binding-decorator.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,WAAW,EAAe,aAAa,EAAE,MAAM,SAAS,CAAC;AAyBlE;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,oBAAoB,CAAC,EAAE,WAAW,EAAE,GAAG,aAAa,CAyB3E"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
(function (factory) {
|
|
2
|
+
if (typeof module === "object" && typeof module.exports === "object") {
|
|
3
|
+
var v = factory(require, exports);
|
|
4
|
+
if (v !== undefined) module.exports = v;
|
|
5
|
+
}
|
|
6
|
+
else if (typeof define === "function" && define.amd) {
|
|
7
|
+
define(["require", "exports", "@cucumber/cucumber", "underscore", "./logger", "./binding-registry", "./managed-scenario-context", "./step-binding"], factory);
|
|
8
|
+
}
|
|
9
|
+
})(function (require, exports) {
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.binding = void 0;
|
|
13
|
+
/* eslint-disable prefer-rest-params */
|
|
14
|
+
const cucumber_1 = require("@cucumber/cucumber");
|
|
15
|
+
const _ = require("underscore");
|
|
16
|
+
const logger_1 = require("./logger");
|
|
17
|
+
const binding_registry_1 = require("./binding-registry");
|
|
18
|
+
const managed_scenario_context_1 = require("./managed-scenario-context");
|
|
19
|
+
const step_binding_1 = require("./step-binding");
|
|
20
|
+
/**
|
|
21
|
+
* The property name of the current scenario context that will be attached to the Cucumber
|
|
22
|
+
* world object.
|
|
23
|
+
*/
|
|
24
|
+
const SCENARIO_CONTEXT_SLOTNAME = '__SCENARIO_CONTEXT';
|
|
25
|
+
/**
|
|
26
|
+
* A set of step patterns that have been registered with Cucumber.
|
|
27
|
+
*
|
|
28
|
+
* In order to support scoped (or tagged) step definitions, we must ensure that any step binding is
|
|
29
|
+
* only registered with Cucumber once. The binding function for that step pattern then becomes
|
|
30
|
+
* responsible for looking up and execuing the step binding based on the context that is in scope at
|
|
31
|
+
* the point of invocation.
|
|
32
|
+
*/
|
|
33
|
+
const stepPatternRegistrations = new Map();
|
|
34
|
+
// tslint:disable:no-bitwise
|
|
35
|
+
/**
|
|
36
|
+
* A class decorator that marks the associated class as a CucumberJS binding.
|
|
37
|
+
*
|
|
38
|
+
* @param requiredContextTypes An optional array of Types that will be created and passed into the created
|
|
39
|
+
* object for each scenario.
|
|
40
|
+
*
|
|
41
|
+
* An instance of the decorated class will be created for each scenario.
|
|
42
|
+
*/
|
|
43
|
+
function binding(requiredContextTypes) {
|
|
44
|
+
return (target) => {
|
|
45
|
+
ensureSystemBindings();
|
|
46
|
+
const bindingRegistry = binding_registry_1.BindingRegistry.instance;
|
|
47
|
+
bindingRegistry.registerContextTypesForTarget(target.prototype, requiredContextTypes);
|
|
48
|
+
const allBindings = [];
|
|
49
|
+
allBindings.push(...bindingRegistry.getStepBindingsForTarget(target));
|
|
50
|
+
allBindings.push(...bindingRegistry.getStepBindingsForTarget(target.prototype));
|
|
51
|
+
allBindings.forEach(stepBinding => {
|
|
52
|
+
if (stepBinding.bindingType & step_binding_1.StepBindingFlags.StepDefinitions) {
|
|
53
|
+
let stepBindingFlags = stepPatternRegistrations.get(stepBinding.stepPattern.toString());
|
|
54
|
+
if (stepBindingFlags === undefined) {
|
|
55
|
+
stepBindingFlags = step_binding_1.StepBindingFlags.none;
|
|
56
|
+
}
|
|
57
|
+
if (stepBindingFlags & stepBinding.bindingType) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
bindStepDefinition(stepBinding);
|
|
61
|
+
stepPatternRegistrations.set(stepBinding.stepPattern.toString(), stepBindingFlags | stepBinding.bindingType);
|
|
62
|
+
}
|
|
63
|
+
else if (stepBinding.bindingType & step_binding_1.StepBindingFlags.Hooks) {
|
|
64
|
+
bindHook(stepBinding);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
exports.binding = binding;
|
|
70
|
+
/**
|
|
71
|
+
* Ensures that the 'cucumber-tsflow' hooks are bound to Cucumber.
|
|
72
|
+
*
|
|
73
|
+
* @param cucumber The cucumber object.
|
|
74
|
+
*
|
|
75
|
+
* The hooks will only be registered with Cucumber once regardless of which binding invokes the
|
|
76
|
+
* function.
|
|
77
|
+
*/
|
|
78
|
+
const ensureSystemBindings = _.once(() => {
|
|
79
|
+
(0, cucumber_1.Before)(function (scenario) {
|
|
80
|
+
var _a, _b, _c, _d;
|
|
81
|
+
logger_1.default.trace('Setting up scenario context for scenario:', JSON.stringify(scenario));
|
|
82
|
+
this[SCENARIO_CONTEXT_SLOTNAME] = new managed_scenario_context_1.ManagedScenarioContext((_b = (_a = scenario.pickle) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : '', _.map((_d = (_c = scenario.pickle) === null || _c === void 0 ? void 0 : _c.tags) !== null && _d !== void 0 ? _d : new Array(), (tag) => { var _a; return (_a = tag === null || tag === void 0 ? void 0 : tag.name) !== null && _a !== void 0 ? _a : ''; }));
|
|
83
|
+
});
|
|
84
|
+
(0, cucumber_1.After)(function () {
|
|
85
|
+
const scenarioContext = this[SCENARIO_CONTEXT_SLOTNAME];
|
|
86
|
+
if (scenarioContext) {
|
|
87
|
+
scenarioContext.dispose();
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
/**
|
|
92
|
+
* Binds a step definition to Cucumber.
|
|
93
|
+
*
|
|
94
|
+
* @param stepBinding The [[StepBinding]] that represents a 'given', 'when', or 'then' step definition.
|
|
95
|
+
*/
|
|
96
|
+
function bindStepDefinition(stepBinding) {
|
|
97
|
+
const bindingFunc = function () {
|
|
98
|
+
const bindingRegistry = binding_registry_1.BindingRegistry.instance;
|
|
99
|
+
const scenarioContext = this[SCENARIO_CONTEXT_SLOTNAME];
|
|
100
|
+
const matchingStepBindings = bindingRegistry.getStepBindings(stepBinding.stepPattern.toString(), scenarioContext.scenarioInfo.tags);
|
|
101
|
+
if (matchingStepBindings.length > 1) {
|
|
102
|
+
let message = `Ambiguous step definitions for '${matchingStepBindings[0].stepPattern}':\n`;
|
|
103
|
+
matchingStepBindings.forEach(matchingStepBinding => {
|
|
104
|
+
message =
|
|
105
|
+
message +
|
|
106
|
+
`\t\t${String(matchingStepBinding.targetPropertyKey)} (${matchingStepBinding.callsite.toString()})\n`;
|
|
107
|
+
});
|
|
108
|
+
throw new Error(message);
|
|
109
|
+
}
|
|
110
|
+
else if (matchingStepBindings.length === 0) {
|
|
111
|
+
throw new Error(`Cannot find matched step definition for ${stepBinding.stepPattern.toString()} with tag ${scenarioContext.scenarioInfo.tags} in binding registry`);
|
|
112
|
+
}
|
|
113
|
+
const contextTypes = bindingRegistry.getContextTypesForTarget(matchingStepBindings[0].targetPrototype);
|
|
114
|
+
const bindingObject = scenarioContext.getOrActivateBindingClass(matchingStepBindings[0].targetPrototype, contextTypes);
|
|
115
|
+
bindingObject._worldObj = this;
|
|
116
|
+
return bindingObject[matchingStepBindings[0].targetPropertyKey].apply(bindingObject, arguments);
|
|
117
|
+
};
|
|
118
|
+
Object.defineProperty(bindingFunc, 'length', {
|
|
119
|
+
value: stepBinding.argsLength
|
|
120
|
+
});
|
|
121
|
+
if (stepBinding.bindingType & step_binding_1.StepBindingFlags.given) {
|
|
122
|
+
(0, cucumber_1.Given)(stepBinding.stepPattern, {
|
|
123
|
+
timeout: stepBinding.timeout,
|
|
124
|
+
wrapperOptions: stepBinding.wrapperOption
|
|
125
|
+
}, bindingFunc);
|
|
126
|
+
}
|
|
127
|
+
else if (stepBinding.bindingType & step_binding_1.StepBindingFlags.when) {
|
|
128
|
+
(0, cucumber_1.When)(stepBinding.stepPattern, {
|
|
129
|
+
timeout: stepBinding.timeout,
|
|
130
|
+
wrapperOptions: stepBinding.wrapperOption
|
|
131
|
+
}, bindingFunc);
|
|
132
|
+
}
|
|
133
|
+
else if (stepBinding.bindingType & step_binding_1.StepBindingFlags.then) {
|
|
134
|
+
(0, cucumber_1.Then)(stepBinding.stepPattern, {
|
|
135
|
+
timeout: stepBinding.timeout,
|
|
136
|
+
wrapperOptions: stepBinding.wrapperOption
|
|
137
|
+
}, bindingFunc);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Binds a hook to Cucumber.
|
|
142
|
+
*
|
|
143
|
+
* @param cucumber The cucumber object.
|
|
144
|
+
* @param stepBinding The [[StepBinding]] that represents a 'before', or 'after', step definition.
|
|
145
|
+
*/
|
|
146
|
+
function bindHook(stepBinding) {
|
|
147
|
+
const bindingFunc = function () {
|
|
148
|
+
const scenarioContext = this[SCENARIO_CONTEXT_SLOTNAME];
|
|
149
|
+
const contextTypes = binding_registry_1.BindingRegistry.instance.getContextTypesForTarget(stepBinding.targetPrototype);
|
|
150
|
+
const bindingObject = scenarioContext.getOrActivateBindingClass(stepBinding.targetPrototype, contextTypes);
|
|
151
|
+
bindingObject._worldObj = this;
|
|
152
|
+
return bindingObject[stepBinding.targetPropertyKey].apply(bindingObject, arguments);
|
|
153
|
+
};
|
|
154
|
+
const globalBindFunc = () => {
|
|
155
|
+
const targetPrototype = stepBinding.targetPrototype;
|
|
156
|
+
const targetPropertyKey = stepBinding.targetPropertyKey;
|
|
157
|
+
return targetPrototype[targetPropertyKey].apply();
|
|
158
|
+
};
|
|
159
|
+
Object.defineProperty(bindingFunc, 'length', {
|
|
160
|
+
value: stepBinding.argsLength
|
|
161
|
+
});
|
|
162
|
+
const tags = stepBinding.tag === binding_registry_1.DEFAULT_TAG ? undefined : stepBinding.tag;
|
|
163
|
+
switch (stepBinding.bindingType) {
|
|
164
|
+
case step_binding_1.StepBindingFlags.before: {
|
|
165
|
+
(0, cucumber_1.Before)({
|
|
166
|
+
tags: tags,
|
|
167
|
+
timeout: stepBinding.timeout
|
|
168
|
+
}, bindingFunc);
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
case step_binding_1.StepBindingFlags.after: {
|
|
172
|
+
(0, cucumber_1.After)({
|
|
173
|
+
tags: tags,
|
|
174
|
+
timeout: stepBinding.timeout
|
|
175
|
+
}, bindingFunc);
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
case step_binding_1.StepBindingFlags.beforeAll: {
|
|
179
|
+
(0, cucumber_1.BeforeAll)(globalBindFunc);
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
case step_binding_1.StepBindingFlags.afterAll: {
|
|
183
|
+
(0, cucumber_1.AfterAll)(globalBindFunc);
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
//# sourceMappingURL=binding-decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding-decorator.js","sourceRoot":"","sources":["../src/binding-decorator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { StepBinding } from './step-binding';
|
|
2
|
+
import { ContextType, StepPattern, TagName } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Represents the default step pattern.
|
|
5
|
+
*/
|
|
6
|
+
export declare const DEFAULT_STEP_PATTERN = "/.*/";
|
|
7
|
+
/**
|
|
8
|
+
* Represents the default tag.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_TAG = "*";
|
|
11
|
+
/**
|
|
12
|
+
* A metadata registry that captures information about bindings and their bound step bindings.
|
|
13
|
+
*/
|
|
14
|
+
export declare class BindingRegistry {
|
|
15
|
+
private _bindings;
|
|
16
|
+
private _targetBindings;
|
|
17
|
+
/**
|
|
18
|
+
* Gets the binding registry singleton.
|
|
19
|
+
*
|
|
20
|
+
* @returns A [[BindingRegistry]].
|
|
21
|
+
*/
|
|
22
|
+
static get instance(): BindingRegistry;
|
|
23
|
+
/**
|
|
24
|
+
* Updates the binding registry with information about the context types required by a
|
|
25
|
+
* binding class.
|
|
26
|
+
*
|
|
27
|
+
* @param targetPrototype The class representing the binding (constructor function).
|
|
28
|
+
* @param contextTypes An array of [[ContextType]] that define the types of objects that
|
|
29
|
+
* should be injected into the binding class during a scenario execution.
|
|
30
|
+
*/
|
|
31
|
+
registerContextTypesForTarget(targetPrototype: any, contextTypes?: ContextType[]): void;
|
|
32
|
+
/**
|
|
33
|
+
* Retrieves the context types that have been registered for a given binding class.
|
|
34
|
+
*
|
|
35
|
+
* @param targetPrototype The class representing the binding (constructor function).
|
|
36
|
+
*
|
|
37
|
+
* @returns An array of [[ContextType]] that have been registered for the specified
|
|
38
|
+
* binding class.
|
|
39
|
+
*/
|
|
40
|
+
getContextTypesForTarget(targetPrototype: any): ContextType[];
|
|
41
|
+
/**
|
|
42
|
+
* Updates the binding registry indexes with a step binding.
|
|
43
|
+
*
|
|
44
|
+
* @param stepBinding The step binding that is to be registered with the binding registry.
|
|
45
|
+
*/
|
|
46
|
+
registerStepBinding(stepBinding: StepBinding): void;
|
|
47
|
+
/**
|
|
48
|
+
* Retrieves the step bindings that have been registered for a given binding class.
|
|
49
|
+
*
|
|
50
|
+
* @param targetPrototype The class representing the binding (constructor function).
|
|
51
|
+
*
|
|
52
|
+
* @returns An array of [[StepBinding]] objects that have been registered for the specified
|
|
53
|
+
* binding class.
|
|
54
|
+
*/
|
|
55
|
+
getStepBindingsForTarget(targetPrototype: any): StepBinding[];
|
|
56
|
+
/**
|
|
57
|
+
* Retrieves the step bindings for a given step pattern and collection of tag names.
|
|
58
|
+
*
|
|
59
|
+
* @param stepPattern The step pattern to search.
|
|
60
|
+
* @param tags An array of [[TagName]] to search.
|
|
61
|
+
*
|
|
62
|
+
* @returns An array of [[StepBinding]] that map to the given step pattern and set of tag names.
|
|
63
|
+
*/
|
|
64
|
+
getStepBindings(stepPattern: StepPattern, tags: TagName[]): StepBinding[];
|
|
65
|
+
/**
|
|
66
|
+
* Maps an array of tag names to an array of associated step bindings.
|
|
67
|
+
*
|
|
68
|
+
* @param tags An array of [[TagName]].
|
|
69
|
+
* @param tagMap The map of [[TagName]] -> [[StepBinding]] to use when mapping.
|
|
70
|
+
*
|
|
71
|
+
* @returns An array of [[StepBinding]].
|
|
72
|
+
*/
|
|
73
|
+
private mapTagNamesToStepBindings;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=binding-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding-registry.d.ts","sourceRoot":"","sources":["../src/binding-registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAiB5D;;GAEG;AACH,eAAO,MAAM,oBAAoB,SAAS,CAAC;AAE3C;;GAEG;AACH,eAAO,MAAM,WAAW,MAAM,CAAC;AAE/B;;GAEG;AACH,qBAAa,eAAe;IAC3B,OAAO,CAAC,SAAS,CAAuD;IACxE,OAAO,CAAC,eAAe,CAAiC;IAExD;;;;OAIG;IACH,WAAkB,QAAQ,IAAI,eAAe,CAU5C;IAED;;;;;;;OAOG;IACI,6BAA6B,CAAC,eAAe,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI;IAmB9F;;;;;;;OAOG;IACI,wBAAwB,CAAC,eAAe,EAAE,GAAG,GAAG,WAAW,EAAE;IAUpE;;;;OAIG;IACI,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IA6D1D;;;;;;;OAOG;IACI,wBAAwB,CAAC,eAAe,EAAE,GAAG,GAAG,WAAW,EAAE;IAUpE;;;;;;;OAOG;IACI,eAAe,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,WAAW,EAAE;IAgBhF;;;;;;;OAOG;IACH,OAAO,CAAC,yBAAyB;CAKjC"}
|