ruby_raider 3.13.0 → 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.
- checksums.yaml +4 -4
- data/.github/workflows/runtime.yml +38 -0
- data/.github/workflows/system_tests.yml +1 -23
- data/.reek.yml +1 -0
- data/.rspec +1 -0
- data/Gemfile +2 -0
- data/README.md +16 -49
- data/RELEASE.md +22 -0
- data/bin/raider +5 -0
- data/lib/commands/scaffolding_commands.rb +2 -25
- data/lib/commands/utility_commands.rb +23 -3
- data/lib/generators/automation/automation_generator.rb +0 -5
- data/lib/generators/automation/templates/component.tt +1 -0
- data/lib/generators/automation/templates/home.tt +2 -2
- data/lib/generators/automation/templates/login.tt +6 -26
- data/lib/generators/automation/templates/page.tt +23 -18
- data/lib/generators/automation/templates/partials/home_page_selector.tt +1 -2
- data/lib/generators/automation/templates/partials/initialize_selector.tt +0 -8
- data/lib/generators/automation/templates/partials/pdp_page_selector.tt +1 -2
- data/lib/generators/automation/templates/partials/url_methods.tt +8 -2
- data/lib/generators/automation/templates/partials/visit_method.tt +0 -5
- data/lib/generators/automation/templates/pdp.tt +1 -9
- data/lib/generators/common_generator.rb +0 -2
- data/lib/generators/generator.rb +12 -19
- data/lib/generators/helper_generator.rb +21 -19
- data/lib/generators/infrastructure/templates/azure_pipelines.tt +1 -1
- data/lib/generators/infrastructure/templates/github.tt +2 -3
- data/lib/generators/infrastructure/templates/github_appium.tt +0 -8
- data/lib/generators/invoke_generators.rb +4 -23
- data/lib/generators/menu_generator.rb +1 -9
- data/lib/generators/rspec/templates/accessibility_spec.tt +1 -9
- data/lib/generators/rspec/templates/spec.tt +8 -24
- data/lib/generators/template_renderer/partial_cache.rb +3 -1
- data/lib/generators/template_renderer.rb +1 -1
- data/lib/generators/templates/common/gemfile.tt +3 -10
- data/lib/generators/templates/common/git_ignore.tt +0 -5
- data/lib/generators/templates/common/partials/mobile_config.tt +3 -1
- data/lib/generators/templates/common/partials/web_config.tt +10 -1
- data/lib/generators/templates/common/rakefile.tt +0 -15
- data/lib/generators/templates/common/read_me.tt +357 -250
- data/lib/generators/templates/common/rubocop.tt +0 -2
- data/lib/generators/templates/helpers/driver_helper.tt +8 -0
- data/lib/generators/templates/helpers/gesture_helper.tt +78 -0
- data/lib/generators/templates/helpers/network_helper.tt +521 -0
- data/lib/generators/templates/helpers/partials/quit_driver.tt +0 -2
- data/lib/generators/templates/helpers/partials/screenshot.tt +0 -2
- data/lib/generators/templates/helpers/partials/selenium_driver.tt +5 -2
- data/lib/generators/templates/helpers/screenshot_helper.tt +490 -0
- data/lib/generators/templates/helpers/spec_helper.tt +39 -29
- data/lib/generators/templates/helpers/trace_helper.tt +240 -95
- data/lib/generators/templates/helpers/video_helper.tt +3 -8
- data/lib/ruby_raider/runtime/actionability.rb +129 -0
- data/lib/ruby_raider/runtime/actionable.rb +49 -0
- data/lib/ruby_raider/runtime/by_role.rb +55 -0
- data/lib/ruby_raider/runtime/config.rb +79 -0
- data/lib/ruby_raider/runtime/context.rb +38 -0
- data/lib/ruby_raider/runtime/errors.rb +69 -0
- data/lib/ruby_raider/runtime/finders.rb +73 -0
- data/lib/ruby_raider/runtime/js/actionability.js +134 -0
- data/lib/ruby_raider/runtime/js/role_engine.js +315 -0
- data/lib/ruby_raider/runtime/locator_converter.rb +72 -0
- data/lib/ruby_raider/runtime/matchers/base.rb +222 -0
- data/lib/ruby_raider/runtime/matchers/element.rb +183 -0
- data/lib/ruby_raider/runtime/matchers/page.rb +71 -0
- data/lib/ruby_raider/runtime/matchers/presence.rb +41 -0
- data/lib/ruby_raider/runtime/matchers/retrying_block.rb +104 -0
- data/lib/ruby_raider/runtime/observer.rb +170 -0
- data/lib/ruby_raider/runtime/role_finder.rb +83 -0
- data/lib/ruby_raider/runtime/rspec.rb +78 -0
- data/lib/ruby_raider/runtime/selectors.rb +60 -0
- data/lib/ruby_raider/runtime/strict.rb +142 -0
- data/lib/ruby_raider/runtime/wait.rb +84 -0
- data/lib/ruby_raider/runtime.rb +20 -0
- data/lib/scaffolding/name_normalizer.rb +1 -1
- data/lib/scaffolding/project_detector.rb +2 -28
- data/lib/scaffolding/scaffolding.rb +0 -20
- data/lib/scaffolding/templates/component.tt +0 -14
- data/lib/scaffolding/templates/page_object.tt +2 -14
- data/lib/scaffolding/templates/spec.tt +1 -9
- data/lib/utilities/utilities.rb +10 -8
- data/lib/version +1 -1
- data/ruby_raider.gemspec +2 -1
- data/sig/commands/scaffolding_commands.rbs +0 -2
- data/sig/commands/utility_commands.rbs +6 -0
- data/sig/generators/generator.rbs +0 -4
- data/sig/generators/helper_generator.rbs +0 -1
- data/sig/generators/menu_generator.rbs +0 -1
- data/sig/ruby_raider/runtime/actionability.rbs +25 -0
- data/sig/ruby_raider/runtime/actionable.rbs +13 -0
- data/sig/ruby_raider/runtime/by_role.rbs +15 -0
- data/sig/ruby_raider/runtime/config.rbs +26 -0
- data/sig/ruby_raider/runtime/context.rbs +12 -0
- data/sig/ruby_raider/runtime/errors.rbs +36 -0
- data/sig/ruby_raider/runtime/finders.rbs +26 -0
- data/sig/ruby_raider/runtime/locator_converter.rbs +21 -0
- data/sig/ruby_raider/runtime/matchers/base.rbs +64 -0
- data/sig/ruby_raider/runtime/matchers/element.rbs +78 -0
- data/sig/ruby_raider/runtime/matchers/page.rbs +38 -0
- data/sig/ruby_raider/runtime/matchers/presence.rbs +21 -0
- data/sig/ruby_raider/runtime/matchers/retrying_block.rbs +27 -0
- data/sig/ruby_raider/runtime/observer.rbs +46 -0
- data/sig/ruby_raider/runtime/role_finder.rbs +18 -0
- data/sig/ruby_raider/runtime/selectors.rbs +21 -0
- data/sig/ruby_raider/runtime/strict.rbs +35 -0
- data/sig/ruby_raider/runtime/wait.rbs +17 -0
- data/sig/ruby_raider/runtime.rbs +2 -0
- data/sig/scaffolding/project_detector.rbs +0 -4
- data/sig/scaffolding/scaffolding.rbs +0 -5
- data/sig/utilities/utilities.rbs +2 -1
- data/sig/vendor/selenium_webdriver.rbs +71 -0
- data/spec/commands/raider_commands_spec.rb +38 -3
- data/spec/commands/scaffolding_commands_spec.rb +27 -0
- data/spec/commands/utility_commands_spec.rb +53 -0
- data/spec/generators/gesture_helper_spec.rb +123 -0
- data/spec/generators/network_helper_spec.rb +634 -0
- data/spec/generators/screenshot_helper_spec.rb +776 -0
- data/spec/generators/template_renderer_spec.rb +0 -4
- data/spec/generators/trace_helper_spec.rb +489 -97
- data/spec/generators/video_helper_spec.rb +0 -9
- data/spec/integration/commands/browser_update_after_creation_spec.rb +0 -8
- data/spec/integration/commands/scaffolding_commands_spec.rb +12 -70
- data/spec/integration/commands/utility_commands_spec.rb +19 -41
- data/spec/integration/content/azure_content_spec.rb +2 -6
- data/spec/integration/content/ci_content_spec.rb +1 -55
- data/spec/integration/content/common_content_spec.rb +1 -118
- data/spec/integration/content/config_content_spec.rb +34 -31
- data/spec/integration/content/gemfile_content_spec.rb +7 -72
- data/spec/integration/content/helper_content_spec.rb +105 -99
- data/spec/integration/content/page_content_spec.rb +85 -87
- data/spec/integration/content/readme_content_spec.rb +134 -75
- data/spec/integration/content/rspec_reporter_content_spec.rb +2 -2
- data/spec/integration/content/rubocop_content_spec.rb +1 -1
- data/spec/integration/content/syntax_validation_spec.rb +2 -2
- data/spec/integration/content/test_content_spec.rb +23 -147
- data/spec/integration/end_to_end_features_spec.rb +1 -43
- data/spec/integration/end_to_end_spec.rb +319 -326
- data/spec/integration/generators/automation_generator_spec.rb +3 -37
- data/spec/integration/generators/axe_addon_spec.rb +2 -35
- data/spec/integration/generators/azure_generator_spec.rb +1 -1
- data/spec/integration/generators/common_generator_spec.rb +1 -40
- data/spec/integration/generators/config_features_spec.rb +1 -24
- data/spec/integration/generators/github_generator_spec.rb +0 -12
- data/spec/integration/generators/helpers_generator_spec.rb +74 -80
- data/spec/integration/generators/invoke_generators_spec.rb +54 -45
- data/spec/integration/generators/rspec_generator_spec.rb +0 -6
- data/spec/integration/scaffolding_e2e_spec.rb +17 -179
- data/spec/integration/spec_helper.rb +4 -6
- data/spec/integration/trace_format_checker.rb +11 -2
- data/spec/integration/trace_page_server.rb +72 -5
- data/spec/menus/menu_generator_spec.rb +14 -39
- data/spec/runtime/actionability_spec.rb +207 -0
- data/spec/runtime/actionable_spec.rb +125 -0
- data/spec/runtime/browser/actionability_script_browser_spec.rb +150 -0
- data/spec/runtime/browser/actionable_browser_spec.rb +98 -0
- data/spec/runtime/browser/finders_browser_spec.rb +148 -0
- data/spec/runtime/browser/matchers_browser_spec.rb +67 -0
- data/spec/runtime/browser/retrying_block_browser_spec.rb +37 -0
- data/spec/runtime/browser/role_engine_browser_spec.rb +184 -0
- data/spec/runtime/browser/strict_browser_spec.rb +38 -0
- data/spec/runtime/by_role_spec.rb +52 -0
- data/spec/runtime/config_spec.rb +79 -0
- data/spec/runtime/context_spec.rb +73 -0
- data/spec/runtime/errors_spec.rb +89 -0
- data/spec/runtime/finders_spec.rb +165 -0
- data/spec/runtime/fixtures/actionability.html +70 -0
- data/spec/runtime/fixtures/locators.html +46 -0
- data/spec/runtime/fixtures/matchers.html +33 -0
- data/spec/runtime/fixtures/roles.html +162 -0
- data/spec/runtime/matchers/base_spec.rb +165 -0
- data/spec/runtime/matchers/element_spec.rb +277 -0
- data/spec/runtime/matchers/page_spec.rb +102 -0
- data/spec/runtime/matchers/presence_spec.rb +59 -0
- data/spec/runtime/matchers/retrying_block_spec.rb +165 -0
- data/spec/runtime/observer_spec.rb +341 -0
- data/spec/runtime/role_finder_spec.rb +156 -0
- data/spec/runtime/role_query_spec.rb +75 -0
- data/spec/runtime/selectors_spec.rb +135 -0
- data/spec/runtime/strict_spec.rb +257 -0
- data/spec/runtime/support/browser.rb +48 -0
- data/spec/runtime/support/fake_bridge.rb +117 -0
- data/spec/runtime/wait_spec.rb +71 -0
- data/spec/scaffolding/name_normalizer_spec.rb +3 -2
- data/spec/scaffolding/scaffold_project_detector_spec.rb +4 -43
- data/spec/system/selenium_spec.rb +1 -5
- data/spec/system/support/system_test_helper.rb +2 -5
- data/spec/utilities/headless_config_spec.rb +0 -7
- data/spec/utilities/utilities_spec.rb +24 -0
- metadata +113 -48
- data/lib/generators/automation/templates/header.tt +0 -9
- data/lib/generators/cucumber/cucumber_generator.rb +0 -58
- data/lib/generators/cucumber/templates/accessibility_feature.tt +0 -5
- data/lib/generators/cucumber/templates/accessibility_steps.tt +0 -17
- data/lib/generators/cucumber/templates/cucumber.tt +0 -1
- data/lib/generators/cucumber/templates/env.tt +0 -7
- data/lib/generators/cucumber/templates/feature.tt +0 -21
- data/lib/generators/cucumber/templates/partials/appium_env.tt +0 -26
- data/lib/generators/cucumber/templates/partials/driver_world.tt +0 -18
- data/lib/generators/cucumber/templates/partials/mobile_steps.tt +0 -20
- data/lib/generators/cucumber/templates/partials/selenium_env.tt +0 -120
- data/lib/generators/cucumber/templates/partials/watir_env.tt +0 -48
- data/lib/generators/cucumber/templates/partials/watir_world.tt +0 -4
- data/lib/generators/cucumber/templates/partials/web_steps.tt +0 -28
- data/lib/generators/cucumber/templates/steps.tt +0 -5
- data/lib/generators/cucumber/templates/user_factory.tt +0 -15
- data/lib/generators/cucumber/templates/world.tt +0 -7
- data/lib/generators/templates/helpers/browser_helper.tt +0 -31
- data/lib/generators/templates/helpers/raider_element.tt +0 -159
- data/lib/generators/templates/helpers/wait_helper.tt +0 -611
- data/lib/scaffolding/templates/feature.tt +0 -6
- data/lib/scaffolding/templates/steps.tt +0 -19
- data/sig/generators/cucumber/cucumber_generator.rbs +0 -12
- data/spec/fixtures/watir_master/cucumber_watir/Readme.md.snapshot +0 -175
- data/spec/fixtures/watir_master/cucumber_watir/features/step_definitions/login_steps.rb.snapshot +0 -24
- data/spec/fixtures/watir_master/cucumber_watir/page_objects/abstract/page.rb.snapshot +0 -37
- data/spec/fixtures/watir_master/cucumber_watir/page_objects/pages/login.rb.snapshot +0 -33
- data/spec/fixtures/watir_master/rspec_watir/Readme.md.snapshot +0 -174
- data/spec/fixtures/watir_master/rspec_watir/page_objects/abstract/page.rb.snapshot +0 -37
- data/spec/fixtures/watir_master/rspec_watir/page_objects/pages/login.rb.snapshot +0 -33
- data/spec/fixtures/watir_master/rspec_watir/spec/login_page_spec.rb.snapshot +0 -49
- data/spec/integration/content/cucumber_reporter_content_spec.rb +0 -161
- data/spec/integration/generators/cucumber_generator_spec.rb +0 -100
- data/spec/integration/helpers/wait_helper_mobile_spec.rb +0 -281
- data/spec/integration/helpers/wait_helper_spec.rb +0 -679
- data/spec/integration/helpers/wait_helper_support.rb +0 -183
- data/spec/system/watir_spec.rb +0 -38
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 36caa6e3075d166277f9cafe8073ccd81f9ada8706a3df11ce93a6073b45d130
|
|
4
|
+
data.tar.gz: 6aeedcccd3623931f16eb8e082635f93f4946e6870ca79a7de9f03478d868034
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7581c5bb57fd17624148332100f3e4c963323a02f5bff6dfda8aba500b5b478bfbbcb07741f55eb73909beca99e5a88b769a0af437820507c7b9bd3977038038
|
|
7
|
+
data.tar.gz: 353af9eab7da4783e38bff479bab069a35bbed7fcd57936b22eb525c443fc7b76136c5408371424690082f164d3e76334d93f093c2219c4bbe1cb8e56d49ed0a
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Runtime
|
|
2
|
+
|
|
3
|
+
on: [pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
runtime:
|
|
7
|
+
name: Runtime (Ruby ${{ matrix.ruby }}, selenium ${{ matrix.selenium || 'latest' }})
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
env:
|
|
10
|
+
SELENIUM_VERSION: ${{ matrix.selenium }}
|
|
11
|
+
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
ruby: ['3.2', '3.4']
|
|
16
|
+
selenium: ['4.30.0', '4.44.0', '']
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout repository
|
|
20
|
+
uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Set up Ruby
|
|
23
|
+
uses: ruby/setup-ruby@v1
|
|
24
|
+
with:
|
|
25
|
+
ruby-version: ${{ matrix.ruby }}
|
|
26
|
+
bundler-cache: true
|
|
27
|
+
|
|
28
|
+
- name: Set up Chrome
|
|
29
|
+
uses: browser-actions/setup-chrome@v1
|
|
30
|
+
|
|
31
|
+
- name: Run runtime unit specs
|
|
32
|
+
run: bundle exec rspec spec/runtime
|
|
33
|
+
|
|
34
|
+
- name: Check the role engine syntax
|
|
35
|
+
run: node --check lib/ruby_raider/runtime/js/role_engine.js
|
|
36
|
+
|
|
37
|
+
- name: Run runtime browser specs
|
|
38
|
+
run: bundle exec rspec spec/runtime/browser --tag browser
|
|
@@ -17,7 +17,7 @@ jobs:
|
|
|
17
17
|
bundler-cache: true
|
|
18
18
|
|
|
19
19
|
selenium:
|
|
20
|
-
name: Selenium
|
|
20
|
+
name: Selenium RSpec
|
|
21
21
|
needs: setup
|
|
22
22
|
runs-on: ubuntu-latest
|
|
23
23
|
steps:
|
|
@@ -37,25 +37,3 @@ jobs:
|
|
|
37
37
|
|
|
38
38
|
- name: Run Selenium system tests
|
|
39
39
|
run: bundle exec rspec spec/system/selenium_spec.rb --format documentation
|
|
40
|
-
|
|
41
|
-
watir:
|
|
42
|
-
name: Watir frameworks (deprecated)
|
|
43
|
-
needs: setup
|
|
44
|
-
runs-on: ubuntu-latest
|
|
45
|
-
steps:
|
|
46
|
-
- name: Checkout repository
|
|
47
|
-
uses: actions/checkout@v4
|
|
48
|
-
|
|
49
|
-
- name: Set up Ruby
|
|
50
|
-
uses: ruby/setup-ruby@v1
|
|
51
|
-
with:
|
|
52
|
-
ruby-version: '3.4'
|
|
53
|
-
bundler-cache: true
|
|
54
|
-
|
|
55
|
-
- name: Set up Chrome
|
|
56
|
-
uses: browser-actions/setup-chrome@v1
|
|
57
|
-
with:
|
|
58
|
-
chrome-version: stable
|
|
59
|
-
|
|
60
|
-
- name: Run Watir system tests
|
|
61
|
-
run: bundle exec rspec spec/system/watir_spec.rb --format documentation
|
data/.reek.yml
CHANGED
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--tag ~browser
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -33,19 +33,17 @@ Ruby Raider is a CLI gem for scaffolding and generating UI test automation frame
|
|
|
33
33
|
|
|
34
34
|
### Web Testing
|
|
35
35
|
|
|
36
|
-
| Test Framework | Selenium |
|
|
37
|
-
|
|
38
|
-
| RSpec | ✅ |
|
|
39
|
-
| Cucumber | ✅ | ✅ |
|
|
36
|
+
| Test Framework | Selenium |
|
|
37
|
+
|----------------|----------|
|
|
38
|
+
| RSpec | ✅ |
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
ruby_raider 4.0 generates Selenium projects with RSpec only. Projects generated by 3.x (Cucumber, Watir) keep working on the 3.x line through the `ruby_raider` pin in their Gemfile (`~> 3.15` or an older `~> 3.x` requirement); 4.0 does not read or convert them.
|
|
42
41
|
|
|
43
42
|
### Mobile Testing (Appium)
|
|
44
43
|
|
|
45
44
|
| Test Framework | iOS | Android | Cross-Platform |
|
|
46
45
|
|----------------|-----|---------|----------------|
|
|
47
46
|
| RSpec | ✅ | ✅ | ✅ |
|
|
48
|
-
| Cucumber | ✅ | ✅ | ✅ |
|
|
49
47
|
|
|
50
48
|
### Optional Add-on (Web Only)
|
|
51
49
|
|
|
@@ -62,26 +60,22 @@ Every generated project comes with:
|
|
|
62
60
|
|
|
63
61
|
- **Page Object Model** — Base page and component classes with example pages
|
|
64
62
|
- **Test examples** — Working login tests against the [Raider Test Store](https://raider-test-site.onrender.com/)
|
|
65
|
-
- **Raider reporting** —
|
|
66
|
-
- **
|
|
63
|
+
- **Raider reporting** — Generated projects include [raider_reporter](https://github.com/RaiderHQ/raider_reporter), which writes results to `raider-results/` and uploads runs to your Raider Hideout server when `RAIDER_TOKEN` and `RAIDER_ENDPOINT` are set; generated CI runs the suite through `raider-reporter exec` with `RAIDER_QUARANTINE`, so quarantined tests do not fail the build; an opt-in `raider-gate` job (`RAIDER_GATE=1`) fails CI when the Raider quality gate fails
|
|
64
|
+
- **Locators, waiting and assertions**: The runtime (`ruby_raider/runtime`), loaded by every generated project, adds waiting to Selenium and Appium themselves. Locators go beyond `id` and `css`: `label:`, `placeholder:`, `alt:`, `title:`, `text:`, `test_id:` and `by_role('button', name: 'Save')` find elements the way a person sees them, and `find_element` fails when a locator matches more than one. `find_element` and `find_elements` wait for a match, so there is no implicit wait and no `sleep`. Before an action the runtime waits until the element is ready: `click` waits until it is visible, enabled, not inert, stable and not covered; `send_keys` and `clear` until it is visible, enabled, editable and not inert; `submit` until it is visible, enabled and not inert (on native apps, displayed and enabled); `force: true` skips the checks for one call. `timeout`, `strict` and `actionability` in `config.yml` (or `RAIDER_TIMEOUT`, `RAIDER_STRICT`, `RAIDER_ACTIONABILITY`) set the rules. RSpec matchers (`have_text`, `have_value`, `have_attribute`, `have_css`, `have_xpath`, `be_visible`, `be_hidden`, `be_enabled`, `be_disabled`, `be_checked`, `have_count`, `have_title`, `have_url`, `have_element`) retry until the page matches, and a block expectation such as `expect { driver.find_element(id: 'status').text }.to eq('done')` retries with any value matcher
|
|
67
65
|
- **Example tests or a skeleton (`examples:false`)** — start from the working login examples, or pass `examples:false` for an empty skeleton with the helpers, config, CI and README (see [Getting Started](#getting-started))
|
|
68
|
-
- **Login reuse** — generated web projects (Selenium
|
|
69
|
-
- **Failure video replay** — Every test is recorded and the video is kept only for failing tests, attached to the report as `video` (WebM from page screenshots for Selenium
|
|
70
|
-
- **Failure trace replay** (Selenium
|
|
66
|
+
- **Login reuse** — generated web projects (Selenium) log in once and restore the saved session for examples tagged `:logged_in`; `RAIDER_LOGIN_STATE=off|refresh` and `login_state: max_age:` control it, and the state stays in git-ignored `.raider/auth/`
|
|
67
|
+
- **Failure video replay** — Every test is recorded and the video is kept only for failing tests, attached to the report as `video` (WebM from page screenshots for Selenium, Appium's own MP4 for mobile, which needs `ffmpeg` on the Appium server host for iOS and for Android recordings over 180 s). Turn it off per run with `VIDEO=off`, or per project with `raider u video off`; ffmpeg is downloaded once, SHA-256 checked and cached in `~/.cache/raider`. The RaiderHQ `ffmpeg-7.1` build that the download uses is not published yet, so for now set `RAIDER_FFMPEG_PATH` to an ffmpeg with libvpx to get web videos
|
|
68
|
+
- **Failure trace replay** (Selenium) — Failing tests keep a step-by-step trace: each action with its locator and wait time, a screenshot and the page HTML after every step that changes the page, plus network requests and console messages on Chrome, Edge and Firefox. It is saved as `raider-results/attachments/<n>-trace.zip`, attached to the report as `trace` and opened in Raider Desktop or on Hideout. `TRACE=on` keeps passing tests too, `TRACE=off` captures nothing, and `raider u trace on|off` sets it for the project. Typed values in password fields and `RAIDER_SECRET_*` values are hidden; other typed values, page text and URLs are kept, so treat a trace like the video. Request headers, cookies and bodies are never captured
|
|
69
|
+
- **Network mocking** (Selenium) — Answer a request with your own response or block it, from the test: `mock_request('**/api/users', json: { users: [] })`, `mock_request(url, status: 500)` and `block_request('**/*.png')`, with `calls` to check what the page asked for. It uses WebDriver BiDi on Chrome, Edge and Firefox (Safari and `BIDI=off` raise `NetworkHelper::Unavailable`), handles CORS for cross-origin mocks, clears mocks after each test, and marks mocked requests in the trace
|
|
70
|
+
- **Screenshot comparison** (Selenium) — `match_screenshot('home')` compares the page, or an element with `element:`, with a baseline in `screenshots/baselines/<browser>/`. The first run saves the baseline; later runs fail on a difference and attach the expected, actual and diff pictures to the report and the trace. `SCREENSHOTS=update` rewrites baselines, a missing baseline fails on CI, and tolerances (`threshold`, `max_diff_pixels`, `max_diff_ratio`) go in `config/config.yml` under `screenshots:`. Generate baselines where CI runs: a Retina laptop makes 2x pictures
|
|
71
71
|
- **GitHub Actions CI** — Ready-to-use test pipeline that caches ffmpeg for failure videos
|
|
72
72
|
- **Rake tasks** — Default, smoke, and regression tasks with tag-based filtering
|
|
73
73
|
- **Retry support** — RSpec retry with configurable retry count via `RETRY_COUNT` env var
|
|
74
|
-
- **Re-run failed tests** — RSpec keeps `spec/examples.txt` for `--only-failures
|
|
74
|
+
- **Re-run failed tests** — RSpec keeps `spec/examples.txt` for `--only-failures`
|
|
75
75
|
- **Parallel execution** — parallel_tests and parallel_split_test gems included
|
|
76
76
|
- **Configurable browser** — Chrome/Firefox with customizable arguments, viewport, timeout, and headless mode
|
|
77
77
|
- **Linting** — RuboCop and Reek configs included
|
|
78
78
|
|
|
79
|
-
> **Upgrading from 3.9 or earlier:** existing projects are not changed automatically. To get failure videos, generate a
|
|
80
|
-
> new project with the same options and copy `helpers/video_helper.rb`, the video lines in `helpers/spec_helper.rb`
|
|
81
|
-
> (RSpec) or `features/support/env.rb` (Cucumber), the `listener:` in the driver or browser helper, the `video:` block
|
|
82
|
-
> in `config/config.yml`, and the ffmpeg cache and install steps in your CI pipeline. raider_reporter 0.10 or later
|
|
83
|
-
> adds the inline video player in `raider-results/index.html` and a larger size limit for video attachments.
|
|
84
|
-
|
|
85
79
|
For Appium projects, download the example [app](https://github.com/RaiderHQ/raider_test_app) and start the server:
|
|
86
80
|
|
|
87
81
|
```bash
|
|
@@ -129,34 +123,7 @@ Generate an empty skeleton, without the example pages and tests (the menu asks `
|
|
|
129
123
|
raider new my_project -p framework:rspec automation:selenium examples:false
|
|
130
124
|
```
|
|
131
125
|
|
|
132
|
-
The skeleton keeps the helpers, config, CI and README, and its empty suite passes; grow it with `raider g`.
|
|
133
|
-
|
|
134
|
-
## Migrating from Watir
|
|
135
|
-
|
|
136
|
-
Watir is deprecated; to move a Watir project to Selenium, generate a Selenium project and port your pages. The common mappings:
|
|
137
|
-
|
|
138
|
-
| Watir | Selenium project (waiting layer) |
|
|
139
|
-
|-------|----------------------------------|
|
|
140
|
-
| `browser.goto(url)` | `driver.navigate.to(url)` |
|
|
141
|
-
| `browser.text_field(id: 'x').set(v)` | `clear({ id: 'x' })` and `send_keys({ id: 'x' }, v)` |
|
|
142
|
-
| `browser.button(id: 'x').click` | `click({ id: 'x' })` |
|
|
143
|
-
| `Watir.default_timeout = n` | `timeout: n` in `config/config.yml` |
|
|
144
|
-
|
|
145
|
-
## Adopting waiting in an existing project
|
|
146
|
-
|
|
147
|
-
Gem upgrades do not rewrite generated code, so existing projects keep their implicit wait until you opt in:
|
|
148
|
-
|
|
149
|
-
1. Copy both `helpers/wait_helper.rb` and `helpers/raider_element.rb` from a freshly generated project into your
|
|
150
|
-
`helpers/` folder. Keep them side by side: `wait_helper.rb` loads the other with `require_relative 'raider_element'`.
|
|
151
|
-
2. Include it in `Page`, the spec helper, or the World, after loading it with `require_relative`, for example
|
|
152
|
-
`require_relative '../../helpers/wait_helper'` at the top of `page_objects/abstract/page.rb`.
|
|
153
|
-
3. Set how long it waits: add `timeout: 10` to `config/config.yml`. Single-platform mobile projects (iOS or Android
|
|
154
|
-
only) have no `config/config.yml`, so pass `timeout:` to a call, or create `config/config.yml` with that line;
|
|
155
|
-
without either, it waits 10 seconds.
|
|
156
|
-
4. Remove the `implicit_wait` line.
|
|
157
|
-
5. Move flaky spots to `click`, `send_keys` and `eventually` first.
|
|
158
|
-
|
|
159
|
-
Keep in mind that keeping the implicit wait while using the layer makes every `find` miss cost up to `timeout` seconds per poll cycle, so remove it once you have moved over.
|
|
126
|
+
The skeleton keeps the helpers, config, CI and README, and its empty suite passes; grow it with `raider g`.
|
|
160
127
|
|
|
161
128
|
## Commands
|
|
162
129
|
|
|
@@ -179,11 +146,9 @@ Shortcuts: `n` (new), `g` (generate), `u` (utility), `v` (version)
|
|
|
179
146
|
```
|
|
180
147
|
raider g page [NAME] # Create a page object
|
|
181
148
|
raider g spec [NAME] # Create an RSpec test
|
|
182
|
-
raider g feature [NAME] # Create a Cucumber feature
|
|
183
|
-
raider g steps [NAME] # Create step definitions
|
|
184
149
|
raider g helper [NAME] # Create a helper class
|
|
185
150
|
raider g component [NAME] # Create a component class
|
|
186
|
-
raider g scaffold [NAME(S)] # Create page +
|
|
151
|
+
raider g scaffold [NAME(S)] # Create page + spec
|
|
187
152
|
```
|
|
188
153
|
|
|
189
154
|
Options:
|
|
@@ -198,6 +163,8 @@ raider u url [URL] # Set default project URL
|
|
|
198
163
|
raider u browser [BROWSER] # Set default browser
|
|
199
164
|
raider u browser_options [OPTS] # Set browser arguments (e.g., no-sandbox, headless)
|
|
200
165
|
raider u headless [on/off] # Toggle headless mode
|
|
166
|
+
raider u strict [on/off] # Toggle strict find_element (fail on multiple matches)
|
|
167
|
+
raider u actionability [on/off] # Toggle the actionability wait before element actions
|
|
201
168
|
raider u raid # Run all tests (-p for parallel)
|
|
202
169
|
raider u timeout [SECONDS] # Set test timeout
|
|
203
170
|
raider u viewport [DIMENSIONS] # Set viewport size (e.g., 1920x1080)
|
data/RELEASE.md
CHANGED
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
## Release Notes
|
|
4
4
|
|
|
5
|
+
### 4.0.0
|
|
6
|
+
|
|
7
|
+
- Watir is removed: `automation:watir` is no longer a valid automation value.
|
|
8
|
+
- Cucumber is removed: `raider new` generates RSpec projects only and `framework:cucumber` is no longer a valid framework value.
|
|
9
|
+
- `raider g feature`, `raider g steps` and `raider u path --feature` are removed; `raider g scaffold` always writes a spec and a page.
|
|
10
|
+
- Generated projects no longer emit `cucumber_step` trace groups.
|
|
11
|
+
- ruby_raider now depends on selenium-webdriver >= 4.30.
|
|
12
|
+
- Every generated project loads `require 'ruby_raider/runtime'`, which adds waiting and actionability to Selenium and Appium themselves.
|
|
13
|
+
- `WaitHelper`, `RaiderElement`, `helpers/wait_helper.rb` and `helpers/raider_element.rb` are removed. Page objects call Selenium and Appium directly (`driver.find_element(...)`, `element.click`, `element.send_keys`).
|
|
14
|
+
- New locator keys `label`, `placeholder`, `alt`, `title`, `text` and `test_id`, and `by_role(role, name:, exact:, include_hidden:, level:)`.
|
|
15
|
+
- `find_element` is strict: it fails with `Raider::AmbiguousMatch` when a locator matches more than one element. `find_elements` never does.
|
|
16
|
+
- `find_element` and `find_elements` wait for a match (`find_elements` returns `[]` at the deadline). A missing element fails with `no such element: { id: "x" } (waited 10s)`.
|
|
17
|
+
- `eventually` is removed. Block-form expectations retry: `expect { value }.to eq(...)` works with any value matcher. RSpec's block matchers (`raise_error`, `change`, `output`, `throw_symbol`, `yield_*`) keep their stock behaviour, and `expect(value)` without a block does not retry.
|
|
18
|
+
- New RSpec matchers `have_text`, `have_value`, `have_attribute`, `be_visible`, `be_hidden`, `be_enabled`, `be_disabled`, `be_checked`, `have_count`, `have_title`, `have_url`, `have_element`, `have_css` and `have_xpath`, each with `wait:`.
|
|
19
|
+
- `click`, `send_keys`, `clear` and `submit` wait until the element is actionable (visible, enabled, not inert, stable, receives events). `force: true` skips the checks for one call.
|
|
20
|
+
- Native Appium actions wait for the element to be displayed and enabled. On XCUITest an element reported as not displayed waits the full `timeout` and then raises `Raider::NotActionable`; use `force: true` or `Raider.actionability = false` as the way out.
|
|
21
|
+
- `config/config.yml` gets `strict` and `actionability` next to `timeout`. `raider u strict on|off` and `raider u actionability on|off` set them, and `RAIDER_TIMEOUT`, `RAIDER_STRICT`, `RAIDER_ACTIONABILITY` and `RAIDER_QUIET` apply to every project, including single-platform mobile projects, which have no `config.yml`.
|
|
22
|
+
- Mobile gestures (`swipe`, `scroll`, `scroll_to`) move to `helpers/gesture_helper.rb`.
|
|
23
|
+
- Traces record element actions from the runtime: `click`, `send_keys`, `clear` and `submit` with their locators, `within` and `waited_ms`. `text`, `find_element` and other reads are no longer steps, and there are no `eventually` groups.
|
|
24
|
+
- The generated Gemfile pins `raider_reporter` `~> 1.0` (1.0.0 drops the Cucumber plugin).
|
|
25
|
+
- Existing projects pin `gem 'ruby_raider', '~> 3.15'` (or an older `~> 3.x`) in their Gemfile, so `bundle update` never moves them to 4.0; to upgrade, change the pin to `~> 4.0` and run `bundle update ruby_raider`.
|
|
26
|
+
|
|
5
27
|
### 3.7.0
|
|
6
28
|
|
|
7
29
|
- Generated RSpec projects no longer include Allure: the `allure-rspec` and `allure-ruby-commons` gems, `helpers/allure_helper.rb`, the `allure-results` folder and `.gitignore` entry, and the Allure report and gh-pages steps in the GitHub Actions workflow are gone. `raider_reporter` is now the only reporter.
|
data/bin/raider
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
+
# Read and write UTF-8 whatever the locale: a shell with no LANG (macOS GUI apps) defaults Ruby to US-ASCII,
|
|
5
|
+
# which broke the generator templates and any command that edits a generated file.
|
|
6
|
+
Encoding.default_external = Encoding::UTF_8
|
|
7
|
+
Encoding.default_internal = Encoding::UTF_8
|
|
8
|
+
|
|
4
9
|
require_relative '../lib/ruby_raider'
|
|
5
10
|
|
|
6
11
|
RubyRaider::Raider.start
|
|
@@ -20,14 +20,6 @@ class ScaffoldingCommands < Thor
|
|
|
20
20
|
generate_scaffolding(name, 'page', options[:path])
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
desc 'feature [NAME]', 'Creates a new feature'
|
|
24
|
-
option :path, type: :string, required: false,
|
|
25
|
-
desc: 'The path where your feature will be created', aliases: '-p'
|
|
26
|
-
|
|
27
|
-
def feature(name)
|
|
28
|
-
generate_scaffolding(name, 'feature', options[:path])
|
|
29
|
-
end
|
|
30
|
-
|
|
31
23
|
desc 'spec [SPEC_NAME]', 'Creates a new spec'
|
|
32
24
|
option :path, type: :string, required: false,
|
|
33
25
|
desc: 'The path where your spec will be created', aliases: '-p'
|
|
@@ -44,14 +36,6 @@ class ScaffoldingCommands < Thor
|
|
|
44
36
|
generate_scaffolding(name, 'helper', options[:path])
|
|
45
37
|
end
|
|
46
38
|
|
|
47
|
-
desc 'steps [STEPS_NAME]', 'Creates a new steps definition'
|
|
48
|
-
option :path, type: :string, required: false,
|
|
49
|
-
desc: 'The path where your steps will be created', aliases: '-p'
|
|
50
|
-
|
|
51
|
-
def steps(name)
|
|
52
|
-
generate_scaffolding(name, 'steps', options[:path])
|
|
53
|
-
end
|
|
54
|
-
|
|
55
39
|
desc 'component [NAME]', 'Creates a component inheriting from Component'
|
|
56
40
|
option :path, type: :string, required: false,
|
|
57
41
|
desc: 'The path where your component will be created', aliases: '-p'
|
|
@@ -60,7 +44,7 @@ class ScaffoldingCommands < Thor
|
|
|
60
44
|
generate_scaffolding(name, 'component', options[:path])
|
|
61
45
|
end
|
|
62
46
|
|
|
63
|
-
desc 'scaffold [NAMES...]', 'Generates pages, specs
|
|
47
|
+
desc 'scaffold [NAMES...]', 'Generates pages, specs, and helpers for one or more names'
|
|
64
48
|
|
|
65
49
|
def scaffold(*names)
|
|
66
50
|
names.each { |name| generate_default_scaffold(name) }
|
|
@@ -83,9 +67,7 @@ class ScaffoldingCommands < Thor
|
|
|
83
67
|
say 'Warning: No Gemfile found, defaulting to selenium + rspec templates.', :yellow
|
|
84
68
|
else
|
|
85
69
|
automation = ScaffoldProjectDetector.detect_automation(gemfile)
|
|
86
|
-
framework = ScaffoldProjectDetector.detect_framework(gemfile)
|
|
87
70
|
say 'Warning: Could not detect automation library from Gemfile, defaulting to selenium.', :yellow if automation.nil?
|
|
88
|
-
say 'Warning: Could not detect test framework from Gemfile, defaulting to rspec.', :yellow if framework.nil?
|
|
89
71
|
end
|
|
90
72
|
end
|
|
91
73
|
|
|
@@ -97,12 +79,7 @@ class ScaffoldingCommands < Thor
|
|
|
97
79
|
|
|
98
80
|
def generate_default_scaffold(name)
|
|
99
81
|
validate_project!
|
|
100
|
-
|
|
101
|
-
generate_scaffolding(name, 'spec', load_config_path('spec'))
|
|
102
|
-
else
|
|
103
|
-
generate_scaffolding(name, 'feature', load_config_path('feature'))
|
|
104
|
-
generate_scaffolding(name, 'steps', load_config_path('steps'))
|
|
105
|
-
end
|
|
82
|
+
generate_scaffolding(name, 'spec', load_config_path('spec'))
|
|
106
83
|
generate_scaffolding(name, 'page', load_config_path('page'))
|
|
107
84
|
end
|
|
108
85
|
end
|
|
@@ -7,8 +7,6 @@ class UtilityCommands < Thor
|
|
|
7
7
|
def self.exit_on_failure? = true
|
|
8
8
|
|
|
9
9
|
desc 'path [PATH]', 'Sets the default path for scaffolding'
|
|
10
|
-
option :feature,
|
|
11
|
-
type: :boolean, required: false, desc: 'The default path for your features', aliases: '-f'
|
|
12
10
|
option :helper,
|
|
13
11
|
type: :boolean, required: false, desc: 'The default path for your helpers', aliases: '-h'
|
|
14
12
|
option :spec,
|
|
@@ -49,12 +47,28 @@ class UtilityCommands < Thor
|
|
|
49
47
|
desc 'headless [on/off]', 'Toggles headless mode for browser tests'
|
|
50
48
|
|
|
51
49
|
def headless(toggle)
|
|
52
|
-
enabled =
|
|
50
|
+
enabled = on?(toggle)
|
|
53
51
|
Utilities.headless = enabled
|
|
54
52
|
state = enabled ? 'enabled' : 'disabled'
|
|
55
53
|
say "Headless mode #{state}", :green
|
|
56
54
|
end
|
|
57
55
|
|
|
56
|
+
desc 'strict [on/off]', 'Toggles strict find_element (fails when a locator matches more than one element)'
|
|
57
|
+
|
|
58
|
+
def strict(toggle)
|
|
59
|
+
enabled = on?(toggle)
|
|
60
|
+
Utilities.strict = enabled
|
|
61
|
+
say "Strict mode #{enabled ? 'enabled' : 'disabled'}", :green
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
desc 'actionability [on/off]', 'Toggles the actionability wait before element actions'
|
|
65
|
+
|
|
66
|
+
def actionability(toggle)
|
|
67
|
+
enabled = on?(toggle)
|
|
68
|
+
Utilities.actionability = enabled
|
|
69
|
+
say "Actionability #{enabled ? 'enabled' : 'disabled'}", :green
|
|
70
|
+
end
|
|
71
|
+
|
|
58
72
|
desc 'raid', 'It runs all the tests in a project'
|
|
59
73
|
option :parallel,
|
|
60
74
|
type: :boolean, required: false, desc: 'It runs the tests in parallel', aliases: '-p'
|
|
@@ -160,4 +174,10 @@ class UtilityCommands < Thor
|
|
|
160
174
|
say "Failure video #{enabled ? 'enabled' : 'disabled'}", :green
|
|
161
175
|
end
|
|
162
176
|
end
|
|
177
|
+
|
|
178
|
+
private
|
|
179
|
+
|
|
180
|
+
def on?(toggle)
|
|
181
|
+
%w[on true 1 yes].include?(toggle.downcase)
|
|
182
|
+
end
|
|
163
183
|
end
|
|
@@ -17,7 +17,6 @@ class AutomationGenerator < Generator
|
|
|
17
17
|
generate_home_page
|
|
18
18
|
generate_pdp_page
|
|
19
19
|
else
|
|
20
|
-
generate_header_component
|
|
21
20
|
generate_model_files
|
|
22
21
|
generate_pages
|
|
23
22
|
end
|
|
@@ -67,10 +66,6 @@ class AutomationGenerator < Generator
|
|
|
67
66
|
template('pdp.tt', "#{name}/page_objects/pages/pdp.rb")
|
|
68
67
|
end
|
|
69
68
|
|
|
70
|
-
def generate_header_component
|
|
71
|
-
template('header.tt', "#{name}/page_objects/components/header.rb")
|
|
72
|
-
end
|
|
73
|
-
|
|
74
69
|
def generate_model_factory
|
|
75
70
|
template('factory.tt', "#{name}/models/model_factory.rb")
|
|
76
71
|
end
|
|
@@ -6,7 +6,7 @@ class Home < Page
|
|
|
6
6
|
# Actions
|
|
7
7
|
|
|
8
8
|
def go_to_product_detail
|
|
9
|
-
|
|
9
|
+
first_product.click
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
private
|
|
@@ -14,6 +14,6 @@ class Home < Page
|
|
|
14
14
|
# Elements
|
|
15
15
|
|
|
16
16
|
def first_product
|
|
17
|
-
<%= partial('home_page_selector') -%>
|
|
17
|
+
<%= cross_platform? ? 'element(' : 'driver.find_element(' -%><%= partial('home_page_selector').strip -%>)
|
|
18
18
|
end
|
|
19
19
|
end
|
|
@@ -9,46 +9,26 @@ class Login < Page
|
|
|
9
9
|
|
|
10
10
|
# Actions
|
|
11
11
|
|
|
12
|
-
<%- if selenium_based? -%>
|
|
13
12
|
def login(username, password)
|
|
14
|
-
send_keys(
|
|
15
|
-
send_keys(
|
|
16
|
-
click(login_button)
|
|
17
|
-
end
|
|
18
|
-
alias log_as login
|
|
19
|
-
<%- else -%>
|
|
20
|
-
def login(username, password)
|
|
21
|
-
username_field.set username
|
|
22
|
-
password_field.set password
|
|
13
|
+
username_field.send_keys(username)
|
|
14
|
+
password_field.send_keys(password)
|
|
23
15
|
login_button.click
|
|
24
16
|
end
|
|
25
|
-
|
|
17
|
+
alias log_as login
|
|
26
18
|
|
|
27
19
|
private
|
|
28
20
|
|
|
29
21
|
# Elements
|
|
30
22
|
|
|
31
23
|
def username_field
|
|
32
|
-
|
|
33
|
-
{ id: 'loginFrm_loginname' }
|
|
34
|
-
<%- else -%>
|
|
35
|
-
browser.text_field(id: 'loginFrm_loginname')
|
|
36
|
-
<%- end -%>
|
|
24
|
+
driver.find_element(id: 'loginFrm_loginname')
|
|
37
25
|
end
|
|
38
26
|
|
|
39
27
|
def password_field
|
|
40
|
-
|
|
41
|
-
{ id: 'loginFrm_password' }
|
|
42
|
-
<%- else -%>
|
|
43
|
-
browser.text_field(id: 'loginFrm_password')
|
|
44
|
-
<%- end -%>
|
|
28
|
+
driver.find_element(id: 'loginFrm_password')
|
|
45
29
|
end
|
|
46
30
|
|
|
47
31
|
def login_button
|
|
48
|
-
|
|
49
|
-
{ xpath: "//button[@title='Login']" }
|
|
50
|
-
<%- else -%>
|
|
51
|
-
browser.button(xpath: "//button[@title='Login']")
|
|
52
|
-
<%- end -%>
|
|
32
|
+
driver.find_element(by_role('button', name: 'Login'))
|
|
53
33
|
end
|
|
54
34
|
end
|
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
require 'ruby_raider/runtime'
|
|
4
|
+
<%- if cross_platform? -%>
|
|
5
|
+
require_relative '../../helpers/appium_helper'
|
|
6
|
+
<%- end -%>
|
|
7
|
+
<%- if mobile? -%>
|
|
8
|
+
require_relative '../../helpers/gesture_helper'
|
|
9
|
+
<%- end -%>
|
|
10
|
+
<%- if network_helper? -%>
|
|
11
|
+
require_relative '../../helpers/network_helper'
|
|
5
12
|
<%- end -%>
|
|
6
|
-
<%- if
|
|
7
|
-
require_relative '../../helpers/
|
|
13
|
+
<%- if screenshot_helper? -%>
|
|
14
|
+
require_relative '../../helpers/screenshot_helper'
|
|
8
15
|
<%- end -%>
|
|
9
16
|
|
|
10
17
|
class Page
|
|
11
18
|
<%- if cross_platform? -%>
|
|
12
19
|
include AppiumHelper
|
|
13
20
|
<%- end -%>
|
|
14
|
-
|
|
15
|
-
|
|
21
|
+
include Raider::Helpers
|
|
22
|
+
<%- if mobile? -%>
|
|
23
|
+
include GestureHelper
|
|
16
24
|
<%- end -%>
|
|
17
|
-
<%- if
|
|
18
|
-
|
|
25
|
+
<%- if network_helper? -%>
|
|
26
|
+
include NetworkHelper
|
|
27
|
+
<%- end -%>
|
|
28
|
+
<%- if screenshot_helper? -%>
|
|
29
|
+
include ScreenshotHelper
|
|
19
30
|
<%- end -%>
|
|
31
|
+
|
|
20
32
|
<%= partial('initialize_selector') -%>
|
|
21
33
|
<%= partial('visit_method') -%>
|
|
22
34
|
<%= partial('url_methods') -%>
|
|
@@ -26,17 +38,10 @@ class Page
|
|
|
26
38
|
end
|
|
27
39
|
<%- if selenium_based? && examples? -%>
|
|
28
40
|
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
def header
|
|
32
|
-
Header.new(find_element(css: '.welcome-msg'))
|
|
33
|
-
end
|
|
34
|
-
<%- elsif watir? -%>
|
|
35
|
-
|
|
36
|
-
# Components
|
|
41
|
+
# Elements
|
|
37
42
|
|
|
38
|
-
def
|
|
39
|
-
|
|
43
|
+
def welcome_message
|
|
44
|
+
driver.find_element(css: '.welcome-msg')
|
|
40
45
|
end
|
|
41
46
|
<%- end -%>
|
|
42
47
|
end
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<%- if cross_platform? -%>
|
|
2
|
-
{ ios: { accessibility_id: 'product-item-1' },
|
|
3
|
-
android: { accessibility_id: 'product-item-1' } }
|
|
2
|
+
{ ios: { accessibility_id: 'product-item-1' }, android: { accessibility_id: 'product-item-1' } }
|
|
4
3
|
<%- else -%>
|
|
5
4
|
{ accessibility_id: 'product-item-1' }
|
|
6
5
|
<%- end -%>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<%- if cross_platform? -%>
|
|
2
|
-
{ ios: { accessibility_id: 'add-to-cart-button' },
|
|
3
|
-
android: { accessibility_id: 'add-to-cart-button' } }
|
|
2
|
+
{ ios: { accessibility_id: 'add-to-cart-button' }, android: { accessibility_id: 'add-to-cart-button' } }
|
|
4
3
|
<%- else -%>
|
|
5
4
|
{ accessibility_id: 'add-to-cart-button' }
|
|
6
5
|
<%- end -%>
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
<%- if web? -%>
|
|
2
2
|
|
|
3
3
|
def full_url(*page)
|
|
4
|
-
|
|
4
|
+
path = url(*page).to_s
|
|
5
|
+
base = base_url
|
|
6
|
+
base.empty? ? path : "#{base}#{path.delete_prefix('/')}"
|
|
5
7
|
end
|
|
6
8
|
|
|
9
|
+
# The configured url with a trailing slash, so page paths never run into its last segment.
|
|
7
10
|
def base_url
|
|
8
|
-
YAML.load_file('config/config.yml')['url']
|
|
11
|
+
base = YAML.load_file('config/config.yml')['url'].to_s
|
|
12
|
+
return base if base.empty? || base.end_with?('/')
|
|
13
|
+
|
|
14
|
+
"#{base}/"
|
|
9
15
|
end
|
|
10
16
|
|
|
11
17
|
def url(_page)
|
|
@@ -3,17 +3,9 @@
|
|
|
3
3
|
require_relative '../abstract/page'
|
|
4
4
|
|
|
5
5
|
class Pdp < Page
|
|
6
|
-
# Actions
|
|
7
|
-
|
|
8
|
-
def add_to_cart_text
|
|
9
|
-
text(add_to_cart_button)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
private
|
|
13
|
-
|
|
14
6
|
# Elements
|
|
15
7
|
|
|
16
8
|
def add_to_cart_button
|
|
17
|
-
<%= partial('pdp_page_selector') -%>
|
|
9
|
+
<%= cross_platform? ? 'element(' : 'driver.find_element(' -%><%= partial('pdp_page_selector').strip -%>)
|
|
18
10
|
end
|
|
19
11
|
end
|