Skip to content

Commit 83a9101

Browse files
authored
Merge pull request #85 from olexale/feature/absolute_path_to_steps
Add relativeToTestFolder
2 parents 8999dea + b1d15ab commit 83a9101

11 files changed

Lines changed: 128 additions & 12 deletions

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,15 @@ targets:
429429

430430
Since Patrol version 3.0.0, `IntegrationTestWidgetsFlutterBinding.ensureInitialized` must not be called. Set `includeIntegrationTestBinding` to `false`.
431431

432+
### I don't like that the plugin creates steps under `test` folder. How to change that?
433+
434+
You may set a relative path in the `build.yaml` file (see the `example` folder):
435+
```yaml
436+
relativeToTestFolder: false
437+
stepFolderName: integration_test/steps # if you want to have steps in the integration_test folder
438+
hookFolderName: integration_test/bdd_hooks # if you want to have hooks in the integration_test folder
439+
```
440+
432441
## Contributing
433442

434443
If you find a bug or would like to request a new feature, just [open an issue](https://github.com/olexale/bdd_widget_test/issues/new). Your contributions are always welcome!

example/build.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ targets:
1010
options:
1111
includeIntegrationTestBinding: false # if false, integration test will not include binding; default is true
1212
stepFolderName: step # this trick is required to share steps between widget and integration tests
13+
# relativeToTestFolder: false # if false, steps will be generated in the root of the package; default is true
1314
# testMethodName: customTestMethodName
15+
# addHooks: true # if true, hooks will be added to the test; default is false
16+
# hookFolderName: bdd_hooks
1417
include: package:bdd_widget_test/bdd_options.yaml # you may add defaul external steps with this line
1518
externalSteps: # or list only steps that you need
1619
- package:bdd_widget_test/step/i_see_text.dart

lib/bdd_widget_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class FeatureBuilder implements Builder {
3333
final feature = FeatureFile(
3434
featureDir: featureDir,
3535
package: inputId.package,
36-
existingSteps: getExistingStepSubfolders(featureDir, options.stepFolder),
36+
existingSteps: getExistingStepSubfolders(featureDir, options),
3737
input: contents,
3838
generatorOptions: options,
3939
includeIntegrationTestImport: isIntegrationTest,

lib/src/existing_steps.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
import 'package:bdd_widget_test/src/util/constants.dart';
1+
import 'package:bdd_widget_test/src/generator_options.dart';
22
import 'package:bdd_widget_test/src/util/fs.dart';
3+
import 'package:bdd_widget_test/src/util/get_test_folder_name.dart';
34
import 'package:path/path.dart' as p;
45

56
/// key - step filename, value - path for import (ex: {'i_have_a_step.dart': 'step/common'})
67
Map<String, String> getExistingStepSubfolders(
78
String featureDir,
8-
String stepFolderName,
9+
GeneratorOptions options,
910
) {
11+
final stepFolderName = options.stepFolder;
1012
final stepFolder = p.join(
1113
stepFolderName.startsWith('./') || stepFolderName.startsWith('../')
1214
? featureDir
13-
: testFolderName,
15+
: getPathToStepFolder(options),
1416
stepFolderName,
1517
);
1618

lib/src/generator_options.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ class GeneratorOptions {
1313
String? testMethodName,
1414
List<String>? externalSteps,
1515
String? stepFolderName,
16+
bool? relativeToTestFolder,
1617
String? testerType,
1718
String? testerName,
1819
bool? addHooks,
1920
String? hookFolderName,
2021
this.include,
2122
bool? includeIntegrationTestBinding,
2223
}) : stepFolder = stepFolderName ?? _stepFolderName,
24+
relativeToTestFolder = relativeToTestFolder ?? true,
2325
testMethodName = testMethodName ?? _defaultTestMethodName,
2426
testerType = testerType ?? _defaultTesterType,
2527
testerName = testerName ?? _defaultTesterName,
@@ -35,6 +37,7 @@ class GeneratorOptions {
3537
testerName: json['testerName'] as String?,
3638
externalSteps: (json['externalSteps'] as List?)?.cast<String>(),
3739
stepFolderName: json['stepFolderName'] as String?,
40+
relativeToTestFolder: json['relativeToTestFolder'] as bool?,
3841
addHooks: json['addHooks'] as bool?,
3942
hookFolderName: json['hookFolderName'] as String?,
4043
include: json['include'] is String
@@ -45,6 +48,7 @@ class GeneratorOptions {
4548
);
4649

4750
final String stepFolder;
51+
final bool relativeToTestFolder;
4852
final String testMethodName;
4953
final String testerType;
5054
final String testerName;
@@ -96,6 +100,7 @@ GeneratorOptions merge(GeneratorOptions a, GeneratorOptions b) =>
96100
a.testerName != _defaultTesterName ? a.testerName : b.testerName,
97101
stepFolderName:
98102
a.stepFolder != _stepFolderName ? a.stepFolder : b.stepFolder,
103+
relativeToTestFolder: a.relativeToTestFolder && b.relativeToTestFolder,
99104
externalSteps: [...a.externalSteps, ...b.externalSteps],
100105
addHooks: a.addHooks || b.addHooks,
101106
hookFolderName: a.hookFolderName != _hookFolderName

lib/src/hook_file.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:bdd_widget_test/src/generator_options.dart';
22
import 'package:bdd_widget_test/src/util/constants.dart';
3+
import 'package:bdd_widget_test/src/util/get_test_folder_name.dart';
34
import 'package:path/path.dart' as p;
45

56
class HookFile {
@@ -31,10 +32,13 @@ class HookFile {
3132
return HookFile._create(
3233
featureDir: featureDir,
3334
package: package,
34-
fileName:
35-
p.join(testFolderName, generatorOptions.hookFolderName, fileName),
35+
fileName: p.join(
36+
getPathToStepFolder(generatorOptions),
37+
generatorOptions.hookFolderName,
38+
fileName,
39+
),
3640
import: p.join(
37-
p.relative(testFolderName, from: featureDir),
41+
p.relative(getPathToStepFolder(generatorOptions), from: featureDir),
3842
generatorOptions.hookFolderName,
3943
fileName,
4044
),

lib/src/step_file.dart

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import 'package:bdd_widget_test/src/bdd_line.dart';
22
import 'package:bdd_widget_test/src/generator_options.dart';
33
import 'package:bdd_widget_test/src/step_generator.dart';
4-
import 'package:bdd_widget_test/src/util/constants.dart';
4+
import 'package:bdd_widget_test/src/util/get_test_folder_name.dart';
55
import 'package:path/path.dart' as p;
66

77
abstract class StepFile {
@@ -33,6 +33,7 @@ abstract class StepFile {
3333

3434
if (generatorOptions.stepFolder.startsWith('./') ||
3535
generatorOptions.stepFolder.startsWith('../')) {
36+
// step folder is relative to feature file
3637
final import =
3738
p.join(generatorOptions.stepFolder, file).replaceAll(r'\', '/');
3839
final filename = p.join(featureDir, generatorOptions.stepFolder, file);
@@ -47,11 +48,17 @@ abstract class StepFile {
4748
);
4849
}
4950

50-
final pathToTestFolder = p.relative(testFolderName, from: featureDir);
51+
// step folder is relative to test folder
52+
final pathToTestFolder =
53+
p.relative(getPathToStepFolder(generatorOptions), from: featureDir);
5154
final import = p
5255
.join(pathToTestFolder, generatorOptions.stepFolder, file)
5356
.replaceAll(r'\', '/');
54-
final filename = p.join(testFolderName, generatorOptions.stepFolder, file);
57+
final filename = p.join(
58+
getPathToStepFolder(generatorOptions),
59+
generatorOptions.stepFolder,
60+
file,
61+
);
5562
return NewStepFile._(
5663
import,
5764
filename,

lib/src/util/constants.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,3 @@ const testerNameTag = '@testerName:';
3030
/// scenario functions for example: @scenarioParams: skip: false, timeout: Timeout(Duration(seconds: 1))
3131
/// because some test packaages like `patrol` support this.
3232
const scenarioParamsTag = '@scenarioParams:';
33-
34-
const testFolderName = 'test';
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import 'package:bdd_widget_test/src/generator_options.dart';
2+
import 'package:bdd_widget_test/src/util/fs.dart';
3+
4+
const _testFolderName = 'test';
5+
6+
/// Returns the folder where step folder is located.
7+
String getPathToStepFolder(GeneratorOptions options) {
8+
if (options.relativeToTestFolder) {
9+
return _testFolderName;
10+
}
11+
return fs.currentDirectory.path;
12+
}

test/feature_generator_test.dart

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,46 @@ void main() {
5656
expect(content, expectedFileContent);
5757
});
5858

59+
test('existing step outside test folder should be found', () async {
60+
const bddOptions = '''
61+
stepFolderName: my_steps
62+
relativeToTestFolder: false
63+
''';
64+
fs.file('bdd_options.yaml')
65+
..createSync()
66+
..writeAsStringSync(bddOptions);
67+
68+
const scenario = 'existing_step_outside_test_folder';
69+
final dummyStepPath =
70+
p.join(fs.currentDirectory.path, 'my_steps', 'the_app_is_running.dart');
71+
fs.file(dummyStepPath)
72+
..createSync(recursive: true)
73+
..writeAsStringSync('dummy');
74+
75+
// note: the import is so weird because p.relative() can not
76+
// find intersection between two paths (however, somehow it works)
77+
// not a problem in the real world
78+
const expected = '// GENERATED CODE - DO NOT MODIFY BY HAND\n'
79+
'// ignore_for_file: unused_import, directives_ordering\n'
80+
'\n'
81+
"import 'package:flutter/material.dart';\n"
82+
"import 'package:flutter_test/flutter_test.dart';\n"
83+
'\n'
84+
"import './../../../../../../../../my_steps/the_app_is_running.dart';\n"
85+
'\n'
86+
'void main() {\n'
87+
" group('''Testing feature''', () {\n"
88+
" testWidgets('''Testing scenario''', (tester) async {\n"
89+
' await theAppIsRunning(tester);\n'
90+
' });\n'
91+
' });\n'
92+
'}\n';
93+
94+
final content = await generate(scenario);
95+
96+
expect(content, expected);
97+
});
98+
5999
test('custom bdd_options', () async {
60100
const bddOptions = '''
61101
stepFolderName: ./scenarios

0 commit comments

Comments
 (0)