ruby_raider 3.0.0 → 3.1.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.
- checksums.yaml +4 -4
- data/.github/workflows/e2e_tests.yml +0 -17
- data/.github/workflows/system_tests.yml +0 -22
- data/README.md +8 -62
- data/lib/commands/scaffolding_commands.rb +22 -188
- data/lib/commands/utility_commands.rb +10 -44
- data/lib/generators/automation/templates/login.tt +1 -9
- data/lib/generators/automation/templates/page.tt +1 -7
- data/lib/generators/automation/templates/partials/initialize_selector.tt +1 -3
- data/lib/generators/automation/templates/partials/visit_method.tt +2 -6
- data/lib/generators/common_generator.rb +0 -6
- data/lib/generators/cucumber/cucumber_generator.rb +0 -24
- data/lib/generators/cucumber/templates/accessibility_steps.tt +2 -6
- data/lib/generators/cucumber/templates/cucumber.tt +0 -7
- data/lib/generators/cucumber/templates/env.tt +1 -3
- data/lib/generators/cucumber/templates/partials/appium_env.tt +1 -6
- data/lib/generators/cucumber/templates/partials/selenium_env.tt +0 -5
- data/lib/generators/cucumber/templates/partials/watir_env.tt +0 -5
- data/lib/generators/cucumber/templates/partials/web_steps.tt +4 -4
- data/lib/generators/cucumber/templates/world.tt +1 -3
- data/lib/generators/generator.rb +2 -46
- data/lib/generators/helper_generator.rb +4 -42
- data/lib/generators/infrastructure/templates/github.tt +2 -2
- data/lib/generators/infrastructure/templates/github_appium.tt +2 -6
- data/lib/generators/invoke_generators.rb +4 -25
- data/lib/generators/menu_generator.rb +10 -100
- data/lib/generators/rspec/rspec_generator.rb +0 -11
- data/lib/generators/rspec/templates/accessibility_spec.tt +2 -6
- data/lib/generators/rspec/templates/spec.tt +6 -8
- data/lib/generators/templates/common/gemfile.tt +0 -26
- data/lib/generators/templates/common/git_ignore.tt +0 -2
- data/lib/generators/templates/common/partials/mobile_config.tt +0 -4
- data/lib/generators/templates/common/partials/web_config.tt +0 -4
- data/lib/generators/templates/common/rakefile.tt +0 -9
- data/lib/generators/templates/common/read_me.tt +4 -10
- data/lib/generators/templates/helpers/allure_helper.tt +0 -10
- data/lib/generators/templates/helpers/browser_helper.tt +1 -1
- data/lib/generators/templates/helpers/partials/debug_diagnostics.tt +1 -3
- data/lib/generators/templates/helpers/partials/debug_start.tt +1 -3
- data/lib/generators/templates/helpers/partials/quit_driver.tt +1 -3
- data/lib/generators/templates/helpers/partials/screenshot.tt +1 -3
- data/lib/generators/templates/helpers/partials/selenium_driver.tt +1 -1
- data/lib/generators/templates/helpers/spec_helper.tt +2 -39
- data/lib/ruby_raider.rb +2 -50
- data/lib/scaffolding/project_detector.rb +30 -13
- data/lib/scaffolding/scaffolding.rb +0 -109
- data/lib/scaffolding/templates/component.tt +1 -4
- data/lib/scaffolding/templates/page_object.tt +0 -10
- data/lib/scaffolding/templates/spec.tt +2 -6
- data/lib/scaffolding/templates/steps.tt +0 -2
- data/lib/utilities/utilities.rb +26 -24
- data/lib/version +1 -1
- data/sig/commands/scaffolding_commands.rbs +0 -12
- data/sig/commands/utility_commands.rbs +0 -6
- data/sig/generators/cucumber/cucumber_generator.rbs +0 -4
- data/sig/generators/generator.rbs +0 -11
- data/sig/generators/helper_generator.rbs +1 -5
- data/sig/generators/invoke_generators.rbs +1 -2
- data/sig/generators/menu_generator.rbs +2 -6
- data/sig/generators/rspec/rspec_generator.rbs +0 -2
- data/sig/ruby_raider.rbs +1 -3
- data/sig/scaffolding/project_detector.rbs +0 -1
- data/sig/scaffolding/scaffolding.rbs +0 -23
- data/sig/utilities/utilities.rbs +0 -4
- data/spec/commands/raider_commands_spec.rb +0 -61
- data/spec/commands/scaffolding_commands_spec.rb +22 -0
- data/spec/integration/commands/browser_update_after_creation_spec.rb +123 -0
- data/spec/integration/commands/scaffolding_commands_spec.rb +0 -20
- data/spec/integration/commands/utility_commands_spec.rb +9 -9
- data/spec/integration/content/ci_content_spec.rb +6 -61
- data/spec/integration/content/common_content_spec.rb +0 -64
- data/spec/integration/content/config_content_spec.rb +1 -51
- data/spec/integration/content/content_helper.rb +2 -2
- data/spec/integration/content/gemfile_content_spec.rb +0 -71
- data/spec/integration/content/helper_content_spec.rb +4 -240
- data/spec/integration/content/page_content_spec.rb +0 -89
- data/spec/integration/content/syntax_validation_spec.rb +2 -2
- data/spec/integration/content/test_content_spec.rb +0 -119
- data/spec/integration/end_to_end_features_spec.rb +13 -411
- data/spec/integration/end_to_end_spec.rb +0 -96
- data/spec/integration/generators/axe_addon_spec.rb +2 -52
- data/spec/integration/generators/common_generator_spec.rb +1 -13
- data/spec/integration/generators/config_features_spec.rb +3 -81
- data/spec/integration/generators/debug_helper_spec.rb +0 -20
- data/spec/integration/generators/github_generator_spec.rb +5 -15
- data/spec/integration/generators/helpers_generator_spec.rb +0 -37
- data/spec/integration/scaffolding_e2e_spec.rb +540 -0
- data/spec/integration/settings_helper.rb +1 -3
- data/spec/integration/spec_helper.rb +6 -11
- data/spec/menus/menu_generator_spec.rb +4 -107
- data/spec/scaffolding/scaffold_project_detector_spec.rb +42 -26
- data/spec/scaffolding/scaffolding_features_spec.rb +0 -183
- data/spec/system/selenium_spec.rb +1 -4
- data/spec/system/support/system_test_helper.rb +0 -1
- data/spec/system/watir_spec.rb +1 -4
- data/spec/utilities/headless_config_spec.rb +82 -0
- data/spec/utilities/utilities_spec.rb +105 -0
- metadata +7 -97
- data/lib/adopter/adopt_menu.rb +0 -146
- data/lib/adopter/converters/base_converter.rb +0 -84
- data/lib/adopter/converters/identity_converter.rb +0 -53
- data/lib/adopter/migration_plan.rb +0 -74
- data/lib/adopter/migrator.rb +0 -96
- data/lib/adopter/plan_builder.rb +0 -275
- data/lib/adopter/project_analyzer.rb +0 -252
- data/lib/adopter/project_detector.rb +0 -157
- data/lib/generators/cucumber/templates/partials/capybara_env.tt +0 -38
- data/lib/generators/cucumber/templates/partials/capybara_world.tt +0 -6
- data/lib/generators/cucumber/templates/performance_feature.tt +0 -5
- data/lib/generators/cucumber/templates/performance_steps.tt +0 -17
- data/lib/generators/cucumber/templates/visual_feature.tt +0 -5
- data/lib/generators/cucumber/templates/visual_steps.tt +0 -19
- data/lib/generators/infrastructure/gitlab_generator.rb +0 -11
- data/lib/generators/infrastructure/templates/gitlab.tt +0 -46
- data/lib/generators/minitest/minitest_generator.rb +0 -35
- data/lib/generators/minitest/templates/accessibility_test.tt +0 -26
- data/lib/generators/minitest/templates/performance_test.tt +0 -18
- data/lib/generators/minitest/templates/test.tt +0 -64
- data/lib/generators/minitest/templates/visual_test.tt +0 -23
- data/lib/generators/rspec/templates/performance_spec.tt +0 -18
- data/lib/generators/rspec/templates/visual_spec.tt +0 -20
- data/lib/generators/templates/helpers/capybara_helper.tt +0 -32
- data/lib/generators/templates/helpers/performance_helper.tt +0 -57
- data/lib/generators/templates/helpers/visual_helper.tt +0 -58
- data/lib/llm/client.rb +0 -79
- data/lib/llm/config.rb +0 -57
- data/lib/llm/prompts.rb +0 -84
- data/lib/llm/provider.rb +0 -27
- data/lib/llm/providers/anthropic_provider.rb +0 -43
- data/lib/llm/providers/ollama_provider.rb +0 -56
- data/lib/llm/providers/openai_provider.rb +0 -42
- data/lib/llm/response_parser.rb +0 -67
- data/lib/plugin/plugin.rb +0 -111
- data/lib/plugin/plugin_exposer.rb +0 -55
- data/lib/scaffolding/crud_generator.rb +0 -94
- data/lib/scaffolding/dry_run_presenter.rb +0 -16
- data/lib/scaffolding/page_introspector.rb +0 -45
- data/lib/scaffolding/scaffold_menu.rb +0 -103
- data/lib/scaffolding/templates/page_from_url.tt +0 -75
- data/lib/scaffolding/templates/spec_from_page.tt +0 -31
- data/lib/scaffolding/templates/spec_from_url.tt +0 -46
- data/lib/scaffolding/url_analyzer.rb +0 -179
- data/sig/adopter/adopt_menu.rbs +0 -25
- data/sig/adopter/converters/base_converter.rbs +0 -23
- data/sig/adopter/converters/identity_converter.rbs +0 -16
- data/sig/adopter/migration_plan.rbs +0 -34
- data/sig/adopter/migrator.rbs +0 -21
- data/sig/adopter/plan_builder.rbs +0 -38
- data/sig/adopter/project_analyzer.rbs +0 -39
- data/sig/adopter/project_detector.rbs +0 -26
- data/sig/generators/infrastructure/gitlab_generator.rbs +0 -4
- data/sig/generators/minitest/minitest_generator.rbs +0 -8
- data/sig/llm/client.rbs +0 -15
- data/sig/llm/config.rbs +0 -20
- data/sig/llm/prompts.rbs +0 -8
- data/sig/llm/provider.rbs +0 -12
- data/sig/llm/providers/anthropic_provider.rbs +0 -16
- data/sig/llm/providers/ollama_provider.rbs +0 -18
- data/sig/llm/providers/openai_provider.rbs +0 -16
- data/sig/llm/response_parser.rbs +0 -13
- data/sig/plugin/plugin.rbs +0 -24
- data/sig/plugin/plugin_exposer.rbs +0 -20
- data/sig/scaffolding/crud_generator.rbs +0 -16
- data/sig/scaffolding/dry_run_presenter.rbs +0 -4
- data/sig/scaffolding/page_introspector.rbs +0 -14
- data/sig/scaffolding/scaffold_menu.rbs +0 -18
- data/sig/scaffolding/url_analyzer.rbs +0 -28
- data/spec/adopter/adopt_menu_spec.rb +0 -176
- data/spec/adopter/converters/identity_converter_spec.rb +0 -145
- data/spec/adopter/migration_plan_spec.rb +0 -113
- data/spec/adopter/migrator_spec.rb +0 -277
- data/spec/adopter/plan_builder_spec.rb +0 -298
- data/spec/adopter/project_analyzer_spec.rb +0 -337
- data/spec/adopter/project_detector_spec.rb +0 -295
- data/spec/generators/generator_spec.rb +0 -23
- data/spec/integration/content/reporter_content_spec.rb +0 -236
- data/spec/integration/content/skip_flags_content_spec.rb +0 -206
- data/spec/integration/generators/gitlab_generator_spec.rb +0 -38
- data/spec/integration/generators/lighthouse_addon_spec.rb +0 -132
- data/spec/integration/generators/minitest_generator_spec.rb +0 -64
- data/spec/integration/generators/reporter_spec.rb +0 -159
- data/spec/integration/generators/skip_flags_spec.rb +0 -134
- data/spec/integration/generators/visual_addon_spec.rb +0 -148
- data/spec/llm/client_spec.rb +0 -79
- data/spec/llm/config_spec.rb +0 -92
- data/spec/llm/prompts_spec.rb +0 -49
- data/spec/llm/response_parser_spec.rb +0 -92
- data/spec/menus/adopter_adopt_menu_spec.rb +0 -97
- data/spec/scaffolding/page_introspector_spec.rb +0 -82
- data/spec/scaffolding/url_analyzer_spec.rb +0 -110
- data/spec/system/adopt_matrix_spec.rb +0 -537
- data/spec/system/adopt_spec.rb +0 -225
- data/spec/system/capybara_spec.rb +0 -42
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce03b1ba3081d2259a481dc00f40b5bf95e7012784a593b187f3031fd9d0b33b
|
|
4
|
+
data.tar.gz: d42284c333748033d19c05231fb2da690896793745e93495382cafe1c6ccc4d0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 525f632e44410a8adff2addb4e7d60b2e9e9c8a48294672e2b6689898a0c7d88047ce5c0a908db4197595d2f85dabc2c589b93b75497b3e8df9d4001a7d179d5
|
|
7
|
+
data.tar.gz: 34862b92a99c1e1a743dbc3c6b4a48a3d0d8ebca5253b7c666078cb5acf957f5c4e7935167aa4556a4a119c03b928264014edda5dd58e357f4665b73f098c056
|
|
@@ -20,23 +20,6 @@ jobs:
|
|
|
20
20
|
- name: Run content validation tests
|
|
21
21
|
run: bundle exec rspec spec/integration/content/ --format documentation
|
|
22
22
|
|
|
23
|
-
e2e-adopt:
|
|
24
|
-
name: Adopt E2E tests
|
|
25
|
-
runs-on: ubuntu-latest
|
|
26
|
-
|
|
27
|
-
steps:
|
|
28
|
-
- name: Checkout repository
|
|
29
|
-
uses: actions/checkout@v4
|
|
30
|
-
|
|
31
|
-
- name: Set up Ruby
|
|
32
|
-
uses: ruby/setup-ruby@v1
|
|
33
|
-
with:
|
|
34
|
-
ruby-version: '3.3'
|
|
35
|
-
bundler-cache: true
|
|
36
|
-
|
|
37
|
-
- name: Run adopt system tests
|
|
38
|
-
run: bundle exec rspec spec/system/adopt_spec.rb --format documentation
|
|
39
|
-
|
|
40
23
|
command-and-menu-tests:
|
|
41
24
|
name: Command routing and menu tests
|
|
42
25
|
runs-on: ubuntu-latest
|
|
@@ -59,25 +59,3 @@ jobs:
|
|
|
59
59
|
|
|
60
60
|
- name: Run Watir system tests
|
|
61
61
|
run: bundle exec rspec spec/system/watir_spec.rb --format documentation
|
|
62
|
-
|
|
63
|
-
capybara:
|
|
64
|
-
name: Capybara frameworks
|
|
65
|
-
needs: setup
|
|
66
|
-
runs-on: ubuntu-latest
|
|
67
|
-
steps:
|
|
68
|
-
- name: Checkout repository
|
|
69
|
-
uses: actions/checkout@v4
|
|
70
|
-
|
|
71
|
-
- name: Set up Ruby
|
|
72
|
-
uses: ruby/setup-ruby@v1
|
|
73
|
-
with:
|
|
74
|
-
ruby-version: '3.4'
|
|
75
|
-
bundler-cache: true
|
|
76
|
-
|
|
77
|
-
- name: Set up Chrome
|
|
78
|
-
uses: browser-actions/setup-chrome@v1
|
|
79
|
-
with:
|
|
80
|
-
chrome-version: stable
|
|
81
|
-
|
|
82
|
-
- name: Run Capybara system tests
|
|
83
|
-
run: bundle exec rspec spec/system/capybara_spec.rb --format documentation
|
data/README.md
CHANGED
|
@@ -33,11 +33,10 @@ Ruby Raider is a CLI gem and API backend for scaffolding and generating UI test
|
|
|
33
33
|
|
|
34
34
|
### Web Testing
|
|
35
35
|
|
|
36
|
-
| Test Framework | Selenium | Watir |
|
|
37
|
-
|
|
38
|
-
| RSpec | ✅ | ✅ |
|
|
39
|
-
| Cucumber | ✅ | ✅ |
|
|
40
|
-
| Minitest | ✅ | ✅ | ✅ |
|
|
36
|
+
| Test Framework | Selenium | Watir |
|
|
37
|
+
|----------------|----------|-------|
|
|
38
|
+
| RSpec | ✅ | ✅ |
|
|
39
|
+
| Cucumber | ✅ | ✅ |
|
|
41
40
|
|
|
42
41
|
### Mobile Testing (Appium)
|
|
43
42
|
|
|
@@ -45,23 +44,14 @@ Ruby Raider is a CLI gem and API backend for scaffolding and generating UI test
|
|
|
45
44
|
|----------------|-----|---------|----------------|
|
|
46
45
|
| RSpec | ✅ | ✅ | ✅ |
|
|
47
46
|
| Cucumber | ✅ | ✅ | ✅ |
|
|
48
|
-
| Minitest | ✅ | ✅ | ✅ |
|
|
49
47
|
|
|
50
|
-
### Optional Add-
|
|
48
|
+
### Optional Add-on (Web Only)
|
|
51
49
|
|
|
52
50
|
| Add-on | Flag | Description |
|
|
53
51
|
|--------|------|-------------|
|
|
54
52
|
| Accessibility | `--accessibility` | Adds axe gem + example accessibility tests |
|
|
55
|
-
| Visual Regression | `--visual` | Adds chunky_png + visual comparison helpers |
|
|
56
|
-
| Performance | `--performance` | Adds Lighthouse auditing (requires `npm install -g lighthouse`) |
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
Projects can be generated with built-in CI/CD pipelines for **GitHub Actions** or **GitLab CI/CD**.
|
|
61
|
-
|
|
62
|
-
### Test Reporters
|
|
63
|
-
|
|
64
|
-
Choose a reporter with `--reporter`: `allure`, `junit`, `json`, `both`, `all`, or `none`.
|
|
54
|
+
All generated projects include a **GitHub Actions** CI pipeline out of the box.
|
|
65
55
|
|
|
66
56
|
***The web tests run against the [Raider Test Store](https://raider-test-site.onrender.com/).***
|
|
67
57
|
|
|
@@ -96,13 +86,7 @@ raider new [project_name] -p framework:rspec automation:selenium
|
|
|
96
86
|
Add optional features:
|
|
97
87
|
|
|
98
88
|
```bash
|
|
99
|
-
raider new my_project -p framework:rspec automation:selenium --accessibility
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Skip flags for leaner projects:
|
|
103
|
-
|
|
104
|
-
```bash
|
|
105
|
-
raider new my_project -p framework:cucumber automation:watir --skip_ci --skip_video --reporter none
|
|
89
|
+
raider new my_project -p framework:rspec automation:selenium --accessibility
|
|
106
90
|
```
|
|
107
91
|
|
|
108
92
|
## Commands
|
|
@@ -113,15 +97,13 @@ raider new my_project -p framework:cucumber automation:watir --skip_ci --skip_vi
|
|
|
113
97
|
|
|
114
98
|
```
|
|
115
99
|
raider new [PROJECT_NAME] # Create a new framework project
|
|
116
|
-
raider adopt # Import an existing test project
|
|
117
100
|
raider generate # Access scaffolding commands
|
|
118
101
|
raider utility # Access utility commands
|
|
119
|
-
raider plugin_manager # Manage plugins
|
|
120
102
|
raider version # Show current version
|
|
121
103
|
raider help [COMMAND] # Describe available commands
|
|
122
104
|
```
|
|
123
105
|
|
|
124
|
-
Shortcuts: `n` (new), `
|
|
106
|
+
Shortcuts: `n` (new), `g` (generate), `u` (utility), `v` (version)
|
|
125
107
|
|
|
126
108
|
### Scaffolding Commands
|
|
127
109
|
|
|
@@ -133,18 +115,12 @@ raider g steps [NAME] # Create step definitions
|
|
|
133
115
|
raider g helper [NAME] # Create a helper class
|
|
134
116
|
raider g component [NAME] # Create a component class
|
|
135
117
|
raider g scaffold [NAME(S)] # Create page + test + steps
|
|
136
|
-
raider g destroy [NAME(S)] # Delete scaffolded files
|
|
137
|
-
raider g from_url [URL] # Generate page & spec from a live URL
|
|
138
118
|
```
|
|
139
119
|
|
|
140
120
|
Options:
|
|
141
121
|
|
|
142
|
-
* `--from [FILE]` — Generate spec from an existing page object
|
|
143
|
-
* `--ai` — Use LLM for intelligent test scenario generation
|
|
144
|
-
* `--dry_run` — Preview files without creating them
|
|
145
122
|
* `--uses [PAGES]` — Specify page dependencies
|
|
146
123
|
* `--path [PATH]` — Custom output path
|
|
147
|
-
* `--crud` — Generate full CRUD scaffold (list, create, detail, edit + tests)
|
|
148
124
|
|
|
149
125
|
### Utility Commands
|
|
150
126
|
|
|
@@ -160,38 +136,8 @@ raider u platform [PLATFORM] # Set platform for cross-platform tests
|
|
|
160
136
|
raider u debug [on/off] # Toggle debug mode
|
|
161
137
|
raider u start_appium # Start Appium server
|
|
162
138
|
raider u desktop # Download Raider Desktop
|
|
163
|
-
raider u llm [PROVIDER] # Configure LLM provider (openai, anthropic, ollama)
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Plugin Commands
|
|
167
|
-
|
|
168
|
-
```
|
|
169
|
-
raider pm add [NAME] # Add a plugin to your project
|
|
170
|
-
raider pm delete [NAME] # Remove a plugin
|
|
171
|
-
raider pm list # List available plugins
|
|
172
|
-
raider pm local # List installed plugins
|
|
173
139
|
```
|
|
174
140
|
|
|
175
|
-
### Adopt Command
|
|
176
|
-
|
|
177
|
-
Import an existing test project into Ruby Raider conventions:
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
raider adopt project [SOURCE_PATH]
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
## LLM Integration
|
|
184
|
-
|
|
185
|
-
Ruby Raider supports optional LLM-powered features for intelligent test generation. Configure a provider:
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
raider u llm openai # Configure OpenAI
|
|
189
|
-
raider u llm anthropic # Configure Anthropic
|
|
190
|
-
raider u llm ollama # Configure Ollama (local, no API key needed)
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
Then use the `--ai` flag with scaffolding commands for smarter code generation.
|
|
194
|
-
|
|
195
141
|
## Development
|
|
196
142
|
|
|
197
143
|
```bash
|
|
@@ -2,174 +2,97 @@
|
|
|
2
2
|
|
|
3
3
|
require 'thor'
|
|
4
4
|
require 'fileutils'
|
|
5
|
+
require 'pathname'
|
|
5
6
|
require_relative '../generators/menu_generator'
|
|
6
7
|
require_relative '../scaffolding/scaffolding'
|
|
7
8
|
require_relative '../scaffolding/name_normalizer'
|
|
8
|
-
require_relative '../scaffolding/dry_run_presenter'
|
|
9
9
|
require_relative '../scaffolding/project_detector'
|
|
10
10
|
require_relative '../commands/utility_commands'
|
|
11
11
|
|
|
12
12
|
class ScaffoldingCommands < Thor
|
|
13
|
-
class_option :dry_run, type: :boolean, default: false,
|
|
14
|
-
desc: 'Preview files without creating them', banner: ''
|
|
15
|
-
|
|
16
13
|
desc 'page [PAGE_NAME]', 'Creates a new page object'
|
|
17
14
|
option :path, type: :string, required: false,
|
|
18
15
|
desc: 'The path where your page will be created', aliases: '-p'
|
|
19
|
-
option :delete, type: :boolean, required: false,
|
|
20
|
-
desc: 'This will delete the selected page', aliases: '-d'
|
|
21
16
|
option :uses, type: :array, required: false,
|
|
22
17
|
desc: 'Dependent pages to require', aliases: '-u'
|
|
23
18
|
|
|
24
19
|
def page(name)
|
|
25
|
-
return delete_scaffolding(name, 'page') if options[:delete]
|
|
26
|
-
return dry_run_preview(name, 'page') if options[:dry_run]
|
|
27
|
-
|
|
28
20
|
generate_scaffolding(name, 'page', options[:path], uses: options[:uses])
|
|
29
21
|
end
|
|
30
22
|
|
|
31
23
|
desc 'feature [NAME]', 'Creates a new feature'
|
|
32
24
|
option :path, type: :string, required: false,
|
|
33
25
|
desc: 'The path where your feature will be created', aliases: '-p'
|
|
34
|
-
option :delete, type: :boolean, required: false,
|
|
35
|
-
desc: 'This will delete the selected feature', aliases: '-d'
|
|
36
26
|
|
|
37
27
|
def feature(name)
|
|
38
|
-
return delete_scaffolding(name, 'feature') if options[:delete]
|
|
39
|
-
return dry_run_preview(name, 'feature') if options[:dry_run]
|
|
40
|
-
|
|
41
28
|
generate_scaffolding(name, 'feature', options[:path])
|
|
42
29
|
end
|
|
43
30
|
|
|
44
31
|
desc 'spec [SPEC_NAME]', 'Creates a new spec'
|
|
45
32
|
option :path, type: :string, required: false,
|
|
46
33
|
desc: 'The path where your spec will be created', aliases: '-p'
|
|
47
|
-
option :delete, type: :boolean, required: false,
|
|
48
|
-
desc: 'This will delete the selected spec', aliases: '-d'
|
|
49
|
-
option :from, type: :string, required: false,
|
|
50
|
-
desc: 'Generate spec stubs from an existing page object file', aliases: '-f'
|
|
51
34
|
option :uses, type: :array, required: false,
|
|
52
35
|
desc: 'Dependent pages to require', aliases: '-u'
|
|
53
|
-
option :ai, type: :boolean, default: false,
|
|
54
|
-
desc: 'Use LLM to generate meaningful test scenarios'
|
|
55
36
|
|
|
56
37
|
def spec(name)
|
|
57
|
-
return delete_scaffolding(name, 'spec') if options[:delete]
|
|
58
|
-
return dry_run_preview(name, 'spec') if options[:dry_run]
|
|
59
|
-
return generate_spec_from_page(name, options[:from], ai: options[:ai]) if options[:from]
|
|
60
|
-
|
|
61
38
|
generate_scaffolding(name, 'spec', options[:path], uses: options[:uses])
|
|
62
39
|
end
|
|
63
40
|
|
|
64
41
|
desc 'helper [HELPER_NAME]', 'Creates a new helper'
|
|
65
42
|
option :path, type: :string, required: false,
|
|
66
43
|
desc: 'The path where your helper will be created', aliases: '-p'
|
|
67
|
-
option :delete, type: :boolean, required: false,
|
|
68
|
-
desc: 'This will delete the selected helper', aliases: '-d'
|
|
69
44
|
|
|
70
45
|
def helper(name)
|
|
71
|
-
return delete_scaffolding(name, 'helper') if options[:delete]
|
|
72
|
-
return dry_run_preview(name, 'helper') if options[:dry_run]
|
|
73
|
-
|
|
74
46
|
generate_scaffolding(name, 'helper', options[:path])
|
|
75
47
|
end
|
|
76
48
|
|
|
77
49
|
desc 'steps [STEPS_NAME]', 'Creates a new steps definition'
|
|
78
50
|
option :path, type: :string, required: false,
|
|
79
51
|
desc: 'The path where your steps will be created', aliases: '-p'
|
|
80
|
-
option :delete, type: :boolean, required: false,
|
|
81
|
-
desc: 'This will delete the selected steps', aliases: '-d'
|
|
82
52
|
|
|
83
53
|
def steps(name)
|
|
84
|
-
return delete_scaffolding(name, 'steps') if options[:delete]
|
|
85
|
-
return dry_run_preview(name, 'steps') if options[:dry_run]
|
|
86
|
-
|
|
87
54
|
generate_scaffolding(name, 'steps', options[:path])
|
|
88
55
|
end
|
|
89
56
|
|
|
90
57
|
desc 'component [NAME]', 'Creates a component inheriting from Component'
|
|
91
58
|
option :path, type: :string, required: false,
|
|
92
59
|
desc: 'The path where your component will be created', aliases: '-p'
|
|
93
|
-
option :delete, type: :boolean, required: false,
|
|
94
|
-
desc: 'This will delete the selected component', aliases: '-d'
|
|
95
60
|
|
|
96
61
|
def component(name)
|
|
97
|
-
return delete_scaffolding(name, 'component') if options[:delete]
|
|
98
|
-
return dry_run_preview(name, 'component') if options[:dry_run]
|
|
99
|
-
|
|
100
62
|
generate_scaffolding(name, 'component', options[:path])
|
|
101
63
|
end
|
|
102
64
|
|
|
103
65
|
desc 'scaffold [NAMES...]', 'Generates pages, specs/features, and helpers for one or more names'
|
|
104
|
-
option :with, type: :array, required: false,
|
|
105
|
-
desc: 'Components to generate (page,spec,feature,steps,helper,component,model)', aliases: '-w'
|
|
106
|
-
option :crud, type: :boolean, required: false,
|
|
107
|
-
desc: 'Generate CRUD pages (list, create, detail, edit) + tests + model'
|
|
108
66
|
option :uses, type: :array, required: false,
|
|
109
67
|
desc: 'Dependent pages to require', aliases: '-u'
|
|
110
68
|
|
|
111
69
|
def scaffold(*names)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
names.each do |name|
|
|
115
|
-
if options[:crud]
|
|
116
|
-
generate_crud(name)
|
|
117
|
-
elsif options[:with]
|
|
118
|
-
generate_selected_components(name, options[:with])
|
|
119
|
-
else
|
|
120
|
-
generate_default_scaffold(name)
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
desc 'destroy [NAMES...]', 'Removes all scaffolded files for the given names (page, spec/feature, steps)'
|
|
126
|
-
option :with, type: :array, required: false,
|
|
127
|
-
desc: 'Components to destroy (page,spec,feature,steps,helper,component)', aliases: '-w'
|
|
128
|
-
|
|
129
|
-
def destroy(*names)
|
|
130
|
-
if names.empty?
|
|
131
|
-
say 'Please provide at least one name to destroy', :red
|
|
132
|
-
return
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
names.each { |name| destroy_scaffold(name, options[:with]) }
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
map 'd' => 'destroy'
|
|
139
|
-
|
|
140
|
-
desc 'from_url [URL]', 'Generates page object and spec from a live URL'
|
|
141
|
-
option :name, type: :string, required: false,
|
|
142
|
-
desc: 'Override the page object name', aliases: '-n'
|
|
143
|
-
option :ai, type: :boolean, default: false,
|
|
144
|
-
desc: 'Use LLM for intelligent page analysis'
|
|
145
|
-
|
|
146
|
-
def from_url(url)
|
|
147
|
-
require_relative '../scaffolding/url_analyzer'
|
|
148
|
-
analyzer = UrlAnalyzer.new(url, name_override: options[:name], ai: options[:ai])
|
|
149
|
-
analysis = analyzer.analyze.to_h
|
|
150
|
-
|
|
151
|
-
page_name = analysis[:page_name]
|
|
152
|
-
|
|
153
|
-
if options[:dry_run]
|
|
154
|
-
DryRunPresenter.preview([
|
|
155
|
-
"page_objects/pages/#{page_name}.rb",
|
|
156
|
-
"spec/#{page_name}_spec.rb"
|
|
157
|
-
])
|
|
158
|
-
return
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
Scaffolding.new([page_name]).generate_page_from_url(analysis)
|
|
162
|
-
Scaffolding.new([page_name]).generate_spec_from_url(analysis)
|
|
163
|
-
say "Generated page object and spec for #{url}"
|
|
70
|
+
names.each { |name| generate_default_scaffold(name) }
|
|
164
71
|
end
|
|
165
72
|
|
|
166
73
|
no_commands do
|
|
167
74
|
def load_config_path(type)
|
|
168
|
-
|
|
75
|
+
ScaffoldProjectDetector.config_path(type)
|
|
169
76
|
end
|
|
170
77
|
|
|
171
|
-
def
|
|
172
|
-
|
|
78
|
+
def validate_project!
|
|
79
|
+
warnings = ScaffoldProjectDetector.validate_project
|
|
80
|
+
warnings.each { |w| say "Warning: #{w}", :yellow }
|
|
81
|
+
show_detection_defaults
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def show_detection_defaults
|
|
85
|
+
gemfile = ScaffoldProjectDetector.read_gemfile
|
|
86
|
+
if gemfile.empty?
|
|
87
|
+
say 'Warning: No Gemfile found, defaulting to selenium + rspec templates.', :yellow
|
|
88
|
+
else
|
|
89
|
+
automation = ScaffoldProjectDetector.detect_automation(gemfile)
|
|
90
|
+
framework = ScaffoldProjectDetector.detect_framework(gemfile)
|
|
91
|
+
if automation.nil?
|
|
92
|
+
say 'Warning: Could not detect automation library from Gemfile, defaulting to selenium.', :yellow
|
|
93
|
+
end
|
|
94
|
+
say 'Warning: Could not detect test framework from Gemfile, defaulting to rspec.', :yellow if framework.nil?
|
|
95
|
+
end
|
|
173
96
|
end
|
|
174
97
|
|
|
175
98
|
def generate_scaffolding(name, type, path, uses: nil)
|
|
@@ -179,13 +102,8 @@ class ScaffoldingCommands < Thor
|
|
|
179
102
|
scaffolding.send("generate_#{type}")
|
|
180
103
|
end
|
|
181
104
|
|
|
182
|
-
def dry_run_preview(name, type)
|
|
183
|
-
path = options[:path] || load_config_path(type)
|
|
184
|
-
file = Scaffolding.planned_path(name, type, path)
|
|
185
|
-
DryRunPresenter.preview([file])
|
|
186
|
-
end
|
|
187
|
-
|
|
188
105
|
def generate_default_scaffold(name)
|
|
106
|
+
validate_project!
|
|
189
107
|
uses = options[:uses]
|
|
190
108
|
if Pathname.new('spec').exist? && !Pathname.new('features').exist?
|
|
191
109
|
generate_scaffolding(name, 'spec', load_config_path('spec'), uses:)
|
|
@@ -195,89 +113,5 @@ class ScaffoldingCommands < Thor
|
|
|
195
113
|
end
|
|
196
114
|
generate_scaffolding(name, 'page', load_config_path('page'), uses:)
|
|
197
115
|
end
|
|
198
|
-
|
|
199
|
-
def generate_selected_components(name, components)
|
|
200
|
-
uses = options[:uses]
|
|
201
|
-
components.each do |comp|
|
|
202
|
-
comp = comp.downcase.strip
|
|
203
|
-
case comp
|
|
204
|
-
when 'model'
|
|
205
|
-
generate_model_data(name)
|
|
206
|
-
else
|
|
207
|
-
generate_scaffolding(name, comp, load_config_path(comp), uses:)
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
def generate_crud(name)
|
|
213
|
-
require_relative '../scaffolding/crud_generator'
|
|
214
|
-
if options[:dry_run]
|
|
215
|
-
crud = CrudGenerator.new(name, Scaffolding, method(:load_config_path))
|
|
216
|
-
DryRunPresenter.preview(crud.planned_files)
|
|
217
|
-
return
|
|
218
|
-
end
|
|
219
|
-
crud = CrudGenerator.new(name, Scaffolding, method(:load_config_path))
|
|
220
|
-
generated = crud.generate
|
|
221
|
-
say "Generated CRUD scaffold for: #{generated.join(', ')}"
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
def generate_spec_from_page(name, source_file, ai: false) # rubocop:disable Naming/MethodParameterName
|
|
225
|
-
Scaffolding.new([name]).generate_spec_from_page(source_file, ai:)
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
def generate_model_data(name)
|
|
229
|
-
normalized = NameNormalizer.normalize(name)
|
|
230
|
-
path = "models/data/#{normalized}.yml"
|
|
231
|
-
return if File.exist?(path)
|
|
232
|
-
|
|
233
|
-
FileUtils.mkdir_p(File.dirname(path))
|
|
234
|
-
File.write(path, model_template(normalized))
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
def model_template(name)
|
|
238
|
-
<<~YAML
|
|
239
|
-
# Data model for #{name}
|
|
240
|
-
default:
|
|
241
|
-
name: 'Test #{name.capitalize}'
|
|
242
|
-
email: 'test@example.com'
|
|
243
|
-
|
|
244
|
-
valid:
|
|
245
|
-
name: 'Valid #{name.capitalize}'
|
|
246
|
-
email: 'valid@example.com'
|
|
247
|
-
|
|
248
|
-
invalid:
|
|
249
|
-
name: ''
|
|
250
|
-
email: 'invalid'
|
|
251
|
-
YAML
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
def destroy_scaffold(name, components = nil)
|
|
255
|
-
types = components ? components.map { |c| c.downcase.strip } : detect_scaffold_types
|
|
256
|
-
types.each { |type| delete_scaffolding(name, type) }
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
def detect_scaffold_types
|
|
260
|
-
if Pathname.new('spec').exist? && !Pathname.new('features').exist?
|
|
261
|
-
%w[page spec]
|
|
262
|
-
else
|
|
263
|
-
%w[page feature steps]
|
|
264
|
-
end
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
def interactive_scaffold
|
|
268
|
-
require_relative '../scaffolding/scaffold_menu'
|
|
269
|
-
result = ScaffoldMenu.new.run
|
|
270
|
-
return unless result
|
|
271
|
-
|
|
272
|
-
result[:names].each do |name|
|
|
273
|
-
result[:components].each do |comp|
|
|
274
|
-
if comp == :model
|
|
275
|
-
generate_model_data(name)
|
|
276
|
-
else
|
|
277
|
-
generate_scaffolding(name, comp.to_s, load_config_path(comp.to_s), uses: result[:uses])
|
|
278
|
-
end
|
|
279
|
-
end
|
|
280
|
-
end
|
|
281
|
-
end
|
|
282
116
|
end
|
|
283
117
|
end
|
|
@@ -35,7 +35,7 @@ class UtilityCommands < Thor
|
|
|
35
35
|
browser_options(selected_options) if selected_options || options[:delete]
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
desc 'browser_options [OPTIONS]', 'Sets the browser
|
|
38
|
+
desc 'browser_options [OPTIONS]', 'Sets the browser arguments for the current browser (e.g. no-sandbox, headless)'
|
|
39
39
|
option :delete,
|
|
40
40
|
type: :boolean, required: false, desc: 'This will delete your browser options', aliases: '-d'
|
|
41
41
|
|
|
@@ -44,6 +44,15 @@ class UtilityCommands < Thor
|
|
|
44
44
|
Utilities.delete_browser_options if options[:delete]
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
+
desc 'headless [on/off]', 'Toggles headless mode for browser tests'
|
|
48
|
+
|
|
49
|
+
def headless(toggle)
|
|
50
|
+
enabled = %w[on true 1 yes].include?(toggle.downcase)
|
|
51
|
+
Utilities.headless = enabled
|
|
52
|
+
state = enabled ? 'enabled' : 'disabled'
|
|
53
|
+
say "Headless mode #{state}", :green
|
|
54
|
+
end
|
|
55
|
+
|
|
47
56
|
desc 'raid', 'It runs all the tests in a project'
|
|
48
57
|
option :parallel,
|
|
49
58
|
type: :boolean, required: false, desc: 'It runs the tests in parallel', aliases: '-p'
|
|
@@ -114,47 +123,4 @@ class UtilityCommands < Thor
|
|
|
114
123
|
say 'Raider Desktop downloaded successfully!', :green
|
|
115
124
|
end
|
|
116
125
|
|
|
117
|
-
desc 'llm [PROVIDER]', 'Configures the LLM provider (openai, anthropic, ollama)'
|
|
118
|
-
option :key, type: :string, required: false, desc: 'API key for the provider', aliases: '-k'
|
|
119
|
-
option :model, type: :string, required: false, desc: 'Model name to use', aliases: '-m'
|
|
120
|
-
option :url, type: :string, required: false, desc: 'API URL (for ollama)', aliases: '-u'
|
|
121
|
-
option :status, type: :boolean, required: false, desc: 'Show current LLM configuration', aliases: '-s'
|
|
122
|
-
|
|
123
|
-
def llm(provider = nil)
|
|
124
|
-
if options[:status] || provider.nil?
|
|
125
|
-
show_llm_status
|
|
126
|
-
return
|
|
127
|
-
end
|
|
128
|
-
configure_llm(provider)
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
no_commands do
|
|
132
|
-
def configure_llm(provider)
|
|
133
|
-
unless %w[openai anthropic ollama].include?(provider)
|
|
134
|
-
say "Unknown provider '#{provider}'. Choose: openai, anthropic, ollama", :red
|
|
135
|
-
return
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
Utilities.llm_provider = provider
|
|
139
|
-
Utilities.llm_api_key = options[:key] if options[:key]
|
|
140
|
-
Utilities.llm_model = options[:model] if options[:model]
|
|
141
|
-
Utilities.llm_url = options[:url] if options[:url]
|
|
142
|
-
say "LLM configured: #{provider}", :green
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
def show_llm_status
|
|
146
|
-
require_relative '../llm/client'
|
|
147
|
-
status = Llm::Client.status
|
|
148
|
-
if status[:configured]
|
|
149
|
-
say "Provider: #{status[:provider]}"
|
|
150
|
-
say "Model: #{status[:model] || 'default'}"
|
|
151
|
-
say "Available: #{status[:available] ? 'yes' : 'no'}"
|
|
152
|
-
else
|
|
153
|
-
say 'No LLM configured. Use: raider u llm <provider>', :yellow
|
|
154
|
-
say ' Providers: openai, anthropic, ollama'
|
|
155
|
-
say ' Example: raider u llm ollama'
|
|
156
|
-
say ' Example: raider u llm openai -k sk-...'
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
126
|
end
|
|
@@ -9,13 +9,7 @@ class Login < Page
|
|
|
9
9
|
|
|
10
10
|
# Actions
|
|
11
11
|
|
|
12
|
-
<%- if
|
|
13
|
-
def login(username, password)
|
|
14
|
-
fill_in 'loginFrm_loginname', with: username
|
|
15
|
-
fill_in 'loginFrm_password', with: password
|
|
16
|
-
click_button 'Login'
|
|
17
|
-
end
|
|
18
|
-
<%- elsif selenium_based? -%>
|
|
12
|
+
<%- if selenium_based? -%>
|
|
19
13
|
def login(username, password)
|
|
20
14
|
username_field.send_keys username
|
|
21
15
|
password_field.send_keys password
|
|
@@ -29,7 +23,6 @@ class Login < Page
|
|
|
29
23
|
login_button.click
|
|
30
24
|
end
|
|
31
25
|
<%- end -%>
|
|
32
|
-
<%- unless capybara? -%>
|
|
33
26
|
|
|
34
27
|
private
|
|
35
28
|
|
|
@@ -58,5 +51,4 @@ class Login < Page
|
|
|
58
51
|
browser.button(xpath: "//button[@title='Login']")
|
|
59
52
|
<%- end -%>
|
|
60
53
|
end
|
|
61
|
-
<%- end -%>
|
|
62
54
|
end
|
|
@@ -14,13 +14,7 @@ class Page
|
|
|
14
14
|
self.class.to_s.sub('Page', ' Page')
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
<%- if
|
|
18
|
-
# Components
|
|
19
|
-
|
|
20
|
-
def header
|
|
21
|
-
Header.new(find('.welcome-msg'))
|
|
22
|
-
end
|
|
23
|
-
<%- elsif selenium_based? -%>
|
|
17
|
+
<%- if selenium_based? -%>
|
|
24
18
|
# Components
|
|
25
19
|
|
|
26
20
|
def header
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
<% if web? %>
|
|
2
|
-
<% if
|
|
3
|
-
def visit_page(*page)
|
|
4
|
-
Capybara.visit full_url(page.first)
|
|
5
|
-
end
|
|
6
|
-
<% elsif selenium_based? %>
|
|
2
|
+
<% if selenium_based? %>
|
|
7
3
|
def visit(*page)
|
|
8
4
|
@driver.navigate.to full_url(page.first)
|
|
9
5
|
end
|
|
@@ -12,4 +8,4 @@
|
|
|
12
8
|
@browser.goto full_url(page.first)
|
|
13
9
|
end
|
|
14
10
|
<% end %>
|
|
15
|
-
<% end %>
|
|
11
|
+
<% end %>
|
|
@@ -17,10 +17,6 @@ class CommonGenerator < Generator
|
|
|
17
17
|
template('common/rakefile.tt', "#{name}/Rakefile")
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
def generate_ruby_version_file
|
|
21
|
-
template('common/ruby_version.tt', "#{name}/.ruby-version")
|
|
22
|
-
end
|
|
23
|
-
|
|
24
20
|
def generate_gemfile
|
|
25
21
|
template('common/gemfile.tt', "#{name}/Gemfile")
|
|
26
22
|
end
|
|
@@ -44,8 +40,6 @@ class CommonGenerator < Generator
|
|
|
44
40
|
end
|
|
45
41
|
|
|
46
42
|
def create_allure_folder
|
|
47
|
-
return unless allure_reporter?
|
|
48
|
-
|
|
49
43
|
empty_directory "#{name}/allure-results"
|
|
50
44
|
end
|
|
51
45
|
end
|