Compare commits
68 Commits
main
...
releases_v
Author | SHA1 | Date |
---|---|---|
runner | dbc6b319b8 | |
runner | ccb3d86a7d | |
runner | 23a8fe907d | |
runner | 7a3ab8eb1b | |
runner | a775df7f4a | |
runner | 03174492af | |
runner | c9999c9a08 | |
runner | 8416c7624b | |
runner | 0d1fbec00a | |
runner | 326c54362a | |
runner | 614b6b3ee2 | |
runner | 938883e589 | |
runner | fc471fd653 | |
runner | 7dc5b50559 | |
runner | 8031115eab | |
Mozilla Releng Treescript | b5da40cc0d | |
github-actions[bot] | ea47fd8cb0 | |
runner | 1aee502270 | |
runner | e973baafa6 | |
runner | 553ccbc2d4 | |
runner | 65aac1f1ee | |
runner | f712a3137d | |
runner | 27a5dbf43a | |
runner | 402be76d8a | |
runner | 683be63691 | |
runner | 3b94b67039 | |
runner | d9cfb825af | |
runner | c9c2ac96e1 | |
runner | e27ea84e56 | |
runner | b77fe0d294 | |
runner | 8a341fd621 | |
github-actions[bot] | a354b73d8f | |
runner | 4c5cb92fdf | |
runner | 444437cd27 | |
runner | 1f093c4585 | |
runner | b645315a5c | |
runner | 3c6c4c3b4e | |
runner | e63880796b | |
runner | cbab3912e4 | |
runner | 89acc2f92d | |
runner | e58398fb77 | |
runner | 55bf1f6389 | |
runner | 46533ac4d8 | |
runner | 69353cf813 | |
runner | 857a87f3db | |
runner | 8858e3c445 | |
runner | bb157fa317 | |
runner | c4523feba7 | |
Arturo Mejia | 9aa86cd7bb | |
runner | 7d343dee3f | |
Mozilla Releng Treescript | 39cfc131d1 | |
github-actions[bot] | 9df4e7a39d | |
runner | 8db9993500 | |
mergify[bot] | 9ea848b543 | |
rxu | 6904f4ecd5 | |
Mozilla Releng Treescript | 95fb1e7395 | |
github-actions[bot] | 4e393a9230 | |
Arturo Mejia | 280c0eb2bc | |
runner | 1008d7d754 | |
github-actions[bot] | bf028904e5 | |
Mozilla Releng Treescript | a3dae43b3c | |
github-actions[bot] | 3d8e729195 | |
github-actions[bot] | d0471d167f | |
runner | 5495a39ee4 | |
github-actions[bot] | 53f0887225 | |
runner | 455b1e98f2 | |
Mozilla Releng Treescript | cdbe5fee57 | |
Donal Meehan | 6e0ad035e3 |
19
.cron.yml
19
.cron.yml
|
@ -12,28 +12,21 @@ jobs:
|
|||
when:
|
||||
- {hour: 5, minute: 0}
|
||||
- {hour: 17, minute: 0}
|
||||
- name: nightly-test
|
||||
job:
|
||||
type: decision-task
|
||||
treeherder-symbol: Nt
|
||||
target-tasks-method: nightly-test
|
||||
when:
|
||||
- {hour: 5, minute: 0}
|
||||
- name: fennec-production
|
||||
job:
|
||||
type: decision-task
|
||||
treeherder-symbol: fennec-production
|
||||
target-tasks-method: fennec-production
|
||||
when: [] # Force hook only
|
||||
- name: bump-android-components
|
||||
job:
|
||||
type: decision-task
|
||||
treeherder-symbol: bump-ac
|
||||
target-tasks-method: bump_android_components
|
||||
when: [{hour: 15, minute: 30}]
|
||||
- name: screenshots
|
||||
job:
|
||||
type: decision-task
|
||||
treeherder-symbol: screenshots-D
|
||||
target-tasks-method: screenshots
|
||||
when: [{weekday: 'Monday', hour: 10, minute: 0}]
|
||||
- name: legacy-api-ui-tests
|
||||
job:
|
||||
type: decision-task
|
||||
treeherder-symbol: legacy-api-ui
|
||||
target-tasks-method: legacy_api_ui_tests
|
||||
when: [] # temporarily unscheduled
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
[*.{kt,kts}]
|
||||
ij_kotlin_allow_trailing_comma_on_call_site=true
|
||||
ij_kotlin_allow_trailing_comma=true
|
||||
|
||||
[*]
|
||||
insert_final_newline = true
|
||||
# Disabling rules that were added in the latest versions of ktlint
|
||||
# tracking here: https://github.com/mozilla-mobile/fenix/issues/4861
|
||||
disabled_rules=import-ordering
|
|
@ -1,20 +1,23 @@
|
|||
---
|
||||
cookie-banners:
|
||||
description: Features for cookie banner handling.
|
||||
default-browser-message:
|
||||
description: A small feature allowing experiments on the placement of a default browser message.
|
||||
hasExposure: true
|
||||
exposureDescription: ""
|
||||
variables:
|
||||
sections-enabled:
|
||||
type: json
|
||||
description: This property provides a lookup table of whether or not the given section should be enabled.
|
||||
growth-data:
|
||||
description: A feature measuring campaign growth data
|
||||
message-location:
|
||||
type: string
|
||||
description: Where is the message to be put.
|
||||
engine-settings:
|
||||
description: Contains a set of settings for controlling the web engine configurations.
|
||||
hasExposure: true
|
||||
exposureDescription: ""
|
||||
variables:
|
||||
enabled:
|
||||
tabs-prioritization-enabled:
|
||||
type: boolean
|
||||
description: "If true, the feature is active"
|
||||
description: "If true, enables tabs prioritization feature."
|
||||
total-cookie-protection-enabled:
|
||||
type: boolean
|
||||
description: "If true, enables the total cookie protection in all browsing modes."
|
||||
homescreen:
|
||||
description: The homescreen that the user goes to when they press home or new tab.
|
||||
hasExposure: true
|
||||
|
@ -37,9 +40,6 @@ messaging:
|
|||
messages:
|
||||
type: json
|
||||
description: A growable collection of messages
|
||||
notification-config:
|
||||
type: json
|
||||
description: Configuration of the notification worker for all notification messages.
|
||||
on-control:
|
||||
type: string
|
||||
description: What should be displayed when a control message is selected.
|
||||
|
@ -52,14 +52,6 @@ messaging:
|
|||
triggers:
|
||||
type: json
|
||||
description: "A collection of out the box trigger expressions. Each entry maps to a valid JEXL expression.\n"
|
||||
mr2022:
|
||||
description: Features for MR 2022.
|
||||
hasExposure: true
|
||||
exposureDescription: ""
|
||||
variables:
|
||||
sections-enabled:
|
||||
type: json
|
||||
description: This property provides a lookup table of whether or not the given section should be enabled.
|
||||
nimbus-validation:
|
||||
description: A feature that does not correspond to an application feature suitable for showing that Nimbus is working. This should never be used in production.
|
||||
hasExposure: true
|
||||
|
@ -74,22 +66,14 @@ nimbus-validation:
|
|||
settings-title:
|
||||
type: string
|
||||
description: The title of displayed in the Settings screen and app menu.
|
||||
pre-permission-notification-prompt:
|
||||
description: A feature that shows the pre-permission notification prompt.
|
||||
pocket-sponsored-stories:
|
||||
description: A feature showing sponsored stories in between the other Pocket recommended stories on homescreen.
|
||||
hasExposure: true
|
||||
exposureDescription: ""
|
||||
variables:
|
||||
enabled:
|
||||
type: boolean
|
||||
description: "if true, the pre-permission notification prompt is shown to the user."
|
||||
re-engagement-notification:
|
||||
description: A feature that shows the re-enagement notification if the user is inactive.
|
||||
hasExposure: true
|
||||
exposureDescription: ""
|
||||
variables:
|
||||
enabled:
|
||||
type: boolean
|
||||
description: "If true, the re-engagement notification is shown to the inactive user."
|
||||
description: "If true, the Pocket stories shown on homescreen should contain sponsored stories also."
|
||||
search-term-groups:
|
||||
description: A feature allowing the grouping of URLs around the search term that it came from.
|
||||
hasExposure: true
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
# .git-blame-ignore-revs
|
||||
# For #27667 - Remove import-ordering from the list of disabled ktlint rules (#27680)
|
||||
9654b4dfb122b54b04369fe80a2f9c95811478e8
|
||||
# For #26844: Fix ktlint issues and remove them from baseline. (#26901)
|
||||
ffcef5ff2e3f78b6972dd16551f3f653b7035ccc
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
name: "\U0001F6A8 Intermittent Unit Test Issue"
|
||||
about: Create an issue to help log a Unit Test failure
|
||||
labels: "eng:intermittent-test"
|
||||
title: "Intermittent Unit Test failure - <Classname.testName>"
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Test Run:
|
||||
Provide a test run report link here showcasing the problem (e.g, Taskcluster), and a link to the source Github event
|
||||
### Stacktrace:
|
||||
### Build:
|
|
@ -6,18 +6,8 @@
|
|||
- [ ] **Screenshots**: This PR includes screenshots or GIFs of the changes made or an explanation of why it does not
|
||||
- [ ] **Accessibility**: The code in this PR follows [accessibility best practices](https://github.com/mozilla-mobile/shared-docs/blob/master/android/accessibility_guide.md) or does not include any user facing features. In addition, it includes a screenshot of a successful [accessibility scan](https://play.google.com/store/apps/details?id=com.google.android.apps.accessibility.auditor&hl=en_US) to ensure no new defects are added to the product.
|
||||
|
||||
### QA
|
||||
<!-- Before submitting the PR, please address each item -->
|
||||
- [x] **QA Needed**
|
||||
|
||||
### To download an APK when reviewing a PR (after all CI tasks finished running):
|
||||
1. Click on `Checks` at the top of the PR page.
|
||||
2. Click on the `firefoxci-taskcluster` group on the left to expand all tasks.
|
||||
3. Click on the `build-debug` task.
|
||||
4. Click on `View task in Taskcluster` in the new `DETAILS` section.
|
||||
5. The APK links should be on the right side of the screen, named for each CPU architecture.
|
||||
|
||||
### GitHub Automation
|
||||
<!-- Do not add anything below this line -->
|
||||
|
||||
Used by GitHub Actions.
|
||||
### To download an APK when reviewing a PR:
|
||||
1. click on Show All Checks,
|
||||
2. click Details next to "Taskcluster (pull_request)" after it appears and then finishes with a green checkmark,
|
||||
3. click on the "Fenix - assemble" task, then click "Run Artifacts".
|
||||
4. the APK links should be on the left side of the screen, named for each CPU architecture
|
||||
|
|
|
@ -3,7 +3,7 @@ on: [pull_request]
|
|||
jobs:
|
||||
run-build:
|
||||
runs-on: ubuntu-20.04
|
||||
if: ${{ false }}
|
||||
if: github.event.pull_request.head.repo.full_name != github.repository && github.actor != 'MickeyMoz'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
@ -108,6 +108,7 @@ jobs:
|
|||
run-ui:
|
||||
runs-on: macos-11
|
||||
if: ${{ false }}
|
||||
|
||||
timeout-minutes: 60
|
||||
strategy:
|
||||
matrix:
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/
|
||||
|
||||
name: "Fenix - Update Nimbus Experiments"
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '*/30 * * * *'
|
||||
workflow_dispatch: {}
|
||||
|
||||
jobs:
|
||||
update-nimbus-experiments:
|
||||
name: "Update Nimbus Experiments"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Checkout Main Branch"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: fenix
|
||||
ref: main
|
||||
fetch-depth: 0
|
||||
- name: "Update Experiments JSON"
|
||||
id: update-experiments-json
|
||||
uses: mozilla-mobile/update-experiments@v2
|
||||
with:
|
||||
repo-path: fenix
|
||||
output-path: app/src/main/res/raw/initial_experiments.json
|
||||
experimenter-url: https://experimenter.services.mozilla.com/api/v6/experiments-first-run/
|
||||
app-name: fenix
|
||||
branch: automation/update-nimbus-experiments
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
if: steps.update-experiments-json.outputs.changed == 1 && steps.update-experiments-json.outputs.changed-branch == 1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
path: fenix
|
||||
branch: automation/update-nimbus-experiments
|
||||
commit-message: "update initial_experiments.json based on the current first-run experiments in experimenter"
|
||||
title: "Update initial experiments JSON for Nimbus"
|
||||
body: "This (automated) PR updates the initial_experiments.json on the `main` branch"
|
||||
delete-branch: true
|
|
@ -1,10 +0,0 @@
|
|||
---
|
||||
name: Glean probe-scraper
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
jobs:
|
||||
glean-probe-scraper:
|
||||
uses: mozilla/probe-scraper/.github/workflows/glean.yaml@main
|
|
@ -1,21 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/
|
||||
|
||||
name: Issue Linker
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
issue_linker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Issue Linker
|
||||
uses: gabrielluong/issue-linker@1.0.0
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-regexp: "#(\\d+)+"
|
||||
section: "### GitHub Automation"
|
|
@ -1,20 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/
|
||||
|
||||
name: Tag Milestone
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- closed
|
||||
|
||||
jobs:
|
||||
milestone:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.actor == 'mergify[bot]'
|
||||
steps:
|
||||
- name: Tag Milestone
|
||||
uses: gabrielluong/milestone@1.0.0
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@ -1,22 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/
|
||||
|
||||
name: QA Needed
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
qa_needed:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: QA Needed
|
||||
uses: gabrielluong/qa-needed@1.0.1
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
label: "eng:reopen-for-qa"
|
||||
check-regexp: "- \\[([ xX]?)\\] \\*\\*QA Needed\\*\\*"
|
||||
commit-regexp: "#(\\d+)+"
|
|
@ -1,21 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/
|
||||
|
||||
name: Reopen for QA Needed
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- closed
|
||||
|
||||
jobs:
|
||||
reopen_qa_needed:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Reopen for QA Needed
|
||||
uses: gabrielluong/reopen-for-qa-needed@1.0.0
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
reopen-label: "eng:reopen-for-qa"
|
||||
qa-label: "eng:qa:needed"
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/
|
||||
|
||||
name: "Fenix - Sync Strings"
|
||||
name: "Sync Strings"
|
||||
|
||||
on:
|
||||
schedule:
|
||||
|
@ -15,10 +15,10 @@ jobs:
|
|||
steps:
|
||||
- name: "Discover Fenix Beta Version"
|
||||
id: fenix-beta-version
|
||||
uses: mozilla-mobile/fenix-beta-version@4.1.0
|
||||
uses: mozilla-mobile/fenix-beta-version@2.0.0
|
||||
- name: "Skip non-beta versions"
|
||||
uses: andymckay/cancel-action@0.2
|
||||
if: ${{ steps.fenix-beta-version.outputs.beta_version == '' }}
|
||||
if: ${{ steps.fenix-beta-version.outputs.fenix-beta-version == '' }}
|
||||
- name: "Checkout Master Branch"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
|
@ -28,7 +28,7 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: beta
|
||||
ref: "releases_v${{ steps.fenix-beta-version.outputs.beta_version }}.0.0"
|
||||
ref: "releases_v${{ steps.fenix-beta-version.outputs.fenix-beta-version }}.0.0"
|
||||
- name: "Sync Strings"
|
||||
uses: mozilla-mobile/sync-strings-action@1.0.1
|
||||
with:
|
||||
|
@ -39,6 +39,7 @@ jobs:
|
|||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
path: beta
|
||||
branch: automation/sync-strings-${{ steps.fenix-beta-version.outputs.beta_version }}
|
||||
title: "Sync Strings from main to releases_${{steps.fenix-beta-version.outputs.beta_version}}.0"
|
||||
body: "This (automated) PR syncs strings from `main` to `releases_${{steps.fenix-beta-version.outputs.beta_version}}.0.0`"
|
||||
branch: automation/sync-strings-${{ steps.fenix-beta-version.outputs.major-beta-version }}
|
||||
title: "Sync Strings from main to releases_${{steps.fenix-beta-version.outputs.fenix-beta-version}}.0"
|
||||
body: "This (automated) PR syncs strings from `main` to `releases_${{steps.fenix-beta-version.outputs.fenix-beta-version}}.0.0`"
|
||||
labels: needs:review
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/
|
||||
|
||||
name: "Fenix - Update Android-Components"
|
||||
name: "Update Android-Components"
|
||||
|
||||
on:
|
||||
schedule:
|
||||
|
@ -14,7 +14,7 @@ jobs:
|
|||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: "Update Android-Components"
|
||||
uses: mozilla-mobile/relbot@5.0.2
|
||||
uses: mozilla-mobile/relbot@master
|
||||
if: github.repository == 'mozilla-mobile/fenix'
|
||||
with:
|
||||
project: fenix
|
119
.mergify.yml
119
.mergify.yml
|
@ -1,9 +1,7 @@
|
|||
queue_rules:
|
||||
- name: default
|
||||
conditions:
|
||||
- or:
|
||||
- status-success=complete-pr
|
||||
- status-success=complete-push
|
||||
- status-success=pr-complete
|
||||
pull_request_rules:
|
||||
- name: Resolve conflict
|
||||
conditions:
|
||||
|
@ -11,20 +9,50 @@ pull_request_rules:
|
|||
actions:
|
||||
comment:
|
||||
message: This pull request has conflicts when rebasing. Could you fix it @{{author}}? 🙏
|
||||
- name: Android-Components bump - Auto Merge
|
||||
- name: MickeyMoz - Auto Merge
|
||||
conditions:
|
||||
- and:
|
||||
- files=buildSrc/src/main/java/AndroidComponents.kt
|
||||
- -files~=^(?!buildSrc/src/main/java/AndroidComponents.kt).+$
|
||||
- author=github-actions[bot]
|
||||
- status-success=complete-push
|
||||
- or:
|
||||
- and:
|
||||
- base=main
|
||||
- head~=^relbot/AC-Nightly-.+
|
||||
- and:
|
||||
- base~=^releases[_/].*
|
||||
- head~=^relbot/fenix-\d+
|
||||
- author=MickeyMoz
|
||||
- status-success=pr-complete
|
||||
- files~=(Gecko.kt|AndroidComponents.kt)
|
||||
actions:
|
||||
review:
|
||||
type: APPROVE
|
||||
message: MickeyMoz 💪
|
||||
queue:
|
||||
method: rebase
|
||||
name: default
|
||||
rebase_fallback: none
|
||||
- name: L10N - Auto Merge
|
||||
conditions:
|
||||
- author=mozilla-l10n-automation-bot
|
||||
- status-success=pr-complete
|
||||
- files~=(strings.xml|l10n.toml)
|
||||
actions:
|
||||
review:
|
||||
type: APPROVE
|
||||
message: LGTM 😎
|
||||
queue:
|
||||
method: rebase
|
||||
name: default
|
||||
rebase_fallback: none
|
||||
- name: Release automation (Old)
|
||||
conditions:
|
||||
- base~=releases[_/].*
|
||||
- author=github-actions[bot]
|
||||
# Listing checks manually beause we do not have a "push complete" check yet.
|
||||
- check-success=build-android-test-debug
|
||||
- check-success=build-debug
|
||||
- check-success=build-nightly-simulation
|
||||
- check-success=lint-compare-locales
|
||||
- check-success=lint-detekt
|
||||
- check-success=lint-ktlint
|
||||
- check-success=lint-lint
|
||||
- check-success=signing-android-test-debug
|
||||
- check-success=signing-debug
|
||||
- check-success=signing-nightly-simulation
|
||||
- check-success=test-debug
|
||||
- check-success=ui-test-x86-debug
|
||||
- files~=(AndroidComponents.kt)
|
||||
actions:
|
||||
review:
|
||||
type: APPROVE
|
||||
|
@ -33,42 +61,41 @@ pull_request_rules:
|
|||
method: rebase
|
||||
name: default
|
||||
rebase_fallback: none
|
||||
- name: L10N - Auto Merge
|
||||
delete_head_branch:
|
||||
force: false
|
||||
- name: Release automation (New)
|
||||
conditions:
|
||||
- and:
|
||||
- files~=^(l10n.toml|app/src/main/res/values[A-Za-z-]*/strings\.xml)$
|
||||
# /!\ The line above doesn't prevent random files to be changed alongside
|
||||
# l10n ones. That's why the additional condition exists below. For more
|
||||
# information: https://docs.mergify.com/conditions/#how-to-match-lists
|
||||
- -files~=^(?!(l10n.toml|app/src/main/res/values[A-Za-z-]*/strings\.xml)).+$
|
||||
- or:
|
||||
- and:
|
||||
- author=mozilla-l10n-automation-bot
|
||||
- base=main
|
||||
- head=import-l10n
|
||||
- status-success=complete-pr
|
||||
- and:
|
||||
- author=github-actions[bot]
|
||||
- base~=^releases[_/].*
|
||||
- head~=^automation/sync-strings-\d+
|
||||
- status-success=complete-push
|
||||
# Taskcluster only runs on git-push events because github-actions[bot] is not considered
|
||||
# a collaborator, so pull request events are triggered. That said, github-actions[bot]
|
||||
# doesn't create the PR on a separate fork (unlike mozilla-l10n-automation-bot). That's
|
||||
# why git-push events are taken into account
|
||||
- base~=releases[_/].*
|
||||
- author=github-actions[bot]
|
||||
# Listing checks manually beause we do not have a "push complete" check yet.
|
||||
- check-success=build-android-test-beta
|
||||
- check-success=build-android-test-debug
|
||||
- check-success=build-beta-firebase
|
||||
- check-success=build-debug
|
||||
- check-success=build-nightly-simulation
|
||||
- check-success=lint-compare-locales
|
||||
- check-success=lint-detekt
|
||||
- check-success=lint-ktlint
|
||||
- check-success=lint-lint
|
||||
- check-success=signing-android-test-beta
|
||||
- check-success=signing-beta-firebase
|
||||
- check-success=signing-nightly-simulation
|
||||
- check-success=test-debug
|
||||
- check-success=ui-test-x86-beta
|
||||
- files~=(AndroidComponents.kt)
|
||||
actions:
|
||||
review:
|
||||
type: APPROVE
|
||||
message: LGTM 😎
|
||||
message: 🚢
|
||||
queue:
|
||||
method: squash
|
||||
method: rebase
|
||||
name: default
|
||||
rebase_fallback: none
|
||||
delete_head_branch:
|
||||
force: false
|
||||
- name: Needs landing - Rebase
|
||||
conditions:
|
||||
- or:
|
||||
- check-success=complete-pr
|
||||
- check-success=complete-push
|
||||
- check-success=pr-complete
|
||||
- label=pr:needs-landing
|
||||
- "#approved-reviews-by>=1"
|
||||
- -draft
|
||||
|
@ -81,10 +108,8 @@ pull_request_rules:
|
|||
rebase_fallback: none
|
||||
- name: Needs landing - Squash
|
||||
conditions:
|
||||
- or:
|
||||
- check-success=complete-pr
|
||||
- check-success=complete-push
|
||||
- label=pr:needs-landing-squashed
|
||||
- check-success=pr-complete
|
||||
- label=pr:needs-landing-squashed
|
||||
- "#approved-reviews-by>=1"
|
||||
- -draft
|
||||
- label!=pr:work-in-progress
|
||||
|
|
|
@ -13,14 +13,14 @@ tasks:
|
|||
$if: 'tasks_for in ["cron", "action"]'
|
||||
then: '${tasks_for}@noreply.mozilla.org'
|
||||
else:
|
||||
$if: 'tasks_for == "github-push"'
|
||||
then:
|
||||
$if: 'event.pusher.email'
|
||||
then: '${event.pusher.email}'
|
||||
else: '${event.pusher.name}@users.noreply.github.com'
|
||||
$if: 'event.sender.login == "bors[bot]"'
|
||||
then: 'skaspari+mozlando@mozilla.com' # It must match what's in bors.toml
|
||||
else:
|
||||
$if: 'tasks_for == "github-pull-request"'
|
||||
then: '${event.pull_request.user.login}@users.noreply.github.com'
|
||||
$if: 'tasks_for == "github-push"'
|
||||
then: '${event.pusher.email}'
|
||||
else:
|
||||
$if: 'tasks_for == "github-pull-request"'
|
||||
then: '${event.pull_request.user.login}@users.noreply.github.com'
|
||||
baseRepoUrl:
|
||||
$if: 'tasks_for == "github-push"'
|
||||
then: '${event.repository.html_url}'
|
||||
|
@ -122,7 +122,7 @@ tasks:
|
|||
name: "Decision Task for cron job ${cron.job_name}"
|
||||
description: 'Created by a [cron task](https://firefox-ci-tc.services.mozilla.com/tasks/${cron.task_id})'
|
||||
provisionerId: "${trustDomain}-${level}"
|
||||
workerType: "decision-gcp"
|
||||
workerType: "decision"
|
||||
tags:
|
||||
$if: 'tasks_for in ["github-push", "github-pull-request"]'
|
||||
then:
|
||||
|
@ -203,7 +203,7 @@ tasks:
|
|||
chainOfTrust: true
|
||||
# Note: This task is built server side without the context or tooling that
|
||||
# exist in tree so we must hard code the hash
|
||||
image: mozillareleases/taskgraph:decision-mobile-625975b642c148be4c6f1d8ee5cedf7399f5d0dd33d275ff69d5934e3082d4a9@sha256:bfb26700182486e1c6c52701baea6f386fa39e5e25417423c27845933605ad43
|
||||
image: mozillareleases/taskgraph:decision-mobile-7e11b0cc3966ad9729e08b19551399b3343d3b385eac067b6335d4c34431a899@sha256:b309fa59efd59991ba286a326cb43b724c38e6f3872c52d0f85e96428899c2fc
|
||||
|
||||
maxRunTime: 1800
|
||||
|
||||
|
@ -215,7 +215,7 @@ tasks:
|
|||
- bash
|
||||
- -cx
|
||||
- $let:
|
||||
extraArgs:
|
||||
extraArgs:
|
||||
$if: 'tasks_for == "cron"'
|
||||
then: '${cron.quoted_args}'
|
||||
else: ''
|
||||
|
@ -247,7 +247,7 @@ tasks:
|
|||
'public':
|
||||
type: 'directory'
|
||||
path: '/builds/worker/artifacts'
|
||||
expires:
|
||||
expires:
|
||||
$fromNow: '1 year'
|
||||
'public/docker-contexts':
|
||||
type: 'directory'
|
||||
|
@ -256,7 +256,7 @@ tasks:
|
|||
# decision task + the docker-image task deadlines.
|
||||
# It is set to a week to allow for some time for
|
||||
# debugging, but they are not useful long-term.
|
||||
expires:
|
||||
expires:
|
||||
$fromNow: '7 day'
|
||||
|
||||
extra:
|
||||
|
|
13
README.md
13
README.md
|
@ -23,7 +23,7 @@ Please read the [Community Participation Guidelines](https://www.mozilla.org/en-
|
|||
* Check out the [project wiki](https://github.com/mozilla-mobile/fenix/wiki) for more information.
|
||||
* See [our guide on Writing Custom Lint Rules](https://github.com/mozilla-mobile/shared-docs/blob/master/android/writing_lint_rules.md).
|
||||
|
||||
* Localization happens on [Pontoon](https://pontoon.mozilla.org/projects/firefox-for-android/). Please get in touch with delphine (at) mozilla (dot) com directly for more information.
|
||||
* Localization happens on [Pontoon](https://pontoon.mozilla.org/projects/android-l10n/). Please get in touch with delphine (at) mozilla (dot) com directly for more information.
|
||||
|
||||
**Beginners!** - Watch out for [Issues with the "Good First Issue" label](https://github.com/mozilla-mobile/fenix/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). These are easy bugs that have been left for first timers to have a go, get involved and make a positive contribution to the project!
|
||||
|
||||
|
@ -199,12 +199,10 @@ raptorEnabled
|
|||
If you're making changes to these projects and want to test them in Fenix, auto-publication workflow is the fastest, most reliable
|
||||
way to do that.
|
||||
|
||||
In `local.properties`, specify a relative path to your local `android-components` and/or `application-services` projects. E.g.:
|
||||
- `autoPublish.android-components.dir=../firefox-android/android-components`
|
||||
In `local.properties`, specify a relative path to your local `android-components` and/or `application-services` checkouts. E.g.:
|
||||
- `autoPublish.android-components.dir=../android-components`
|
||||
- `autoPublish.application-services.dir=../application-services`
|
||||
|
||||
*Note that the Android Components project was already migrated to the new [firefox-android](https://github.com/mozilla-mobile/firefox-android) repository. Therefore, this auto publication workflow won't be neccessary for Android Components once Fenix is integrated in the new repository as well.*
|
||||
|
||||
Once these flags are set, your Fenix builds will include any local modifications present in these projects.
|
||||
|
||||
See a [demo of auto-publication workflow in action](https://www.youtube.com/watch?v=qZKlBzVvQGc).
|
||||
|
@ -224,11 +222,6 @@ If you wish to use a Nimbus server during local development, you can add a `http
|
|||
|
||||
Testing experimental branches should be possible without a server.
|
||||
|
||||
### Using custom Glean servers during local development
|
||||
If you wish to use a custom Glean server during local development, you can add a `https://` endpoint to the `local.properties` file.
|
||||
|
||||
- `glean.custom.server.url`
|
||||
|
||||
### GeckoView
|
||||
Specify a relative path to your local `mozilla-central` checkout via `dependencySubstitutions.geckoviewTopsrcdir`,
|
||||
and optional a path to m-c object directory via `dependencySubstitutions.geckoviewTopobjdir`.
|
||||
|
|
324
app/build.gradle
324
app/build.gradle
|
@ -2,7 +2,7 @@ import org.mozilla.fenix.gradle.tasks.ApkSizeTask
|
|||
|
||||
plugins {
|
||||
id "com.jetbrains.python.envs" version "0.0.26"
|
||||
id "com.google.protobuf" version "0.8.19"
|
||||
id "com.google.protobuf" version "0.8.17"
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
|
@ -47,7 +47,7 @@ android {
|
|||
buildConfigField "String", "GIT_HASH", "\"\"" // see override in release builds for why it's blank.
|
||||
// This should be the "public" base URL of AMO.
|
||||
buildConfigField "String", "AMO_BASE_URL", "\"https://addons.mozilla.org\""
|
||||
buildConfigField "String", "AMO_COLLECTION_NAME", "\"Extensions-for-Android\""
|
||||
buildConfigField "String", "AMO_COLLECTION_NAME", "\"7dfae8669acc4312a65e8ba5553036\""
|
||||
buildConfigField "String", "AMO_COLLECTION_USER", "\"mozilla\""
|
||||
// These add-ons should be excluded for Mozilla Online builds.
|
||||
buildConfigField "String[]", "MOZILLA_ONLINE_ADDON_EXCLUSIONS",
|
||||
|
@ -59,8 +59,7 @@ android {
|
|||
"\"foxyproxy@eric.h.jung\"," +
|
||||
"\"{73a6fe31-595d-460b-a920-fcc0f8843232}\"," +
|
||||
"\"jid1-BoFifL9Vbdl2zQ@jetpack\"," +
|
||||
"\"woop-NoopscooPsnSXQ@jetpack\"," +
|
||||
"\"adnauseam@rednoise.org\"" +
|
||||
"\"woop-NoopscooPsnSXQ@jetpack\"" +
|
||||
"}"
|
||||
// This should be the base URL used to call the AMO API.
|
||||
buildConfigField "String", "AMO_SERVER_URL", "\"https://services.addons.mozilla.org\""
|
||||
|
@ -225,7 +224,7 @@ android {
|
|||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = FenixVersions.androidx_compose_compiler
|
||||
kotlinCompilerExtensionVersion = Versions.androidx_compose
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -236,7 +235,7 @@ android.applicationVariants.all { variant ->
|
|||
// Generate version codes for builds
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
def isDebug = variant.buildType.resValues['bool/IS_DEBUG']?.value ?: false
|
||||
def isDebug = variant.buildType.resValues['IS_DEBUG']?.value ?: false
|
||||
def useReleaseVersioning = variant.buildType.buildConfigFields['USE_RELEASE_VERSIONING']?.value ?: false
|
||||
|
||||
println("----------------------------------------------")
|
||||
|
@ -366,21 +365,6 @@ android.applicationVariants.all { variant ->
|
|||
println("--")
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// Glean: Read custom server URL from local.properties of a local file if it exists
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
print("Glean custom server URL: ")
|
||||
|
||||
if (gradle.hasProperty("localProperties.glean.custom.server.url")) {
|
||||
def url=gradle.getProperty("localProperties.glean.custom.server.url")
|
||||
buildConfigField 'String', 'GLEAN_CUSTOM_URL', url
|
||||
println "(Added from local.properties file)"
|
||||
} else {
|
||||
buildConfigField 'String', 'GLEAN_CUSTOM_URL', 'null'
|
||||
println("--")
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// BuildConfig: Set flag for official builds; similar to MOZILLA_OFFICIAL in mozilla-central.
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
@ -465,164 +449,159 @@ configurations {
|
|||
|
||||
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs += "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi"
|
||||
freeCompilerArgs += "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
jnaForTest FenixDependencies.jna
|
||||
jnaForTest Deps.jna
|
||||
testImplementation files(configurations.jnaForTest.copyRecursive().files)
|
||||
|
||||
implementation FenixDependencies.mozilla_browser_engine_gecko
|
||||
implementation Deps.mozilla_browser_engine_gecko
|
||||
|
||||
implementation FenixDependencies.kotlin_stdlib
|
||||
implementation FenixDependencies.kotlin_coroutines
|
||||
implementation FenixDependencies.kotlin_coroutines_android
|
||||
testImplementation FenixDependencies.kotlin_coroutines_test
|
||||
implementation FenixDependencies.androidx_appcompat
|
||||
implementation FenixDependencies.androidx_constraintlayout
|
||||
implementation FenixDependencies.androidx_coordinatorlayout
|
||||
implementation FenixDependencies.google_accompanist_drawablepainter
|
||||
implementation FenixDependencies.google_accompanist_insets
|
||||
implementation Deps.kotlin_stdlib
|
||||
implementation Deps.kotlin_coroutines
|
||||
implementation Deps.kotlin_coroutines_android
|
||||
testImplementation Deps.kotlin_coroutines_test
|
||||
implementation Deps.androidx_appcompat
|
||||
implementation Deps.androidx_constraintlayout
|
||||
implementation Deps.androidx_coordinatorlayout
|
||||
|
||||
implementation FenixDependencies.sentry
|
||||
implementation Deps.sentry
|
||||
|
||||
implementation FenixDependencies.mozilla_compose_awesomebar
|
||||
implementation Deps.mozilla_compose_awesomebar
|
||||
|
||||
implementation FenixDependencies.mozilla_concept_awesomebar
|
||||
implementation FenixDependencies.mozilla_concept_base
|
||||
implementation FenixDependencies.mozilla_concept_engine
|
||||
implementation FenixDependencies.mozilla_concept_menu
|
||||
implementation FenixDependencies.mozilla_concept_push
|
||||
implementation FenixDependencies.mozilla_concept_storage
|
||||
implementation FenixDependencies.mozilla_concept_sync
|
||||
implementation FenixDependencies.mozilla_concept_toolbar
|
||||
implementation FenixDependencies.mozilla_concept_tabstray
|
||||
implementation Deps.mozilla_concept_awesomebar
|
||||
implementation Deps.mozilla_concept_base
|
||||
implementation Deps.mozilla_concept_engine
|
||||
implementation Deps.mozilla_concept_menu
|
||||
implementation Deps.mozilla_concept_push
|
||||
implementation Deps.mozilla_concept_storage
|
||||
implementation Deps.mozilla_concept_sync
|
||||
implementation Deps.mozilla_concept_toolbar
|
||||
implementation Deps.mozilla_concept_tabstray
|
||||
|
||||
implementation FenixDependencies.mozilla_browser_domains
|
||||
implementation FenixDependencies.mozilla_browser_icons
|
||||
implementation FenixDependencies.mozilla_browser_menu
|
||||
implementation FenixDependencies.mozilla_browser_menu2
|
||||
implementation FenixDependencies.mozilla_browser_session_storage
|
||||
implementation FenixDependencies.mozilla_browser_state
|
||||
implementation FenixDependencies.mozilla_browser_storage_sync
|
||||
implementation FenixDependencies.mozilla_browser_tabstray
|
||||
implementation FenixDependencies.mozilla_browser_thumbnails
|
||||
implementation FenixDependencies.mozilla_browser_toolbar
|
||||
implementation Deps.mozilla_browser_domains
|
||||
implementation Deps.mozilla_browser_icons
|
||||
implementation Deps.mozilla_browser_menu
|
||||
implementation Deps.mozilla_browser_menu2
|
||||
implementation Deps.mozilla_browser_session_storage
|
||||
implementation Deps.mozilla_browser_state
|
||||
implementation Deps.mozilla_browser_storage_sync
|
||||
implementation Deps.mozilla_browser_tabstray
|
||||
implementation Deps.mozilla_browser_thumbnails
|
||||
implementation Deps.mozilla_browser_toolbar
|
||||
|
||||
implementation FenixDependencies.mozilla_feature_addons
|
||||
implementation FenixDependencies.mozilla_feature_accounts
|
||||
implementation FenixDependencies.mozilla_feature_app_links
|
||||
implementation FenixDependencies.mozilla_feature_autofill
|
||||
implementation FenixDependencies.mozilla_feature_awesomebar
|
||||
implementation FenixDependencies.mozilla_feature_contextmenu
|
||||
implementation FenixDependencies.mozilla_feature_customtabs
|
||||
implementation FenixDependencies.mozilla_feature_downloads
|
||||
implementation FenixDependencies.mozilla_feature_intent
|
||||
implementation FenixDependencies.mozilla_feature_media
|
||||
implementation FenixDependencies.mozilla_feature_prompts
|
||||
implementation FenixDependencies.mozilla_feature_push
|
||||
implementation FenixDependencies.mozilla_feature_privatemode
|
||||
implementation FenixDependencies.mozilla_feature_pwa
|
||||
implementation FenixDependencies.mozilla_feature_qr
|
||||
implementation FenixDependencies.mozilla_feature_search
|
||||
implementation FenixDependencies.mozilla_feature_session
|
||||
implementation FenixDependencies.mozilla_feature_syncedtabs
|
||||
implementation FenixDependencies.mozilla_feature_toolbar
|
||||
implementation FenixDependencies.mozilla_feature_tabs
|
||||
implementation FenixDependencies.mozilla_feature_findinpage
|
||||
implementation FenixDependencies.mozilla_feature_logins
|
||||
implementation FenixDependencies.mozilla_feature_site_permissions
|
||||
implementation FenixDependencies.mozilla_feature_readerview
|
||||
implementation FenixDependencies.mozilla_feature_tab_collections
|
||||
implementation FenixDependencies.mozilla_feature_recentlyclosed
|
||||
implementation FenixDependencies.mozilla_feature_top_sites
|
||||
implementation FenixDependencies.mozilla_feature_share
|
||||
implementation FenixDependencies.mozilla_feature_accounts_push
|
||||
implementation FenixDependencies.mozilla_feature_webauthn
|
||||
implementation FenixDependencies.mozilla_feature_webcompat
|
||||
implementation FenixDependencies.mozilla_feature_webnotifications
|
||||
implementation FenixDependencies.mozilla_feature_webcompat_reporter
|
||||
implementation Deps.mozilla_feature_addons
|
||||
implementation Deps.mozilla_feature_accounts
|
||||
implementation Deps.mozilla_feature_app_links
|
||||
implementation Deps.mozilla_feature_autofill
|
||||
implementation Deps.mozilla_feature_awesomebar
|
||||
implementation Deps.mozilla_feature_contextmenu
|
||||
implementation Deps.mozilla_feature_customtabs
|
||||
implementation Deps.mozilla_feature_downloads
|
||||
implementation Deps.mozilla_feature_intent
|
||||
implementation Deps.mozilla_feature_media
|
||||
implementation Deps.mozilla_feature_prompts
|
||||
implementation Deps.mozilla_feature_push
|
||||
implementation Deps.mozilla_feature_privatemode
|
||||
implementation Deps.mozilla_feature_pwa
|
||||
implementation Deps.mozilla_feature_qr
|
||||
implementation Deps.mozilla_feature_search
|
||||
implementation Deps.mozilla_feature_session
|
||||
implementation Deps.mozilla_feature_syncedtabs
|
||||
implementation Deps.mozilla_feature_toolbar
|
||||
implementation Deps.mozilla_feature_tabs
|
||||
implementation Deps.mozilla_feature_findinpage
|
||||
implementation Deps.mozilla_feature_logins
|
||||
implementation Deps.mozilla_feature_site_permissions
|
||||
implementation Deps.mozilla_feature_readerview
|
||||
implementation Deps.mozilla_feature_tab_collections
|
||||
implementation Deps.mozilla_feature_recentlyclosed
|
||||
implementation Deps.mozilla_feature_top_sites
|
||||
implementation Deps.mozilla_feature_share
|
||||
implementation Deps.mozilla_feature_accounts_push
|
||||
implementation Deps.mozilla_feature_webauthn
|
||||
implementation Deps.mozilla_feature_webcompat
|
||||
implementation Deps.mozilla_feature_webnotifications
|
||||
implementation Deps.mozilla_feature_webcompat_reporter
|
||||
|
||||
implementation FenixDependencies.mozilla_service_pocket
|
||||
implementation FenixDependencies.mozilla_service_contile
|
||||
implementation FenixDependencies.mozilla_service_digitalassetlinks
|
||||
implementation FenixDependencies.mozilla_service_sync_autofill
|
||||
implementation FenixDependencies.mozilla_service_sync_logins
|
||||
implementation FenixDependencies.mozilla_service_firefox_accounts
|
||||
implementation(FenixDependencies.mozilla_service_glean)
|
||||
implementation FenixDependencies.mozilla_service_location
|
||||
implementation FenixDependencies.mozilla_service_nimbus
|
||||
implementation Deps.mozilla_service_pocket
|
||||
implementation Deps.mozilla_service_contile
|
||||
implementation Deps.mozilla_service_digitalassetlinks
|
||||
implementation Deps.mozilla_service_sync_autofill
|
||||
implementation Deps.mozilla_service_sync_logins
|
||||
implementation Deps.mozilla_service_firefox_accounts
|
||||
implementation(Deps.mozilla_service_glean)
|
||||
implementation Deps.mozilla_service_location
|
||||
implementation Deps.mozilla_service_nimbus
|
||||
|
||||
implementation FenixDependencies.mozilla_support_extensions
|
||||
implementation FenixDependencies.mozilla_support_base
|
||||
implementation FenixDependencies.mozilla_support_rusterrors
|
||||
implementation FenixDependencies.mozilla_support_images
|
||||
implementation FenixDependencies.mozilla_support_ktx
|
||||
implementation FenixDependencies.mozilla_support_rustlog
|
||||
implementation FenixDependencies.mozilla_support_utils
|
||||
implementation FenixDependencies.mozilla_support_locale
|
||||
implementation Deps.mozilla_support_extensions
|
||||
implementation Deps.mozilla_support_base
|
||||
implementation Deps.mozilla_support_rusterrors
|
||||
implementation Deps.mozilla_support_images
|
||||
implementation Deps.mozilla_support_ktx
|
||||
implementation Deps.mozilla_support_rustlog
|
||||
implementation Deps.mozilla_support_utils
|
||||
implementation Deps.mozilla_support_locale
|
||||
|
||||
implementation FenixDependencies.mozilla_ui_colors
|
||||
implementation FenixDependencies.mozilla_ui_icons
|
||||
implementation FenixDependencies.mozilla_lib_publicsuffixlist
|
||||
implementation FenixDependencies.mozilla_ui_widgets
|
||||
implementation FenixDependencies.mozilla_ui_tabcounter
|
||||
implementation Deps.mozilla_ui_colors
|
||||
implementation Deps.mozilla_ui_icons
|
||||
implementation Deps.mozilla_lib_publicsuffixlist
|
||||
implementation Deps.mozilla_ui_widgets
|
||||
implementation Deps.mozilla_ui_tabcounter
|
||||
|
||||
implementation FenixDependencies.mozilla_lib_crash
|
||||
implementation FenixDependencies.lib_crash_sentry
|
||||
implementation FenixDependencies.mozilla_lib_push_firebase
|
||||
implementation FenixDependencies.mozilla_lib_state
|
||||
implementation FenixDependencies.mozilla_lib_dataprotect
|
||||
debugImplementation FenixDependencies.leakcanary
|
||||
implementation Deps.mozilla_lib_crash
|
||||
implementation Deps.lib_crash_sentry
|
||||
implementation Deps.mozilla_lib_push_firebase
|
||||
implementation Deps.mozilla_lib_state
|
||||
implementation Deps.mozilla_lib_dataprotect
|
||||
debugImplementation Deps.leakcanary
|
||||
|
||||
implementation FenixDependencies.androidx_annotation
|
||||
implementation FenixDependencies.androidx_compose_ui
|
||||
implementation FenixDependencies.androidx_compose_ui_tooling
|
||||
implementation FenixDependencies.androidx_compose_foundation
|
||||
implementation FenixDependencies.androidx_compose_material
|
||||
implementation FenixDependencies.androidx_legacy
|
||||
implementation FenixDependencies.androidx_biometric
|
||||
implementation FenixDependencies.androidx_paging
|
||||
implementation FenixDependencies.androidx_preference
|
||||
implementation FenixDependencies.androidx_fragment
|
||||
implementation FenixDependencies.androidx_navigation_fragment
|
||||
implementation FenixDependencies.androidx_navigation_ui
|
||||
implementation FenixDependencies.androidx_recyclerview
|
||||
implementation FenixDependencies.androidx_lifecycle_common
|
||||
implementation FenixDependencies.androidx_lifecycle_livedata
|
||||
implementation FenixDependencies.androidx_lifecycle_process
|
||||
implementation FenixDependencies.androidx_lifecycle_runtime
|
||||
implementation FenixDependencies.androidx_lifecycle_viewmodel
|
||||
implementation FenixDependencies.androidx_core
|
||||
implementation FenixDependencies.androidx_core_ktx
|
||||
implementation FenixDependencies.androidx_transition
|
||||
implementation FenixDependencies.androidx_work_ktx
|
||||
implementation FenixDependencies.androidx_datastore
|
||||
implementation FenixDependencies.protobuf_javalite
|
||||
implementation FenixDependencies.google_material
|
||||
implementation Deps.androidx_compose_ui
|
||||
implementation Deps.androidx_compose_ui_tooling
|
||||
implementation Deps.androidx_compose_foundation
|
||||
implementation Deps.androidx_compose_material
|
||||
implementation Deps.androidx_legacy
|
||||
implementation Deps.androidx_biometric
|
||||
implementation Deps.androidx_paging
|
||||
implementation Deps.androidx_preference
|
||||
implementation Deps.androidx_fragment
|
||||
implementation Deps.androidx_navigation_fragment
|
||||
implementation Deps.androidx_navigation_ui
|
||||
implementation Deps.androidx_recyclerview
|
||||
implementation Deps.androidx_lifecycle_common
|
||||
implementation Deps.androidx_lifecycle_livedata
|
||||
implementation Deps.androidx_lifecycle_process
|
||||
implementation Deps.androidx_lifecycle_runtime
|
||||
implementation Deps.androidx_lifecycle_viewmodel
|
||||
implementation Deps.androidx_core
|
||||
implementation Deps.androidx_core_ktx
|
||||
implementation Deps.androidx_transition
|
||||
implementation Deps.androidx_work_ktx
|
||||
implementation Deps.androidx_datastore
|
||||
implementation Deps.protobuf_javalite
|
||||
implementation Deps.google_material
|
||||
|
||||
implementation FenixDependencies.adjust
|
||||
implementation FenixDependencies.installreferrer // Required by Adjust
|
||||
implementation Deps.adjust
|
||||
implementation Deps.installreferrer // Required by Adjust
|
||||
|
||||
implementation FenixDependencies.google_ads_id // Required for the Google Advertising ID
|
||||
implementation Deps.google_ads_id // Required for the Google Advertising ID
|
||||
|
||||
// Required for in-app reviews
|
||||
implementation FenixDependencies.google_play_review
|
||||
implementation FenixDependencies.google_play_review_ktx
|
||||
implementation Deps.google_play_store // Required for in-app reviews
|
||||
|
||||
androidTestImplementation FenixDependencies.uiautomator
|
||||
androidTestImplementation Deps.uiautomator
|
||||
androidTestImplementation "tools.fastlane:screengrab:2.0.0"
|
||||
// This Falcon version is added to maven central now required for Screengrab
|
||||
implementation 'com.jraska:falcon:2.2.0'
|
||||
|
||||
androidTestImplementation FenixDependencies.androidx_compose_ui_test
|
||||
androidTestImplementation Deps.androidx_compose_ui_test
|
||||
|
||||
androidTestImplementation FenixDependencies.espresso_core, {
|
||||
androidTestImplementation Deps.espresso_core, {
|
||||
exclude group: 'com.android.support', module: 'support-annotations'
|
||||
}
|
||||
|
||||
androidTestImplementation(FenixDependencies.espresso_contrib) {
|
||||
androidTestImplementation(Deps.espresso_contrib) {
|
||||
exclude module: 'appcompat-v7'
|
||||
exclude module: 'support-v4'
|
||||
exclude module: 'support-annotations'
|
||||
|
@ -632,36 +611,35 @@ dependencies {
|
|||
exclude module: 'protobuf-lite'
|
||||
}
|
||||
|
||||
androidTestImplementation FenixDependencies.androidx_test_core
|
||||
androidTestImplementation FenixDependencies.espresso_idling_resources
|
||||
androidTestImplementation FenixDependencies.espresso_intents
|
||||
androidTestImplementation Deps.androidx_test_core
|
||||
androidTestImplementation Deps.espresso_idling_resources
|
||||
androidTestImplementation Deps.espresso_intents
|
||||
|
||||
androidTestImplementation FenixDependencies.tools_test_runner
|
||||
androidTestImplementation FenixDependencies.tools_test_rules
|
||||
androidTestUtil FenixDependencies.orchestrator
|
||||
androidTestImplementation FenixDependencies.espresso_core, {
|
||||
androidTestImplementation Deps.tools_test_runner
|
||||
androidTestImplementation Deps.tools_test_rules
|
||||
androidTestUtil Deps.orchestrator
|
||||
androidTestImplementation Deps.espresso_core, {
|
||||
exclude group: 'com.android.support', module: 'support-annotations'
|
||||
}
|
||||
|
||||
androidTestImplementation FenixDependencies.androidx_junit
|
||||
androidTestImplementation FenixDependencies.androidx_test_extensions
|
||||
androidTestImplementation FenixDependencies.androidx_work_testing
|
||||
androidTestImplementation FenixDependencies.androidx_benchmark_junit4
|
||||
androidTestImplementation FenixDependencies.mockwebserver
|
||||
testImplementation FenixDependencies.mozilla_support_test
|
||||
testImplementation FenixDependencies.mozilla_support_test_libstate
|
||||
testImplementation FenixDependencies.androidx_junit
|
||||
testImplementation FenixDependencies.androidx_test_extensions
|
||||
testImplementation FenixDependencies.androidx_work_testing
|
||||
testImplementation (FenixDependencies.robolectric) {
|
||||
androidTestImplementation Deps.androidx_junit
|
||||
androidTestImplementation Deps.androidx_test_extensions
|
||||
androidTestImplementation Deps.androidx_work_testing
|
||||
androidTestImplementation Deps.androidx_benchmark_junit4
|
||||
androidTestImplementation Deps.mockwebserver
|
||||
testImplementation Deps.mozilla_support_test
|
||||
testImplementation Deps.mozilla_support_test_libstate
|
||||
testImplementation Deps.androidx_junit
|
||||
testImplementation Deps.androidx_test_extensions
|
||||
testImplementation Deps.androidx_work_testing
|
||||
testImplementation (Deps.robolectric) {
|
||||
exclude group: 'org.apache.maven'
|
||||
}
|
||||
|
||||
testImplementation 'org.apache.maven:maven-ant-tasks:2.1.3'
|
||||
implementation FenixDependencies.mozilla_support_rusthttp
|
||||
implementation Deps.mozilla_support_rusthttp
|
||||
|
||||
androidTestImplementation FenixDependencies.mockk_android
|
||||
testImplementation FenixDependencies.mockk
|
||||
testImplementation Deps.mockk
|
||||
|
||||
// For the initial release of Glean 19, we require consumer applications to
|
||||
// depend on a separate library for unit tests. This will be removed in future releases.
|
||||
|
@ -675,9 +653,9 @@ protobuf {
|
|||
// See https://github.com/mozilla-mobile/fenix/issues/22321
|
||||
protoc {
|
||||
if (osdetector.os == "osx") {
|
||||
artifact = "${FenixDependencies.protobuf_compiler}:osx-x86_64"
|
||||
artifact = "${Deps.protobuf_compiler}:osx-x86_64"
|
||||
} else {
|
||||
artifact = FenixDependencies.protobuf_compiler
|
||||
artifact = Deps.protobuf_compiler
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
1900
app/metrics.yaml
1900
app/metrics.yaml
File diff suppressed because it is too large
Load Diff
|
@ -43,22 +43,3 @@ topsites-impression:
|
|||
- https://github.com/mozilla-mobile/fenix/pull/23945
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
|
||||
spoc:
|
||||
description: |
|
||||
Contains data identifying with which Pocket sponsored story the user
|
||||
interacted with and the type of interaction: story impression or click.
|
||||
include_client_id: false
|
||||
reasons:
|
||||
impression: |
|
||||
A sponsored story had more than 50% of it's content visible
|
||||
on the screen.
|
||||
click: |
|
||||
A sponsored story was clicked by the user.
|
||||
bugs:
|
||||
- https://github.com/mozilla-mobile/fenix/issues/27549
|
||||
- https://mozilla-hub.atlassian.net/browse/FNXV2-21791
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/fenix/pull/27550#issuecomment-1295027631
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Address_Form</title>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
<p>Street Address: <input id="streetAddress" type="text"></p>
|
||||
<p>City: <input id="city" type="text"></p>
|
||||
<p>Zip Code: <input id="zipCode" type="text"></p>
|
||||
<p>Country: <input id="country" type="text"></p>
|
||||
<p>Telephone: <input id="telephone" type="text"></p>
|
||||
<p>Email: <input id="email" type="text"></p>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -1,13 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Credit_Card_Form</title>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
<p>Card information</p>
|
||||
<p>Card Number: <input id="cardNumber" type="text" placeholder="1234 1234 1234 1234"></p>
|
||||
<p>Name on card: <input id="nameOnCard"type="text" placeholder="Name on card"></p>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -1,8 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<h2>Cross-site cookies storage access test</h2>
|
||||
<h3>anti-tracker-test.com</h3>
|
||||
<h4>different site, cross-origin iframe</h4>
|
||||
<iframe width=500 height=1000 src="https://mozilla-mobile.github.io/testapp/anti-tracker-test_set_storage_with_sa_api.html"></iframe>
|
||||
</body>
|
||||
</html>
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Html_Control_Form</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
</head>
|
||||
|
||||
<p>Misc Link Types</p>
|
||||
<section>
|
||||
<a href="https://duckduckgo.com/">External link</a>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<a href="mailto://example@example.com">Email link</a>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<a href="tel://1234567890">Telephone link</a>
|
||||
</section>
|
||||
|
||||
</html>
|
|
@ -1,74 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Html_Control_Form</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
</head>
|
||||
|
||||
<p>Calendar Form</p>
|
||||
<section>
|
||||
<input type="date" id="calendar">
|
||||
<button onclick="printDate()" id="submitDate"> Submit date </button>
|
||||
<div id="displayDate"></div>
|
||||
</section>
|
||||
|
||||
<p>Clock Form</p>
|
||||
<section>
|
||||
<input type="time" id="clock">
|
||||
<button onclick="printTime()" id="submitTime"> Submit time </button>
|
||||
<div id="displayTime"></div>
|
||||
</section>
|
||||
|
||||
<p>Color Form</p>
|
||||
<section>
|
||||
<input type="color" id="colorPicker">
|
||||
<button onclick="printColor()" id="submitColor"> Submit color </button>
|
||||
<div id="displayColor"></div>
|
||||
</section>
|
||||
|
||||
<p>Drop-down Form</p>
|
||||
<select id="dropDown">
|
||||
<option type="text" text="The Only Ones">The Only Ones</option>
|
||||
<option type="text" text="The National">The National</option>
|
||||
</select>
|
||||
<button onclick="printOption()" id="submitOption"> Submit drop down option </button>
|
||||
<div id="displayOption"></div>
|
||||
|
||||
<script>
|
||||
function printOption() {
|
||||
let dropDown = document.querySelector("#dropDown");
|
||||
let displayOption = document.querySelector("#displayOption");
|
||||
|
||||
displayOption.innerHTML = "Selected option is: " + dropDown.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
function printDate() {
|
||||
let calendar = document.querySelector("#calendar");
|
||||
let displayDate = document.querySelector("#displayDate");
|
||||
|
||||
displayDate.innerHTML = "Selected date is: " + calendar.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
function printTime() {
|
||||
let time = document.querySelector("#clock");
|
||||
let displayTime = document.querySelector("#displayTime");
|
||||
|
||||
displayTime.innerHTML = "Selected time is: " + time.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
function printColor() {
|
||||
let colorPicker = document.querySelector("#colorPicker");
|
||||
let displayColor = document.querySelector("#displayColor");
|
||||
|
||||
displayColor.innerHTML = "Selected color is: " + colorPicker.value;
|
||||
}
|
||||
</script>
|
||||
</html>
|
|
@ -1,23 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<body>
|
||||
|
||||
<h1>Storage check</h1>
|
||||
|
||||
<script type="text/javascript">
|
||||
if (sessionStorage.getItem('sessionTest') == 'session storage') {
|
||||
document.write('<p>Session storage has value</p>');
|
||||
} else {
|
||||
document.write('<p>Session storage empty</p>');
|
||||
}
|
||||
|
||||
if (localStorage.getItem('localTest') == 'local storage') {
|
||||
document.write('<p>Local storage has value</p>');
|
||||
} else {
|
||||
document.write('<p>Local storage empty</p>');
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,28 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<body>
|
||||
|
||||
<h1>Storage Write</h1>
|
||||
|
||||
<p id="cookies"></p>
|
||||
<button id="setCookies">Set cookies</button>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
document.getElementById("cookies").textContent = document.cookie?document.cookie:"No cookies set";
|
||||
})();
|
||||
|
||||
document.getElementById("setCookies").addEventListener("click", function() {
|
||||
document.cookie = "user=android";
|
||||
document.getElementById("cookies").textContent = document.cookie;
|
||||
});
|
||||
|
||||
sessionStorage.setItem('sessionTest', 'session storage');
|
||||
localStorage.setItem('localTest', 'local storage');
|
||||
|
||||
document.write('<p>Values written to storage</p>');
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -13,31 +13,31 @@
|
|||
<h3>Level 1 (Basic) List</h3>
|
||||
<p>social-track-digest256:</p>
|
||||
<img
|
||||
src="https://social-track-digest256.dummytracker.org/test_not_blocked.png" alt="social not blocked"
|
||||
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';this.alt='social blocked'">
|
||||
src="https://social-track-digest256.dummytracker.org/test_not_blocked.png"
|
||||
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png'">
|
||||
<br/>
|
||||
<p>ads-track-digest256:</p>
|
||||
<img
|
||||
src="https://ads-track-digest256.dummytracker.org/test_not_blocked.png"
|
||||
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';this.alt='ads blocked'">
|
||||
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png'">
|
||||
<br/>
|
||||
<p>analytics-track-digest256:</p>
|
||||
<img
|
||||
src="https://analytics-track-digest256.dummytracker.org/test_not_blocked.png"
|
||||
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';this.alt='analytics blocked'">
|
||||
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png'">
|
||||
<br/>
|
||||
<p>Fingerprinting:
|
||||
<pre id="result">test not run</pre>
|
||||
<script src="https://base-fingerprinting-track-digest256.dummytracker.org/tracker.js"
|
||||
onerror="this.onerror=null;var result=document.getElementById('result');result.innerHTML='Fingerprinting blocked';"
|
||||
onload="this.onload=null;var result=document.getElementById('result');result.innerHTML='Fingerprinting NOT blocked';"
|
||||
onerror="this.onerror=null;var result=document.getElementById('result');result.innerHTML='blocked';"
|
||||
onload="this.onload=null;var result=document.getElementById('result');result.innerHTML='NOT blocked';"
|
||||
></script>
|
||||
</p>
|
||||
<br/>
|
||||
<p>Cryptomining:
|
||||
<img
|
||||
src="https://base-cryptomining-track-digest256.dummytracker.org/test_not_blocked.png" alt="Cryptomining not blocked"
|
||||
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';this.alt='Cryptomining blocked'">
|
||||
src="https://base-cryptomining-track-digest256.dummytracker.org/test_not_blocked.png" alt="not blocked"
|
||||
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';this.alt='blocked'">
|
||||
</p>
|
||||
|
||||
<p><b>Cookie blocking</b>
|
||||
|
|
|
@ -39,8 +39,9 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
|
|||
isSameDomain: Boolean,
|
||||
isRedirect: Boolean,
|
||||
isDirectNavigation: Boolean,
|
||||
isSubframeRequest: Boolean,
|
||||
isSubframeRequest: Boolean
|
||||
): RequestInterceptor.InterceptionResponse? {
|
||||
|
||||
interceptFxaRequest(
|
||||
engineSession,
|
||||
uri,
|
||||
|
@ -49,7 +50,7 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
|
|||
isSameDomain,
|
||||
isRedirect,
|
||||
isDirectNavigation,
|
||||
isSubframeRequest,
|
||||
isSubframeRequest
|
||||
)?.let { response ->
|
||||
return response
|
||||
}
|
||||
|
@ -67,14 +68,14 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
|
|||
isSameDomain,
|
||||
isRedirect,
|
||||
isDirectNavigation,
|
||||
isSubframeRequest,
|
||||
isSubframeRequest
|
||||
)
|
||||
}
|
||||
|
||||
override fun onErrorRequest(
|
||||
session: EngineSession,
|
||||
errorType: ErrorType,
|
||||
uri: String?,
|
||||
uri: String?
|
||||
): RequestInterceptor.ErrorResponse? {
|
||||
val improvedErrorType = improveErrorType(errorType)
|
||||
val riskLevel = getRiskLevel(improvedErrorType)
|
||||
|
@ -85,7 +86,7 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
|
|||
context = context,
|
||||
errorType = improvedErrorType,
|
||||
uri = uri,
|
||||
htmlResource = riskLevel.htmlRes,
|
||||
htmlResource = riskLevel.htmlRes
|
||||
)
|
||||
|
||||
return RequestInterceptor.ErrorResponse(errorPageUri)
|
||||
|
@ -101,18 +102,20 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
|
|||
private fun interceptAmoRequest(
|
||||
uri: String,
|
||||
isSameDomain: Boolean,
|
||||
hasUserGesture: Boolean,
|
||||
hasUserGesture: Boolean
|
||||
): RequestInterceptor.InterceptionResponse? {
|
||||
// First we execute a quick check to see if this is a request we're interested in i.e. a
|
||||
// request triggered by the user and coming from AMO.
|
||||
if (hasUserGesture && isSameDomain && uri.startsWith(AMO_BASE_URL)) {
|
||||
|
||||
// Check if this is a request to install an add-on.
|
||||
val matchResult = AMO_INSTALL_URL_REGEX.toRegex().matchEntire(uri)
|
||||
if (matchResult != null) {
|
||||
|
||||
// Navigate and trigger add-on installation.
|
||||
matchResult.groupValues.getOrNull(1)?.let { addonId ->
|
||||
navController?.get()?.navigate(
|
||||
NavGraphDirections.actionGlobalAddonsManagementFragment(addonId),
|
||||
NavGraphDirections.actionGlobalAddonsManagementFragment(addonId)
|
||||
)
|
||||
|
||||
// We've redirected to the add-ons management fragment, skip original request.
|
||||
|
@ -134,7 +137,7 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
|
|||
isSameDomain: Boolean,
|
||||
isRedirect: Boolean,
|
||||
isDirectNavigation: Boolean,
|
||||
isSubframeRequest: Boolean,
|
||||
isSubframeRequest: Boolean
|
||||
): RequestInterceptor.InterceptionResponse? {
|
||||
return appContext.components.services.accountsAuthFeature.interceptor.onLoadRequest(
|
||||
engineSession,
|
||||
|
@ -144,7 +147,7 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
|
|||
isSameDomain,
|
||||
isRedirect,
|
||||
isDirectNavigation,
|
||||
isSubframeRequest,
|
||||
isSubframeRequest
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -186,19 +189,16 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
|
|||
ErrorType.ERROR_NO_INTERNET,
|
||||
ErrorType.ERROR_HTTPS_ONLY,
|
||||
ErrorType.ERROR_BAD_HSTS_CERT,
|
||||
ErrorType.ERROR_UNKNOWN_PROTOCOL,
|
||||
-> RiskLevel.Low
|
||||
ErrorType.ERROR_UNKNOWN_PROTOCOL -> RiskLevel.Low
|
||||
|
||||
ErrorType.ERROR_SECURITY_BAD_CERT,
|
||||
ErrorType.ERROR_SECURITY_SSL,
|
||||
ErrorType.ERROR_PORT_BLOCKED,
|
||||
-> RiskLevel.Medium
|
||||
ErrorType.ERROR_PORT_BLOCKED -> RiskLevel.Medium
|
||||
|
||||
ErrorType.ERROR_SAFEBROWSING_HARMFUL_URI,
|
||||
ErrorType.ERROR_SAFEBROWSING_MALWARE_URI,
|
||||
ErrorType.ERROR_SAFEBROWSING_PHISHING_URI,
|
||||
ErrorType.ERROR_SAFEBROWSING_UNWANTED_URI,
|
||||
-> RiskLevel.High
|
||||
ErrorType.ERROR_SAFEBROWSING_UNWANTED_URI -> RiskLevel.High
|
||||
}
|
||||
|
||||
internal enum class RiskLevel(val htmlRes: String) {
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
package org.mozilla.fenix.components
|
||||
|
||||
import android.content.Context
|
||||
import mozilla.components.service.fxa.ServerConfig
|
||||
import mozilla.components.service.fxa.ServerConfig.Server
|
||||
import mozilla.components.service.fxa.ServerConfig
|
||||
|
||||
/**
|
||||
* Utility to configure Firefox Account stage servers.
|
||||
|
|
|
@ -24,11 +24,9 @@ import mozilla.components.service.glean.net.ConceptFetchHttpUploader
|
|||
import mozilla.components.service.glean.testing.GleanTestLocalServer
|
||||
import okhttp3.mockwebserver.RecordedRequest
|
||||
import org.json.JSONObject
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
@ -37,9 +35,9 @@ import org.mozilla.fenix.HomeActivity
|
|||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.MockWebServerHelper
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.io.BufferedReader
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.zip.GZIPInputStream
|
||||
|
||||
/**
|
||||
|
@ -71,7 +69,6 @@ fun RecordedRequest.getPlainBody(): String {
|
|||
@RunWith(AndroidJUnit4::class)
|
||||
class BaselinePingTest {
|
||||
private val server = MockWebServerHelper.createAlwaysOkMockWebServer()
|
||||
private lateinit var mDevice: UiDevice
|
||||
|
||||
@get:Rule
|
||||
val activityRule: ActivityTestRule<HomeActivity> = HomeActivityTestRule()
|
||||
|
@ -79,11 +76,6 @@ class BaselinePingTest {
|
|||
@get:Rule
|
||||
val gleanRule = GleanTestLocalServer(ApplicationProvider.getApplicationContext(), server.port)
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
}
|
||||
|
||||
companion object {
|
||||
@BeforeClass
|
||||
@JvmStatic
|
||||
|
@ -92,7 +84,7 @@ class BaselinePingTest {
|
|||
val httpClient = ConceptFetchHttpUploader(
|
||||
lazy {
|
||||
GeckoViewFetchClient(ApplicationProvider.getApplicationContext())
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Fenix does not initialize the Glean SDK in tests/debug builds, but this test
|
||||
|
@ -103,7 +95,7 @@ class BaselinePingTest {
|
|||
applicationContext = ApplicationProvider.getApplicationContext(),
|
||||
uploadEnabled = true,
|
||||
configuration = Configuration(httpClient = httpClient),
|
||||
buildInfo = GleanBuildInfo.buildInfo,
|
||||
buildInfo = GleanBuildInfo.buildInfo
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +112,7 @@ class BaselinePingTest {
|
|||
private fun waitForPingContent(
|
||||
pingName: String,
|
||||
pingReason: String?,
|
||||
maxAttempts: Int = 3,
|
||||
maxAttempts: Int = 3
|
||||
): JSONObject? {
|
||||
var attempts = 0
|
||||
do {
|
||||
|
@ -144,29 +136,29 @@ class BaselinePingTest {
|
|||
return null
|
||||
}
|
||||
|
||||
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807288")
|
||||
@Test
|
||||
fun validateBaselinePing() {
|
||||
// Wait for the app to be idle/ready.
|
||||
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
|
||||
mDevice.waitForIdle()
|
||||
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
device.waitForIdle()
|
||||
|
||||
// Wait for 1 second: this should guarantee we have some valid duration in the
|
||||
// ping.
|
||||
Thread.sleep(1000)
|
||||
|
||||
// Move it to background.
|
||||
mDevice.pressHome()
|
||||
device.pressHome()
|
||||
|
||||
// Due to bug 1632184, we need move the activity to foreground again, in order
|
||||
// for a 'background' ping with reason 'foreground' to be generated and also trigger
|
||||
// sending the ping that was submitted on background. This can go away once bug 1634375
|
||||
// is fixed.
|
||||
mDevice.pressRecentApps()
|
||||
mDevice.findObject(
|
||||
device.pressRecentApps()
|
||||
device.findObject(
|
||||
UiSelector().descriptionContains(
|
||||
ApplicationProvider.getApplicationContext<Context>().getString(R.string.app_name),
|
||||
),
|
||||
ApplicationProvider.getApplicationContext<Context>().getString(R.string.app_name)
|
||||
)
|
||||
)
|
||||
.click()
|
||||
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
package org.mozilla.fenix.helpers
|
||||
|
||||
import android.graphics.Bitmap
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import android.graphics.Color
|
||||
import org.junit.Assert.assertEquals
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
package org.mozilla.fenix.helpers
|
||||
|
||||
import org.mozilla.fenix.helpers.TestHelper.getSponsoredShortcutTitle
|
||||
|
||||
object Constants {
|
||||
|
||||
// Device or AVD requires a Google Services Android OS installation
|
||||
|
@ -16,32 +14,10 @@ object Constants {
|
|||
const val YOUTUBE_APP = "com.google.android.youtube"
|
||||
const val GMAIL_APP = "com.google.android.gm"
|
||||
const val PHONE_APP = "com.android.dialer"
|
||||
const val ANDROID_SETTINGS = "com.android.settings"
|
||||
}
|
||||
|
||||
const val SPEECH_RECOGNITION = "android.speech.action.RECOGNIZE_SPEECH"
|
||||
const val POCKET_RECOMMENDED_STORIES_UTM_PARAM = "utm_source=pocket-newtab-android"
|
||||
const val LONG_CLICK_DURATION: Long = 5000
|
||||
const val LISTS_MAXSWIPES: Int = 3
|
||||
const val RETRY_COUNT = 3
|
||||
|
||||
val searchEngineCodes = mapOf(
|
||||
"Google" to "client=firefox-b-m",
|
||||
"Bing" to "firefox&pc=MOZB&form=MOZMBA",
|
||||
"DuckDuckGo" to "t=fpas",
|
||||
)
|
||||
|
||||
val firstSponsoredShortcutTitle by lazy { getSponsoredShortcutTitle(2) }
|
||||
val secondSponsoredShortcutTitle by lazy { getSponsoredShortcutTitle(3) }
|
||||
|
||||
// Expected for en-us defaults
|
||||
val defaultTopSitesList by lazy {
|
||||
mapOf(
|
||||
"Google" to "Google",
|
||||
"First sponsored shortcut" to firstSponsoredShortcutTitle,
|
||||
"Second sponsored shortcut" to secondSponsoredShortcutTitle,
|
||||
"Top Articles" to "Top Articles",
|
||||
"Wikipedia" to "Wikipedia",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.helpers
|
||||
|
||||
import org.mozilla.experiments.nimbus.GleanPlumbMessageHelper
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
|
||||
object Experimentation {
|
||||
val experiments =
|
||||
appContext.components.analytics.experiments
|
||||
|
||||
fun withHelper(block: GleanPlumbMessageHelper.() -> Unit) {
|
||||
val helper = experiments.createMessageHelper()
|
||||
block(helper)
|
||||
}
|
||||
}
|
|
@ -4,84 +4,57 @@
|
|||
|
||||
package org.mozilla.fenix.helpers
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import org.mozilla.fenix.ext.settings
|
||||
|
||||
/**
|
||||
* Helper for querying the status and modifying various features and settings in the application.
|
||||
*/
|
||||
interface FeatureSettingsHelper {
|
||||
/**
|
||||
* Whether the onboarding for existing users should be shown or not.
|
||||
* It should appear only once on the first visit to homescreen.
|
||||
*/
|
||||
var isHomeOnboardingDialogEnabled: Boolean
|
||||
class FeatureSettingsHelper {
|
||||
private val context: Context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
private val settings = context.settings()
|
||||
|
||||
/**
|
||||
* Whether the Pocket stories feature is enabled or not.
|
||||
*/
|
||||
var isPocketEnabled: Boolean
|
||||
// saving default values of feature flags
|
||||
private var isPocketEnabled: Boolean = settings.showPocketRecommendationsFeature
|
||||
private var isJumpBackInCFREnabled: Boolean = settings.shouldShowJumpBackInCFR
|
||||
private var isRecentTabsFeatureEnabled: Boolean = settings.showRecentTabsFeature
|
||||
private var isRecentlyVisitedFeatureEnabled: Boolean = settings.historyMetadataUIFeature
|
||||
private var isUserKnowsAboutPwasTrue: Boolean = settings.userKnowsAboutPwas
|
||||
|
||||
/**
|
||||
* Whether the "Jump back in" CFR should be shown or not.
|
||||
* It should appear on the first visit to homescreen given that there is a tab opened.
|
||||
*/
|
||||
var isJumpBackInCFREnabled: Boolean
|
||||
fun setPocketEnabled(enabled: Boolean) {
|
||||
settings.showPocketRecommendationsFeature = enabled
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the onboarding dialog for choosing wallpapers should be shown or not.
|
||||
*/
|
||||
var isWallpaperOnboardingEnabled: Boolean
|
||||
fun setJumpBackCFREnabled(enabled: Boolean) {
|
||||
settings.shouldShowJumpBackInCFR = enabled
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the "Jump back in" homescreen section is enabled or not.
|
||||
* It shows the last visited tab on this device and on other synced devices.
|
||||
*/
|
||||
var isRecentTabsFeatureEnabled: Boolean
|
||||
fun setRecentTabsFeatureEnabled(enabled: Boolean) {
|
||||
settings.showRecentTabsFeature = enabled
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the "Recently visited" homescreen section is enabled or not.
|
||||
* It can show up to 9 history highlights and history groups.
|
||||
*/
|
||||
var isRecentlyVisitedFeatureEnabled: Boolean
|
||||
fun setRecentlyVisitedFeatureEnabled(enabled: Boolean) {
|
||||
settings.historyMetadataUIFeature = enabled
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the onboarding dialog for PWAs should be shown or not.
|
||||
* It can show the first time a website that can be installed as a PWA is accessed.
|
||||
*/
|
||||
var isPWAsPromptEnabled: Boolean
|
||||
fun setStrictETPEnabled() {
|
||||
settings.setStrictETP()
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the "Site permissions" option is checked in the "Delete browsing data" screen or not.
|
||||
*/
|
||||
var isDeleteSitePermissionsEnabled: Boolean
|
||||
fun disablePwaCFR(disable: Boolean) {
|
||||
settings.userKnowsAboutPwas = disable
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable showing the TCP CFR when accessing a webpage for the first time.
|
||||
*/
|
||||
var isTCPCFREnabled: Boolean
|
||||
fun deleteSitePermissions(delete: Boolean) {
|
||||
settings.deleteSitePermissions = delete
|
||||
}
|
||||
|
||||
/**
|
||||
* The current "Enhanced Tracking Protection" policy.
|
||||
* @see ETPPolicy
|
||||
*/
|
||||
var etpPolicy: ETPPolicy
|
||||
|
||||
fun applyFlagUpdates()
|
||||
|
||||
fun resetAllFeatureFlags()
|
||||
|
||||
companion object {
|
||||
val settings = InstrumentationRegistry.getInstrumentation().targetContext.settings()
|
||||
// Important:
|
||||
// Use this after each test if you have modified these feature settings
|
||||
// to make sure the app goes back to the default state
|
||||
fun resetAllFeatureFlags() {
|
||||
settings.showPocketRecommendationsFeature = isPocketEnabled
|
||||
settings.shouldShowJumpBackInCFR = isJumpBackInCFREnabled
|
||||
settings.showRecentTabsFeature = isRecentTabsFeatureEnabled
|
||||
settings.historyMetadataUIFeature = isRecentlyVisitedFeatureEnabled
|
||||
settings.userKnowsAboutPwas = isUserKnowsAboutPwasTrue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* All "Enhanced Tracking Protection" modes.
|
||||
*/
|
||||
enum class ETPPolicy {
|
||||
STANDARD,
|
||||
STRICT,
|
||||
CUSTOM,
|
||||
;
|
||||
}
|
||||
|
|
|
@ -1,159 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.helpers
|
||||
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.getPreferenceKey
|
||||
import org.mozilla.fenix.helpers.ETPPolicy.CUSTOM
|
||||
import org.mozilla.fenix.helpers.ETPPolicy.STANDARD
|
||||
import org.mozilla.fenix.helpers.ETPPolicy.STRICT
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper.Companion.settings
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
import org.mozilla.fenix.onboarding.FenixOnboarding
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
/**
|
||||
* Helper for querying the status and modifying various features and settings in the application.
|
||||
*/
|
||||
class FeatureSettingsHelperDelegate : FeatureSettingsHelper {
|
||||
/**
|
||||
* The current feature flags used inside the app before the tests start.
|
||||
* These will be restored when the tests end.
|
||||
*/
|
||||
private val initialFeatureFlags = FeatureFlags(
|
||||
isHomeOnboardingDialogEnabled = settings.showHomeOnboardingDialog,
|
||||
homeOnboardingDialogVersion = getHomeOnboardingVersion(),
|
||||
isPocketEnabled = settings.showPocketRecommendationsFeature,
|
||||
isJumpBackInCFREnabled = settings.shouldShowJumpBackInCFR,
|
||||
isRecentTabsFeatureEnabled = settings.showRecentTabsFeature,
|
||||
isRecentlyVisitedFeatureEnabled = settings.historyMetadataUIFeature,
|
||||
isPWAsPromptEnabled = !settings.userKnowsAboutPwas,
|
||||
isTCPCFREnabled = settings.shouldShowTotalCookieProtectionCFR,
|
||||
isWallpaperOnboardingEnabled = settings.showWallpaperOnboarding,
|
||||
isDeleteSitePermissionsEnabled = settings.deleteSitePermissions,
|
||||
etpPolicy = getETPPolicy(settings),
|
||||
)
|
||||
|
||||
/**
|
||||
* The current feature flags updated in tests.
|
||||
*/
|
||||
private var updatedFeatureFlags = initialFeatureFlags.copy()
|
||||
|
||||
override var isHomeOnboardingDialogEnabled: Boolean
|
||||
get() = updatedFeatureFlags.isHomeOnboardingDialogEnabled &&
|
||||
FenixOnboarding(appContext).userHasBeenOnboarded()
|
||||
set(value) {
|
||||
updatedFeatureFlags.isHomeOnboardingDialogEnabled = value
|
||||
updatedFeatureFlags.homeOnboardingDialogVersion = when (value) {
|
||||
true -> FenixOnboarding.CURRENT_ONBOARDING_VERSION
|
||||
false -> 0
|
||||
}
|
||||
}
|
||||
override var isPocketEnabled: Boolean by updatedFeatureFlags::isPocketEnabled
|
||||
override var isJumpBackInCFREnabled: Boolean by updatedFeatureFlags::isJumpBackInCFREnabled
|
||||
override var isWallpaperOnboardingEnabled: Boolean by updatedFeatureFlags::isWallpaperOnboardingEnabled
|
||||
override var isRecentTabsFeatureEnabled: Boolean by updatedFeatureFlags::isRecentTabsFeatureEnabled
|
||||
override var isRecentlyVisitedFeatureEnabled: Boolean by updatedFeatureFlags::isRecentlyVisitedFeatureEnabled
|
||||
override var isPWAsPromptEnabled: Boolean by updatedFeatureFlags::isPWAsPromptEnabled
|
||||
override var isTCPCFREnabled: Boolean by updatedFeatureFlags::isTCPCFREnabled
|
||||
override var etpPolicy: ETPPolicy by updatedFeatureFlags::etpPolicy
|
||||
|
||||
override fun applyFlagUpdates() {
|
||||
applyFeatureFlags(updatedFeatureFlags)
|
||||
}
|
||||
|
||||
override fun resetAllFeatureFlags() {
|
||||
applyFeatureFlags(initialFeatureFlags)
|
||||
}
|
||||
override var isDeleteSitePermissionsEnabled: Boolean by updatedFeatureFlags::isDeleteSitePermissionsEnabled
|
||||
|
||||
private fun applyFeatureFlags(featureFlags: FeatureFlags) {
|
||||
settings.showHomeOnboardingDialog = featureFlags.isHomeOnboardingDialogEnabled
|
||||
setHomeOnboardingVersion(featureFlags.homeOnboardingDialogVersion)
|
||||
settings.showPocketRecommendationsFeature = featureFlags.isPocketEnabled
|
||||
settings.shouldShowJumpBackInCFR = featureFlags.isJumpBackInCFREnabled
|
||||
settings.showRecentTabsFeature = featureFlags.isRecentTabsFeatureEnabled
|
||||
settings.historyMetadataUIFeature = featureFlags.isRecentlyVisitedFeatureEnabled
|
||||
settings.userKnowsAboutPwas = !featureFlags.isPWAsPromptEnabled
|
||||
settings.shouldShowTotalCookieProtectionCFR = featureFlags.isTCPCFREnabled
|
||||
settings.showWallpaperOnboarding = featureFlags.isWallpaperOnboardingEnabled
|
||||
settings.deleteSitePermissions = featureFlags.isDeleteSitePermissionsEnabled
|
||||
setETPPolicy(featureFlags.etpPolicy)
|
||||
}
|
||||
}
|
||||
|
||||
private data class FeatureFlags(
|
||||
var isHomeOnboardingDialogEnabled: Boolean,
|
||||
var homeOnboardingDialogVersion: Int,
|
||||
var isPocketEnabled: Boolean,
|
||||
var isJumpBackInCFREnabled: Boolean,
|
||||
var isRecentTabsFeatureEnabled: Boolean,
|
||||
var isRecentlyVisitedFeatureEnabled: Boolean,
|
||||
var isPWAsPromptEnabled: Boolean,
|
||||
var isTCPCFREnabled: Boolean,
|
||||
var isWallpaperOnboardingEnabled: Boolean,
|
||||
var isDeleteSitePermissionsEnabled: Boolean,
|
||||
var etpPolicy: ETPPolicy,
|
||||
)
|
||||
|
||||
internal fun getETPPolicy(settings: Settings): ETPPolicy {
|
||||
return when {
|
||||
settings.useStrictTrackingProtection -> STRICT
|
||||
settings.useCustomTrackingProtection -> CUSTOM
|
||||
else -> STANDARD
|
||||
}
|
||||
}
|
||||
|
||||
private fun setETPPolicy(policy: ETPPolicy) {
|
||||
when (policy) {
|
||||
STRICT -> settings.setStrictETP()
|
||||
// The following two cases update ETP in the same way "setStrictETP" does.
|
||||
STANDARD -> {
|
||||
settings.preferences.edit()
|
||||
.putBoolean(
|
||||
appContext.getPreferenceKey(R.string.pref_key_tracking_protection_strict_default),
|
||||
false,
|
||||
)
|
||||
.putBoolean(
|
||||
appContext.getPreferenceKey(R.string.pref_key_tracking_protection_custom_option),
|
||||
false,
|
||||
)
|
||||
.putBoolean(
|
||||
appContext.getPreferenceKey(R.string.pref_key_tracking_protection_standard_option),
|
||||
true,
|
||||
)
|
||||
.commit()
|
||||
}
|
||||
CUSTOM -> {
|
||||
settings.preferences.edit()
|
||||
.putBoolean(
|
||||
appContext.getPreferenceKey(R.string.pref_key_tracking_protection_strict_default),
|
||||
false,
|
||||
)
|
||||
.putBoolean(
|
||||
appContext.getPreferenceKey(R.string.pref_key_tracking_protection_standard_option),
|
||||
true,
|
||||
)
|
||||
.putBoolean(
|
||||
appContext.getPreferenceKey(R.string.pref_key_tracking_protection_custom_option),
|
||||
true,
|
||||
)
|
||||
.commit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getHomeOnboardingVersion(): Int {
|
||||
return FenixOnboarding(appContext)
|
||||
.preferences
|
||||
.getInt(FenixOnboarding.LAST_VERSION_ONBOARDING_KEY, 0)
|
||||
}
|
||||
|
||||
private fun setHomeOnboardingVersion(version: Int) {
|
||||
FenixOnboarding(appContext)
|
||||
.preferences.edit()
|
||||
.putInt(FenixOnboarding.LAST_VERSION_ONBOARDING_KEY, version)
|
||||
.commit()
|
||||
}
|
|
@ -6,15 +6,14 @@
|
|||
|
||||
package org.mozilla.fenix.helpers
|
||||
|
||||
import android.content.Intent
|
||||
import android.view.ViewConfiguration.getLongPressTimeout
|
||||
import androidx.test.espresso.intent.rule.IntentsTestRule
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.UiSelector
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper.Companion.settings
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.onboarding.FenixOnboarding
|
||||
|
||||
/**
|
||||
|
@ -27,92 +26,22 @@ import org.mozilla.fenix.onboarding.FenixOnboarding
|
|||
class HomeActivityTestRule(
|
||||
initialTouchMode: Boolean = false,
|
||||
launchActivity: Boolean = true,
|
||||
private val skipOnboarding: Boolean = false,
|
||||
) : ActivityTestRule<HomeActivity>(HomeActivity::class.java, initialTouchMode, launchActivity),
|
||||
FeatureSettingsHelper by FeatureSettingsHelperDelegate() {
|
||||
|
||||
// Using a secondary constructor allows us to easily delegate the settings to FeatureSettingsHelperDelegate.
|
||||
// Otherwise if wanting to use the same names we would have to override these settings in the primary
|
||||
// constructor and in that elide the FeatureSettingsHelperDelegate.
|
||||
constructor(
|
||||
initialTouchMode: Boolean = false,
|
||||
launchActivity: Boolean = true,
|
||||
skipOnboarding: Boolean = false,
|
||||
isHomeOnboardingDialogEnabled: Boolean = settings.showHomeOnboardingDialog &&
|
||||
FenixOnboarding(appContext).userHasBeenOnboarded(),
|
||||
isPocketEnabled: Boolean = settings.showPocketRecommendationsFeature,
|
||||
isJumpBackInCFREnabled: Boolean = settings.shouldShowJumpBackInCFR,
|
||||
isRecentTabsFeatureEnabled: Boolean = settings.showRecentTabsFeature,
|
||||
isRecentlyVisitedFeatureEnabled: Boolean = settings.historyMetadataUIFeature,
|
||||
isPWAsPromptEnabled: Boolean = !settings.userKnowsAboutPwas,
|
||||
isTCPCFREnabled: Boolean = settings.shouldShowTotalCookieProtectionCFR,
|
||||
isWallpaperOnboardingEnabled: Boolean = settings.showWallpaperOnboarding,
|
||||
isDeleteSitePermissionsEnabled: Boolean = settings.deleteSitePermissions,
|
||||
etpPolicy: ETPPolicy = getETPPolicy(settings),
|
||||
) : this(initialTouchMode, launchActivity, skipOnboarding) {
|
||||
this.isHomeOnboardingDialogEnabled = isHomeOnboardingDialogEnabled
|
||||
this.isPocketEnabled = isPocketEnabled
|
||||
this.isJumpBackInCFREnabled = isJumpBackInCFREnabled
|
||||
this.isRecentTabsFeatureEnabled = isRecentTabsFeatureEnabled
|
||||
this.isRecentlyVisitedFeatureEnabled = isRecentlyVisitedFeatureEnabled
|
||||
this.isPWAsPromptEnabled = isPWAsPromptEnabled
|
||||
this.isTCPCFREnabled = isTCPCFREnabled
|
||||
this.isWallpaperOnboardingEnabled = isWallpaperOnboardingEnabled
|
||||
this.isDeleteSitePermissionsEnabled = isDeleteSitePermissionsEnabled
|
||||
this.etpPolicy = etpPolicy
|
||||
}
|
||||
|
||||
/**
|
||||
* Update settings after the activity was created.
|
||||
*/
|
||||
fun applySettingsExceptions(settings: (FeatureSettingsHelper) -> Unit) {
|
||||
FeatureSettingsHelperDelegate().also {
|
||||
settings(it)
|
||||
applyFlagUpdates()
|
||||
}
|
||||
}
|
||||
|
||||
private val skipOnboarding: Boolean = false
|
||||
) :
|
||||
ActivityTestRule<HomeActivity>(HomeActivity::class.java, initialTouchMode, launchActivity) {
|
||||
private val longTapUserPreference = getLongPressTimeout()
|
||||
|
||||
override fun beforeActivityLaunched() {
|
||||
super.beforeActivityLaunched()
|
||||
setLongTapTimeout(3000)
|
||||
applyFlagUpdates()
|
||||
if (skipOnboarding) { skipOnboardingBeforeLaunch() }
|
||||
}
|
||||
|
||||
override fun afterActivityFinished() {
|
||||
super.afterActivityFinished()
|
||||
setLongTapTimeout(longTapUserPreference)
|
||||
resetAllFeatureFlags()
|
||||
closeNotificationShade()
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Create a new instance of [HomeActivityTestRule] which by default will disable specific
|
||||
* app features that would otherwise negatively impact most tests.
|
||||
*
|
||||
* The disabled features are:
|
||||
* - the Jump back in CFR,
|
||||
* - the Total Cookie Protection CFR,
|
||||
* - the PWA prompt dialog,
|
||||
* - the wallpaper onboarding.
|
||||
*/
|
||||
fun withDefaultSettingsOverrides(
|
||||
initialTouchMode: Boolean = false,
|
||||
launchActivity: Boolean = true,
|
||||
skipOnboarding: Boolean = false,
|
||||
) = HomeActivityTestRule(
|
||||
initialTouchMode = initialTouchMode,
|
||||
launchActivity = launchActivity,
|
||||
skipOnboarding = skipOnboarding,
|
||||
isJumpBackInCFREnabled = false,
|
||||
isPWAsPromptEnabled = false,
|
||||
isTCPCFREnabled = false,
|
||||
isWallpaperOnboardingEnabled = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,74 +52,17 @@ class HomeActivityTestRule(
|
|||
* @param launchActivity See [IntentsTestRule]
|
||||
*/
|
||||
|
||||
class HomeActivityIntentTestRule internal constructor(
|
||||
class HomeActivityIntentTestRule(
|
||||
initialTouchMode: Boolean = false,
|
||||
launchActivity: Boolean = true,
|
||||
private val skipOnboarding: Boolean = false,
|
||||
) : IntentsTestRule<HomeActivity>(HomeActivity::class.java, initialTouchMode, launchActivity),
|
||||
FeatureSettingsHelper by FeatureSettingsHelperDelegate() {
|
||||
// Using a secondary constructor allows us to easily delegate the settings to FeatureSettingsHelperDelegate.
|
||||
// Otherwise if wanting to use the same names we would have to override these settings in the primary
|
||||
// constructor and in that elide the FeatureSettingsHelperDelegate.
|
||||
constructor(
|
||||
initialTouchMode: Boolean = false,
|
||||
launchActivity: Boolean = true,
|
||||
skipOnboarding: Boolean = false,
|
||||
isHomeOnboardingDialogEnabled: Boolean = settings.showHomeOnboardingDialog &&
|
||||
FenixOnboarding(appContext).userHasBeenOnboarded(),
|
||||
isPocketEnabled: Boolean = settings.showPocketRecommendationsFeature,
|
||||
isJumpBackInCFREnabled: Boolean = settings.shouldShowJumpBackInCFR,
|
||||
isRecentTabsFeatureEnabled: Boolean = settings.showRecentTabsFeature,
|
||||
isRecentlyVisitedFeatureEnabled: Boolean = settings.historyMetadataUIFeature,
|
||||
isPWAsPromptEnabled: Boolean = !settings.userKnowsAboutPwas,
|
||||
isTCPCFREnabled: Boolean = settings.shouldShowTotalCookieProtectionCFR,
|
||||
isWallpaperOnboardingEnabled: Boolean = settings.showWallpaperOnboarding,
|
||||
isDeleteSitePermissionsEnabled: Boolean = settings.deleteSitePermissions,
|
||||
etpPolicy: ETPPolicy = getETPPolicy(settings),
|
||||
) : this(initialTouchMode, launchActivity, skipOnboarding) {
|
||||
this.isHomeOnboardingDialogEnabled = isHomeOnboardingDialogEnabled
|
||||
this.isPocketEnabled = isPocketEnabled
|
||||
this.isJumpBackInCFREnabled = isJumpBackInCFREnabled
|
||||
this.isRecentTabsFeatureEnabled = isRecentTabsFeatureEnabled
|
||||
this.isRecentlyVisitedFeatureEnabled = isRecentlyVisitedFeatureEnabled
|
||||
this.isPWAsPromptEnabled = isPWAsPromptEnabled
|
||||
this.isTCPCFREnabled = isTCPCFREnabled
|
||||
this.isWallpaperOnboardingEnabled = isWallpaperOnboardingEnabled
|
||||
this.isDeleteSitePermissionsEnabled = isDeleteSitePermissionsEnabled
|
||||
this.etpPolicy = etpPolicy
|
||||
}
|
||||
|
||||
private val skipOnboarding: Boolean = false
|
||||
) :
|
||||
IntentsTestRule<HomeActivity>(HomeActivity::class.java, initialTouchMode, launchActivity) {
|
||||
private val longTapUserPreference = getLongPressTimeout()
|
||||
|
||||
private lateinit var intent: Intent
|
||||
|
||||
/**
|
||||
* Update settings after the activity was created.
|
||||
*/
|
||||
fun applySettingsExceptions(settings: (FeatureSettingsHelper) -> Unit) {
|
||||
FeatureSettingsHelperDelegate().apply {
|
||||
settings(this)
|
||||
applyFlagUpdates()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getActivityIntent(): Intent? {
|
||||
return if (this::intent.isInitialized) {
|
||||
this.intent
|
||||
} else {
|
||||
super.getActivityIntent()
|
||||
}
|
||||
}
|
||||
|
||||
fun withIntent(intent: Intent): HomeActivityIntentTestRule {
|
||||
this.intent = intent
|
||||
return this
|
||||
}
|
||||
|
||||
override fun beforeActivityLaunched() {
|
||||
super.beforeActivityLaunched()
|
||||
setLongTapTimeout(3000)
|
||||
applyFlagUpdates()
|
||||
if (skipOnboarding) { skipOnboardingBeforeLaunch() }
|
||||
}
|
||||
|
||||
|
@ -198,53 +70,6 @@ class HomeActivityIntentTestRule internal constructor(
|
|||
super.afterActivityFinished()
|
||||
setLongTapTimeout(longTapUserPreference)
|
||||
closeNotificationShade()
|
||||
resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the settings values from when this rule was first instantiated to account for any changes
|
||||
* done while running the tests.
|
||||
* Useful in the scenario about the activity being restarted which would otherwise set the initial
|
||||
* settings and override any changes made in the meantime.
|
||||
*/
|
||||
fun updateCachedSettings() {
|
||||
isHomeOnboardingDialogEnabled =
|
||||
settings.showHomeOnboardingDialog && FenixOnboarding(appContext).userHasBeenOnboarded()
|
||||
isPocketEnabled = settings.showPocketRecommendationsFeature
|
||||
isJumpBackInCFREnabled = settings.shouldShowJumpBackInCFR
|
||||
isRecentTabsFeatureEnabled = settings.showRecentTabsFeature
|
||||
isRecentlyVisitedFeatureEnabled = settings.historyMetadataUIFeature
|
||||
isPWAsPromptEnabled = !settings.userKnowsAboutPwas
|
||||
isTCPCFREnabled = settings.shouldShowTotalCookieProtectionCFR
|
||||
isWallpaperOnboardingEnabled = settings.showWallpaperOnboarding
|
||||
isDeleteSitePermissionsEnabled = settings.deleteSitePermissions
|
||||
etpPolicy = getETPPolicy(settings)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Create a new instance of [HomeActivityIntentTestRule] which by default will disable specific
|
||||
* app features that would otherwise negatively impact most tests.
|
||||
*
|
||||
* The disabled features are:
|
||||
* - the Jump back in CFR,
|
||||
* - the Total Cookie Protection CFR,
|
||||
* - the PWA prompt dialog,
|
||||
* - the wallpaper onboarding.
|
||||
*/
|
||||
fun withDefaultSettingsOverrides(
|
||||
initialTouchMode: Boolean = false,
|
||||
launchActivity: Boolean = true,
|
||||
skipOnboarding: Boolean = false,
|
||||
) = HomeActivityIntentTestRule(
|
||||
initialTouchMode = initialTouchMode,
|
||||
launchActivity = launchActivity,
|
||||
skipOnboarding = skipOnboarding,
|
||||
isJumpBackInCFREnabled = false,
|
||||
isPWAsPromptEnabled = false,
|
||||
isTCPCFREnabled = false,
|
||||
isWallpaperOnboardingEnabled = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,6 +79,7 @@ fun setLongTapTimeout(delay: Int) {
|
|||
var attempts = 0
|
||||
while (attempts++ < 3) {
|
||||
try {
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mDevice.executeShellCommand("settings put secure long_press_timeout $delay")
|
||||
break
|
||||
} catch (e: RuntimeException) {
|
||||
|
@ -269,8 +95,9 @@ private fun skipOnboardingBeforeLaunch() {
|
|||
}
|
||||
|
||||
private fun closeNotificationShade() {
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
if (mDevice.findObject(
|
||||
UiSelector().resourceId("com.android.systemui:id/notification_stack_scroller"),
|
||||
UiSelector().resourceId("com.android.systemui:id/notification_stack_scroller")
|
||||
).exists()
|
||||
) {
|
||||
mDevice.pressHome()
|
||||
|
|
|
@ -17,16 +17,16 @@ object IdlingResourceHelper {
|
|||
fun registerAddonInstallingIdlingResource(activityTestRule: ActivityTestRule<HomeActivity>) {
|
||||
IdlingRegistry.getInstance().register(
|
||||
AddonsInstallingIdlingResource(
|
||||
activityTestRule.activity.supportFragmentManager,
|
||||
),
|
||||
activityTestRule.activity.supportFragmentManager
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun unregisterAddonInstallingIdlingResource(activityTestRule: ActivityTestRule<HomeActivity>) {
|
||||
IdlingRegistry.getInstance().unregister(
|
||||
AddonsInstallingIdlingResource(
|
||||
activityTestRule.activity.supportFragmentManager,
|
||||
),
|
||||
activityTestRule.activity.supportFragmentManager
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.helpers
|
||||
|
||||
import androidx.test.uiautomator.UiObject
|
||||
import androidx.test.uiautomator.UiSelector
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
|
||||
/**
|
||||
* Helper for querying and interacting with items based on their matchers.
|
||||
*/
|
||||
object MatcherHelper {
|
||||
|
||||
fun itemWithResId(resourceId: String) =
|
||||
mDevice.findObject(UiSelector().resourceId(resourceId))
|
||||
|
||||
fun itemContainingText(itemText: String) =
|
||||
mDevice.findObject(UiSelector().textContains(itemText))
|
||||
|
||||
fun itemWithDescription(description: String) =
|
||||
mDevice.findObject(UiSelector().descriptionContains(description))
|
||||
|
||||
fun checkedItemWithResId(resourceId: String, isChecked: Boolean) =
|
||||
mDevice.findObject(UiSelector().resourceId(resourceId).checked(isChecked))
|
||||
|
||||
fun checkedItemWithResIdAndText(resourceId: String, text: String, isChecked: Boolean) =
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.resourceId(resourceId)
|
||||
.textContains(text)
|
||||
.checked(isChecked),
|
||||
)
|
||||
|
||||
fun itemWithResIdAndDescription(resourceId: String, description: String) =
|
||||
mDevice.findObject(UiSelector().resourceId(resourceId).descriptionContains(description))
|
||||
|
||||
fun itemWithResIdAndText(resourceId: String, text: String) =
|
||||
mDevice.findObject(UiSelector().resourceId(resourceId).text(text))
|
||||
|
||||
fun assertItemWithResIdExists(vararg appItems: UiObject) {
|
||||
for (appItem in appItems) {
|
||||
assertTrue(appItem.waitForExists(waitingTime))
|
||||
}
|
||||
}
|
||||
|
||||
fun assertItemContainingTextExists(vararg appItems: UiObject) {
|
||||
for (appItem in appItems) {
|
||||
assertTrue(appItem.waitForExists(waitingTime))
|
||||
}
|
||||
}
|
||||
|
||||
fun assertItemWithDescriptionExists(vararg appItems: UiObject) {
|
||||
for (appItem in appItems) {
|
||||
assertTrue(appItem.waitForExists(waitingTime))
|
||||
}
|
||||
}
|
||||
|
||||
fun assertCheckedItemWithResIdExists(vararg appItems: UiObject) {
|
||||
for (appItem in appItems) {
|
||||
assertTrue(appItem.waitForExists(waitingTime))
|
||||
}
|
||||
}
|
||||
|
||||
fun assertCheckedItemWithResIdAndTextExists(vararg appItems: UiObject) {
|
||||
for (appItem in appItems) {
|
||||
assertTrue(appItem.waitForExists(waitingTime))
|
||||
}
|
||||
}
|
||||
|
||||
fun assertItemWithResIdAndDescriptionExists(vararg appItems: UiObject) {
|
||||
for (appItem in appItems) {
|
||||
assertTrue(appItem.waitForExists(waitingTime))
|
||||
}
|
||||
}
|
||||
|
||||
fun assertItemWithResIdAndTextExists(vararg appItems: UiObject) {
|
||||
for (appItem in appItems) {
|
||||
assertTrue(appItem.waitForExists(waitingTime))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -44,7 +44,7 @@ fun withBitmapDrawable(bitmap: Bitmap, name: String): Matcher<View>? = BitmapDra
|
|||
|
||||
fun nthChildOf(
|
||||
parentMatcher: Matcher<View>,
|
||||
childPosition: Int,
|
||||
childPosition: Int
|
||||
): Matcher<View> {
|
||||
return object : TypeSafeMatcher<View>() {
|
||||
override fun describeTo(description: Description) {
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.helpers
|
||||
|
||||
import android.content.Context
|
||||
import android.location.Location
|
||||
import android.location.LocationManager
|
||||
import android.os.Build
|
||||
import android.os.SystemClock
|
||||
import android.util.Log
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import org.junit.rules.ExternalResource
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import java.util.Date
|
||||
import kotlin.random.Random
|
||||
|
||||
private const val mockProviderName = LocationManager.GPS_PROVIDER
|
||||
|
||||
/**
|
||||
* Rule that sets up a mock location provider that can inject location samples
|
||||
* straight to the device that the test is running on.
|
||||
*
|
||||
* Credit to the mapbox team
|
||||
* https://github.com/mapbox/mapbox-navigation-android/blob/87fab7ea1152b29533ee121eaf6c05bc202adf02/libtesting-ui/src/main/java/com/mapbox/navigation/testing/ui/MockLocationUpdatesRule.kt
|
||||
*
|
||||
*/
|
||||
class MockLocationUpdatesRule : ExternalResource() {
|
||||
private val appContext = (ApplicationProvider.getApplicationContext() as Context)
|
||||
val latitude = Random.nextDouble(-90.0, 90.0)
|
||||
val longitude = Random.nextDouble(-180.0, 180.0)
|
||||
|
||||
private val locationManager: LocationManager by lazy {
|
||||
(appContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager)
|
||||
}
|
||||
|
||||
override fun before() {
|
||||
/* ADB command to enable the mock location setting on the device.
|
||||
* Will not be turned back off due to limitations on knowing its initial state.
|
||||
*/
|
||||
mDevice.executeShellCommand(
|
||||
"appops set " +
|
||||
appContext.packageName +
|
||||
" android:mock_location allow",
|
||||
)
|
||||
|
||||
// To mock locations we need a location provider, so we generate and set it here.
|
||||
try {
|
||||
locationManager.addTestProvider(
|
||||
mockProviderName,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
3,
|
||||
2,
|
||||
)
|
||||
} catch (ex: Exception) {
|
||||
// unstable
|
||||
Log.w("MockLocationUpdatesRule", "addTestProvider failed")
|
||||
}
|
||||
locationManager.setTestProviderEnabled(mockProviderName, true)
|
||||
}
|
||||
|
||||
// Cleaning up the location provider after the test.
|
||||
override fun after() {
|
||||
locationManager.setTestProviderEnabled(mockProviderName, false)
|
||||
locationManager.removeTestProvider(mockProviderName)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a valid mock location data and set with the help of a test provider.
|
||||
*
|
||||
* @param modifyLocation optional callback for modifying the constructed location before setting it.
|
||||
*/
|
||||
fun setMockLocation(modifyLocation: (Location.() -> Unit)? = null) {
|
||||
check(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
"MockLocationUpdatesRule is supported only on Android devices " +
|
||||
"running version >= Build.VERSION_CODES.M"
|
||||
}
|
||||
|
||||
val location = Location(mockProviderName)
|
||||
location.time = Date().time
|
||||
location.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
|
||||
location.accuracy = 5f
|
||||
location.altitude = 0.0
|
||||
location.bearing = 0f
|
||||
location.speed = 5f
|
||||
location.latitude = latitude
|
||||
location.longitude = longitude
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
location.verticalAccuracyMeters = 5f
|
||||
location.bearingAccuracyDegrees = 5f
|
||||
location.speedAccuracyMetersPerSecond = 5f
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
location.elapsedRealtimeUncertaintyNanos = 0.0
|
||||
}
|
||||
|
||||
modifyLocation?.let {
|
||||
location.apply(it)
|
||||
}
|
||||
|
||||
locationManager.setTestProviderLocation(mockProviderName, location)
|
||||
}
|
||||
}
|
|
@ -8,23 +8,12 @@ import androidx.test.espresso.IdlingResourceTimeoutException
|
|||
import androidx.test.espresso.NoMatchingViewException
|
||||
import androidx.test.uiautomator.UiObjectNotFoundException
|
||||
import junit.framework.AssertionFailedError
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.Description
|
||||
import org.junit.runners.model.Statement
|
||||
import org.mozilla.fenix.components.PermissionStorage
|
||||
import org.mozilla.fenix.helpers.IdlingResourceHelper.unregisterAllIdlingResources
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
|
||||
/**
|
||||
* Rule to retry flaky tests for a given number of times, catching some of the more common exceptions.
|
||||
* The Rule doesn't clear the app state in between retries, so we are doing some cleanup here.
|
||||
* The @Before and @After methods are not called between retries.
|
||||
*
|
||||
*/
|
||||
class RetryTestRule(private val retryCount: Int = 5) : TestRule {
|
||||
// Used for clearing all permission data after each test try
|
||||
private val permissionStorage = PermissionStorage(appContext.applicationContext)
|
||||
|
||||
@Suppress("TooGenericExceptionCaught", "ComplexMethod")
|
||||
override fun apply(base: Statement, description: Description): Statement {
|
||||
|
@ -35,57 +24,36 @@ class RetryTestRule(private val retryCount: Int = 5) : TestRule {
|
|||
break
|
||||
} catch (t: AssertionError) {
|
||||
unregisterAllIdlingResources()
|
||||
runBlocking {
|
||||
permissionStorage.deleteAllSitePermissions()
|
||||
}
|
||||
if (i == retryCount) {
|
||||
throw t
|
||||
}
|
||||
} catch (t: AssertionFailedError) {
|
||||
unregisterAllIdlingResources()
|
||||
runBlocking {
|
||||
permissionStorage.deleteAllSitePermissions()
|
||||
}
|
||||
if (i == retryCount) {
|
||||
throw t
|
||||
}
|
||||
} catch (t: UiObjectNotFoundException) {
|
||||
unregisterAllIdlingResources()
|
||||
runBlocking {
|
||||
permissionStorage.deleteAllSitePermissions()
|
||||
}
|
||||
if (i == retryCount) {
|
||||
throw t
|
||||
}
|
||||
} catch (t: NoMatchingViewException) {
|
||||
unregisterAllIdlingResources()
|
||||
runBlocking {
|
||||
permissionStorage.deleteAllSitePermissions()
|
||||
}
|
||||
if (i == retryCount) {
|
||||
throw t
|
||||
}
|
||||
} catch (t: IdlingResourceTimeoutException) {
|
||||
unregisterAllIdlingResources()
|
||||
runBlocking {
|
||||
permissionStorage.deleteAllSitePermissions()
|
||||
}
|
||||
if (i == retryCount) {
|
||||
throw t
|
||||
}
|
||||
} catch (t: RuntimeException) {
|
||||
unregisterAllIdlingResources()
|
||||
runBlocking {
|
||||
permissionStorage.deleteAllSitePermissions()
|
||||
}
|
||||
if (i == retryCount) {
|
||||
throw t
|
||||
}
|
||||
} catch (t: NullPointerException) {
|
||||
unregisterAllIdlingResources()
|
||||
runBlocking {
|
||||
permissionStorage.deleteAllSitePermissions()
|
||||
}
|
||||
if (i == retryCount) {
|
||||
throw t
|
||||
}
|
||||
|
|
|
@ -7,14 +7,14 @@ package org.mozilla.fenix.helpers
|
|||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import okhttp3.mockwebserver.Dispatcher
|
||||
import okhttp3.mockwebserver.MockResponse
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import okhttp3.mockwebserver.RecordedRequest
|
||||
import okio.Buffer
|
||||
import okio.source
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
||||
/**
|
||||
* A [MockWebServer] [Dispatcher] that will return a generic search results page in the body of
|
||||
|
|
|
@ -34,7 +34,7 @@ object TestAssetHelper {
|
|||
TestAsset(
|
||||
server.url("pages/generic$it.html").toString().toUri()!!,
|
||||
"Page content: $it",
|
||||
"",
|
||||
""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -87,30 +87,6 @@ object TestAssetHelper {
|
|||
return TestAsset(url, "", "")
|
||||
}
|
||||
|
||||
fun getAddressFormAsset(server: MockWebServer): TestAsset {
|
||||
val url = server.url("pages/addressForm.html").toString().toUri()!!
|
||||
|
||||
return TestAsset(url, "", "")
|
||||
}
|
||||
|
||||
fun getCreditCardFormAsset(server: MockWebServer): TestAsset {
|
||||
val url = server.url("pages/creditCardForm.html").toString().toUri()!!
|
||||
|
||||
return TestAsset(url, "", "")
|
||||
}
|
||||
|
||||
fun getHTMLControlsFormAsset(server: MockWebServer): TestAsset {
|
||||
val url = server.url("pages/htmlControls.html").toString().toUri()!!
|
||||
|
||||
return TestAsset(url, "", "")
|
||||
}
|
||||
|
||||
fun getExternalLinksAsset(server: MockWebServer): TestAsset {
|
||||
val url = server.url("pages/externalLinks.html").toString().toUri()!!
|
||||
|
||||
return TestAsset(url, "", "")
|
||||
}
|
||||
|
||||
fun getAudioPageAsset(server: MockWebServer): TestAsset {
|
||||
val url = server.url("pages/audioMediaPage.html").toString().toUri()!!
|
||||
val title = "Audio_Test_Page"
|
||||
|
@ -126,10 +102,4 @@ object TestAssetHelper {
|
|||
|
||||
return TestAsset(url, content, title)
|
||||
}
|
||||
|
||||
fun getStorageTestAsset(server: MockWebServer, pageAsset: String): TestAsset {
|
||||
val url = server.url("pages/$pageAsset").toString().toUri()!!
|
||||
|
||||
return TestAsset(url, "", "")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,36 +2,23 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
@file:Suppress("DEPRECATION")
|
||||
|
||||
package org.mozilla.fenix.helpers
|
||||
|
||||
import android.Manifest
|
||||
import android.app.ActivityManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.storage.StorageManager
|
||||
import android.os.storage.StorageVolume
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import androidx.test.espresso.Espresso
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.IdlingRegistry
|
||||
import androidx.test.espresso.IdlingResource
|
||||
import androidx.test.espresso.action.ViewActions.longClick
|
||||
import androidx.test.espresso.assertion.ViewAssertions
|
||||
import androidx.test.espresso.intent.Intents.intended
|
||||
|
@ -42,11 +29,10 @@ import androidx.test.espresso.matcher.ViewMatchers.withId
|
|||
import androidx.test.espresso.matcher.ViewMatchers.withParent
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import androidx.test.runner.permission.PermissionRequester
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.UiObject
|
||||
import androidx.test.uiautomator.UiObjectNotFoundException
|
||||
import androidx.test.uiautomator.UiScrollable
|
||||
import androidx.test.uiautomator.UiSelector
|
||||
import androidx.test.uiautomator.Until
|
||||
|
@ -57,30 +43,23 @@ import org.hamcrest.CoreMatchers
|
|||
import org.hamcrest.CoreMatchers.allOf
|
||||
import org.hamcrest.Matcher
|
||||
import org.junit.Assert
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.mozilla.fenix.Config
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.customtabs.ExternalAppBrowserActivity
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_APPS_PHOTOS
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
|
||||
import org.mozilla.fenix.helpers.ext.waitNotNull
|
||||
import org.mozilla.fenix.helpers.idlingresource.NetworkConnectionIdlingResource
|
||||
import org.mozilla.fenix.ui.robots.BrowserRobot
|
||||
import org.mozilla.fenix.ui.robots.mDevice
|
||||
import org.mozilla.fenix.utils.IntentUtils
|
||||
import org.mozilla.gecko.util.ThreadUtils
|
||||
import java.io.File
|
||||
import java.util.Locale
|
||||
import java.util.regex.Pattern
|
||||
|
||||
object TestHelper {
|
||||
|
||||
val appContext: Context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
val appName = appContext.appName
|
||||
var mDevice: UiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
val packageName: String = appContext.packageName
|
||||
val appName = appContext.appName
|
||||
|
||||
fun scrollToElementByText(text: String): UiScrollable {
|
||||
val appView = UiScrollable(UiSelector().scrollable(true))
|
||||
|
@ -92,19 +71,18 @@ object TestHelper {
|
|||
fun longTapSelectItem(url: Uri) {
|
||||
mDevice.waitNotNull(
|
||||
Until.findObject(By.text(url.toString())),
|
||||
waitingTime,
|
||||
waitingTime
|
||||
)
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.url),
|
||||
withText(url.toString()),
|
||||
),
|
||||
withText(url.toString())
|
||||
)
|
||||
).perform(longClick())
|
||||
}
|
||||
|
||||
fun restartApp(activity: HomeActivityIntentTestRule) {
|
||||
with(activity) {
|
||||
updateCachedSettings()
|
||||
finishActivity()
|
||||
mDevice.waitForIdle()
|
||||
launchActivity(null)
|
||||
|
@ -122,16 +100,10 @@ object TestHelper {
|
|||
fun waitUntilObjectIsFound(resourceName: String) {
|
||||
mDevice.waitNotNull(
|
||||
Until.findObjects(By.res(resourceName)),
|
||||
waitingTime,
|
||||
waitingTime
|
||||
)
|
||||
}
|
||||
|
||||
fun waitUntilSnackbarGone() {
|
||||
mDevice.findObject(
|
||||
UiSelector().resourceId("$packageName:id/snackbar_layout"),
|
||||
).waitUntilGone(waitingTime)
|
||||
}
|
||||
|
||||
fun verifyUrl(urlSubstring: String, resourceName: String, resId: Int) {
|
||||
waitUntilObjectIsFound(resourceName)
|
||||
mDevice.findObject(UiSelector().text(urlSubstring)).waitForExists(waitingTime)
|
||||
|
@ -154,24 +126,25 @@ object TestHelper {
|
|||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.R)
|
||||
fun deleteDownloadedFileOnStorage(fileName: String) {
|
||||
val storageManager: StorageManager? = appContext.getSystemService(Context.STORAGE_SERVICE) as StorageManager?
|
||||
val storageVolumes = storageManager!!.storageVolumes
|
||||
val storageVolume: StorageVolume = storageVolumes[0]
|
||||
val file = File(storageVolume.directory!!.path + "/Download/" + fileName)
|
||||
// Remove test file from Google Photos (AOSP) on Firebase
|
||||
fun deleteDownloadFromStorage() {
|
||||
val deleteButton = mDevice.findObject(UiSelector().resourceId("$GOOGLE_APPS_PHOTOS:id/trash"))
|
||||
deleteButton.click()
|
||||
|
||||
// Sometimes there's a secondary confirmation
|
||||
try {
|
||||
file.delete()
|
||||
Log.d("TestLog", "File delete try 1")
|
||||
assertFalse("The file was not deleted", file.exists())
|
||||
} catch (e: AssertionError) {
|
||||
file.delete()
|
||||
Log.d("TestLog", "File delete retried")
|
||||
assertFalse("The file was not deleted", file.exists())
|
||||
val deleteConfirm = mDevice.findObject(UiSelector().text("Got it"))
|
||||
deleteConfirm.click()
|
||||
} catch (e: UiObjectNotFoundException) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
val trashIt = mDevice.findObject(UiSelector().resourceId("$GOOGLE_APPS_PHOTOS:id/move_to_trash"))
|
||||
trashIt.click()
|
||||
}
|
||||
|
||||
fun setNetworkEnabled(enabled: Boolean) {
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
val networkDisconnectedIdlingResource = NetworkConnectionIdlingResource(false)
|
||||
val networkConnectedIdlingResource = NetworkConnectionIdlingResource(true)
|
||||
|
||||
|
@ -203,7 +176,7 @@ object TestHelper {
|
|||
fun createCustomTabIntent(
|
||||
pageUrl: String,
|
||||
customMenuItemLabel: String = "",
|
||||
customActionButtonDescription: String = "",
|
||||
customActionButtonDescription: String = ""
|
||||
): Intent {
|
||||
val appContext = InstrumentationRegistry.getInstrumentation()
|
||||
.targetContext
|
||||
|
@ -214,9 +187,7 @@ object TestHelper {
|
|||
.setShareState(CustomTabsIntent.SHARE_STATE_ON)
|
||||
.setActionButton(
|
||||
createTestBitmap(),
|
||||
customActionButtonDescription,
|
||||
pendingIntent,
|
||||
true,
|
||||
customActionButtonDescription, pendingIntent, true
|
||||
)
|
||||
.build()
|
||||
customTabsIntent.intent.data = Uri.parse(pageUrl)
|
||||
|
@ -247,73 +218,23 @@ object TestHelper {
|
|||
e.printStackTrace()
|
||||
}
|
||||
} else {
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mDevice.waitNotNull(
|
||||
Until.findObject(By.text("Could not open file")),
|
||||
waitingTime,
|
||||
waitingTime
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun assertNativeAppOpens(appPackageName: String, url: String = "") {
|
||||
fun assertNativeAppOpens(appPackageName: String, url: String) {
|
||||
if (isPackageInstalled(appPackageName)) {
|
||||
mDevice.waitForIdle(waitingTimeShort)
|
||||
assertTrue(
|
||||
mDevice.findObject(UiSelector().packageName(appPackageName))
|
||||
.waitForExists(waitingTime),
|
||||
)
|
||||
intended(toPackage(appPackageName))
|
||||
} else {
|
||||
BrowserRobot().verifyUrl(url)
|
||||
}
|
||||
}
|
||||
|
||||
fun assertPlayStoreOpens() {
|
||||
if (isPackageInstalled(Constants.PackageName.GOOGLE_PLAY_SERVICES)) {
|
||||
try {
|
||||
intended(toPackage(Constants.PackageName.GOOGLE_PLAY_SERVICES))
|
||||
} catch (e: AssertionFailedError) {
|
||||
BrowserRobot().verifyRateOnGooglePlayURL()
|
||||
}
|
||||
} else {
|
||||
BrowserRobot().verifyRateOnGooglePlayURL()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the latest activity of the application is used for custom tabs or PWAs.
|
||||
*
|
||||
* @return Boolean value that helps us know if the current activity supports custom tabs or PWAs.
|
||||
*/
|
||||
fun isExternalAppBrowserActivityInCurrentTask(): Boolean {
|
||||
val activityManager = appContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
||||
|
||||
mDevice.waitForIdle(waitingTimeShort)
|
||||
|
||||
return activityManager.appTasks[0].taskInfo.topActivity!!.className == ExternalAppBrowserActivity::class.java.name
|
||||
}
|
||||
|
||||
/**
|
||||
* Run test with automatically registering idling resources and cleanup.
|
||||
*
|
||||
* @param idlingResources zero or more [IdlingResource] to be used when running [testBlock].
|
||||
* @param testBlock test code to execute.
|
||||
*/
|
||||
fun registerAndCleanupIdlingResources(
|
||||
vararg idlingResources: IdlingResource,
|
||||
testBlock: () -> Unit,
|
||||
) {
|
||||
idlingResources.forEach {
|
||||
IdlingRegistry.getInstance().register(it)
|
||||
}
|
||||
|
||||
try {
|
||||
testBlock()
|
||||
} finally {
|
||||
idlingResources.forEach {
|
||||
IdlingRegistry.getInstance().unregister(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// exit from Menus to home screen or browser
|
||||
fun exitMenu() {
|
||||
val toolbar =
|
||||
|
@ -332,9 +253,9 @@ object TestHelper {
|
|||
return withParent(
|
||||
hasSibling(
|
||||
withChild(
|
||||
matcher,
|
||||
),
|
||||
),
|
||||
matcher
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -348,117 +269,34 @@ object TestHelper {
|
|||
}
|
||||
|
||||
fun grantPermission() {
|
||||
val instrumentation = InstrumentationRegistry.getInstrumentation()
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
mDevice.findObject(
|
||||
UiDevice.getInstance(instrumentation).findObject(
|
||||
By.text(
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.R -> Pattern.compile(
|
||||
"WHILE USING THE APP",
|
||||
Pattern.CASE_INSENSITIVE,
|
||||
"WHILE USING THE APP", Pattern.CASE_INSENSITIVE
|
||||
)
|
||||
else -> Pattern.compile("Allow", Pattern.CASE_INSENSITIVE)
|
||||
},
|
||||
),
|
||||
}
|
||||
)
|
||||
).click()
|
||||
}
|
||||
}
|
||||
|
||||
fun denyPermission() {
|
||||
val instrumentation = InstrumentationRegistry.getInstrumentation()
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
mDevice.findObject(
|
||||
UiDevice.getInstance(instrumentation).findObject(
|
||||
By.text(
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
Build.VERSION_CODES.R -> Pattern.compile(
|
||||
"DENY",
|
||||
Pattern.CASE_INSENSITIVE,
|
||||
"DENY", Pattern.CASE_INSENSITIVE
|
||||
)
|
||||
else -> Pattern.compile("Deny", Pattern.CASE_INSENSITIVE)
|
||||
},
|
||||
),
|
||||
}
|
||||
)
|
||||
).click()
|
||||
}
|
||||
}
|
||||
|
||||
fun isTestLab(): Boolean {
|
||||
return Settings.System.getString(appContext.contentResolver, "firebase.test.lab").toBoolean()
|
||||
}
|
||||
|
||||
private val charPool: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9')
|
||||
fun generateRandomString(stringLength: Int) =
|
||||
(1..stringLength)
|
||||
.map { kotlin.random.Random.nextInt(0, charPool.size) }
|
||||
.map(charPool::get)
|
||||
.joinToString("")
|
||||
|
||||
/**
|
||||
* Changes the default language of the entire device, not just the app.
|
||||
* Runs on Debug variant as we don't want to adjust Release permission manifests
|
||||
* Runs the test in its testBlock.
|
||||
* Cleans up and sets the default locale after it's done.
|
||||
*/
|
||||
fun runWithSystemLocaleChanged(locale: Locale, testRule: ActivityTestRule<HomeActivity>, testBlock: () -> Unit) {
|
||||
if (Config.channel.isDebug) {
|
||||
/* Sets permission to change device language */
|
||||
PermissionRequester().apply {
|
||||
addPermissions(
|
||||
Manifest.permission.CHANGE_CONFIGURATION,
|
||||
)
|
||||
requestPermissions()
|
||||
}
|
||||
|
||||
val defaultLocale = Locale.getDefault()
|
||||
|
||||
try {
|
||||
setSystemLocale(locale)
|
||||
testBlock()
|
||||
ThreadUtils.runOnUiThread { testRule.activity.recreate() }
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
setSystemLocale(defaultLocale)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the default language of the entire device, not just the app.
|
||||
*/
|
||||
private fun setSystemLocale(locale: Locale) {
|
||||
val activityManagerNative = Class.forName("android.app.ActivityManagerNative")
|
||||
val am = activityManagerNative.getMethod("getDefault", *arrayOfNulls(0))
|
||||
.invoke(activityManagerNative, *arrayOfNulls(0))
|
||||
val config = InstrumentationRegistry.getInstrumentation().context.resources.configuration
|
||||
config.javaClass.getDeclaredField("locale")[config] = locale
|
||||
config.javaClass.getDeclaredField("userSetLocale").setBoolean(config, true)
|
||||
am.javaClass.getMethod(
|
||||
"updateConfiguration",
|
||||
Configuration::class.java,
|
||||
).invoke(am, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates clipboard data.
|
||||
*/
|
||||
fun setTextToClipBoard(context: Context, message: String) {
|
||||
val clipBoard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clipData = ClipData.newPlainText("label", message)
|
||||
|
||||
clipBoard.setPrimaryClip(clipData)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sponsored shortcut title based on the index.
|
||||
*/
|
||||
fun getSponsoredShortcutTitle(position: Int): String {
|
||||
val sponsoredShortcut = mDevice.findObject(
|
||||
UiSelector()
|
||||
.resourceId("$packageName:id/top_site_item")
|
||||
.index(position - 1),
|
||||
).getChild(
|
||||
UiSelector()
|
||||
.resourceId("$packageName:id/top_site_title"),
|
||||
).text
|
||||
|
||||
return sponsoredShortcut
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import androidx.test.espresso.IdlingResource
|
|||
|
||||
class ViewVisibilityIdlingResource(
|
||||
private val view: View,
|
||||
private val expectedVisibility: Int,
|
||||
private val expectedVisibility: Int
|
||||
) : IdlingResource {
|
||||
private var resourceCallback: IdlingResource.ResourceCallback? = null
|
||||
private var isIdle: Boolean = false
|
||||
|
|
|
@ -43,6 +43,6 @@ fun ViewInteraction.clickAtLocationInView(locationInView: GeneralLocation): View
|
|||
locationInView,
|
||||
Press.FINGER,
|
||||
InputDevice.SOURCE_UNKNOWN,
|
||||
MotionEvent.BUTTON_PRIMARY,
|
||||
),
|
||||
MotionEvent.BUTTON_PRIMARY
|
||||
)
|
||||
)
|
||||
|
|
|
@ -16,5 +16,5 @@ import org.mozilla.fenix.helpers.TestAssetHelper
|
|||
*/
|
||||
fun UiDevice.waitNotNull(
|
||||
searchCondition: SearchCondition<*>,
|
||||
waitTime: Long = TestAssetHelper.waitingTime,
|
||||
waitTime: Long = TestAssetHelper.waitingTime
|
||||
) = assertNotNull(wait(searchCondition, waitTime))
|
||||
|
|
|
@ -10,7 +10,7 @@ import androidx.test.espresso.IdlingResource
|
|||
import mozilla.components.feature.addons.ui.AddonInstallationDialogFragment
|
||||
|
||||
class AddonsInstallingIdlingResource(
|
||||
private val fragmentManager: FragmentManager,
|
||||
private val fragmentManager: FragmentManager
|
||||
) :
|
||||
IdlingResource {
|
||||
private var resourceCallback: IdlingResource.ResourceCallback? = null
|
||||
|
@ -25,9 +25,8 @@ class AddonsInstallingIdlingResource(
|
|||
}
|
||||
|
||||
override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback?) {
|
||||
if (callback != null) {
|
||||
if (callback != null)
|
||||
resourceCallback = callback
|
||||
}
|
||||
}
|
||||
|
||||
private fun isInstalledAddonDialogShown(): Boolean {
|
||||
|
|
|
@ -20,16 +20,14 @@ class AddonsLoadingIdlingResource(val fragmentManager: FragmentManager) : Idling
|
|||
|
||||
override fun isIdleNow(): Boolean {
|
||||
val idle = addonsFinishedLoading()
|
||||
if (idle) {
|
||||
if (idle)
|
||||
resourceCallback?.onTransitionToIdle()
|
||||
}
|
||||
return idle
|
||||
}
|
||||
|
||||
override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback?) {
|
||||
if (callback != null) {
|
||||
if (callback != null)
|
||||
resourceCallback = callback
|
||||
}
|
||||
}
|
||||
|
||||
private fun addonsFinishedLoading(): Boolean {
|
||||
|
@ -39,9 +37,8 @@ class AddonsLoadingIdlingResource(val fragmentManager: FragmentManager) : Idling
|
|||
addonsManagementFragment.view?.findViewById<View>(R.id.add_ons_progress_bar)
|
||||
} ?: return true
|
||||
|
||||
if (progressbar.visibility == VISIBLE) {
|
||||
if (progressbar.visibility == VISIBLE)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -32,16 +32,14 @@ class NetworkConnectionIdlingResource(private val networkConnected: Boolean) : I
|
|||
} else {
|
||||
!isOnline()
|
||||
}
|
||||
if (idle) {
|
||||
if (idle)
|
||||
resourceCallback?.onTransitionToIdle()
|
||||
}
|
||||
return idle
|
||||
}
|
||||
|
||||
override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback?) {
|
||||
if (callback != null) {
|
||||
if (callback != null)
|
||||
resourceCallback = callback
|
||||
}
|
||||
}
|
||||
|
||||
private fun isOnline(): Boolean {
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
package org.mozilla.fenix.helpers.matchers
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.StateListDrawable
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import androidx.test.espresso.matcher.BoundedMatcher
|
||||
import org.hamcrest.Description
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.StateListDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
|
||||
class BitmapDrawableMatcher(private val bitmap: Bitmap, private val name: String) :
|
||||
BoundedMatcher<View, ImageView>(ImageView::class.java) {
|
||||
|
|
|
@ -28,7 +28,7 @@ class BottomSheetBehaviorHalfExpandedMaxRatioMatcher(private val maxHalfExpanded
|
|||
override fun describeTo(description: Description?) {
|
||||
description?.appendText(
|
||||
"BottomSheetBehavior with an at max halfExpandedRation: " +
|
||||
"$maxHalfExpandedRatio",
|
||||
"$maxHalfExpandedRatio"
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ package org.mozilla.fenix.perf
|
|||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.children
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
@ -15,6 +16,7 @@ import org.junit.Assert.assertEquals
|
|||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
|
||||
|
@ -33,7 +35,7 @@ import org.mozilla.fenix.helpers.HomeActivityTestRule
|
|||
*
|
||||
* Say no to main thread IO! 🙅
|
||||
*/
|
||||
private const val EXPECTED_SUPPRESSION_COUNT = 18
|
||||
private const val EXPECTED_SUPPRESSION_COUNT = 19
|
||||
|
||||
/**
|
||||
* The number of times we call the `runBlocking` coroutine method on the main thread during this
|
||||
|
@ -46,7 +48,7 @@ private const val EXPECTED_SUPPRESSION_COUNT = 18
|
|||
* generally be replaced with a slow operation on a background thread launching onto the main thread
|
||||
* when completed. However, in a very small number of cases, blocking may be impossible to avoid.
|
||||
*/
|
||||
private val EXPECTED_RUNBLOCKING_RANGE = 0..2 // CI has +1 counts compared to local runs: increment these together
|
||||
private val EXPECTED_RUNBLOCKING_RANGE = 0..1 // CI has +1 counts compared to local runs: increment these together
|
||||
|
||||
/**
|
||||
* The number of `ConstraintLayout`s we inflate that are children of a `RecyclerView` during this
|
||||
|
@ -61,7 +63,7 @@ private val EXPECTED_RUNBLOCKING_RANGE = 0..2 // CI has +1 counts compared to lo
|
|||
* If the view hierarchy uses Jetpack Compose, switching to that is also an option.
|
||||
*/
|
||||
private val EXPECTED_RECYCLER_VIEW_CONSTRAINT_LAYOUT_CHILDREN =
|
||||
4..6 // The messaging framework is not deterministic and could add to the count.
|
||||
3..4 // The messaging framework is not deterministic and could add a +1 to the count
|
||||
|
||||
/**
|
||||
* The number of layouts we inflate during this start up scenario. Incrementing the expected value
|
||||
|
@ -79,7 +81,7 @@ private val EXPECTED_NUMBER_OF_INFLATION =
|
|||
private val failureMsgStrictMode = getErrorMessage("StrictMode suppression")
|
||||
private val failureMsgRunBlocking = getErrorMessage("runBlockingIncrement")
|
||||
private val failureMsgRecyclerViewConstraintLayoutChildren = getErrorMessage(
|
||||
"ConstraintLayout being a common direct descendant of a RecyclerView",
|
||||
"ConstraintLayout being a common direct descendant of a RecyclerView"
|
||||
)
|
||||
private val failureMsgNumberOfInflation = getErrorMessage("start up inflation")
|
||||
|
||||
|
@ -114,24 +116,21 @@ class StartupExcessiveResourceUseTest {
|
|||
val actualSuppresionCount = activityTestRule.activity.components.strictMode.suppressionCount.get().toInt()
|
||||
val actualRunBlocking = RunBlockingCounter.count.get()
|
||||
|
||||
val rootView = activityTestRule.activity.findViewById<LinearLayout>(R.id.rootContainer)
|
||||
val actualRecyclerViewConstraintLayoutChildren = countRecyclerViewConstraintLayoutChildren(rootView, null)
|
||||
|
||||
val actualNumberOfInflations = InflationCounter.inflationCount.get()
|
||||
|
||||
assertEquals(failureMsgStrictMode, EXPECTED_SUPPRESSION_COUNT, actualSuppresionCount)
|
||||
assertTrue(failureMsgRunBlocking + "actual: $actualRunBlocking", actualRunBlocking in EXPECTED_RUNBLOCKING_RANGE)
|
||||
|
||||
// This below asserts fail in Firebase with different values for
|
||||
// "actualRecyclerViewConstraintLayoutChildren" or "actualNumberOfInflations"
|
||||
// See https://github.com/mozilla-mobile/fenix/pull/26512 and https://github.com/mozilla-mobile/fenix/issues/25142
|
||||
//
|
||||
// val rootView = activityTestRule.activity.findViewById<LinearLayout>(R.id.rootContainer)
|
||||
// val actualRecyclerViewConstraintLayoutChildren = countRecyclerViewConstraintLayoutChildren(rootView, null)
|
||||
// assertTrue(
|
||||
// failureMsgRecyclerViewConstraintLayoutChildren + "actual: $actualRecyclerViewConstraintLayoutChildren",
|
||||
// actualRecyclerViewConstraintLayoutChildren in EXPECTED_RECYCLER_VIEW_CONSTRAINT_LAYOUT_CHILDREN,
|
||||
// )
|
||||
// val actualNumberOfInflations = InflationCounter.inflationCount.get()
|
||||
// assertTrue(
|
||||
// failureMsgNumberOfInflation + "actual: $actualNumberOfInflations",
|
||||
// actualNumberOfInflations in EXPECTED_NUMBER_OF_INFLATION,
|
||||
// )
|
||||
assertTrue(
|
||||
failureMsgRecyclerViewConstraintLayoutChildren + "actual: $actualRecyclerViewConstraintLayoutChildren",
|
||||
actualRecyclerViewConstraintLayoutChildren in EXPECTED_RECYCLER_VIEW_CONSTRAINT_LAYOUT_CHILDREN,
|
||||
)
|
||||
assertTrue(
|
||||
failureMsgNumberOfInflation + "actual: $actualNumberOfInflations",
|
||||
actualNumberOfInflations in EXPECTED_NUMBER_OF_INFLATION,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,34 +7,24 @@
|
|||
package org.mozilla.fenix.screenshots
|
||||
|
||||
import android.os.SystemClock
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.mDevice
|
||||
import tools.fastlane.screengrab.Screengrab
|
||||
import tools.fastlane.screengrab.locale.LocaleTestRule
|
||||
|
||||
class DefaultHomeScreenTest : ScreenshotTest() {
|
||||
private lateinit var mDevice: UiDevice
|
||||
|
||||
@Rule @JvmField
|
||||
val localeTestRule = LocaleTestRule()
|
||||
|
||||
@get:Rule
|
||||
var mActivityTestRule: ActivityTestRule<HomeActivity> = HomeActivityTestRule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mActivityTestRule.getActivity().finishAndRemoveTask()
|
||||
|
@ -43,6 +33,7 @@ class DefaultHomeScreenTest : ScreenshotTest() {
|
|||
@Test
|
||||
fun showDefaultHomeScreen() {
|
||||
homeScreen {
|
||||
swipeToBottom()
|
||||
verifyAccountsSignInButton()
|
||||
Screengrab.screenshot("HomeScreenRobot_home-screen-scroll")
|
||||
TestAssetHelper.waitingTime
|
||||
|
|
|
@ -10,24 +10,24 @@ import android.os.SystemClock
|
|||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.Until
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.click
|
||||
import org.mozilla.fenix.helpers.ext.waitNotNull
|
||||
import org.mozilla.fenix.ui.robots.bookmarksMenu
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.mDevice
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
import org.mozilla.fenix.ui.robots.swipeToBottom
|
||||
import tools.fastlane.screengrab.Screengrab
|
||||
|
@ -35,18 +35,15 @@ import tools.fastlane.screengrab.locale.LocaleTestRule
|
|||
|
||||
class MenuScreenShotTest : ScreenshotTest() {
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private lateinit var mDevice: UiDevice
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val localeTestRule = LocaleTestRule()
|
||||
|
||||
@get:Rule
|
||||
var mActivityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides()
|
||||
var mActivityTestRule: ActivityTestRule<HomeActivity> = HomeActivityTestRule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -201,7 +198,7 @@ fun deleteBookmarkFolder() = onView(withText(R.string.bookmark_menu_delete_butto
|
|||
|
||||
fun tapOnTabCounter() = onView(withId(R.id.counter_text)).click()
|
||||
|
||||
fun settingsAccountPreferences() = onView(withText(R.string.preferences_sync_2)).click()
|
||||
fun settingsAccountPreferences() = onView(withText(R.string.preferences_sync)).click()
|
||||
|
||||
fun settingsSearch() = onView(withText(R.string.preferences_search)).click()
|
||||
|
||||
|
|
|
@ -19,4 +19,4 @@ requests = "*"
|
|||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.10"
|
||||
python_version = "2.7"
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "cf743d605ee37525af06865c7961ee99f1720fa9d6352eedc4bbfa5fa78f75ef"
|
||||
"sha256": "112a12fa2e9e8117b399b60a49b4c8799a614ef655992640c95149bf95f33e8b"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.10"
|
||||
"python_version": "2.7"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
|
@ -16,21 +16,27 @@
|
|||
]
|
||||
},
|
||||
"default": {
|
||||
"async-generator": {
|
||||
"atomicwrites": {
|
||||
"hashes": [
|
||||
"sha256:01c7bf666359b4967d2cda0000cc2e4af16a0ae098cbffcb8472fb9e8ad6585b",
|
||||
"sha256:6ebb3d106c12920aaae42ccb6f787ef5eefdcdd166ea3d628fa8476abe712144"
|
||||
"sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197",
|
||||
"sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==1.10"
|
||||
"version": "==1.4.0"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6",
|
||||
"sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"
|
||||
"sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6",
|
||||
"sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==22.1.0"
|
||||
"version": "==20.3.0"
|
||||
},
|
||||
"backports.functools-lru-cache": {
|
||||
"hashes": [
|
||||
"sha256:0bada4c2f8a43d533e4ecb7a12214d9420e66eb206d54bf2d682581ca4b80848",
|
||||
"sha256:8fde5f188da2d593bd5bc0be98d9abc46c95bb8a9dde93429570192ee6cc2d4a"
|
||||
],
|
||||
"markers": "python_version < '3.2'",
|
||||
"version": "==1.6.1"
|
||||
},
|
||||
"blessings": {
|
||||
"hashes": [
|
||||
|
@ -38,127 +44,130 @@
|
|||
"sha256:b1fdd7e7a675295630f9ae71527a8ebc10bfefa236b3d6aa4932ee4462c17ba3",
|
||||
"sha256:caad5211e7ba5afe04367cdd4cfc68fa886e2e08f6f35e76b7387d2109ccea6e"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.7"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d",
|
||||
"sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"
|
||||
"sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c",
|
||||
"sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"
|
||||
],
|
||||
"version": "==2022.6.15"
|
||||
"version": "==2020.12.5"
|
||||
},
|
||||
"cffi": {
|
||||
"hashes": [
|
||||
"sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5",
|
||||
"sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef",
|
||||
"sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104",
|
||||
"sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426",
|
||||
"sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405",
|
||||
"sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375",
|
||||
"sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a",
|
||||
"sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e",
|
||||
"sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc",
|
||||
"sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf",
|
||||
"sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185",
|
||||
"sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497",
|
||||
"sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3",
|
||||
"sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35",
|
||||
"sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c",
|
||||
"sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83",
|
||||
"sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21",
|
||||
"sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca",
|
||||
"sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984",
|
||||
"sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac",
|
||||
"sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd",
|
||||
"sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee",
|
||||
"sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a",
|
||||
"sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2",
|
||||
"sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192",
|
||||
"sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7",
|
||||
"sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585",
|
||||
"sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f",
|
||||
"sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e",
|
||||
"sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27",
|
||||
"sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b",
|
||||
"sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e",
|
||||
"sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e",
|
||||
"sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d",
|
||||
"sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c",
|
||||
"sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415",
|
||||
"sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82",
|
||||
"sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02",
|
||||
"sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314",
|
||||
"sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325",
|
||||
"sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c",
|
||||
"sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3",
|
||||
"sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914",
|
||||
"sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045",
|
||||
"sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d",
|
||||
"sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9",
|
||||
"sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5",
|
||||
"sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2",
|
||||
"sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c",
|
||||
"sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3",
|
||||
"sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2",
|
||||
"sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8",
|
||||
"sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d",
|
||||
"sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d",
|
||||
"sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9",
|
||||
"sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162",
|
||||
"sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76",
|
||||
"sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4",
|
||||
"sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e",
|
||||
"sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9",
|
||||
"sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6",
|
||||
"sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b",
|
||||
"sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01",
|
||||
"sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"
|
||||
"sha256:00a1ba5e2e95684448de9b89888ccd02c98d512064b4cb987d48f4b40aa0421e",
|
||||
"sha256:00e28066507bfc3fe865a31f325c8391a1ac2916219340f87dfad602c3e48e5d",
|
||||
"sha256:045d792900a75e8b1e1b0ab6787dd733a8190ffcf80e8c8ceb2fb10a29ff238a",
|
||||
"sha256:0638c3ae1a0edfb77c6765d487fee624d2b1ee1bdfeffc1f0b58c64d149e7eec",
|
||||
"sha256:105abaf8a6075dc96c1fe5ae7aae073f4696f2905fde6aeada4c9d2926752362",
|
||||
"sha256:155136b51fd733fa94e1c2ea5211dcd4c8879869008fc811648f16541bf99668",
|
||||
"sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c",
|
||||
"sha256:1d2c4994f515e5b485fd6d3a73d05526aa0fcf248eb135996b088d25dfa1865b",
|
||||
"sha256:2c24d61263f511551f740d1a065eb0212db1dbbbbd241db758f5244281590c06",
|
||||
"sha256:51a8b381b16ddd370178a65360ebe15fbc1c71cf6f584613a7ea08bfad946698",
|
||||
"sha256:594234691ac0e9b770aee9fcdb8fa02c22e43e5c619456efd0d6c2bf276f3eb2",
|
||||
"sha256:5cf4be6c304ad0b6602f5c4e90e2f59b47653ac1ed9c662ed379fe48a8f26b0c",
|
||||
"sha256:64081b3f8f6f3c3de6191ec89d7dc6c86a8a43911f7ecb422c60e90c70be41c7",
|
||||
"sha256:6bc25fc545a6b3d57b5f8618e59fc13d3a3a68431e8ca5fd4c13241cd70d0009",
|
||||
"sha256:798caa2a2384b1cbe8a2a139d80734c9db54f9cc155c99d7cc92441a23871c03",
|
||||
"sha256:7c6b1dece89874d9541fc974917b631406233ea0440d0bdfbb8e03bf39a49b3b",
|
||||
"sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909",
|
||||
"sha256:8d6603078baf4e11edc4168a514c5ce5b3ba6e3e9c374298cb88437957960a53",
|
||||
"sha256:9cc46bc107224ff5b6d04369e7c595acb700c3613ad7bcf2e2012f62ece80c35",
|
||||
"sha256:9f7a31251289b2ab6d4012f6e83e58bc3b96bd151f5b5262467f4bb6b34a7c26",
|
||||
"sha256:9ffb888f19d54a4d4dfd4b3f29bc2c16aa4972f1c2ab9c4ab09b8ab8685b9c2b",
|
||||
"sha256:a5ed8c05548b54b998b9498753fb9cadbfd92ee88e884641377d8a8b291bcc01",
|
||||
"sha256:a7711edca4dcef1a75257b50a2fbfe92a65187c47dab5a0f1b9b332c5919a3fb",
|
||||
"sha256:af5c59122a011049aad5dd87424b8e65a80e4a6477419c0c1015f73fb5ea0293",
|
||||
"sha256:b18e0a9ef57d2b41f5c68beefa32317d286c3d6ac0484efd10d6e07491bb95dd",
|
||||
"sha256:b4e248d1087abf9f4c10f3c398896c87ce82a9856494a7155823eb45a892395d",
|
||||
"sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3",
|
||||
"sha256:c6332685306b6417a91b1ff9fae889b3ba65c2292d64bd9245c093b1b284809d",
|
||||
"sha256:d5ff0621c88ce83a28a10d2ce719b2ee85635e85c515f12bac99a95306da4b2e",
|
||||
"sha256:d9efd8b7a3ef378dd61a1e77367f1924375befc2eba06168b6ebfa903a5e59ca",
|
||||
"sha256:df5169c4396adc04f9b0a05f13c074df878b6052430e03f50e68adf3a57aa28d",
|
||||
"sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775",
|
||||
"sha256:ec80dc47f54e6e9a78181ce05feb71a0353854cc26999db963695f950b5fb375",
|
||||
"sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b",
|
||||
"sha256:f60567825f791c6f8a592f3c6e3bd93dd2934e3f9dac189308426bd76b00ef3b",
|
||||
"sha256:f803eaa94c2fcda012c047e62bc7a51b0bdabda1cad7a92a522694ea2d76e49f"
|
||||
],
|
||||
"version": "==1.15.1"
|
||||
"version": "==1.14.4"
|
||||
},
|
||||
"charset-normalizer": {
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
"sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5",
|
||||
"sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"
|
||||
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
||||
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.1.0"
|
||||
"version": "==3.0.4"
|
||||
},
|
||||
"configparser": {
|
||||
"hashes": [
|
||||
"sha256:254c1d9c79f60c45dfde850850883d5aaa7f19a23f13561243a050d5a7c3fe4c",
|
||||
"sha256:c7d282687a5308319bf3d2e7706e575c635b0a470342641c93bea0ea3b5331df"
|
||||
],
|
||||
"markers": "python_version < '3'",
|
||||
"version": "==4.0.2"
|
||||
},
|
||||
"contextlib2": {
|
||||
"hashes": [
|
||||
"sha256:01f490098c18b19d2bd5bb5dc445b2054d2fa97f09a4280ba2c5f3c394c8162e",
|
||||
"sha256:3355078a159fbb44ee60ea80abd0d87b80b78c248643b49aa6d94673b413609b"
|
||||
],
|
||||
"markers": "python_version < '3.4'",
|
||||
"version": "==0.6.0.post1"
|
||||
},
|
||||
"cryptography": {
|
||||
"hashes": [
|
||||
"sha256:190f82f3e87033821828f60787cfa42bff98404483577b591429ed99bed39d59",
|
||||
"sha256:2be53f9f5505673eeda5f2736bea736c40f051a739bfae2f92d18aed1eb54596",
|
||||
"sha256:30788e070800fec9bbcf9faa71ea6d8068f5136f60029759fd8c3efec3c9dcb3",
|
||||
"sha256:3d41b965b3380f10e4611dbae366f6dc3cefc7c9ac4e8842a806b9672ae9add5",
|
||||
"sha256:4c590ec31550a724ef893c50f9a97a0c14e9c851c85621c5650d699a7b88f7ab",
|
||||
"sha256:549153378611c0cca1042f20fd9c5030d37a72f634c9326e225c9f666d472884",
|
||||
"sha256:63f9c17c0e2474ccbebc9302ce2f07b55b3b3fcb211ded18a42d5764f5c10a82",
|
||||
"sha256:6bc95ed67b6741b2607298f9ea4932ff157e570ef456ef7ff0ef4884a134cc4b",
|
||||
"sha256:7099a8d55cd49b737ffc99c17de504f2257e3787e02abe6d1a6d136574873441",
|
||||
"sha256:75976c217f10d48a8b5a8de3d70c454c249e4b91851f6838a4e48b8f41eb71aa",
|
||||
"sha256:7bc997818309f56c0038a33b8da5c0bfbb3f1f067f315f9abd6fc07ad359398d",
|
||||
"sha256:80f49023dd13ba35f7c34072fa17f604d2f19bf0989f292cedf7ab5770b87a0b",
|
||||
"sha256:91ce48d35f4e3d3f1d83e29ef4a9267246e6a3be51864a5b7d2247d5086fa99a",
|
||||
"sha256:a958c52505c8adf0d3822703078580d2c0456dd1d27fabfb6f76fe63d2971cd6",
|
||||
"sha256:b62439d7cd1222f3da897e9a9fe53bbf5c104fff4d60893ad1355d4c14a24157",
|
||||
"sha256:b7f8dd0d4c1f21759695c05a5ec8536c12f31611541f8904083f3dc582604280",
|
||||
"sha256:d204833f3c8a33bbe11eda63a54b1aad7aa7456ed769a982f21ec599ba5fa282",
|
||||
"sha256:e007f052ed10cc316df59bc90fbb7ff7950d7e2919c9757fd42a2b8ecf8a5f67",
|
||||
"sha256:f2dcb0b3b63afb6df7fd94ec6fbddac81b5492513f7b0436210d390c14d46ee8",
|
||||
"sha256:f721d1885ecae9078c3f6bbe8a88bc0786b6e749bf32ccec1ef2b18929a05046",
|
||||
"sha256:f7a6de3e98771e183645181b3627e2563dcde3ce94a9e42a3f427d2255190327",
|
||||
"sha256:f8c0a6e9e1dd3eb0414ba320f85da6b0dcbd543126e30fcc546e7372a7fbf3b9"
|
||||
"sha256:22f8251f68953553af4f9c11ec5f191198bc96cff9f0ac5dd5ff94daede0ee6d",
|
||||
"sha256:284e275e3c099a80831f9898fb5c9559120d27675c3521278faba54e584a7832",
|
||||
"sha256:3e17d02941c0f169c5b877597ca8be895fca0e5e3eb882526a74aa4804380a98",
|
||||
"sha256:52a47e60953679eea0b4d490ca3c241fb1b166a7b161847ef4667dfd49e7699d",
|
||||
"sha256:57b8c1ed13b8aa386cabbfde3be175d7b155682470b0e259fecfe53850967f8a",
|
||||
"sha256:6a8f64ed096d13f92d1f601a92d9fd1f1025dc73a2ca1ced46dcf5e0d4930943",
|
||||
"sha256:6e8a3c7c45101a7eeee93102500e1b08f2307c717ff553fcb3c1127efc9b6917",
|
||||
"sha256:7ef41304bf978f33cfb6f43ca13bb0faac0c99cda33693aa20ad4f5e34e8cb8f",
|
||||
"sha256:87c2fffd61e934bc0e2c927c3764c20b22d7f5f7f812ee1a477de4c89b044ca6",
|
||||
"sha256:88069392cd9a1e68d2cfd5c3a2b0d72a44ef3b24b8977a4f7956e9e3c4c9477a",
|
||||
"sha256:8a0866891326d3badb17c5fd3e02c926b635e8923fa271b4813cd4d972a57ff3",
|
||||
"sha256:8f0fd8b0751d75c4483c534b209e39e918f0d14232c0d8a2a76e687f64ced831",
|
||||
"sha256:9a07e6d255053674506091d63ab4270a119e9fc83462c7ab1dbcb495b76307af",
|
||||
"sha256:9a8580c9afcdcddabbd064c0a74f337af74ff4529cdf3a12fa2e9782d677a2e5",
|
||||
"sha256:bd80bc156d3729b38cb227a5a76532aef693b7ac9e395eea8063ee50ceed46a5",
|
||||
"sha256:d1cbc3426e6150583b22b517ef3720036d7e3152d428c864ff0f3fcad2b97591",
|
||||
"sha256:e15ac84dcdb89f92424cbaca4b0b34e211e7ce3ee7b0ec0e4f3c55cee65fae5a",
|
||||
"sha256:e4789b84f8dedf190148441f7c5bfe7244782d9cbb194a36e17b91e7d3e1cca9",
|
||||
"sha256:f01c9116bfb3ad2831e125a73dcd957d173d6ddca7701528eff1e7d97972872c",
|
||||
"sha256:f0e3986f6cce007216b23c490f093f35ce2068f3c244051e559f647f6731b7ae",
|
||||
"sha256:f2aa3f8ba9e2e3fd49bd3de743b976ab192fbf0eb0348cebde5d2a9de0090a9f",
|
||||
"sha256:fb70a4cedd69dc52396ee114416a3656e011fb0311fca55eb55c7be6ed9c8aef"
|
||||
],
|
||||
"version": "==37.0.4"
|
||||
"index": "pypi",
|
||||
"version": "==3.2"
|
||||
},
|
||||
"distro": {
|
||||
"hashes": [
|
||||
"sha256:151aeccf60c216402932b52e40ee477a939f8d58898927378a02abbe852c1c39",
|
||||
"sha256:d596311d707e692c2160c37807f83e3820c5d539d5a83e87cfb6babd8ba3a06b"
|
||||
"sha256:0e58756ae38fbd8fc3020d54badb8eae17c5b9dcbed388b17bb55b8a5928df92",
|
||||
"sha256:df74eed763e18d10d0da624258524ae80486432cd17392d9c3d96f5e83cd2799"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==1.7.0"
|
||||
"version": "==1.5.0"
|
||||
},
|
||||
"enum34": {
|
||||
"hashes": [
|
||||
"sha256:a98a201d6de3f2ab3db284e70a33b0f896fbf35f8086594e8c9e74b909058d53",
|
||||
"sha256:c3858660960c984d6ab0ebad691265180da2b43f07e061c0f8dca9ef3cffd328",
|
||||
"sha256:cce6a7477ed816bd2542d03d53db9f0db935dd013b70f336a95c73979289f248"
|
||||
],
|
||||
"markers": "python_version < '3'",
|
||||
"version": "==1.1.10"
|
||||
},
|
||||
"funcsigs": {
|
||||
"hashes": [
|
||||
"sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca",
|
||||
"sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50"
|
||||
],
|
||||
"markers": "python_version < '3.0'",
|
||||
"version": "==1.0.2"
|
||||
},
|
||||
"fxapom": {
|
||||
"hashes": [
|
||||
|
@ -168,14 +177,6 @@
|
|||
"index": "pypi",
|
||||
"version": "==1.10.2"
|
||||
},
|
||||
"h11": {
|
||||
"hashes": [
|
||||
"sha256:70813c1135087a248a4d38cc0e1a0181ffab2188141a93eaf567940c3957ff06",
|
||||
"sha256:8ddd78563b633ca55346c8cd41ec0af27d3c79931828beffb46ce70a379e7442"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.13.0"
|
||||
},
|
||||
"hawkauthlib": {
|
||||
"hashes": [
|
||||
"sha256:935878d3a75832aa76f78ddee13491f1466cbd69a8e7e4248902763cf9953ba9",
|
||||
|
@ -185,17 +186,35 @@
|
|||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff",
|
||||
"sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"
|
||||
"sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6",
|
||||
"sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"
|
||||
],
|
||||
"version": "==3.3"
|
||||
"version": "==2.10"
|
||||
},
|
||||
"iniconfig": {
|
||||
"importlib-metadata": {
|
||||
"hashes": [
|
||||
"sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3",
|
||||
"sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"
|
||||
"sha256:b8de9eff2b35fb037368f28a7df1df4e6436f578fa74423505b6c6a778d5b5dd",
|
||||
"sha256:c2d6341ff566f609e89a2acb2db190e5e1d23d5409d6cc8d2fe34d72443876d4"
|
||||
],
|
||||
"version": "==1.1.1"
|
||||
"markers": "python_version < '3.8'",
|
||||
"version": "==2.1.1"
|
||||
},
|
||||
"ipaddress": {
|
||||
"hashes": [
|
||||
"sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc",
|
||||
"sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2"
|
||||
],
|
||||
"markers": "python_version < '3'",
|
||||
"version": "==1.0.23"
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:38a936c0a6d98a38bcc2d03fdaaedaba9f412879461dd2ceff8d37564d6522e4",
|
||||
"sha256:c0a5785b1109a6bd7fac76d6837fd1feca158e54e521ccd2ae8bfe393cc9d4fc",
|
||||
"sha256:fe7a7cae1ccb57d33952113ff4fa1bc5f879963600ed74918f1236e212ee50b9"
|
||||
],
|
||||
"markers": "python_version <= '2.7'",
|
||||
"version": "==5.0.0"
|
||||
},
|
||||
"mozdevice": {
|
||||
"hashes": [
|
||||
|
@ -226,24 +245,25 @@
|
|||
},
|
||||
"mozinstall": {
|
||||
"hashes": [
|
||||
"sha256:0b14000a88d6a45c37b877eedf897655f665e89410ca629dd500415406ed465e",
|
||||
"sha256:ec364cfefd3435fb155edd48be9e71819834e4dcacc6c3294c7f2452e200095b"
|
||||
"sha256:219ba7c51308433487b4f30a2615cb9b3ecd40a76b9faf41cf1b1b005bb5dda7",
|
||||
"sha256:bbc31a18ee8a1fbec74b67b99c6c0289ffc7daf39eb5b5ff7dc99f1be687eb08"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.1"
|
||||
"version": "==2.0.0"
|
||||
},
|
||||
"mozlog": {
|
||||
"hashes": [
|
||||
"sha256:54b9a1e781ce31fc10079dc8aec509fff7feca83714edeae6c981e279ceb796f"
|
||||
"sha256:4719d3d00bf1a0b77285d306eb3180f9c1311fffae9640a423fad9d80170e43d",
|
||||
"sha256:d035f722c15d700e4a7b48b90bdda0a6ad83e25482760949d1abd73468bad07f"
|
||||
],
|
||||
"version": "==7.1.0"
|
||||
"version": "==7.0.1"
|
||||
},
|
||||
"mozprocess": {
|
||||
"hashes": [
|
||||
"sha256:e64591d02899f6fd50fe391f5635236c5c604d8faae08ab4aafed9c3a66e3966",
|
||||
"sha256:e8093fe990bafd4ff3e2e49641b182c8085ea9cee2a28c7bdf9fabc2ff9f618f"
|
||||
"sha256:08e1036b53819fd144331f6dfbbb17fc8ca782bbed2e28b4aa771b8b91f7dffb",
|
||||
"sha256:54dc59e7f5a9c2c2930bffb7935f36dddd1d94c9fc6ed179e893d2dff353995a"
|
||||
],
|
||||
"version": "==1.3.0"
|
||||
"version": "==1.2.1"
|
||||
},
|
||||
"mozprofile": {
|
||||
"hashes": [
|
||||
|
@ -255,11 +275,11 @@
|
|||
},
|
||||
"mozrunner": {
|
||||
"hashes": [
|
||||
"sha256:35a7d2cf3abee1d8651e92f870f75159605810ba8ea442defae41a5eec462c29",
|
||||
"sha256:4ee4d44123c1daa7f3648e8b3b0e3a8c1712b3e1ea254d9a4bf80295ea795d41"
|
||||
"sha256:5e1bdf1709b4b8cb86b3daf3dbc9352d2abfc8428e26cc75a68ce87a565f4f25",
|
||||
"sha256:f223e9ca7f0acd3f93d4c30760f8d976d41da81edf686cd5063d2973ebbebcfb"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==8.2.1"
|
||||
"version": "==7.8.0"
|
||||
},
|
||||
"mozterm": {
|
||||
"hashes": [
|
||||
|
@ -276,45 +296,41 @@
|
|||
"index": "pypi",
|
||||
"version": "==2.3.0"
|
||||
},
|
||||
"outcome": {
|
||||
"hashes": [
|
||||
"sha256:6f82bd3de45da303cf1f771ecafa1633750a358436a8bb60e06a1ceb745d2672",
|
||||
"sha256:c4ab89a56575d6d38a05aa16daeaa333109c1f96167aba8901ab18b6b5e0f7f5"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==1.2.0"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb",
|
||||
"sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"
|
||||
"sha256:05af3bb85d320377db281cf254ab050e1a7ebcbf5410685a9a407e18a1f81236",
|
||||
"sha256:eb41423378682dadb7166144a4926e443093863024de508ca5c9737d6bc08376"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==21.3"
|
||||
"version": "==20.7"
|
||||
},
|
||||
"pathlib2": {
|
||||
"hashes": [
|
||||
"sha256:0ec8205a157c80d7acc301c0b18fbd5d44fe655968f5d947b6ecef5290fc35db",
|
||||
"sha256:6cd9a47b597b37cc57de1c05e56fb1a1c9cc9fab04fe78c29acd090418529868"
|
||||
],
|
||||
"markers": "python_version < '3.6'",
|
||||
"version": "==2.3.5"
|
||||
},
|
||||
"pluggy": {
|
||||
"hashes": [
|
||||
"sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159",
|
||||
"sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"
|
||||
"sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0",
|
||||
"sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==1.0.0"
|
||||
"version": "==0.13.1"
|
||||
},
|
||||
"progressbar2": {
|
||||
"hashes": [
|
||||
"sha256:14d3165a1781d053ffaa117daf27cc706128d2ec1d2977fdb05b6bb079888013",
|
||||
"sha256:2562ba3e554433f08e81fb7b786208b19de135f3ca1c5da1787d9b05558e6247"
|
||||
"sha256:ef72be284e7f2b61ac0894b44165926f13f5d995b2bf3cd8a8dedc6224b255a7",
|
||||
"sha256:fe2738e7ecb7df52ad76307fe610c460c52b50f5335fd26c3ab80ff7655ba1e0"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==4.0.0"
|
||||
"version": "==3.53.1"
|
||||
},
|
||||
"py": {
|
||||
"hashes": [
|
||||
"sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719",
|
||||
"sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"
|
||||
"sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2",
|
||||
"sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==1.11.0"
|
||||
"version": "==1.9.0"
|
||||
},
|
||||
"pybrowserid": {
|
||||
"hashes": [
|
||||
|
@ -325,10 +341,10 @@
|
|||
},
|
||||
"pycparser": {
|
||||
"hashes": [
|
||||
"sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9",
|
||||
"sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"
|
||||
"sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0",
|
||||
"sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"
|
||||
],
|
||||
"version": "==2.21"
|
||||
"version": "==2.20"
|
||||
},
|
||||
"pyfxa": {
|
||||
"hashes": [
|
||||
|
@ -338,49 +354,32 @@
|
|||
},
|
||||
"pyjwt": {
|
||||
"hashes": [
|
||||
"sha256:72d1d253f32dbd4f5c88eaf1fdc62f3a19f676ccbadb9dbc5d07e951b2b26daf",
|
||||
"sha256:d42908208c699b3b973cbeb01a969ba6a96c821eefb1c5bfe4c390c01d67abba"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.4.0"
|
||||
},
|
||||
"pyopenssl": {
|
||||
"hashes": [
|
||||
"sha256:660b1b1425aac4a1bea1d94168a85d99f0b3144c869dd4390d27629d0087f1bf",
|
||||
"sha256:ea252b38c87425b64116f808355e8da644ef9b07e429398bfece610f893ee2e0"
|
||||
],
|
||||
"version": "==22.0.0"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
"sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb",
|
||||
"sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.8'",
|
||||
"version": "==3.0.9"
|
||||
},
|
||||
"pypom": {
|
||||
"hashes": [
|
||||
"sha256:6f56888d25c1faf8fa0d53ef8a4ba1d7dc828e57212f7fe04e8cd21b5eaa924e",
|
||||
"sha256:a65297125c498c4e9cee99de9b2ddf5b908d0041ee1fc1e90956d3750483fa3d"
|
||||
],
|
||||
"version": "==2.2.3"
|
||||
},
|
||||
"pysocks": {
|
||||
"hashes": [
|
||||
"sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299",
|
||||
"sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5",
|
||||
"sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"
|
||||
"sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e",
|
||||
"sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96"
|
||||
],
|
||||
"version": "==1.7.1"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
"sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1",
|
||||
"sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"
|
||||
],
|
||||
"version": "==2.4.7"
|
||||
},
|
||||
"pypom": {
|
||||
"hashes": [
|
||||
"sha256:4bdd57fceb72d7e6a3645cf6c9322f490d9cfb5d777eac2c851a3b658b813939",
|
||||
"sha256:6772ec99f0a21a5bdc8c092007a8c813ed18359e67ed70258bbb233df5e28829"
|
||||
],
|
||||
"version": "==2.2.0"
|
||||
},
|
||||
"pytest": {
|
||||
"hashes": [
|
||||
"sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c",
|
||||
"sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45"
|
||||
"sha256:19e8f75eac01dd3f211edd465b39efbcbdc8fc5f7866d7dd49fedb30d8adf339",
|
||||
"sha256:c77a5f30a90e0ce24db9eaa14ddfd38d4afb5ea159309bdd2dae55b931bc9324"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==7.1.2"
|
||||
"version": "==4.6.9"
|
||||
},
|
||||
"pytest-fxa": {
|
||||
"hashes": [
|
||||
|
@ -392,27 +391,26 @@
|
|||
},
|
||||
"pytest-html": {
|
||||
"hashes": [
|
||||
"sha256:3ee1cf319c913d19fe53aeb0bc400e7b0bc2dbeb477553733db1dad12eb75ee3",
|
||||
"sha256:b7f82f123936a3f4d2950bc993c2c1ca09ce262c9ae12f9ac763a2401380b455"
|
||||
"sha256:06e7e13131649b4fe522cf04054efb7b4749ff2c7160755e4acfd8e89a7e5955",
|
||||
"sha256:f0fae6de71f02f62f9460f628d0c5f70b0cdc86bb393239860c7dec70fd2973d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.1.1"
|
||||
"version": "==1.22.1"
|
||||
},
|
||||
"pytest-metadata": {
|
||||
"hashes": [
|
||||
"sha256:39261ee0086f17649b180baf2a8633e1922a4c4b6fcc28a2de7d8127a82541bf",
|
||||
"sha256:fcd2f416f15be295943527b3c8ba16a44ae5a7141939c90c3dc5ce9d167cf2a5"
|
||||
"sha256:2071a59285de40d7541fde1eb9f1ddea1c9db165882df82781367471238b66ba",
|
||||
"sha256:c29a1fb470424926c63154c1b632c02585f2ba4282932058a71d35295ff8c96d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.2"
|
||||
"version": "==1.8.0"
|
||||
},
|
||||
"python-utils": {
|
||||
"hashes": [
|
||||
"sha256:3b1c8b706e40e91280eec5fa72ea730880a166cee99afa5555b863d55664478d",
|
||||
"sha256:5cb9cf295018202fb4d6abdd694a33a7f08bc0ce1bf1eab8cce80ab2cde35c07"
|
||||
"sha256:ebaadab29d0cb9dca0a82eab9c405f5be5125dbbff35b8f32cc433fa498dbaa7",
|
||||
"sha256:f21fc09ff58ea5ebd1fd2e8ef7f63e39d456336900f26bdc9334a03a3f7d8089"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.3.3"
|
||||
"version": "==2.4.0"
|
||||
},
|
||||
"redo": {
|
||||
"hashes": [
|
||||
|
@ -423,49 +421,42 @@
|
|||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983",
|
||||
"sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"
|
||||
"sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee",
|
||||
"sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.28.1"
|
||||
"version": "==2.23.0"
|
||||
},
|
||||
"scandir": {
|
||||
"hashes": [
|
||||
"sha256:2586c94e907d99617887daed6c1d102b5ca28f1085f90446554abf1faf73123e",
|
||||
"sha256:2ae41f43797ca0c11591c0c35f2f5875fa99f8797cb1a1fd440497ec0ae4b022",
|
||||
"sha256:2b8e3888b11abb2217a32af0766bc06b65cc4a928d8727828ee68af5a967fa6f",
|
||||
"sha256:2c712840c2e2ee8dfaf36034080108d30060d759c7b73a01a52251cc8989f11f",
|
||||
"sha256:4d4631f6062e658e9007ab3149a9b914f3548cb38bfb021c64f39a025ce578ae",
|
||||
"sha256:67f15b6f83e6507fdc6fca22fedf6ef8b334b399ca27c6b568cbfaa82a364173",
|
||||
"sha256:7d2d7a06a252764061a020407b997dd036f7bd6a175a5ba2b345f0a357f0b3f4",
|
||||
"sha256:8c5922863e44ffc00c5c693190648daa6d15e7c1207ed02d6f46a8dcc2869d32",
|
||||
"sha256:92c85ac42f41ffdc35b6da57ed991575bdbe69db895507af88b9f499b701c188",
|
||||
"sha256:b24086f2375c4a094a6b51e78b4cf7ca16c721dcee2eddd7aa6494b42d6d519d",
|
||||
"sha256:cb925555f43060a1745d0a321cca94bcea927c50114b623d73179189a4e100ac"
|
||||
],
|
||||
"markers": "python_version < '3.5'",
|
||||
"version": "==1.10.0"
|
||||
},
|
||||
"selenium": {
|
||||
"hashes": [
|
||||
"sha256:61c8b02788b66f08f2e61d5295afc956991e394815e33573072e68402ed4e8d5"
|
||||
"sha256:2d7131d7bc5a5b99a2d9b04aaf2612c411b03b8ca1b1ee8d3de5845a9be2cb3c",
|
||||
"sha256:deaf32b60ad91a4611b98d8002757f29e6f2c2d5fcaf202e1c9ad06d6772300d"
|
||||
],
|
||||
"markers": "python_version ~= '3.7'",
|
||||
"version": "==4.4.0"
|
||||
"version": "==3.141.0"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
|
||||
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
|
||||
"sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
|
||||
"sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.16.0"
|
||||
},
|
||||
"sniffio": {
|
||||
"hashes": [
|
||||
"sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663",
|
||||
"sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==1.2.0"
|
||||
},
|
||||
"sortedcontainers": {
|
||||
"hashes": [
|
||||
"sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88",
|
||||
"sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"
|
||||
],
|
||||
"version": "==2.4.0"
|
||||
},
|
||||
"tomli": {
|
||||
"hashes": [
|
||||
"sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
|
||||
"sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.0.1"
|
||||
"version": "==1.15.0"
|
||||
},
|
||||
"treeherder-client": {
|
||||
"hashes": [
|
||||
|
@ -474,57 +465,54 @@
|
|||
],
|
||||
"version": "==5.0.0"
|
||||
},
|
||||
"trio": {
|
||||
"hashes": [
|
||||
"sha256:4dc0bf9d5cc78767fc4516325b6d80cc0968705a31d0eec2ecd7cdda466265b0",
|
||||
"sha256:523f39b7b69eef73501cebfe1aafd400a9aad5b03543a0eded52952488ff1c13"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.21.0"
|
||||
},
|
||||
"trio-websocket": {
|
||||
"hashes": [
|
||||
"sha256:5b558f6e83cc20a37c3b61202476c5295d1addf57bd65543364e0337e37ed2bc",
|
||||
"sha256:a3d34de8fac26023eee701ed1e7bf4da9a8326b61a62934ec9e53b64970fd8fe"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==0.9.2"
|
||||
},
|
||||
"urllib3": {
|
||||
"extras": [
|
||||
"secure",
|
||||
"socks"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:c33ccba33c819596124764c23a97d25f32b28433ba0dedeb77d873a38722c9bc",
|
||||
"sha256:ea6e8fb210b19d950fab93b60c9009226c63a28808bc8386e05301e25883ac0a"
|
||||
"sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2",
|
||||
"sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4.0'",
|
||||
"version": "==1.26.11"
|
||||
"version": "==1.25.11"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784",
|
||||
"sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"
|
||||
],
|
||||
"version": "==0.2.5"
|
||||
},
|
||||
"webob": {
|
||||
"hashes": [
|
||||
"sha256:73aae30359291c14fa3b956f8b5ca31960e420c28c1bec002547fb04928cf89b",
|
||||
"sha256:b64ef5141be559cfade448f044fa45c2260351edcb6a8ef6b7e00c7dcef0c323"
|
||||
"sha256:a3c89a8e9ba0aeb17382836cdb73c516d0ecf6630ec40ec28288f3ed459ce87b",
|
||||
"sha256:aa3a917ed752ba3e0b242234b2a373f9c4e2a75d35291dcbe977649bd21fd108"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.8.7"
|
||||
"version": "==1.8.6"
|
||||
},
|
||||
"wsproto": {
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
"sha256:2218cb57952d90b9fca325c0dcfb08c3bda93e8fd8070b0a17f048e2e47a521b",
|
||||
"sha256:a2e56bfd5c7cd83c1369d83b5feccd6d37798b74872866e62616e0ecf111bda8"
|
||||
"sha256:c70410551488251b0fee67b460fb9a536af8d6f9f008ad10ac51f615b6a521b1",
|
||||
"sha256:e0d9e63797e483a30d27e09fffd308c59a700d365ec34e93cc100844168bf921"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==1.1.0"
|
||||
"version": "==1.2.0"
|
||||
},
|
||||
"zope.component": {
|
||||
"hashes": [
|
||||
"sha256:32cbe426ba8fa7b62ce5b211f80f0718a0c749cc7ff09e3f4b43a57f7ccdf5e5",
|
||||
"sha256:e955eb9f1e55d30e2d8097c8baa9ee012c356887eef3b0d43e6bfcd4868221e5"
|
||||
"sha256:607628e4c84f7887a69a958542b5c304663e726b73aba0882e3a3f059bff14f3",
|
||||
"sha256:91628918218b3e6f6323de2a7b845e09ddc5cae131c034896c051b084bba3c92"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==5.0.1"
|
||||
"version": "==4.6.2"
|
||||
},
|
||||
"zope.deferredimport": {
|
||||
"hashes": [
|
||||
"sha256:57b2345e7b5eef47efcd4f634ff16c93e4265de3dcf325afc7315ade48d909e1",
|
||||
"sha256:9a0c211df44aa95f1c4e6d2626f90b400f56989180d3ef96032d708da3d23e0a"
|
||||
],
|
||||
"version": "==4.3.1"
|
||||
},
|
||||
"zope.deprecation": {
|
||||
"hashes": [
|
||||
"sha256:0d453338f04bacf91bbfba545d8bcdf529aa829e67b705eac8c1a7fdce66e2df",
|
||||
"sha256:f1480b74995958b24ce37b0ef04d3663d2683e5d6debc96726eff18acf4ea113"
|
||||
],
|
||||
"version": "==4.4.0"
|
||||
},
|
||||
"zope.event": {
|
||||
"hashes": [
|
||||
|
@ -535,96 +523,150 @@
|
|||
},
|
||||
"zope.hookable": {
|
||||
"hashes": [
|
||||
"sha256:031e7672540685dc9d07565f2b968c6e21c7899c9391da58a23e63f229a8fdcd",
|
||||
"sha256:14bac9afd00e9577227749b37dfc3b9fe4f4fb855923262fc016be47baa42712",
|
||||
"sha256:16c0748438f716894cb61f3ed00adaa65359a5abe7a12bb44d7133d4b0cd3453",
|
||||
"sha256:1da8d3386238983e97302b2cbdb510e126968e65e3cb8a8745da9744655001fc",
|
||||
"sha256:24e4489ccf0dbd4c0e9d2d8b845b46994debb30cc22f96da76e973f9cb582799",
|
||||
"sha256:3111fbc3ddae5d98655691ff81b1c71bd7ad0c3bcf2c2ef659fdc8e66f664603",
|
||||
"sha256:34a84e15f2e6a3b2e372a67f7d845a372e3f0438319f26dfe9b7cb66ab75be44",
|
||||
"sha256:35320d283a364c42dbf91694066bc1e7f07628bbd5ec87c1ae08143036e1de49",
|
||||
"sha256:43855fbab9fb949fa14b5bbcf4c471e4d359428c2196061efe0d82fe3b387101",
|
||||
"sha256:4711443b964bf7ace58780a3473f520151de8d441e57583b8d8cd8a231fb7656",
|
||||
"sha256:49427208d9f65e5aa7df5c1be4dc818c51da34e261f4e52fe944a695ae90e3b3",
|
||||
"sha256:4dbdfe522741effbb507d55354664c93c81db6db66ca124c981d1e3a41e5a31b",
|
||||
"sha256:4dc9693fa28a238f063ba169110ef4199e0f86f9f976b57824c1d742eb21ad2e",
|
||||
"sha256:64337672794b01d039e2380d11dd895ab17043530f27b5e3e0709a11fbe5b532",
|
||||
"sha256:7067a450b15c8d41d00060890573ddc06f3414e62173dac55b38f6683920c20e",
|
||||
"sha256:7091df7b4d6d897dd00e8717f0fa62b020e28aabe54a92005df22130ed204f6f",
|
||||
"sha256:7b63de104e531109f606d4e3765b82fa3364e387d63b71a02460d321e24b33c8",
|
||||
"sha256:7ef3128b5bcb97029c19df95126f57638afe6d2aca0ffede989149fa0bbd744a",
|
||||
"sha256:800f93479202b05e46ba7696a2dd5411cfdd9d87c47a7d2b6fcda5394a5f9042",
|
||||
"sha256:84dfb4f5189c8a3b70dfdf0d268840d5dce69048d4767120910f4665fa5ee2f3",
|
||||
"sha256:8cf9982d43f6a732d041cf68b08fa969e5bcf090212ab519a637c8a393015eda",
|
||||
"sha256:8fc3e6cd0486c6af48e3317c299def719b57538332a194e0b3bc6a772f4faa0e",
|
||||
"sha256:a766186b97e493928dfac4a4b6c7508e47411e78c6f3be9846e8981eb91542d4",
|
||||
"sha256:bfd1b1107a51ddfbd628c1ff884c6a67e92519b23012563b6082d438dbd16b9d",
|
||||
"sha256:cbcbf6d31092caafb40ab26d07c065bf4f60f3ba7925d23d51a4e19469034544",
|
||||
"sha256:cf27270212fa51005162d75cae83bb943c84ece7c7f8d30d68efebfad2f469d9",
|
||||
"sha256:cf7f1f973aeced06ab1a245faa71e867cec6a053b807c2aad4c1728964aac071",
|
||||
"sha256:de77a946ef020d08643647e417713ed753a2eed1f4495259c38a241c8eb31dbf",
|
||||
"sha256:e3b01e7cf16b4a3257ee05e4c354737a4f64af302846826c46a296a7944b8da9",
|
||||
"sha256:ff08276e555f2ef262fd03d872cca130e7ee376b87d7651a5595aae2fa5b2425"
|
||||
"sha256:0194b9b9e7f614abba60c90b231908861036578297515d3d6508eb10190f266d",
|
||||
"sha256:0c2977473918bdefc6fa8dfb311f154e7f13c6133957fe649704deca79b92093",
|
||||
"sha256:17b8bdb3b77e03a152ca0d5ca185a7ae0156f5e5a2dbddf538676633a1f7380f",
|
||||
"sha256:29d07681a78042cdd15b268ae9decffed9ace68a53eebeb61d65ae931d158841",
|
||||
"sha256:36fb1b35d1150267cb0543a1ddd950c0bc2c75ed0e6e92e3aaa6ac2e29416cb7",
|
||||
"sha256:3aed60c2bb5e812bbf9295c70f25b17ac37c233f30447a96c67913ba5073642f",
|
||||
"sha256:3cac1565cc768911e72ca9ec4ddf5c5109e1fef0104f19f06649cf1874943b60",
|
||||
"sha256:3d4bc0cc4a37c3cd3081063142eeb2125511db3c13f6dc932d899c512690378e",
|
||||
"sha256:3f73096f27b8c28be53ffb6604f7b570fbbb82f273c6febe5f58119009b59898",
|
||||
"sha256:522d1153d93f2d48aa0bd9fb778d8d4500be2e4dcf86c3150768f0e3adbbc4ef",
|
||||
"sha256:523d2928fb7377bbdbc9af9c0b14ad73e6eaf226349f105733bdae27efd15b5a",
|
||||
"sha256:5848309d4fc5c02150a45e8f8d2227e5bfda386a508bbd3160fed7c633c5a2fa",
|
||||
"sha256:6781f86e6d54a110980a76e761eb54590630fd2af2a17d7edf02a079d2646c1d",
|
||||
"sha256:6fd27921ebf3aaa945fa25d790f1f2046204f24dba4946f82f5f0a442577c3e9",
|
||||
"sha256:70d581862863f6bf9e175e85c9d70c2d7155f53fb04dcdb2f73cf288ca559a53",
|
||||
"sha256:81867c23b0dc66c8366f351d00923f2bc5902820a24c2534dfd7bf01a5879963",
|
||||
"sha256:81db29edadcbb740cd2716c95a297893a546ed89db1bfe9110168732d7f0afdd",
|
||||
"sha256:86bd12624068cea60860a0759af5e2c3adc89c12aef6f71cf12f577e28deefe3",
|
||||
"sha256:9c184d8f9f7a76e1ced99855ccf390ffdd0ec3765e5cbf7b9cada600accc0a1e",
|
||||
"sha256:acc789e8c29c13555e43fe4bf9fcd15a65512c9645e97bbaa5602e3201252b02",
|
||||
"sha256:afaa740206b7660d4cc3b8f120426c85761f51379af7a5b05451f624ad12b0af",
|
||||
"sha256:b5f5fa323f878bb16eae68ea1ba7f6c0419d4695d0248bed4b18f51d7ce5ab85",
|
||||
"sha256:bd89e0e2c67bf4ac3aca2a19702b1a37269fb1923827f68324ac2e7afd6e3406",
|
||||
"sha256:c212de743283ec0735db24ec6ad913758df3af1b7217550ff270038062afd6ae",
|
||||
"sha256:ca553f524293a0bdea05e7f44c3e685e4b7b022cb37d87bc4a3efa0f86587a8d",
|
||||
"sha256:cab67065a3db92f636128d3157cc5424a145f82d96fb47159c539132833a6d36",
|
||||
"sha256:d3b3b3eedfdbf6b02898216e85aa6baf50207f4378a2a6803d6d47650cd37031",
|
||||
"sha256:d9f4a5a72f40256b686d31c5c0b1fde503172307beb12c1568296e76118e402c",
|
||||
"sha256:df5067d87aaa111ed5d050e1ee853ba284969497f91806efd42425f5348f1c06",
|
||||
"sha256:e2587644812c6138f05b8a41594a8337c6790e3baf9a01915e52438c13fc6bef",
|
||||
"sha256:e27fd877662db94f897f3fd532ef211ca4901eb1a70ba456f15c0866a985464a",
|
||||
"sha256:e427ebbdd223c72e06ba94c004bb04e996c84dec8a0fa84e837556ae145c439e",
|
||||
"sha256:e583ad4309c203ef75a09d43434cf9c2b4fa247997ecb0dcad769982c39411c7",
|
||||
"sha256:e760b2bc8ece9200804f0c2b64d10147ecaf18455a2a90827fbec4c9d84f3ad5",
|
||||
"sha256:ea9a9cc8bcc70e18023f30fa2f53d11ae069572a162791224e60cd65df55fb69",
|
||||
"sha256:ecb3f17dce4803c1099bd21742cd126b59817a4e76a6544d31d2cca6e30dbffd",
|
||||
"sha256:ed794e3b3de42486d30444fb60b5561e724ee8a2d1b17b0c2e0f81e3ddaf7a87",
|
||||
"sha256:ee885d347279e38226d0a437b6a932f207f691c502ee565aba27a7022f1285df",
|
||||
"sha256:fd5e7bc5f24f7e3d490698f7b854659a9851da2187414617cd5ed360af7efd63",
|
||||
"sha256:fe45f6870f7588ac7b2763ff1ce98cce59369717afe70cc353ec5218bc854bcc"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==5.1.0"
|
||||
"version": "==5.0.1"
|
||||
},
|
||||
"zope.interface": {
|
||||
"hashes": [
|
||||
"sha256:08f9636e99a9d5410181ba0729e0408d3d8748026ea938f3b970a0249daa8192",
|
||||
"sha256:0b465ae0962d49c68aa9733ba92a001b2a0933c317780435f00be7ecb959c702",
|
||||
"sha256:0cba8477e300d64a11a9789ed40ee8932b59f9ee05f85276dbb4b59acee5dd09",
|
||||
"sha256:0cee5187b60ed26d56eb2960136288ce91bcf61e2a9405660d271d1f122a69a4",
|
||||
"sha256:0ea1d73b7c9dcbc5080bb8aaffb776f1c68e807767069b9ccdd06f27a161914a",
|
||||
"sha256:0f91b5b948686659a8e28b728ff5e74b1be6bf40cb04704453617e5f1e945ef3",
|
||||
"sha256:15e7d1f7a6ee16572e21e3576d2012b2778cbacf75eb4b7400be37455f5ca8bf",
|
||||
"sha256:17776ecd3a1fdd2b2cd5373e5ef8b307162f581c693575ec62e7c5399d80794c",
|
||||
"sha256:194d0bcb1374ac3e1e023961610dc8f2c78a0f5f634d0c737691e215569e640d",
|
||||
"sha256:1c0e316c9add0db48a5b703833881351444398b04111188069a26a61cfb4df78",
|
||||
"sha256:205e40ccde0f37496904572035deea747390a8b7dc65146d30b96e2dd1359a83",
|
||||
"sha256:273f158fabc5ea33cbc936da0ab3d4ba80ede5351babc4f577d768e057651531",
|
||||
"sha256:2876246527c91e101184f63ccd1d716ec9c46519cc5f3d5375a3351c46467c46",
|
||||
"sha256:2c98384b254b37ce50eddd55db8d381a5c53b4c10ee66e1e7fe749824f894021",
|
||||
"sha256:2e5a26f16503be6c826abca904e45f1a44ff275fdb7e9d1b75c10671c26f8b94",
|
||||
"sha256:334701327f37c47fa628fc8b8d28c7d7730ce7daaf4bda1efb741679c2b087fc",
|
||||
"sha256:3748fac0d0f6a304e674955ab1365d515993b3a0a865e16a11ec9d86fb307f63",
|
||||
"sha256:3c02411a3b62668200910090a0dff17c0b25aaa36145082a5a6adf08fa281e54",
|
||||
"sha256:3dd4952748521205697bc2802e4afac5ed4b02909bb799ba1fe239f77fd4e117",
|
||||
"sha256:3f24df7124c323fceb53ff6168da70dbfbae1442b4f3da439cd441681f54fe25",
|
||||
"sha256:469e2407e0fe9880ac690a3666f03eb4c3c444411a5a5fddfdabc5d184a79f05",
|
||||
"sha256:4de4bc9b6d35c5af65b454d3e9bc98c50eb3960d5a3762c9438df57427134b8e",
|
||||
"sha256:5208ebd5152e040640518a77827bdfcc73773a15a33d6644015b763b9c9febc1",
|
||||
"sha256:52de7fc6c21b419078008f697fd4103dbc763288b1406b4562554bd47514c004",
|
||||
"sha256:5bb3489b4558e49ad2c5118137cfeaf59434f9737fa9c5deefc72d22c23822e2",
|
||||
"sha256:5dba5f530fec3f0988d83b78cc591b58c0b6eb8431a85edd1569a0539a8a5a0e",
|
||||
"sha256:5dd9ca406499444f4c8299f803d4a14edf7890ecc595c8b1c7115c2342cadc5f",
|
||||
"sha256:5f931a1c21dfa7a9c573ec1f50a31135ccce84e32507c54e1ea404894c5eb96f",
|
||||
"sha256:63b82bb63de7c821428d513607e84c6d97d58afd1fe2eb645030bdc185440120",
|
||||
"sha256:66c0061c91b3b9cf542131148ef7ecbecb2690d48d1612ec386de9d36766058f",
|
||||
"sha256:6f0c02cbb9691b7c91d5009108f975f8ffeab5dff8f26d62e21c493060eff2a1",
|
||||
"sha256:71aace0c42d53abe6fc7f726c5d3b60d90f3c5c055a447950ad6ea9cec2e37d9",
|
||||
"sha256:7d97a4306898b05404a0dcdc32d9709b7d8832c0c542b861d9a826301719794e",
|
||||
"sha256:7df1e1c05304f26faa49fa752a8c690126cf98b40b91d54e6e9cc3b7d6ffe8b7",
|
||||
"sha256:8270252effc60b9642b423189a2fe90eb6b59e87cbee54549db3f5562ff8d1b8",
|
||||
"sha256:867a5ad16892bf20e6c4ea2aab1971f45645ff3102ad29bd84c86027fa99997b",
|
||||
"sha256:877473e675fdcc113c138813a5dd440da0769a2d81f4d86614e5d62b69497155",
|
||||
"sha256:8892f89999ffd992208754851e5a052f6b5db70a1e3f7d54b17c5211e37a98c7",
|
||||
"sha256:9a9845c4c6bb56e508651f005c4aeb0404e518c6f000d5a1123ab077ab769f5c",
|
||||
"sha256:a1e6e96217a0f72e2b8629e271e1b280c6fa3fe6e59fa8f6701bec14e3354325",
|
||||
"sha256:a8156e6a7f5e2a0ff0c5b21d6bcb45145efece1909efcbbbf48c56f8da68221d",
|
||||
"sha256:a9506a7e80bcf6eacfff7f804c0ad5350c8c95b9010e4356a4b36f5322f09abb",
|
||||
"sha256:af310ec8335016b5e52cae60cda4a4f2a60a788cbb949a4fbea13d441aa5a09e",
|
||||
"sha256:b0297b1e05fd128d26cc2460c810d42e205d16d76799526dfa8c8ccd50e74959",
|
||||
"sha256:bf68f4b2b6683e52bec69273562df15af352e5ed25d1b6641e7efddc5951d1a7",
|
||||
"sha256:d0c1bc2fa9a7285719e5678584f6b92572a5b639d0e471bb8d4b650a1a910920",
|
||||
"sha256:d4d9d6c1a455d4babd320203b918ccc7fcbefe308615c521062bc2ba1aa4d26e",
|
||||
"sha256:db1fa631737dab9fa0b37f3979d8d2631e348c3b4e8325d6873c2541d0ae5a48",
|
||||
"sha256:dd93ea5c0c7f3e25335ab7d22a507b1dc43976e1345508f845efc573d3d779d8",
|
||||
"sha256:f44e517131a98f7a76696a7b21b164bcb85291cee106a23beccce454e1f433a4",
|
||||
"sha256:f7ee479e96f7ee350db1cf24afa5685a5899e2b34992fb99e1f7c1b0b758d263"
|
||||
"sha256:05a97ba92c1c7c26f25c9f671aa1ef85ffead6cdad13770e5b689cf983adc7e1",
|
||||
"sha256:07d61722dd7d85547b7c6b0f5486b4338001fab349f2ac5cabc0b7182eb3425d",
|
||||
"sha256:0a990dcc97806e5980bbb54b2e46b9cde9e48932d8e6984daf71ef1745516123",
|
||||
"sha256:150e8bcb7253a34a4535aeea3de36c0bb3b1a6a47a183a95d65a194b3e07f232",
|
||||
"sha256:1743bcfe45af8846b775086471c28258f4c6e9ee8ef37484de4495f15a98b549",
|
||||
"sha256:1b5f6c8fff4ed32aa2dd43e84061bc8346f32d3ba6ad6e58f088fe109608f102",
|
||||
"sha256:21e49123f375703cf824214939d39df0af62c47d122d955b2a8d9153ea08cfd5",
|
||||
"sha256:21f579134a47083ffb5ddd1307f0405c91aa8b61ad4be6fd5af0171474fe0c45",
|
||||
"sha256:27c267dc38a0f0079e96a2945ee65786d38ef111e413c702fbaaacbab6361d00",
|
||||
"sha256:299bde0ab9e5c4a92f01a152b7fbabb460f31343f1416f9b7b983167ab1e33bc",
|
||||
"sha256:2ab88d8f228f803fcb8cb7d222c579d13dab2d3622c51e8cf321280da01102a7",
|
||||
"sha256:2ced4c35061eea623bc84c7711eedce8ecc3c2c51cd9c6afa6290df3bae9e104",
|
||||
"sha256:2dcab01c660983ba5e5a612e0c935141ccbee67d2e2e14b833e01c2354bd8034",
|
||||
"sha256:32546af61a9a9b141ca38d971aa6eb9800450fa6620ce6323cc30eec447861f3",
|
||||
"sha256:32b40a4c46d199827d79c86bb8cb88b1bbb764f127876f2cb6f3a47f63dbada3",
|
||||
"sha256:3cc94c69f6bd48ed86e8e24f358cb75095c8129827df1298518ab860115269a4",
|
||||
"sha256:42b278ac0989d6f5cf58d7e0828ea6b5951464e3cf2ff229dd09a96cb6ba0c86",
|
||||
"sha256:495b63fd0302f282ee6c1e6ea0f1c12cb3d1a49c8292d27287f01845ff252a96",
|
||||
"sha256:4af87cdc0d4b14e600e6d3d09793dce3b7171348a094ba818e2a68ae7ee67546",
|
||||
"sha256:4b94df9f2fdde7b9314321bab8448e6ad5a23b80542dcab53e329527d4099dcb",
|
||||
"sha256:4c48ddb63e2b20fba4c6a2bf81b4d49e99b6d4587fb67a6cd33a2c1f003af3e3",
|
||||
"sha256:4df9afd17bd5477e9f8c8b6bb8507e18dd0f8b4efe73bb99729ff203279e9e3b",
|
||||
"sha256:518950fe6a5d56f94ba125107895f938a4f34f704c658986eae8255edb41163b",
|
||||
"sha256:538298e4e113ccb8b41658d5a4b605bebe75e46a30ceca22a5a289cf02c80bec",
|
||||
"sha256:55465121e72e208a7b69b53de791402affe6165083b2ea71b892728bd19ba9ae",
|
||||
"sha256:588384d70a0f19b47409cfdb10e0c27c20e4293b74fc891df3d8eb47782b8b3e",
|
||||
"sha256:6278c080d4afffc9016e14325f8734456831124e8c12caa754fd544435c08386",
|
||||
"sha256:64ea6c221aeee4796860405e1aedec63424cda4202a7ad27a5066876db5b0fd2",
|
||||
"sha256:681dbb33e2b40262b33fd383bae63c36d33fd79fa1a8e4092945430744ffd34a",
|
||||
"sha256:6936aa9da390402d646a32a6a38d5409c2d2afb2950f045a7d02ab25a4e7d08d",
|
||||
"sha256:778d0ec38bbd288b150a3ae363c8ffd88d2207a756842495e9bffd8a8afbc89a",
|
||||
"sha256:8251f06a77985a2729a8bdbefbae79ee78567dddc3acbd499b87e705ca59fe24",
|
||||
"sha256:83b4aa5344cce005a9cff5d0321b2e318e871cc1dfc793b66c32dd4f59e9770d",
|
||||
"sha256:844fad925ac5c2ad4faaceb3b2520ad016b5280105c6e16e79838cf951903a7b",
|
||||
"sha256:8ceb3667dd13b8133f2e4d637b5b00f240f066448e2aa89a41f4c2d78a26ce50",
|
||||
"sha256:92dc0fb79675882d0b6138be4bf0cec7ea7c7eede60aaca78303d8e8dbdaa523",
|
||||
"sha256:9789bd945e9f5bd026ed3f5b453d640befb8b1fc33a779c1fe8d3eb21fe3fb4a",
|
||||
"sha256:a2b6d6eb693bc2fc6c484f2e5d93bd0b0da803fa77bf974f160533e555e4d095",
|
||||
"sha256:aab9f1e34d810feb00bf841993552b8fcc6ae71d473c505381627143d0018a6a",
|
||||
"sha256:abb61afd84f23099ac6099d804cdba9bd3b902aaaded3ffff47e490b0a495520",
|
||||
"sha256:adf9ee115ae8ff8b6da4b854b4152f253b390ba64407a22d75456fe07dcbda65",
|
||||
"sha256:aedc6c672b351afe6dfe17ff83ee5e7eb6ed44718f879a9328a68bdb20b57e11",
|
||||
"sha256:b7a00ecb1434f8183395fac5366a21ee73d14900082ca37cf74993cf46baa56c",
|
||||
"sha256:ba32f4a91c1cb7314c429b03afbf87b1fff4fb1c8db32260e7310104bd77f0c7",
|
||||
"sha256:cbd0f2cbd8689861209cd89141371d3a22a11613304d1f0736492590aa0ab332",
|
||||
"sha256:e4bc372b953bf6cec65a8d48482ba574f6e051621d157cf224227dbb55486b1e",
|
||||
"sha256:eccac3d9aadc68e994b6d228cb0c8919fc47a5350d85a1b4d3d81d1e98baf40c",
|
||||
"sha256:efd550b3da28195746bb43bd1d815058181a7ca6d9d6aa89dd37f5eefe2cacb7",
|
||||
"sha256:efef581c8ba4d990770875e1a2218e856849d32ada2680e53aebc5d154a17e20",
|
||||
"sha256:f057897711a630a0b7a6a03f1acf379b6ba25d37dc5dc217a97191984ba7f2fc",
|
||||
"sha256:f37d45fab14ffef9d33a0dc3bc59ce0c5313e2253323312d47739192da94f5fd",
|
||||
"sha256:f44906f70205d456d503105023041f1e63aece7623b31c390a0103db4de17537"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==5.4.0"
|
||||
"version": "==5.2.0"
|
||||
},
|
||||
"zope.proxy": {
|
||||
"hashes": [
|
||||
"sha256:00573dfa755d0703ab84bb23cb6ecf97bb683c34b340d4df76651f97b0bab068",
|
||||
"sha256:092049280f2848d2ba1b57b71fe04881762a220a97b65288bcb0968bb199ec30",
|
||||
"sha256:0cbd27b4d3718b5ec74fc65ffa53c78d34c65c6fd9411b8352d2a4f855220cf1",
|
||||
"sha256:17fc7e16d0c81f833a138818a30f366696653d521febc8e892858041c4d88785",
|
||||
"sha256:19577dfeb70e8a67249ba92c8ad20589a1a2d86a8d693647fa8385408a4c17b0",
|
||||
"sha256:207aa914576b1181597a1516e1b90599dc690c095343ae281b0772e44945e6a4",
|
||||
"sha256:219a7db5ed53e523eb4a4769f13105118b6d5b04ed169a283c9775af221e231f",
|
||||
"sha256:2b50ea79849e46b5f4f2b0247a3687505d32d161eeb16a75f6f7e6cd81936e43",
|
||||
"sha256:5903d38362b6c716e66bbe470f190579c530a5baf03dbc8500e5c2357aa569a5",
|
||||
"sha256:5c24903675e271bd688c6e9e7df5775ac6b168feb87dbe0e4bcc90805f21b28f",
|
||||
"sha256:5ef6bc5ed98139e084f4e91100f2b098a0cd3493d4e76f9d6b3f7b95d7ad0f06",
|
||||
"sha256:61b55ae3c23a126a788b33ffb18f37d6668e79a05e756588d9e4d4be7246ab1c",
|
||||
"sha256:63ddb992931a5e616c87d3d89f5a58db086e617548005c7f9059fac68c03a5cc",
|
||||
"sha256:6943da9c09870490dcfd50c4909c0cc19f434fa6948f61282dc9cb07bcf08160",
|
||||
"sha256:6ad40f85c1207803d581d5d75e9ea25327cd524925699a83dfc03bf8e4ba72b7",
|
||||
"sha256:6b44433a79bdd7af0e3337bd7bbcf53dd1f9b0fa66bf21bcb756060ce32a96c1",
|
||||
"sha256:6bbaa245015d933a4172395baad7874373f162955d73612f0b66b6c2c33b6366",
|
||||
"sha256:7007227f4ea85b40a2f5e5a244479f6a6dfcf906db9b55e812a814a8f0e2c28d",
|
||||
"sha256:74884a0aec1f1609190ec8b34b5d58fb3b5353cf22b96161e13e0e835f13518f",
|
||||
"sha256:7d25fe5571ddb16369054f54cdd883f23de9941476d97f2b92eb6d7d83afe22d",
|
||||
"sha256:7e162bdc5e3baad26b2262240be7d2bab36991d85a6a556e48b9dfb402370261",
|
||||
"sha256:814d62678dc3a30f4aa081982d830b7c342cf230ffc9d030b020cb154eeebf9e",
|
||||
"sha256:8878a34c5313ee52e20aa50b03138af8d472bae465710fb954d133a9bfd3c38d",
|
||||
"sha256:a66a0d94e5b081d5d695e66d6667e91e74d79e273eee95c1747717ba9cb70792",
|
||||
"sha256:a69f5cbf4addcfdf03dda564a671040127a6b7c34cf9fe4973582e68441b63fa",
|
||||
"sha256:b00f9f0c334d07709d3f73a7cb8ae63c6ca1a90c790a63b5e7effa666ef96021",
|
||||
"sha256:b6ed71e4a7b4690447b626f499d978aa13197a0e592950e5d7020308f6054698",
|
||||
"sha256:bdf5041e5851526e885af579d2f455348dba68d74f14a32781933569a327fddf",
|
||||
"sha256:be034360dd34e62608419f86e799c97d389c10a0e677a25f236a971b2f40dac9",
|
||||
"sha256:cc8f590a5eed30b314ae6b0232d925519ade433f663de79cc3783e4b10d662ba",
|
||||
"sha256:cd7a318a15fe6cc4584bf3c4426f092ed08c0fd012cf2a9173114234fe193e11",
|
||||
"sha256:cf19b5f63a59c20306e034e691402b02055c8f4e38bf6792c23cad489162a642",
|
||||
"sha256:cfc781ce442ec407c841e9aa51d0e1024f72b6ec34caa8fdb6ef9576d549acf2",
|
||||
"sha256:dea9f6f8633571e18bc20cad83603072e697103a567f4b0738d52dd0211b4527",
|
||||
"sha256:e4a86a1d5eb2cce83c5972b3930c7c1eac81ab3508464345e2b8e54f119d5505",
|
||||
"sha256:e7106374d4a74ed9ff00c46cc00f0a9f06a0775f8868e423f85d4464d2333679",
|
||||
"sha256:e98a8a585b5668aa9e34d10f7785abf9545fe72663b4bfc16c99a115185ae6a5",
|
||||
"sha256:f64840e68483316eb58d82c376ad3585ca995e69e33b230436de0cdddf7363f9",
|
||||
"sha256:f8f4b0a9e6683e43889852130595c8854d8ae237f2324a053cdd884de936aa9b",
|
||||
"sha256:fc45a53219ed30a7f670a6d8c98527af0020e6fd4ee4c0a8fb59f147f06d816c"
|
||||
],
|
||||
"version": "==4.3.5"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
|
|
|
@ -34,7 +34,7 @@ import org.mozilla.fenix.ui.robots.settingsSubMenuLoginsAndPassword
|
|||
|
||||
@Suppress("RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
|
||||
class SyncIntegrationTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
@get:Rule
|
||||
|
@ -42,7 +42,6 @@ class SyncIntegrationTest {
|
|||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -177,7 +176,7 @@ class SyncIntegrationTest {
|
|||
val emailInput = mDevice.findObject(
|
||||
UiSelector()
|
||||
.instance(0)
|
||||
.className(EditText::class.java),
|
||||
.className(EditText::class.java)
|
||||
)
|
||||
emailInput.waitForExists(TestAssetHelper.waitingTime)
|
||||
|
||||
|
@ -194,7 +193,7 @@ class SyncIntegrationTest {
|
|||
val passwordInput = mDevice.findObject(
|
||||
UiSelector()
|
||||
.instance(0)
|
||||
.className(EditText::class.java),
|
||||
.className(EditText::class.java)
|
||||
)
|
||||
|
||||
val passwordValue = javaClass.classLoader!!.getResource("password.txt").readText()
|
||||
|
|
|
@ -11,8 +11,8 @@ import mozversion
|
|||
import pytest
|
||||
import requests
|
||||
|
||||
from .tps import TPS
|
||||
from .gradlewbuild import GradlewBuild
|
||||
from tps import TPS
|
||||
from gradlewbuild import GradlewBuild
|
||||
|
||||
here = os.path.dirname(__file__)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import logging
|
|||
import os
|
||||
import subprocess
|
||||
|
||||
from .adbrun import ADBrun
|
||||
from adbrun import ADBrun
|
||||
|
||||
here = os.path.dirname(__file__)
|
||||
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
||||
|
@ -40,4 +40,4 @@ class GradlewBuild(object):
|
|||
os.chdir(testsPath)
|
||||
|
||||
with open(self.log, 'w') as f:
|
||||
f.write(str(out))
|
||||
f.write(out)
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.espresso.IdlingRegistry
|
||||
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import mozilla.appservices.places.BookmarkRoot
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
|
@ -18,17 +17,17 @@ import org.junit.Test
|
|||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.ext.bookmarkStorage
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem
|
||||
import org.mozilla.fenix.helpers.TestHelper.registerAndCleanupIdlingResources
|
||||
import org.mozilla.fenix.ui.robots.bookmarksMenu
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.mDevice
|
||||
import org.mozilla.fenix.ui.robots.multipleSelectionToolbar
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
|
@ -39,15 +38,15 @@ class BookmarksTest {
|
|||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private lateinit var mDevice: UiDevice
|
||||
private val bookmarksFolderName = "New Folder"
|
||||
private val testBookmark = object {
|
||||
var title: String = "Bookmark title"
|
||||
var url: String = "https://www.test.com"
|
||||
}
|
||||
private var bookmarksListIdlingResource: RecyclerViewIdlingResource? = null
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides()
|
||||
val activityTestRule = HomeActivityTestRule()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
|
@ -55,11 +54,12 @@ class BookmarksTest {
|
|||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
val settings = activityTestRule.activity.settings()
|
||||
settings.shouldShowJumpBackInCFR = false
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -71,6 +71,10 @@ class BookmarksTest {
|
|||
val bookmarks = bookmarksStorage?.getTree(BookmarkRoot.Mobile.id)?.children
|
||||
bookmarks?.forEach { bookmarksStorage.deleteNode(it.guid) }
|
||||
}
|
||||
|
||||
if (bookmarksListIdlingResource != null) {
|
||||
IdlingRegistry.getInstance().unregister(bookmarksListIdlingResource!!)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -78,14 +82,17 @@ class BookmarksTest {
|
|||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1),
|
||||
) {
|
||||
verifyBookmarksMenuView()
|
||||
verifyAddFolderButton()
|
||||
verifyCloseButton()
|
||||
verifyBookmarkTitle("Desktop Bookmarks")
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(
|
||||
activityTestRule.activity.findViewById(R.id.bookmark_list),
|
||||
1
|
||||
)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
|
||||
verifyBookmarksMenuView()
|
||||
verifyAddFolderButton()
|
||||
verifyCloseButton()
|
||||
verifyBookmarkTitle("Desktop Bookmarks")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,15 +101,15 @@ class BookmarksTest {
|
|||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1),
|
||||
) {
|
||||
selectFolder("Desktop Bookmarks")
|
||||
verifyFolderTitle("Bookmarks Menu")
|
||||
verifyFolderTitle("Bookmarks Toolbar")
|
||||
verifyFolderTitle("Other Bookmarks")
|
||||
verifySyncSignInButton()
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
|
||||
selectFolder("Desktop Bookmarks")
|
||||
verifyFolderTitle("Bookmarks Menu")
|
||||
verifyFolderTitle("Bookmarks Toolbar")
|
||||
verifyFolderTitle("Other Bookmarks")
|
||||
verifySignInToSyncButton()
|
||||
}.clickSingInToSyncButton {
|
||||
verifyTurnOnSyncToolbarTitle()
|
||||
}
|
||||
|
@ -129,12 +136,12 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {
|
||||
verifyBookmarkedURL(defaultWebPage.url.toString())
|
||||
verifyBookmarkFavicon(defaultWebPage.url)
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
|
||||
verifyBookmarkedURL(defaultWebPage.url.toString())
|
||||
verifyBookmarkFavicon(defaultWebPage.url)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,16 +150,16 @@ class BookmarksTest {
|
|||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1),
|
||||
) {
|
||||
clickAddFolderButton()
|
||||
verifyKeyboardVisible()
|
||||
addNewFolderName(bookmarksFolderName)
|
||||
saveNewFolder()
|
||||
verifyFolderTitle(bookmarksFolderName)
|
||||
verifyKeyboardHidden()
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
|
||||
clickAddFolderButton()
|
||||
verifyKeyboardVisible()
|
||||
addNewFolderName(bookmarksFolderName)
|
||||
saveNewFolder()
|
||||
verifyFolderTitle(bookmarksFolderName)
|
||||
verifyKeyboardHidden()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,9 +185,9 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
}.openThreeDotMenu(defaultWebPage.url) {
|
||||
}.clickEdit {
|
||||
verifyEditBookmarksView()
|
||||
|
@ -204,9 +211,9 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
}.openThreeDotMenu(defaultWebPage.url) {
|
||||
}.clickCopy {
|
||||
verifyCopySnackBarText()
|
||||
|
@ -218,7 +225,7 @@ class BookmarksTest {
|
|||
clickClearButton()
|
||||
longClickToolbar()
|
||||
clickPasteText()
|
||||
verifyTypedToolbarText(defaultWebPage.url.toString())
|
||||
verifyPastedToolbarText(defaultWebPage.url.toString())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,9 +237,9 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
}.openThreeDotMenu(defaultWebPage.url) {
|
||||
}.clickShare {
|
||||
verifyShareOverlay()
|
||||
|
@ -250,9 +257,9 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
}.openThreeDotMenu(defaultWebPage.url) {
|
||||
}.clickOpenInNewTab {
|
||||
verifyTabTrayIsOpened()
|
||||
|
@ -260,83 +267,6 @@ class BookmarksTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun openAllInTabsTest() {
|
||||
val webPages = listOf(
|
||||
TestAssetHelper.getGenericAsset(mockWebServer, 1),
|
||||
TestAssetHelper.getGenericAsset(mockWebServer, 2),
|
||||
TestAssetHelper.getGenericAsset(mockWebServer, 3),
|
||||
TestAssetHelper.getGenericAsset(mockWebServer, 4),
|
||||
)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
createFolder("root")
|
||||
createFolder("sub", "root")
|
||||
createFolder("empty", "root")
|
||||
}.closeMenu {
|
||||
}
|
||||
|
||||
browserScreen {
|
||||
createBookmark(webPages[0].url)
|
||||
createBookmark(webPages[1].url, "root")
|
||||
createBookmark(webPages[2].url, "root")
|
||||
createBookmark(webPages[3].url, "sub")
|
||||
}.openTabDrawer {
|
||||
closeTab()
|
||||
}
|
||||
|
||||
browserScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
}.openThreeDotMenu("root") {
|
||||
}.clickOpenAllInTabs {
|
||||
verifyTabTrayIsOpened()
|
||||
verifyNormalModeSelected()
|
||||
|
||||
verifyExistingOpenTabs("Test_Page_2", "Test_Page_3", "Test_Page_4")
|
||||
|
||||
// Bookmark that is not under the root folder should not be opened
|
||||
verifyNoExistingOpenTabs("Test_Page_1")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun openAllInPrivateTabsTest() {
|
||||
val webPages = listOf(
|
||||
TestAssetHelper.getGenericAsset(mockWebServer, 1),
|
||||
TestAssetHelper.getGenericAsset(mockWebServer, 2),
|
||||
)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
createFolder("root")
|
||||
createFolder("sub", "root")
|
||||
createFolder("empty", "root")
|
||||
}.closeMenu {
|
||||
}
|
||||
|
||||
browserScreen {
|
||||
createBookmark(webPages[0].url, "root")
|
||||
createBookmark(webPages[1].url, "sub")
|
||||
}.openTabDrawer {
|
||||
closeTab()
|
||||
}
|
||||
|
||||
browserScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
}.openThreeDotMenu("root") {
|
||||
}.clickOpenAllInPrivateTabs {
|
||||
verifyTabTrayIsOpened()
|
||||
verifyPrivateModeSelected()
|
||||
|
||||
verifyExistingOpenTabs("Test_Page_1", "Test_Page_2")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun openBookmarkInPrivateTabTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
@ -345,9 +275,9 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
}.openThreeDotMenu(defaultWebPage.url) {
|
||||
}.clickOpenInPrivateTab {
|
||||
verifyTabTrayIsOpened()
|
||||
|
@ -364,10 +294,11 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
}.openThreeDotMenu(defaultWebPage.url) {
|
||||
IdlingRegistry.getInstance().unregister(bookmarksListIdlingResource!!)
|
||||
}.clickDelete {
|
||||
verifyDeleteSnackBarText()
|
||||
verifyUndoDeleteSnackBarButton()
|
||||
|
@ -383,19 +314,19 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
}.openThreeDotMenu(defaultWebPage.url) {
|
||||
IdlingRegistry.getInstance().unregister(bookmarksListIdlingResource!!)
|
||||
}.clickDelete {
|
||||
verifyUndoDeleteSnackBarButton()
|
||||
clickUndoDeleteButton()
|
||||
verifySnackBarHidden()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {
|
||||
verifyBookmarkedURL(defaultWebPage.url.toString())
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
verifyBookmarkedURL(defaultWebPage.url.toString())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,11 +339,11 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {
|
||||
longTapSelectItem(defaultWebPage.url)
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
|
||||
longTapSelectItem(defaultWebPage.url)
|
||||
}
|
||||
|
||||
multipleSelectionToolbar {
|
||||
|
@ -428,6 +359,8 @@ class BookmarksTest {
|
|||
@SmokeTest
|
||||
@Test
|
||||
fun openSelectionInNewTabTest() {
|
||||
val settings = activityTestRule.activity.applicationContext.settings()
|
||||
settings.shouldShowJumpBackInCFR = false
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
browserScreen {
|
||||
|
@ -439,12 +372,12 @@ class BookmarksTest {
|
|||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {
|
||||
longTapSelectItem(defaultWebPage.url)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
|
||||
longTapSelectItem(defaultWebPage.url)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
}
|
||||
|
||||
multipleSelectionToolbar {
|
||||
|
@ -463,12 +396,12 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {
|
||||
longTapSelectItem(defaultWebPage.url)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
|
||||
longTapSelectItem(defaultWebPage.url)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
}
|
||||
|
||||
multipleSelectionToolbar {
|
||||
|
@ -489,12 +422,13 @@ class BookmarksTest {
|
|||
createBookmark(secondWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 3),
|
||||
) {
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
longTapSelectItem(secondWebPage.url)
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 3)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
longTapSelectItem(secondWebPage.url)
|
||||
IdlingRegistry.getInstance().unregister(bookmarksListIdlingResource!!)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
}
|
||||
|
||||
|
@ -518,12 +452,13 @@ class BookmarksTest {
|
|||
createBookmark(secondWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 3),
|
||||
) {
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
longTapSelectItem(secondWebPage.url)
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 3)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
longTapSelectItem(secondWebPage.url)
|
||||
IdlingRegistry.getInstance().unregister(bookmarksListIdlingResource!!)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
}
|
||||
|
||||
|
@ -547,11 +482,11 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {
|
||||
longTapSelectItem(defaultWebPage.url)
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
|
||||
longTapSelectItem(defaultWebPage.url)
|
||||
}
|
||||
|
||||
multipleSelectionToolbar {
|
||||
|
@ -585,8 +520,6 @@ class BookmarksTest {
|
|||
confirmDeletion()
|
||||
verifyDeleteSnackBarText()
|
||||
verifyFolderTitle("3")
|
||||
// On some devices we need to wait for the Snackbar to be gone before continuing
|
||||
TestHelper.waitUntilSnackbarGone()
|
||||
}.closeMenu {
|
||||
}
|
||||
|
||||
|
@ -606,19 +539,27 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {
|
||||
createFolder(bookmarksFolderName)
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
|
||||
createFolder(bookmarksFolderName)
|
||||
|
||||
IdlingRegistry.getInstance().unregister(bookmarksListIdlingResource!!)
|
||||
|
||||
}.openThreeDotMenu(defaultWebPage.title) {
|
||||
}.clickEdit {
|
||||
clickParentFolderSelector()
|
||||
selectFolder(bookmarksFolderName)
|
||||
navigateUp()
|
||||
saveEditBookmark()
|
||||
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
|
||||
selectFolder(bookmarksFolderName)
|
||||
verifyBookmarkedURL(defaultWebPage.url.toString())
|
||||
|
||||
IdlingRegistry.getInstance().unregister(bookmarksListIdlingResource!!)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -650,12 +591,12 @@ class BookmarksTest {
|
|||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list)),
|
||||
) {
|
||||
longTapDesktopFolder("Desktop Bookmarks")
|
||||
verifySelectDefaultFolderSnackBarText()
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list))
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
|
||||
longTapDesktopFolder("Desktop Bookmarks")
|
||||
verifySelectDefaultFolderSnackBarText()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -677,10 +618,11 @@ class BookmarksTest {
|
|||
createBookmark(defaultWebPage.url)
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
|
||||
) {}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
}.openThreeDotMenu(defaultWebPage.url) {
|
||||
IdlingRegistry.getInstance().unregister(bookmarksListIdlingResource!!)
|
||||
}.clickEdit {
|
||||
clickDeleteInEditModeButton()
|
||||
cancelDeletion()
|
||||
|
@ -694,15 +636,16 @@ class BookmarksTest {
|
|||
@SmokeTest
|
||||
@Test
|
||||
fun undoDeleteBookmarkFolderTest() {
|
||||
|
||||
browserScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openBookmarks {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1),
|
||||
) {
|
||||
createFolder("My Folder")
|
||||
verifyFolderTitle("My Folder")
|
||||
}
|
||||
bookmarksListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1)
|
||||
IdlingRegistry.getInstance().register(bookmarksListIdlingResource!!)
|
||||
createFolder("My Folder")
|
||||
verifyFolderTitle("My Folder")
|
||||
IdlingRegistry.getInstance().unregister(bookmarksListIdlingResource!!)
|
||||
}.openThreeDotMenu("My Folder") {
|
||||
}.clickDelete {
|
||||
cancelFolderDeletion()
|
||||
|
|
|
@ -5,10 +5,13 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestHelper.getStringResource
|
||||
|
@ -23,14 +26,26 @@ class BrowsingErrorPagesTest {
|
|||
private val unwantedSoftwareWarning =
|
||||
getStringResource(R.string.mozac_browser_errorpages_safe_browsing_unwanted_uri_title)
|
||||
private val harmfulSiteWarning = getStringResource(R.string.mozac_browser_errorpages_safe_harmful_uri_title)
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
|
||||
@get: Rule
|
||||
val mActivityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides()
|
||||
val mActivityTestRule = HomeActivityTestRule()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val retryTestRule = RetryTestRule(3)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
// disabling the jump-back-in pop-up that interferes with the tests.
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun blockMalwarePageTest() {
|
||||
|
|
|
@ -10,11 +10,11 @@ import androidx.test.uiautomator.UiDevice
|
|||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
|
@ -29,29 +29,28 @@ import org.mozilla.fenix.ui.robots.tabDrawer
|
|||
*/
|
||||
|
||||
class CollectionTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private val firstCollectionName = "testcollection_1"
|
||||
private val secondCollectionName = "testcollection_2"
|
||||
private val collectionName = "First Collection"
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
|
||||
@get:Rule
|
||||
val composeTestRule =
|
||||
AndroidComposeTestRule(
|
||||
HomeActivityIntentTestRule(
|
||||
isHomeOnboardingDialogEnabled = false,
|
||||
isJumpBackInCFREnabled = false,
|
||||
isRecentTabsFeatureEnabled = false,
|
||||
isRecentlyVisitedFeatureEnabled = false,
|
||||
isPocketEnabled = false,
|
||||
isWallpaperOnboardingEnabled = false,
|
||||
isTCPCFREnabled = false,
|
||||
),
|
||||
) { it.activity }
|
||||
val composeTestRule = AndroidComposeTestRule(
|
||||
HomeActivityIntentTestRule(),
|
||||
{ it.activity }
|
||||
)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
// disabling these features to have better visibility of Collections,
|
||||
// and to avoid multiple matches on tab items
|
||||
featureSettingsHelper.setRecentTabsFeatureEnabled(false)
|
||||
featureSettingsHelper.setPocketEnabled(false)
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
featureSettingsHelper.setRecentlyVisitedFeatureEnabled(false)
|
||||
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -61,6 +60,9 @@ class CollectionTest {
|
|||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
|
||||
// resetting modified features enabled setting to default
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
|
@ -77,6 +79,7 @@ class CollectionTest {
|
|||
}.submitQuery(secondWebPage.url.toString()) {
|
||||
mDevice.waitForIdle()
|
||||
}.goToHomescreen {
|
||||
swipeToBottom()
|
||||
}.clickSaveTabsToCollectionButton {
|
||||
longClickTab(firstWebPage.title)
|
||||
selectTab(secondWebPage.title, numOfTabs = 2)
|
||||
|
@ -160,7 +163,7 @@ class CollectionTest {
|
|||
createCollection(
|
||||
firstTestPage.title,
|
||||
secondTestPage.title,
|
||||
collectionName = collectionName,
|
||||
collectionName = collectionName
|
||||
)
|
||||
closeTab()
|
||||
}
|
||||
|
@ -201,10 +204,10 @@ class CollectionTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Test running on beta/release builds in CI:
|
||||
// caution when making changes to it, so they don't block the builds
|
||||
@SmokeTest
|
||||
@Test
|
||||
// Test running on beta/release builds in CI:
|
||||
// caution when making changes to it, so they don't block the builds
|
||||
fun deleteCollectionTest() {
|
||||
val webPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -227,8 +230,8 @@ class CollectionTest {
|
|||
}
|
||||
}
|
||||
|
||||
// open a webpage, and add currently opened tab to existing collection
|
||||
@Test
|
||||
// open a webpage, and add currently opened tab to existing collection
|
||||
fun mainMenuSaveToExistingCollection() {
|
||||
val firstWebPage = getGenericAsset(mockWebServer, 1)
|
||||
val secondWebPage = getGenericAsset(mockWebServer, 2)
|
||||
|
@ -310,9 +313,8 @@ class CollectionTest {
|
|||
createCollection(webPage.title, collectionName = firstCollectionName)
|
||||
verifySnackBarText("Collection saved!")
|
||||
createCollection(
|
||||
webPage.title,
|
||||
collectionName = secondCollectionName,
|
||||
firstCollection = false,
|
||||
webPage.title, collectionName = secondCollectionName,
|
||||
firstCollection = false
|
||||
)
|
||||
verifySnackBarText("Collection saved!")
|
||||
}.closeTabDrawer {
|
||||
|
@ -354,7 +356,7 @@ class CollectionTest {
|
|||
}.openTabDrawer {
|
||||
createCollection(
|
||||
testPage.title,
|
||||
collectionName = collectionName,
|
||||
collectionName = collectionName
|
||||
)
|
||||
closeTab()
|
||||
}
|
||||
|
@ -380,7 +382,7 @@ class CollectionTest {
|
|||
}.openTabDrawer {
|
||||
createCollection(
|
||||
testPage.title,
|
||||
collectionName = collectionName,
|
||||
collectionName = collectionName
|
||||
)
|
||||
closeTab()
|
||||
}
|
||||
|
@ -397,7 +399,6 @@ class CollectionTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087")
|
||||
fun selectTabOnLongTapTest() {
|
||||
val firstWebPage = getGenericAsset(mockWebServer, 1)
|
||||
val secondWebPage = getGenericAsset(mockWebServer, 2)
|
||||
|
@ -429,7 +430,6 @@ class CollectionTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087")
|
||||
fun navigateBackInCollectionFlowTest() {
|
||||
val webPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -463,7 +463,6 @@ class CollectionTest {
|
|||
|
||||
@SmokeTest
|
||||
@Test
|
||||
@Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087")
|
||||
fun undoDeleteCollectionTest() {
|
||||
val webPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -482,7 +481,7 @@ class CollectionTest {
|
|||
|
||||
homeScreen {
|
||||
verifySnackBarText("Collection deleted")
|
||||
clickUndoSnackBarButton()
|
||||
clickUndoCollectionDeletion("UNDO")
|
||||
verifyCollectionIsDisplayed(collectionName, true)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import androidx.test.uiautomator.UiDevice
|
|||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
|
@ -36,11 +37,11 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
|
|||
*/
|
||||
|
||||
class ContextMenusTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
@get:Rule
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
|
@ -49,7 +50,6 @@ class ContextMenusTest {
|
|||
@Before
|
||||
fun setUp() {
|
||||
activityIntentTestRule.activity.applicationContext.settings().shouldShowJumpBackInCFR = false
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -72,7 +72,7 @@ class ContextMenusTest {
|
|||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(pageLinks.url) {
|
||||
mDevice.waitForIdle()
|
||||
longClickLink("Link 1")
|
||||
longClickMatchingText("Link 1")
|
||||
verifyLinkContextMenuItems(genericURL.url)
|
||||
clickContextOpenLinkInNewTab()
|
||||
verifySnackBarText("New tab opened")
|
||||
|
@ -96,7 +96,7 @@ class ContextMenusTest {
|
|||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(pageLinks.url) {
|
||||
mDevice.waitForIdle()
|
||||
longClickLink("Link 2")
|
||||
longClickMatchingText("Link 2")
|
||||
verifyLinkContextMenuItems(genericURL.url)
|
||||
clickContextOpenLinkInPrivateTab()
|
||||
verifySnackBarText("New private tab opened")
|
||||
|
@ -118,23 +118,6 @@ class ContextMenusTest {
|
|||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(pageLinks.url) {
|
||||
mDevice.waitForIdle()
|
||||
longClickLink("Link 3")
|
||||
verifyLinkContextMenuItems(genericURL.url)
|
||||
clickContextCopyLink()
|
||||
verifySnackBarText("Link copied to clipboard")
|
||||
}.openNavigationToolbar {
|
||||
}.visitLinkFromClipboard {
|
||||
verifyUrl(genericURL.url.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyContextCopyLinkNotDisplayedAfterApplied() {
|
||||
val pageLinks = TestAssetHelper.getGenericAsset(mockWebServer, 4)
|
||||
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 3)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(pageLinks.url) {
|
||||
longClickMatchingText("Link 3")
|
||||
verifyLinkContextMenuItems(genericURL.url)
|
||||
clickContextCopyLink()
|
||||
|
@ -142,11 +125,6 @@ class ContextMenusTest {
|
|||
}.openNavigationToolbar {
|
||||
}.visitLinkFromClipboard {
|
||||
verifyUrl(genericURL.url.toString())
|
||||
}.openTabDrawer {
|
||||
}.openNewTab {
|
||||
}
|
||||
navigationToolbar {
|
||||
verifyClipboardSuggestionsAreDisplayed(shouldBeDisplayed = false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,7 +138,7 @@ class ContextMenusTest {
|
|||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(pageLinks.url) {
|
||||
mDevice.waitForIdle()
|
||||
longClickLink("Link 1")
|
||||
longClickMatchingText("Link 1")
|
||||
verifyLinkContextMenuItems(genericURL.url)
|
||||
clickContextShareLink(genericURL.url) // verify share intent is matched with associated URL
|
||||
}
|
||||
|
@ -176,7 +154,7 @@ class ContextMenusTest {
|
|||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(pageLinks.url) {
|
||||
mDevice.waitForIdle()
|
||||
longClickLink("test_link_image")
|
||||
longClickMatchingText("test_link_image")
|
||||
verifyLinkImageContextMenuItems(imageResource.url)
|
||||
clickContextOpenImageNewTab()
|
||||
verifySnackBarText("New tab opened")
|
||||
|
@ -195,7 +173,7 @@ class ContextMenusTest {
|
|||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(pageLinks.url) {
|
||||
mDevice.waitForIdle()
|
||||
longClickLink("test_link_image")
|
||||
longClickMatchingText("test_link_image")
|
||||
verifyLinkImageContextMenuItems(imageResource.url)
|
||||
clickContextCopyImageLocation()
|
||||
verifySnackBarText("Link copied to clipboard")
|
||||
|
@ -215,7 +193,7 @@ class ContextMenusTest {
|
|||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(pageLinks.url) {
|
||||
mDevice.waitForIdle()
|
||||
longClickLink("test_link_image")
|
||||
longClickMatchingText("test_link_image")
|
||||
verifyLinkImageContextMenuItems(imageResource.url)
|
||||
clickContextSaveImage()
|
||||
}
|
||||
|
@ -228,6 +206,7 @@ class ContextMenusTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Failing with frequent ANR: https://bugzilla.mozilla.org/show_bug.cgi?id=1764605")
|
||||
@Test
|
||||
fun verifyContextMixedVariations() {
|
||||
val pageLinks =
|
||||
|
@ -240,13 +219,13 @@ class ContextMenusTest {
|
|||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(pageLinks.url) {
|
||||
mDevice.waitForIdle()
|
||||
longClickLink("Link 1")
|
||||
longClickMatchingText("Link 1")
|
||||
verifyLinkContextMenuItems(genericURL.url)
|
||||
dismissContentContextMenu(genericURL.url)
|
||||
longClickLink("test_link_image")
|
||||
longClickMatchingText("test_link_image")
|
||||
verifyLinkImageContextMenuItems(imageResource.url)
|
||||
dismissContentContextMenu(imageResource.url)
|
||||
longClickLink("test_no_link_image")
|
||||
longClickMatchingText("test_no_link_image")
|
||||
verifyNoLinkImageContextMenuItems(imageResource.url)
|
||||
}
|
||||
}
|
||||
|
@ -258,12 +237,13 @@ class ContextMenusTest {
|
|||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(genericURL.url) {
|
||||
longClickLink(genericURL.content)
|
||||
longClickMatchingText(genericURL.content)
|
||||
}.clickShareSelectedText {
|
||||
verifyAndroidShareLayout()
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/24457")
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun selectAndSearchTextTest() {
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.ui
|
||||
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
/**
|
||||
* Tests for verifying the new Cookie protection & homescreen feature hints.
|
||||
* Note: This involves setting the feature flags On for CFRs which are disabled elsewhere.
|
||||
*
|
||||
*/
|
||||
class ContextualHintsTest {
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityTestRule(
|
||||
isJumpBackInCFREnabled = true,
|
||||
isTCPCFREnabled = true,
|
||||
isPocketEnabled = false,
|
||||
isRecentlyVisitedFeatureEnabled = false,
|
||||
)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun jumpBackInCFRTest() {
|
||||
val genericPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(genericPage.url) {
|
||||
verifyCookiesProtectionHint()
|
||||
// One back press to dismiss the TCP hint
|
||||
mDevice.pressBack()
|
||||
}.goToHomescreen {
|
||||
verifyJumpBackInMessage()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun cookieProtectionHintTest() {
|
||||
val genericPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(genericPage.url) {
|
||||
verifyCookiesProtectionHint()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
|
@ -12,30 +10,31 @@ import org.junit.Test
|
|||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.getStringResource
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.mDevice
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
class CrashReportingTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
private val tabCrashMessage = getStringResource(R.string.tab_crash_title_2)
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = AndroidComposeTestRule(
|
||||
HomeActivityIntentTestRule(
|
||||
isPocketEnabled = false,
|
||||
isJumpBackInCFREnabled = false,
|
||||
isWallpaperOnboardingEnabled = false,
|
||||
isTCPCFREnabled = false,
|
||||
),
|
||||
) { it.activity }
|
||||
HomeActivityIntentTestRule(),
|
||||
{ it.activity }
|
||||
)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
featureSettingsHelper.setPocketEnabled(false)
|
||||
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -45,6 +44,7 @@ class CrashReportingTest {
|
|||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -74,6 +74,7 @@ class CrashReportingTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/25029")
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun useAppWhileTabIsCrashedTest() {
|
||||
|
@ -119,6 +120,7 @@ class CrashReportingTest {
|
|||
}.openNewTab {
|
||||
}.submitQuery(secondWebPage.url.toString()) {
|
||||
waitForPageToLoad()
|
||||
verifyPageContent("Page content: 2")
|
||||
}
|
||||
|
||||
navigationToolbar {
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
|
@ -14,23 +12,21 @@ import org.junit.Test
|
|||
import org.mozilla.fenix.IntentReceiverActivity
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelperDelegate
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.createCustomTabIntent
|
||||
import org.mozilla.fenix.helpers.TestHelper.openAppFromExternalLink
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.customTabScreen
|
||||
import org.mozilla.fenix.ui.robots.mDevice
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
import org.mozilla.fenix.ui.robots.notificationShade
|
||||
import org.mozilla.fenix.ui.robots.openEditURLView
|
||||
import org.mozilla.fenix.ui.robots.searchScreen
|
||||
|
||||
class CustomTabsTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private val customMenuItem = "TestMenuItem"
|
||||
|
||||
/* Updated externalLinks.html to v2.0,
|
||||
changed the hypertext reference to mozilla-mobile.github.io/testapp/downloads for "External link"
|
||||
*/
|
||||
|
@ -42,30 +38,20 @@ class CustomTabsTest {
|
|||
|
||||
@get: Rule
|
||||
val intentReceiverActivityTestRule = ActivityTestRule(
|
||||
IntentReceiverActivity::class.java,
|
||||
true,
|
||||
false,
|
||||
IntentReceiverActivity::class.java, true, false
|
||||
)
|
||||
|
||||
private val featureSettingsHelper = FeatureSettingsHelperDelegate()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
|
||||
featureSettingsHelper.apply {
|
||||
isTCPCFREnabled = false
|
||||
}.applyFlagUpdates()
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
|
@ -76,8 +62,8 @@ class CustomTabsTest {
|
|||
intentReceiverActivityTestRule.launchActivity(
|
||||
createCustomTabIntent(
|
||||
externalLinksPWAPage.toUri().toString(),
|
||||
customMenuItem,
|
||||
),
|
||||
customMenuItem
|
||||
)
|
||||
)
|
||||
|
||||
customTabScreen {
|
||||
|
@ -91,11 +77,12 @@ class CustomTabsTest {
|
|||
@SmokeTest
|
||||
@Test
|
||||
fun customTabsSaveLoginTest() {
|
||||
|
||||
intentReceiverActivityTestRule.launchActivity(
|
||||
createCustomTabIntent(
|
||||
loginPage.toUri().toString(),
|
||||
customMenuItem,
|
||||
),
|
||||
customMenuItem
|
||||
)
|
||||
)
|
||||
|
||||
customTabScreen {
|
||||
|
@ -129,8 +116,8 @@ class CustomTabsTest {
|
|||
intentReceiverActivityTestRule.launchActivity(
|
||||
createCustomTabIntent(
|
||||
customTabPage.url.toString(),
|
||||
customMenuItem,
|
||||
),
|
||||
customMenuItem
|
||||
)
|
||||
)
|
||||
|
||||
customTabScreen {
|
||||
|
@ -147,7 +134,7 @@ class CustomTabsTest {
|
|||
clickClearButton()
|
||||
longClickToolbar()
|
||||
clickPasteText()
|
||||
verifyTypedToolbarText(customTabPage.url.toString())
|
||||
verifyPastedToolbarText(customTabPage.url.toString())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,8 +146,8 @@ class CustomTabsTest {
|
|||
intentReceiverActivityTestRule.launchActivity(
|
||||
createCustomTabIntent(
|
||||
customTabPage.url.toString(),
|
||||
customMenuItem,
|
||||
),
|
||||
customMenuItem
|
||||
)
|
||||
)
|
||||
|
||||
customTabScreen {
|
||||
|
@ -183,8 +170,8 @@ class CustomTabsTest {
|
|||
intentReceiverActivityTestRule.launchActivity(
|
||||
createCustomTabIntent(
|
||||
customTabPage.toUri().toString(),
|
||||
customMenuItem,
|
||||
),
|
||||
customMenuItem
|
||||
)
|
||||
)
|
||||
|
||||
customTabScreen {
|
||||
|
|
|
@ -32,7 +32,7 @@ import org.mozilla.fenix.ui.robots.DeepLinkRobot
|
|||
|
||||
@Ignore("All tests perma-failing, see: https://github.com/mozilla-mobile/fenix/issues/13491")
|
||||
class DeepLinkTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
private val robot = DeepLinkRobot()
|
||||
|
@ -42,7 +42,6 @@ class DeepLinkTest {
|
|||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
|
|
@ -5,11 +5,14 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
|
@ -24,9 +27,10 @@ class DownloadFileTypesTest(fileName: String) {
|
|||
/* Remote test page managed by Mozilla Mobile QA team at https://github.com/mozilla-mobile/testapp */
|
||||
private val downloadTestPage = "https://storage.googleapis.com/mobile_test_assets/test_app/downloads.html"
|
||||
private var downloadFile: String = fileName
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
|
||||
val activityTestRule = HomeActivityIntentTestRule()
|
||||
|
||||
companion object {
|
||||
// Creating test data. The test will take each file name as a parameter and run it individually.
|
||||
|
@ -40,10 +44,23 @@ class DownloadFileTypesTest(fileName: String) {
|
|||
"web_icon.png",
|
||||
"videoSample.webm",
|
||||
"CSVfile.csv",
|
||||
"XMLfile.xml",
|
||||
"XMLfile.xml"
|
||||
)
|
||||
}
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
// disabling the jump-back-in pop-up that interferes with the tests.
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
// disabling the PWA CFR on 3rd visit
|
||||
featureSettingsHelper.disablePwaCFR(true)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun downloadMultipleFileTypesTest() {
|
||||
|
|
|
@ -5,14 +5,17 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.TestHelper.deleteDownloadedFileOnStorage
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestHelper.deleteDownloadFromStorage
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.downloadRobot
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
@ -27,15 +30,21 @@ import org.mozilla.fenix.ui.robots.notificationShade
|
|||
* - Verifies managing downloads inside the Downloads listing.
|
||||
**/
|
||||
class DownloadTest {
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
/* Remote test page managed by Mozilla Mobile QA team at https://github.com/mozilla-mobile/testapp */
|
||||
private val downloadTestPage = "https://storage.googleapis.com/mobile_test_assets/test_app/downloads.html"
|
||||
private var downloadFile: String = ""
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
|
||||
val activityTestRule = HomeActivityIntentTestRule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
// disabling the jump-back-in pop-up that interferes with the tests.
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
// disabling the PWA CFR on 3rd visit
|
||||
featureSettingsHelper.disablePwaCFR(true)
|
||||
// clear all existing notifications
|
||||
notificationShade {
|
||||
mDevice.openNotification()
|
||||
|
@ -45,6 +54,7 @@ class DownloadTest {
|
|||
|
||||
@After
|
||||
fun tearDown() {
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
notificationShade {
|
||||
cancelAllShownNotifications()
|
||||
}
|
||||
|
@ -102,6 +112,7 @@ class DownloadTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Intermittent: https://github.com/mozilla-mobile/fenix/issues/23434")
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun pauseResumeCancelDownloadTest() {
|
||||
|
@ -129,16 +140,16 @@ class DownloadTest {
|
|||
}
|
||||
}
|
||||
|
||||
/* Verifies downloads in the Downloads Menu:
|
||||
- downloads appear in the list
|
||||
- deleting a download from device storage, removes it from the Downloads Menu too
|
||||
*/
|
||||
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/17485")
|
||||
@SmokeTest
|
||||
@Test
|
||||
/* Verifies downloads in the Downloads Menu:
|
||||
- downloads appear in the list
|
||||
- deleting a download from device storage, removes it from the Downloads Menu too
|
||||
*/
|
||||
fun manageDownloadsInDownloadsMenuTest() {
|
||||
// a long filename to verify it's correctly displayed on the prompt and in the Downloads menu
|
||||
downloadFile =
|
||||
"tAJwqaWjJsXS8AhzSninBMCfIZbHBGgcc001lx5DIdDwIcfEgQ6vE5Gb5VgAled17DFZ2A7ZDOHA0NpQPHXXFt.svg"
|
||||
downloadFile = "tAJwqaWjJsXS8AhzSninBMCfIZbHBGgcc001lx5DIdDwIcfEgQ6vE5Gb5VgAled17DFZ2A7ZDOHA0NpQPHXXFt.svg"
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
|
||||
|
@ -154,34 +165,14 @@ class DownloadTest {
|
|||
waitForDownloadsListToExist()
|
||||
verifyDownloadedFileName(downloadFile)
|
||||
verifyDownloadedFileIcon()
|
||||
deleteDownloadedFileOnStorage(downloadFile)
|
||||
openDownloadedFile(downloadFile)
|
||||
verifyPhotosAppOpens()
|
||||
deleteDownloadFromStorage()
|
||||
waitForDownloadsListToExist()
|
||||
}.exitDownloadsManagerToBrowser {
|
||||
}.openThreeDotMenu {
|
||||
}.openDownloadsManager {
|
||||
verifyEmptyDownloadsList()
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun openDownloadedFileTest() {
|
||||
downloadFile = "web_icon.png"
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
}.clickDownloadLink(downloadFile) {
|
||||
verifyDownloadPrompt(downloadFile)
|
||||
}.clickDownload {
|
||||
verifyDownloadNotificationPopup()
|
||||
}
|
||||
browserScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openDownloadsManager {
|
||||
verifyDownloadedFileName(downloadFile)
|
||||
openDownloadedFile(downloadFile)
|
||||
verifyPhotosAppOpens()
|
||||
mDevice.pressBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ package org.mozilla.fenix.ui
|
|||
|
||||
import android.content.Context
|
||||
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
|
||||
import androidx.test.espresso.IdlingRegistry
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import mozilla.components.browser.storage.sync.PlacesHistoryStorage
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
|
@ -23,9 +23,9 @@ import org.mozilla.fenix.helpers.HomeActivityTestRule
|
|||
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem
|
||||
import org.mozilla.fenix.helpers.TestHelper.registerAndCleanupIdlingResources
|
||||
import org.mozilla.fenix.ui.robots.historyMenu
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.mDevice
|
||||
import org.mozilla.fenix.ui.robots.multipleSelectionToolbar
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
|
@ -36,17 +36,17 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
|
|||
class HistoryTest {
|
||||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private lateinit var mDevice: UiDevice
|
||||
private var historyListIdlingResource: RecyclerViewIdlingResource? = null
|
||||
private var recentlyClosedTabsListIdlingResource: RecyclerViewIdlingResource? = null
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides()
|
||||
val activityTestRule = HomeActivityTestRule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
InstrumentationRegistry.getInstrumentation().targetContext.settings()
|
||||
.shouldShowJumpBackInCFR = false
|
||||
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -63,6 +63,14 @@ class HistoryTest {
|
|||
runBlocking {
|
||||
historyStorage.deleteEverything()
|
||||
}
|
||||
|
||||
if (historyListIdlingResource != null) {
|
||||
IdlingRegistry.getInstance().unregister(historyListIdlingResource!!)
|
||||
}
|
||||
|
||||
if (recentlyClosedTabsListIdlingResource != null) {
|
||||
IdlingRegistry.getInstance().unregister(recentlyClosedTabsListIdlingResource!!)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -76,9 +84,9 @@ class HistoryTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
// Test running on beta/release builds in CI:
|
||||
// caution when making changes to it, so they don't block the builds
|
||||
@Test
|
||||
fun visitedUrlHistoryTest() {
|
||||
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -88,14 +96,13 @@ class HistoryTest {
|
|||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyHistoryListExists()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1),
|
||||
) {
|
||||
verifyHistoryMenuView()
|
||||
verifyVisitedTimeTitle()
|
||||
verifyFirstTestPageTitle("Test_Page_1")
|
||||
verifyTestPageUrl(firstWebPage.url)
|
||||
}
|
||||
historyListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1)
|
||||
IdlingRegistry.getInstance().register(historyListIdlingResource!!)
|
||||
verifyHistoryMenuView()
|
||||
verifyVisitedTimeTitle()
|
||||
verifyFirstTestPageTitle("Test_Page_1")
|
||||
verifyTestPageUrl(firstWebPage.url)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,61 +116,16 @@ class HistoryTest {
|
|||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyHistoryListExists()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1),
|
||||
) {
|
||||
clickDeleteHistoryButton(firstWebPage.url.toString())
|
||||
}
|
||||
historyListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1)
|
||||
IdlingRegistry.getInstance().register(historyListIdlingResource!!)
|
||||
clickDeleteHistoryButton(firstWebPage.url.toString())
|
||||
IdlingRegistry.getInstance().unregister(historyListIdlingResource!!)
|
||||
verifyDeleteSnackbarText("Deleted")
|
||||
verifyEmptyHistoryView()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun undoDeleteHistoryItemTest() {
|
||||
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(firstWebPage.url) {
|
||||
mDevice.waitForIdle()
|
||||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyHistoryListExists()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1),
|
||||
) {
|
||||
clickDeleteHistoryButton(firstWebPage.url.toString())
|
||||
}
|
||||
verifyUndoDeleteSnackBarButton()
|
||||
clickUndoDeleteButton()
|
||||
verifyHistoryItemExists(true, firstWebPage.url.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun cancelDeleteAllHistoryTest() {
|
||||
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(firstWebPage.url) {
|
||||
mDevice.waitForIdle()
|
||||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyHistoryListExists()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1),
|
||||
) {
|
||||
clickDeleteAllHistoryButton()
|
||||
|
||||
}
|
||||
verifyDeleteConfirmationMessage()
|
||||
selectEverythingOption()
|
||||
cancelDeleteHistory()
|
||||
verifyHistoryItemExists(true, firstWebPage.url.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun deleteAllHistoryTest() {
|
||||
|
@ -175,13 +137,12 @@ class HistoryTest {
|
|||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyHistoryListExists()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1),
|
||||
) {
|
||||
clickDeleteAllHistoryButton()
|
||||
}
|
||||
historyListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1)
|
||||
IdlingRegistry.getInstance().register(historyListIdlingResource!!)
|
||||
clickDeleteAllHistoryButton()
|
||||
IdlingRegistry.getInstance().unregister(historyListIdlingResource!!)
|
||||
verifyDeleteConfirmationMessage()
|
||||
selectEverythingOption()
|
||||
confirmDeleteAllHistory()
|
||||
verifyDeleteSnackbarText("Browsing data deleted")
|
||||
verifyEmptyHistoryView()
|
||||
|
@ -199,11 +160,10 @@ class HistoryTest {
|
|||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyHistoryListExists()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1),
|
||||
) {
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
}
|
||||
historyListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1)
|
||||
IdlingRegistry.getInstance().register(historyListIdlingResource!!)
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
}
|
||||
|
||||
multipleSelectionToolbar {
|
||||
|
@ -230,12 +190,11 @@ class HistoryTest {
|
|||
homeScreen { }.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyHistoryListExists()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1),
|
||||
) {
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
}
|
||||
historyListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1)
|
||||
IdlingRegistry.getInstance().register(historyListIdlingResource!!)
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
}
|
||||
|
||||
multipleSelectionToolbar {
|
||||
|
@ -255,12 +214,11 @@ class HistoryTest {
|
|||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyHistoryListExists()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1),
|
||||
) {
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
}
|
||||
historyListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1)
|
||||
IdlingRegistry.getInstance().register(historyListIdlingResource!!)
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
}
|
||||
|
||||
multipleSelectionToolbar {
|
||||
|
@ -284,15 +242,15 @@ class HistoryTest {
|
|||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyHistoryListExists()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 2),
|
||||
) {
|
||||
verifyHistoryItemExists(true, firstWebPage.url.toString())
|
||||
verifyHistoryItemExists(true, secondWebPage.url.toString())
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
longTapSelectItem(secondWebPage.url)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
}
|
||||
historyListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 2)
|
||||
IdlingRegistry.getInstance().register(historyListIdlingResource!!)
|
||||
verifyHistoryItemExists(true, firstWebPage.url.toString())
|
||||
verifyHistoryItemExists(true, secondWebPage.url.toString())
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
longTapSelectItem(secondWebPage.url)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
IdlingRegistry.getInstance().unregister(historyListIdlingResource!!)
|
||||
}
|
||||
|
||||
multipleSelectionToolbar {
|
||||
|
@ -314,11 +272,10 @@ class HistoryTest {
|
|||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyHistoryListExists()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1),
|
||||
) {
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
}
|
||||
historyListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1)
|
||||
IdlingRegistry.getInstance().register(historyListIdlingResource!!)
|
||||
longTapSelectItem(firstWebPage.url)
|
||||
}
|
||||
|
||||
multipleSelectionToolbar {
|
||||
|
@ -330,8 +287,8 @@ class HistoryTest {
|
|||
}
|
||||
}
|
||||
|
||||
// This test verifies the Recently Closed Tabs List and items
|
||||
@Test
|
||||
// This test verifies the Recently Closed Tabs List and items
|
||||
fun verifyRecentlyClosedTabsListTest() {
|
||||
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -344,11 +301,11 @@ class HistoryTest {
|
|||
}.openTabDrawer {
|
||||
}.openRecentlyClosedTabs {
|
||||
waitForListToExist()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.recently_closed_list), 1),
|
||||
) {
|
||||
verifyRecentlyClosedTabsMenuView()
|
||||
}
|
||||
recentlyClosedTabsListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.recently_closed_list), 1)
|
||||
IdlingRegistry.getInstance().register(recentlyClosedTabsListIdlingResource!!)
|
||||
verifyRecentlyClosedTabsMenuView()
|
||||
IdlingRegistry.getInstance().unregister(recentlyClosedTabsListIdlingResource!!)
|
||||
verifyRecentlyClosedTabsPageTitle("Test_Page_1")
|
||||
verifyRecentlyClosedTabsUrl(website.url)
|
||||
}
|
||||
|
|
|
@ -4,26 +4,19 @@
|
|||
|
||||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.Until
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.Constants.POCKET_RECOMMENDED_STORIES_UTM_PARAM
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
|
||||
import org.mozilla.fenix.helpers.ext.waitNotNull
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
/**
|
||||
* Tests for verifying the presence of home screen and first-run homescreen elements
|
||||
|
@ -35,58 +28,35 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
|
|||
class HomeScreenTest {
|
||||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
|
||||
private lateinit var mDevice: UiDevice
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private lateinit var firstPocketStoryPublisher: String
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
|
||||
@get:Rule(order = 0)
|
||||
val activityTestRule =
|
||||
AndroidComposeTestRule(HomeActivityTestRule.withDefaultSettingsOverrides()) { it.activity }
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityTestRule()
|
||||
|
||||
@Rule(order = 1)
|
||||
@Rule
|
||||
@JvmField
|
||||
val retryTestRule = RetryTestRule(3)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun homeScreenItemsTest() {
|
||||
homeScreen { }.dismissOnboarding()
|
||||
|
||||
homeScreen {
|
||||
verifyHomeWordmark()
|
||||
verifyHomeScreen()
|
||||
verifyNavigationToolbar()
|
||||
verifyHomePrivateBrowsingButton()
|
||||
verifyHomeMenu()
|
||||
verifyHomeWordmark()
|
||||
verifyTabButton()
|
||||
verifyCollectionsHeader()
|
||||
verifyHomeToolbar()
|
||||
verifyHomeComponent()
|
||||
|
||||
// Verify Top Sites
|
||||
verifyExistingTopSitesList()
|
||||
verifyExistingTopSitesTabs("Wikipedia")
|
||||
verifyExistingTopSitesTabs("Top Articles")
|
||||
verifyExistingTopSitesTabs("Google")
|
||||
verifyCollectionsHeader()
|
||||
verifyNoCollectionsText()
|
||||
scrollToPocketProvokingStories()
|
||||
swipePocketProvokingStories()
|
||||
verifyPocketRecommendedStoriesItems(activityTestRule, 1, 3, 4, 5, 6, 7)
|
||||
verifyPocketSponsoredStoriesItems(activityTestRule, 2, 8)
|
||||
verifyDiscoverMoreStoriesButton(activityTestRule, 9)
|
||||
verifyStoriesByTopicItems()
|
||||
verifyPoweredByPocket(activityTestRule)
|
||||
verifyCustomizeHomepageButton(true)
|
||||
verifyNavigationToolbar()
|
||||
verifyDefaultSearchEngine("Google")
|
||||
verifyHomeMenuButton()
|
||||
verifyTabButton()
|
||||
verifyTabCounter("0")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,11 +69,11 @@ class HomeScreenTest {
|
|||
verifyHomeScreen()
|
||||
verifyNavigationToolbar()
|
||||
verifyHomePrivateBrowsingButton()
|
||||
verifyHomeMenuButton()
|
||||
verifyHomeMenu()
|
||||
verifyHomeWordmark()
|
||||
verifyTabButton()
|
||||
verifyPrivateSessionMessage()
|
||||
verifyNavigationToolbar()
|
||||
verifyHomeToolbar()
|
||||
verifyHomeComponent()
|
||||
}.openCommonMythsLink {
|
||||
verifyUrl("common-myths-about-private-browsing")
|
||||
|
@ -117,47 +87,15 @@ class HomeScreenTest {
|
|||
verifyHomeScreen()
|
||||
verifyNavigationToolbar()
|
||||
verifyHomePrivateBrowsingButton()
|
||||
verifyHomeMenuButton()
|
||||
verifyHomeMenu()
|
||||
verifyHomeWordmark()
|
||||
verifyTabButton()
|
||||
verifyPrivateSessionMessage()
|
||||
verifyNavigationToolbar()
|
||||
verifyHomeToolbar()
|
||||
verifyHomeComponent()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyJumpBackInSectionTest() {
|
||||
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 4)
|
||||
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(firstWebPage.url) {
|
||||
}.goToHomescreen {
|
||||
verifyJumpBackInSectionIsDisplayed()
|
||||
verifyJumpBackInItemTitle(firstWebPage.title)
|
||||
verifyJumpBackInItemWithUrl(firstWebPage.url.toString())
|
||||
verifyJumpBackInShowAllButton()
|
||||
}.clickJumpBackInShowAllButton {
|
||||
verifyExistingOpenTabs(firstWebPage.title)
|
||||
}.closeTabDrawer() {
|
||||
}
|
||||
homeScreen {
|
||||
}.clickJumpBackInItemWithTitle(firstWebPage.title) {
|
||||
verifyUrl(firstWebPage.url.toString())
|
||||
clickLinkMatchingText("Link 1")
|
||||
}.goToHomescreen {
|
||||
verifyJumpBackInSectionIsDisplayed()
|
||||
verifyJumpBackInItemTitle(secondWebPage.title)
|
||||
verifyJumpBackInItemWithUrl(secondWebPage.url.toString())
|
||||
}.openTabDrawer {
|
||||
closeTab()
|
||||
}
|
||||
homeScreen {
|
||||
verifyJumpBackInSectionIsNotDisplayed()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dismissOnboardingUsingSettingsTest() {
|
||||
homeScreen {
|
||||
|
@ -186,11 +124,8 @@ class HomeScreenTest {
|
|||
|
||||
@Test
|
||||
fun dismissOnboardingUsingHelpTest() {
|
||||
activityTestRule.activityRule.applySettingsExceptions {
|
||||
it.isJumpBackInCFREnabled = false
|
||||
it.isWallpaperOnboardingEnabled = false
|
||||
}
|
||||
|
||||
val settings = activityTestRule.activity.applicationContext.settings()
|
||||
settings.shouldShowJumpBackInCFR = false
|
||||
homeScreen {
|
||||
verifyWelcomeHeader()
|
||||
}.openThreeDotMenu {
|
||||
|
@ -201,25 +136,6 @@ class HomeScreenTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dismissOnboardingWithPageLoadTest() {
|
||||
activityTestRule.activityRule.applySettingsExceptions {
|
||||
it.isJumpBackInCFREnabled = false
|
||||
it.isWallpaperOnboardingEnabled = false
|
||||
}
|
||||
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreen {
|
||||
verifyWelcomeHeader()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
}.goToHomescreen {
|
||||
verifyExistingTopSitesList()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toolbarTapDoesntDismissOnboardingTest() {
|
||||
homeScreen {
|
||||
|
@ -233,125 +149,18 @@ class HomeScreenTest {
|
|||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun verifyPocketHomepageStoriesTest() {
|
||||
activityTestRule.activityRule.applySettingsExceptions {
|
||||
it.isRecentTabsFeatureEnabled = false
|
||||
it.isRecentlyVisitedFeatureEnabled = false
|
||||
}
|
||||
|
||||
fun tapLogoToChangeWallpaperTest() {
|
||||
homeScreen {
|
||||
}.dismissOnboarding()
|
||||
|
||||
homeScreen {
|
||||
verifyThoughtProvokingStories(true)
|
||||
scrollToPocketProvokingStories()
|
||||
swipePocketProvokingStories()
|
||||
verifyPocketRecommendedStoriesItems(activityTestRule, 1, 3, 4, 5, 6, 7)
|
||||
verifyPocketSponsoredStoriesItems(activityTestRule, 2, 8)
|
||||
verifyDiscoverMoreStoriesButton(activityTestRule, 9)
|
||||
verifyStoriesByTopic(true)
|
||||
}.openThreeDotMenu {
|
||||
}.openCustomizeHome {
|
||||
clickPocketButton()
|
||||
}.goBack {
|
||||
verifyThoughtProvokingStories(false)
|
||||
verifyStoriesByTopic(false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun openPocketStoryItemTest() {
|
||||
activityTestRule.activityRule.applySettingsExceptions {
|
||||
it.isRecentTabsFeatureEnabled = false
|
||||
it.isRecentlyVisitedFeatureEnabled = false
|
||||
}
|
||||
|
||||
homeScreen {
|
||||
}.dismissOnboarding()
|
||||
|
||||
homeScreen {
|
||||
verifyThoughtProvokingStories(true)
|
||||
scrollToPocketProvokingStories()
|
||||
firstPocketStoryPublisher = getProvokingStoryPublisher(1)
|
||||
}.clickPocketStoryItem(firstPocketStoryPublisher, 1) {
|
||||
verifyUrl(POCKET_RECOMMENDED_STORIES_UTM_PARAM)
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Failed, see: https://github.com/mozilla-mobile/fenix/issues/28098")
|
||||
@Test
|
||||
fun openPocketDiscoverMoreTest() {
|
||||
activityTestRule.activityRule.applySettingsExceptions {
|
||||
it.isRecentTabsFeatureEnabled = false
|
||||
it.isRecentlyVisitedFeatureEnabled = false
|
||||
}
|
||||
|
||||
homeScreen {
|
||||
}.dismissOnboarding()
|
||||
|
||||
homeScreen {
|
||||
scrollToPocketProvokingStories()
|
||||
swipePocketProvokingStories()
|
||||
verifyDiscoverMoreStoriesButton(activityTestRule, 9)
|
||||
}.clickPocketDiscoverMoreButton(activityTestRule, 9) {
|
||||
verifyUrl("getpocket.com/explore")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun selectStoriesByTopicItemTest() {
|
||||
activityTestRule.activityRule.applySettingsExceptions {
|
||||
it.isRecentTabsFeatureEnabled = false
|
||||
it.isRecentlyVisitedFeatureEnabled = false
|
||||
}
|
||||
|
||||
homeScreen {
|
||||
}.dismissOnboarding()
|
||||
|
||||
homeScreen {
|
||||
verifyStoriesByTopicItemState(activityTestRule, false, 1)
|
||||
clickStoriesByTopicItem(activityTestRule, 1)
|
||||
verifyStoriesByTopicItemState(activityTestRule, true, 1)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyPocketLearnMoreLinkTest() {
|
||||
activityTestRule.activityRule.applySettingsExceptions {
|
||||
it.isRecentTabsFeatureEnabled = false
|
||||
it.isRecentlyVisitedFeatureEnabled = false
|
||||
}
|
||||
|
||||
homeScreen {
|
||||
}.dismissOnboarding()
|
||||
|
||||
homeScreen {
|
||||
verifyPoweredByPocket(activityTestRule)
|
||||
}.clickPocketLearnMoreLink(activityTestRule) {
|
||||
verifyUrl("mozilla.org/en-US/firefox/pocket")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyCustomizeHomepageTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
}.goToHomescreen {
|
||||
}.openCustomizeHomepage {
|
||||
clickJumpBackInButton()
|
||||
clickRecentBookmarksButton()
|
||||
clickRecentSearchesButton()
|
||||
clickPocketButton()
|
||||
}.goBack {
|
||||
verifyCustomizeHomepageButton(false)
|
||||
}.openThreeDotMenu {
|
||||
}.openCustomizeHome {
|
||||
clickJumpBackInButton()
|
||||
}.goBack {
|
||||
verifyCustomizeHomepageButton(true)
|
||||
clickFirefoxLogo()
|
||||
verifyWallpaperImageApplied(true)
|
||||
clickFirefoxLogo()
|
||||
verifyWallpaperImageApplied(true)
|
||||
clickFirefoxLogo()
|
||||
verifyWallpaperImageApplied(true)
|
||||
clickFirefoxLogo()
|
||||
verifyWallpaperImageApplied(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,13 +4,12 @@
|
|||
|
||||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import mozilla.components.browser.state.store.BrowserStore
|
||||
import mozilla.components.concept.engine.mediasession.MediaSession
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.ext.components
|
||||
|
@ -20,6 +19,7 @@ import org.mozilla.fenix.helpers.RetryTestRule
|
|||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.mDevice
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
import org.mozilla.fenix.ui.robots.notificationShade
|
||||
|
||||
|
@ -33,10 +33,9 @@ class MediaNotificationTest {
|
|||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private lateinit var mDevice: UiDevice
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides()
|
||||
val activityTestRule = HomeActivityTestRule()
|
||||
private lateinit var browserStore: BrowserStore
|
||||
|
||||
@Rule
|
||||
|
@ -49,7 +48,6 @@ class MediaNotificationTest {
|
|||
// So we are initializing this here instead of in all tests.
|
||||
browserStore = activityTestRule.activity.components.core.store
|
||||
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -61,6 +59,7 @@ class MediaNotificationTest {
|
|||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
@Ignore("Failing with ANR: https://github.com/mozilla-mobile/fenix/issues/15754")
|
||||
@Test
|
||||
fun videoPlaybackSystemNotificationTest() {
|
||||
val videoTestPage = TestAssetHelper.getVideoPageAsset(mockWebServer)
|
||||
|
@ -94,6 +93,7 @@ class MediaNotificationTest {
|
|||
mDevice.pressBack()
|
||||
}
|
||||
|
||||
@Ignore("Failing with frequent ANR: https://bugzilla.mozilla.org/show_bug.cgi?id=1764605")
|
||||
@Test
|
||||
fun mediaSystemNotificationInPrivateModeTest() {
|
||||
val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
|
||||
|
|
|
@ -4,22 +4,19 @@
|
|||
|
||||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.runWithSystemLocaleChanged
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* Tests for verifying basic functionality of browser navigation and page related interactions
|
||||
|
@ -32,20 +29,21 @@ import java.util.Locale
|
|||
*/
|
||||
|
||||
class NavigationToolbarTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides()
|
||||
val activityTestRule = HomeActivityTestRule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
val settings = activityTestRule.activity.settings()
|
||||
settings.shouldShowJumpBackInCFR = false
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -65,7 +63,7 @@ class NavigationToolbarTest {
|
|||
}.enterURLAndEnterToBrowser(nextWebPage.url) {
|
||||
verifyUrl(nextWebPage.url.toString())
|
||||
}.openThreeDotMenu {
|
||||
}.goToPreviousPage {
|
||||
}.goBack {
|
||||
mDevice.waitForIdle()
|
||||
verifyUrl(defaultWebPage.url.toString())
|
||||
}
|
||||
|
@ -84,7 +82,7 @@ class NavigationToolbarTest {
|
|||
mDevice.waitForIdle()
|
||||
verifyUrl(nextWebPage.url.toString())
|
||||
}.openThreeDotMenu {
|
||||
}.goToPreviousPage {
|
||||
}.goBack {
|
||||
mDevice.waitForIdle()
|
||||
verifyUrl(defaultWebPage.url.toString())
|
||||
}
|
||||
|
@ -98,49 +96,9 @@ class NavigationToolbarTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Swipes the nav bar left/right to switch between tabs
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun swipeToSwitchTabTest() {
|
||||
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(firstWebPage.url) {
|
||||
}.openTabDrawer {
|
||||
}.openNewTab {
|
||||
}.submitQuery(secondWebPage.url.toString()) {
|
||||
swipeNavBarRight(secondWebPage.url.toString())
|
||||
verifyUrl(firstWebPage.url.toString())
|
||||
swipeNavBarLeft(firstWebPage.url.toString())
|
||||
verifyUrl(secondWebPage.url.toString())
|
||||
}
|
||||
}
|
||||
|
||||
// Because it requires changing system prefs, this test will run only on Debug builds
|
||||
@Test
|
||||
fun swipeToSwitchTabInRTLTest() {
|
||||
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
|
||||
val arabicLocale = Locale("ar", "AR")
|
||||
|
||||
runWithSystemLocaleChanged(arabicLocale, activityTestRule) {
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(firstWebPage.url) {
|
||||
}.openTabDrawer {
|
||||
}.openNewTab {
|
||||
}.submitQuery(secondWebPage.url.toString()) {
|
||||
swipeNavBarLeft(secondWebPage.url.toString())
|
||||
verifyUrl(firstWebPage.url.toString())
|
||||
swipeNavBarRight(firstWebPage.url.toString())
|
||||
verifyUrl(secondWebPage.url.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test running on beta/release builds in CI:
|
||||
// caution when making changes to it, so they don't block the builds
|
||||
@Test
|
||||
fun visitURLTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -150,13 +108,17 @@ class NavigationToolbarTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Temp disable broken test - see: https://github.com/mozilla-mobile/fenix/issues/5534")
|
||||
@Test
|
||||
fun findInPageTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3)
|
||||
val loremIpsumWebPage = TestAssetHelper.getLoremIpsumAsset(mockWebServer)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
}.enterURLAndEnterToBrowser(loremIpsumWebPage.url) {
|
||||
mDevice.waitForIdle()
|
||||
}
|
||||
|
||||
navigationToolbar {
|
||||
}.openThreeDotMenu {
|
||||
verifyThreeDotMenuExists()
|
||||
verifyFindInPageButton()
|
||||
|
@ -164,58 +126,19 @@ class NavigationToolbarTest {
|
|||
verifyFindInPageNextButton()
|
||||
verifyFindInPagePrevButton()
|
||||
verifyFindInPageCloseButton()
|
||||
enterFindInPageQuery("a")
|
||||
enterFindInPageQuery("lab")
|
||||
verifyFindNextInPageResult("1/3")
|
||||
clickFindInPageNextButton()
|
||||
verifyFindNextInPageResult("2/3")
|
||||
clickFindInPageNextButton()
|
||||
verifyFindNextInPageResult("3/3")
|
||||
clickFindInPagePrevButton()
|
||||
verifyFindPrevInPageResult("2/3")
|
||||
clickFindInPagePrevButton()
|
||||
verifyFindPrevInPageResult("1/3")
|
||||
enterFindInPageQuery("3")
|
||||
verifyFindNextInPageResult("1/1")
|
||||
verifyFindPrevInPageResult("3/3")
|
||||
verifyFindPrevInPageResult("2/3")
|
||||
enterFindInPageQuery("in")
|
||||
verifyFindNextInPageResult("3/7")
|
||||
verifyFindNextInPageResult("4/7")
|
||||
verifyFindNextInPageResult("5/7")
|
||||
verifyFindNextInPageResult("6/7")
|
||||
verifyFindNextInPageResult("7/7")
|
||||
}.closeFindInPage { }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifySecurePageSecuritySubMenuTest() {
|
||||
val defaultWebPage = "https://mozilla-mobile.github.io/testapp/loginForm"
|
||||
val defaultWebPageTitle = "Login_form"
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.toUri()) {
|
||||
}.openSiteSecuritySheet {
|
||||
verifyQuickActionSheet(defaultWebPage, true)
|
||||
openSecureConnectionSubMenu(true)
|
||||
verifySecureConnectionSubMenu(defaultWebPageTitle, defaultWebPage, true)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyInsecurePageSecuritySubMenuTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
}.openSiteSecuritySheet {
|
||||
verifyQuickActionSheet(defaultWebPage.url.toString(), false)
|
||||
openSecureConnectionSubMenu(false)
|
||||
verifySecureConnectionSubMenu(defaultWebPage.title, defaultWebPage.url.toString(), false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyClearCookiesFromQuickSettingsTest() {
|
||||
val helpPageUrl = "mozilla.org"
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openHelp {
|
||||
}.openSiteSecuritySheet {
|
||||
clickQuickActionSheetClearSiteData()
|
||||
verifyClearSiteDataPrompt(helpPageUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.ui
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import io.mockk.mockk
|
||||
import mozilla.components.concept.sync.AuthType
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.components.TelemetryAccountObserver
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.Experimentation
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
||||
class NimbusEventTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
@get:Rule
|
||||
val homeActivityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
|
||||
.withIntent(
|
||||
Intent().apply {
|
||||
action = Intent.ACTION_VIEW
|
||||
},
|
||||
)
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val retryTestRule = RetryTestRule(3)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun homeScreenNimbusEventsTest() {
|
||||
homeScreen { }.dismissOnboarding()
|
||||
|
||||
Experimentation.withHelper {
|
||||
assertTrue(evalJexl("'app_opened'|eventSum('Days', 28, 0) > 0"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun telemetryAccountObserverTest() {
|
||||
val observer = TelemetryAccountObserver(appContext)
|
||||
observer.onAuthenticated(mockk(), AuthType.Signin)
|
||||
|
||||
Experimentation.withHelper {
|
||||
assertTrue(evalJexl("'sync_auth.sign_in'|eventSum('Days', 28, 0) > 0"))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,10 +5,13 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import org.junit.After
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.TestHelper.packageName
|
||||
import org.mozilla.fenix.helpers.TestHelper.setNetworkEnabled
|
||||
|
@ -25,7 +28,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
|
|||
class NoNetworkAccessStartupTests {
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides(launchActivity = false)
|
||||
val activityTestRule = HomeActivityTestRule(launchActivity = false)
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
|
@ -33,10 +36,10 @@ class NoNetworkAccessStartupTests {
|
|||
setNetworkEnabled(true)
|
||||
}
|
||||
|
||||
@Test
|
||||
// Test running on beta/release builds in CI:
|
||||
// caution when making changes to it, so they don't block the builds
|
||||
// Based on STR from https://github.com/mozilla-mobile/fenix/issues/16886
|
||||
@Test
|
||||
fun noNetworkConnectionStartupTest() {
|
||||
setNetworkEnabled(false)
|
||||
|
||||
|
@ -49,10 +52,12 @@ class NoNetworkAccessStartupTests {
|
|||
}
|
||||
}
|
||||
|
||||
// Based on STR from https://github.com/mozilla-mobile/fenix/issues/16886
|
||||
@Test
|
||||
// Based on STR from https://github.com/mozilla-mobile/fenix/issues/16886
|
||||
fun networkInterruptedFromBrowserToHomeTest() {
|
||||
val url = "example.com"
|
||||
val settings = InstrumentationRegistry.getInstrumentation().targetContext.settings()
|
||||
settings.shouldShowJumpBackInCFR = false
|
||||
|
||||
activityTestRule.launchActivity(null)
|
||||
|
||||
|
@ -83,6 +88,7 @@ class NoNetworkAccessStartupTests {
|
|||
}.refreshPage { }
|
||||
}
|
||||
|
||||
@Ignore("Failing with frequent ANR: https://bugzilla.mozilla.org/show_bug.cgi?id=1764605")
|
||||
@Test
|
||||
fun testSignInPageWithNoNetworkConnection() {
|
||||
setNetworkEnabled(false)
|
||||
|
@ -97,7 +103,7 @@ class NoNetworkAccessStartupTests {
|
|||
verifyUrl(
|
||||
"firefox.com",
|
||||
"$packageName:id/mozac_browser_toolbar_url_view",
|
||||
R.id.mozac_browser_toolbar_url_view,
|
||||
R.id.mozac_browser_toolbar_url_view
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
||||
/**
|
||||
* Tests for verifying the new onboarding features.
|
||||
* Note: This involves setting the feature flag On for the onboarding dialog
|
||||
*
|
||||
*/
|
||||
class OnboardingFeaturesTest {
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = AndroidComposeTestRule(
|
||||
HomeActivityTestRule(isHomeOnboardingDialogEnabled = true),
|
||||
) { it.activity }
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun upgradingUsersOnboardingScreensTest() {
|
||||
homeScreen {
|
||||
verifyUpgradingUserOnboardingFirstScreen(activityTestRule)
|
||||
clickGetStartedButton(activityTestRule)
|
||||
verifyUpgradingUserOnboardingSecondScreen(activityTestRule)
|
||||
clickSkipButton(activityTestRule)
|
||||
verifyHomeScreen()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun upgradingUsersOnboardingSignInButtonTest() {
|
||||
homeScreen {
|
||||
verifyUpgradingUserOnboardingFirstScreen(activityTestRule)
|
||||
clickGetStartedButton(activityTestRule)
|
||||
verifyUpgradingUserOnboardingSecondScreen(activityTestRule)
|
||||
}.clickUpgradingUserOnboardingSignInButton(activityTestRule) {
|
||||
verifyTurnOnSyncMenu()
|
||||
mDevice.pressBack()
|
||||
}
|
||||
homeScreen {
|
||||
verifyHomeScreen()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +1,21 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import org.junit.Ignore
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.Constants.PackageName.GMAIL_APP
|
||||
import org.mozilla.fenix.helpers.Constants.PackageName.PHONE_APP
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.TestHelper.assertNativeAppOpens
|
||||
import org.mozilla.fenix.ui.robots.customTabScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
import org.mozilla.fenix.ui.robots.pwaScreen
|
||||
|
||||
class PwaTest {
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
/* Updated externalLinks.html to v2.0,
|
||||
changed the hypertext reference to mozilla-mobile.github.io/testapp/downloads for "External link"
|
||||
*/
|
||||
|
@ -23,7 +25,17 @@ class PwaTest {
|
|||
private val shortcutTitle = "TEST_APP"
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
|
||||
val activityTestRule = HomeActivityIntentTestRule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
featureSettingsHelper.disablePwaCFR(true)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
|
@ -32,8 +44,6 @@ class PwaTest {
|
|||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(externalLinksPWAPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
verifyNotificationDotOnMainMenu()
|
||||
}.openThreeDotMenu {
|
||||
}.clickInstall {
|
||||
clickAddAutomaticallyButton()
|
||||
|
@ -46,14 +56,13 @@ class PwaTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/28212")
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun emailLinkPWATest() {
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(externalLinksPWAPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
verifyNotificationDotOnMainMenu()
|
||||
}.openThreeDotMenu {
|
||||
}.clickInstall {
|
||||
clickAddAutomaticallyButton()
|
||||
|
@ -66,10 +75,10 @@ class PwaTest {
|
|||
@SmokeTest
|
||||
@Test
|
||||
fun telephoneLinkPWATest() {
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(externalLinksPWAPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
verifyNotificationDotOnMainMenu()
|
||||
}.openThreeDotMenu {
|
||||
}.clickInstall {
|
||||
clickAddAutomaticallyButton()
|
||||
|
@ -78,23 +87,4 @@ class PwaTest {
|
|||
assertNativeAppOpens(PHONE_APP, phoneLink)
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun appLikeExperiencePWATest() {
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(externalLinksPWAPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
verifyNotificationDotOnMainMenu()
|
||||
}.openThreeDotMenu {
|
||||
}.clickInstall {
|
||||
clickAddAutomaticallyButton()
|
||||
}.openHomeScreenShortcut(shortcutTitle) {
|
||||
}
|
||||
|
||||
pwaScreen {
|
||||
verifyCustomTabToolbarIsNotDisplayed()
|
||||
verifyPwaActivityInCurrentTask()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import android.view.View
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.espresso.IdlingRegistry
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
|
@ -17,9 +16,9 @@ import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
|||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.registerAndCleanupIdlingResources
|
||||
import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.mDevice
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
/**
|
||||
|
@ -33,11 +32,11 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
|
|||
|
||||
class ReaderViewTest {
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private lateinit var mDevice: UiDevice
|
||||
private var readerViewNotification: ViewVisibilityIdlingResource? = null
|
||||
private val estimatedReadingTime = "1 - 2 minutes"
|
||||
|
||||
@get:Rule
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
|
@ -45,7 +44,6 @@ class ReaderViewTest {
|
|||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -55,6 +53,7 @@ class ReaderViewTest {
|
|||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
IdlingRegistry.getInstance().unregister(readerViewNotification)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,12 +72,12 @@ class ReaderViewTest {
|
|||
mDevice.waitForIdle()
|
||||
}
|
||||
|
||||
registerAndCleanupIdlingResources(
|
||||
ViewVisibilityIdlingResource(
|
||||
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
|
||||
View.VISIBLE,
|
||||
),
|
||||
) {}
|
||||
readerViewNotification = ViewVisibilityIdlingResource(
|
||||
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
|
||||
View.VISIBLE
|
||||
)
|
||||
|
||||
IdlingRegistry.getInstance().register(readerViewNotification)
|
||||
|
||||
navigationToolbar {
|
||||
verifyReaderViewDetected(true)
|
||||
|
@ -116,12 +115,12 @@ class ReaderViewTest {
|
|||
mDevice.waitForIdle()
|
||||
}
|
||||
|
||||
registerAndCleanupIdlingResources(
|
||||
ViewVisibilityIdlingResource(
|
||||
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
|
||||
View.VISIBLE,
|
||||
),
|
||||
) {}
|
||||
readerViewNotification = ViewVisibilityIdlingResource(
|
||||
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
|
||||
View.VISIBLE
|
||||
)
|
||||
|
||||
IdlingRegistry.getInstance().register(readerViewNotification)
|
||||
|
||||
navigationToolbar {
|
||||
verifyReaderViewDetected(true)
|
||||
|
@ -141,7 +140,7 @@ class ReaderViewTest {
|
|||
verifyReaderViewDetected(true)
|
||||
}.openThreeDotMenu {
|
||||
verifyReaderViewAppearance(false)
|
||||
}.closeBrowserMenuToBrowser { }
|
||||
}.close { }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -154,12 +153,12 @@ class ReaderViewTest {
|
|||
mDevice.waitForIdle()
|
||||
}
|
||||
|
||||
registerAndCleanupIdlingResources(
|
||||
ViewVisibilityIdlingResource(
|
||||
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
|
||||
View.VISIBLE,
|
||||
),
|
||||
) {}
|
||||
readerViewNotification = ViewVisibilityIdlingResource(
|
||||
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
|
||||
View.VISIBLE
|
||||
)
|
||||
|
||||
IdlingRegistry.getInstance().register(readerViewNotification)
|
||||
|
||||
navigationToolbar {
|
||||
verifyReaderViewDetected(true)
|
||||
|
@ -194,12 +193,12 @@ class ReaderViewTest {
|
|||
mDevice.waitForIdle()
|
||||
}
|
||||
|
||||
registerAndCleanupIdlingResources(
|
||||
ViewVisibilityIdlingResource(
|
||||
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
|
||||
View.VISIBLE,
|
||||
),
|
||||
) {}
|
||||
readerViewNotification = ViewVisibilityIdlingResource(
|
||||
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
|
||||
View.VISIBLE
|
||||
)
|
||||
|
||||
IdlingRegistry.getInstance().register(readerViewNotification)
|
||||
|
||||
navigationToolbar {
|
||||
verifyReaderViewDetected(true)
|
||||
|
@ -240,12 +239,12 @@ class ReaderViewTest {
|
|||
mDevice.waitForIdle()
|
||||
}
|
||||
|
||||
registerAndCleanupIdlingResources(
|
||||
ViewVisibilityIdlingResource(
|
||||
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
|
||||
View.VISIBLE,
|
||||
),
|
||||
) {}
|
||||
readerViewNotification = ViewVisibilityIdlingResource(
|
||||
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
|
||||
View.VISIBLE
|
||||
)
|
||||
|
||||
IdlingRegistry.getInstance().register(readerViewNotification)
|
||||
|
||||
navigationToolbar {
|
||||
verifyReaderViewDetected(true)
|
||||
|
|
|
@ -4,36 +4,27 @@
|
|||
|
||||
package org.mozilla.fenix.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.hardware.camera2.CameraManager
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.core.net.toUri
|
||||
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
|
||||
import androidx.test.espresso.Espresso.pressBack
|
||||
import mozilla.components.browser.icons.IconRequest
|
||||
import mozilla.components.browser.icons.generator.DefaultIconGenerator
|
||||
import mozilla.components.feature.search.ext.createSearchEngine
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Assume.assumeTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.Constants.PackageName.ANDROID_SETTINGS
|
||||
import org.mozilla.fenix.helpers.Constants.searchEngineCodes
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.SearchDispatcher
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
import org.mozilla.fenix.helpers.TestHelper.assertNativeAppOpens
|
||||
import org.mozilla.fenix.helpers.TestHelper.denyPermission
|
||||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.helpers.TestHelper.grantPermission
|
||||
import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestHelper.setCustomSearchEngine
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.multipleSelectionToolbar
|
||||
|
||||
|
@ -48,20 +39,14 @@ import org.mozilla.fenix.ui.robots.multipleSelectionToolbar
|
|||
*/
|
||||
|
||||
class SearchTest {
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
lateinit var searchMockServer: MockWebServer
|
||||
lateinit var queryString: String
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = AndroidComposeTestRule(
|
||||
HomeActivityTestRule(
|
||||
skipOnboarding = true,
|
||||
isPocketEnabled = false,
|
||||
isJumpBackInCFREnabled = false,
|
||||
isRecentTabsFeatureEnabled = false,
|
||||
isTCPCFREnabled = false,
|
||||
isWallpaperOnboardingEnabled = false,
|
||||
),
|
||||
) { it.activity }
|
||||
HomeActivityTestRule(),
|
||||
{ it.activity }
|
||||
)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
|
@ -69,11 +54,14 @@ class SearchTest {
|
|||
dispatcher = SearchDispatcher()
|
||||
start()
|
||||
}
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
featureSettingsHelper.setPocketEnabled(false)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
searchMockServer.shutdown()
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -88,271 +76,206 @@ class SearchTest {
|
|||
}
|
||||
|
||||
@SmokeTest
|
||||
@Ignore("This test cannot run on virtual devices due to camera permissions being required")
|
||||
@Test
|
||||
fun scanButtonDenyPermissionTest() {
|
||||
val cameraManager = appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager
|
||||
assumeTrue(cameraManager.cameraIdList.isNotEmpty())
|
||||
|
||||
fun scanButtonTest() {
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
clickScanButton()
|
||||
denyPermission()
|
||||
clickDenyPermission()
|
||||
clickScanButton()
|
||||
clickDismissPermissionRequiredDialog()
|
||||
}
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
clickScanButton()
|
||||
clickGoToPermissionsSettings()
|
||||
assertNativeAppOpens(ANDROID_SETTINGS)
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun scanButtonAllowPermissionTest() {
|
||||
val cameraManager = appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager
|
||||
assumeTrue(cameraManager.cameraIdList.isNotEmpty())
|
||||
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
clickScanButton()
|
||||
grantPermission()
|
||||
verifyScannerOpen()
|
||||
clickAllowPermission()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setDefaultSearchEngineFromShortcutsTest() {
|
||||
queryString = "firefox"
|
||||
fun shortcutButtonTest() {
|
||||
val searchEngineURL = "bing.com/search?q=mozilla%20firefox"
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
toggleShowSearchShortcuts()
|
||||
enableShowSearchShortcuts()
|
||||
}.goBack {
|
||||
}.goBack {
|
||||
}.openSearch {
|
||||
verifySearchBarEmpty()
|
||||
clickSearchEngineButton(activityTestRule, "Bing")
|
||||
typeSearch("mozilla")
|
||||
verifySearchEngineResults(activityTestRule, "mozilla firefox", "Bing")
|
||||
clickSearchEngineResult(activityTestRule, "mozilla firefox")
|
||||
}
|
||||
|
||||
browserScreen {
|
||||
waitForPageToLoad()
|
||||
verifyUrl(searchEngineURL)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shortcutSearchEngineSettingsTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
enableShowSearchShortcuts()
|
||||
}.goBack {
|
||||
}.goBack {
|
||||
}.openSearch {
|
||||
scrollToSearchEngineSettings(activityTestRule)
|
||||
}.clickSearchEngineSettings(activityTestRule) {
|
||||
changeDefaultSearchEngine("DuckDuckGo")
|
||||
}
|
||||
|
||||
exitMenu()
|
||||
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
}.submitQuery(queryString) {
|
||||
verifyUrl("duckduckgo.com/?q=firefox")
|
||||
clickSearchEngineSettings(activityTestRule)
|
||||
verifySearchSettings()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun clearSearchTest() {
|
||||
queryString = "test"
|
||||
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
typeSearch(queryString)
|
||||
typeSearch("test")
|
||||
clickClearButton()
|
||||
verifySearchBarEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
|
||||
@Ignore("Failure caused by bugs: https://github.com/mozilla-mobile/fenix/issues/23818")
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun searchGroupShowsInRecentlyVisitedTest() {
|
||||
queryString = "test search"
|
||||
val firstPage = searchMockServer.url("generic1.html").toString()
|
||||
val secondPage = searchMockServer.url("generic2.html").toString()
|
||||
// setting our custom mockWebServer search URL
|
||||
val searchString =
|
||||
"http://localhost:${searchMockServer.port}/pages/searchResults.html?search={searchTerms}"
|
||||
val searchString = "http://localhost:${searchMockServer.port}/searchResults.html?search={searchTerms}"
|
||||
val customSearchEngine = createSearchEngine(
|
||||
name = "TestSearchEngine",
|
||||
url = searchString,
|
||||
icon = DefaultIconGenerator().generate(appContext, IconRequest(searchString)).bitmap,
|
||||
icon = DefaultIconGenerator().generate(appContext, IconRequest(searchString)).bitmap
|
||||
)
|
||||
setCustomSearchEngine(customSearchEngine)
|
||||
|
||||
// Performs a search and opens 2 dummy search results links to create a search group
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
}.submitQuery(queryString) {
|
||||
longClickLink("Link 1")
|
||||
}.submitQuery("test search") {
|
||||
longClickMatchingText("Link 1")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
pressBack()
|
||||
longClickLink("Link 2")
|
||||
longClickMatchingText("Link 2")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
}.goToHomescreen {
|
||||
verifyJumpBackInSectionIsDisplayed()
|
||||
verifyCurrentSearchGroupIsDisplayed(true, "test search", 3)
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(false, "test search", 3)
|
||||
}.openTabDrawer {
|
||||
}.openTabFromGroup(firstPage) {
|
||||
}.openTabDrawer {
|
||||
}.openTabFromGroup(secondPage) {
|
||||
}.openTabDrawer {
|
||||
}.openTabsListThreeDotMenu {
|
||||
}.closeAllTabs {
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(true, queryString, 3)
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(true, "test search", 3)
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
|
||||
@Test
|
||||
fun verifySearchGroupHistoryWithNoDuplicatesTest() {
|
||||
val firstPageUrl = getGenericAsset(searchMockServer, 1).url
|
||||
val secondPageUrl = getGenericAsset(searchMockServer, 2).url
|
||||
val originPageUrl =
|
||||
"http://localhost:${searchMockServer.port}/pages/searchResults.html?search=test%20search".toUri()
|
||||
queryString = "test search"
|
||||
// setting our custom mockWebServer search URL
|
||||
val searchString =
|
||||
"http://localhost:${searchMockServer.port}/pages/searchResults.html?search={searchTerms}"
|
||||
val customSearchEngine = createSearchEngine(
|
||||
name = "TestSearchEngine",
|
||||
url = searchString,
|
||||
icon = DefaultIconGenerator().generate(appContext, IconRequest(searchString)).bitmap,
|
||||
)
|
||||
setCustomSearchEngine(customSearchEngine)
|
||||
|
||||
// Performs a search and opens 2 dummy search results links to create a search group
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
}.submitQuery(queryString) {
|
||||
longClickLink("Link 1")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
pressBack()
|
||||
longClickLink("Link 1")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
pressBack()
|
||||
longClickLink("Link 2")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
pressBack()
|
||||
longClickLink("Link 1")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
}.openTabDrawer {
|
||||
}.openTabsListThreeDotMenu {
|
||||
}.closeAllTabs {
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(true, queryString, 3)
|
||||
}.openRecentlyVisitedSearchGroupHistoryList(queryString) {
|
||||
verifyTestPageUrl(firstPageUrl)
|
||||
verifyTestPageUrl(secondPageUrl)
|
||||
verifyTestPageUrl(originPageUrl)
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Failing due to known bug, see https://github.com/mozilla-mobile/fenix/issues/23818")
|
||||
@Test
|
||||
fun searchGroupGeneratedInTheSameTabTest() {
|
||||
queryString = "test search"
|
||||
// setting our custom mockWebServer search URL
|
||||
val searchString =
|
||||
"http://localhost:${searchMockServer.port}/pages/searchResults.html?search={searchTerms}"
|
||||
val customSearchEngine = createSearchEngine(
|
||||
name = "TestSearchEngine",
|
||||
url = searchString,
|
||||
icon = DefaultIconGenerator().generate(appContext, IconRequest(searchString)).bitmap,
|
||||
)
|
||||
setCustomSearchEngine(customSearchEngine)
|
||||
|
||||
// Performs a search and opens 2 dummy search results links to create a search group
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
}.submitQuery(queryString) {
|
||||
clickLinkMatchingText("Link 1")
|
||||
waitForPageToLoad()
|
||||
pressBack()
|
||||
clickLinkMatchingText("Link 2")
|
||||
waitForPageToLoad()
|
||||
}.openTabDrawer {
|
||||
}.openTabsListThreeDotMenu {
|
||||
}.closeAllTabs {
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(true, queryString, 3)
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun noSearchGroupFromPrivateBrowsingTest() {
|
||||
queryString = "test search"
|
||||
fun noCurrentSearchGroupFromPrivateBrowsingTest() {
|
||||
// setting our custom mockWebServer search URL
|
||||
val searchString =
|
||||
"http://localhost:${searchMockServer.port}/pages/searchResults.html?search={searchTerms}"
|
||||
val searchString = "http://localhost:${searchMockServer.port}/searchResults.html?search={searchTerms}"
|
||||
val customSearchEngine = createSearchEngine(
|
||||
name = "TestSearchEngine",
|
||||
url = searchString,
|
||||
icon = DefaultIconGenerator().generate(appContext, IconRequest(searchString)).bitmap,
|
||||
icon = DefaultIconGenerator().generate(appContext, IconRequest(searchString)).bitmap
|
||||
)
|
||||
setCustomSearchEngine(customSearchEngine)
|
||||
|
||||
// Performs a search and opens 2 dummy search results links to create a search group
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
}.submitQuery(queryString) {
|
||||
longClickLink("Link 1")
|
||||
}.submitQuery("test search") {
|
||||
longClickMatchingText("Link 1")
|
||||
clickContextOpenLinkInPrivateTab()
|
||||
longClickLink("Link 2")
|
||||
longClickMatchingText("Link 2")
|
||||
clickContextOpenLinkInPrivateTab()
|
||||
}.openTabDrawer {
|
||||
}.toggleToPrivateTabs {
|
||||
}.openTabWithIndex(0) {
|
||||
}.openTabDrawer {
|
||||
}.openTabWithIndex(1) {
|
||||
}.openTabDrawer {
|
||||
}.openTabsListThreeDotMenu {
|
||||
}.closeAllTabs {
|
||||
togglePrivateBrowsingModeOnOff()
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(false, queryString, 3)
|
||||
}.goToHomescreen {
|
||||
verifyCurrentSearchGroupIsDisplayed(false, "test search", 3)
|
||||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyHistoryItemExists(false, "3 sites")
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun deleteItemsFromSearchGroupHistoryTest() {
|
||||
queryString = "test search"
|
||||
val firstPageUrl = getGenericAsset(searchMockServer, 1).url
|
||||
val secondPageUrl = getGenericAsset(searchMockServer, 2).url
|
||||
fun noRecentlyVisitedSearchGroupInPrivateBrowsingTest() {
|
||||
val firstPage = searchMockServer.url("generic1.html").toString()
|
||||
val secondPage = searchMockServer.url("generic2.html").toString()
|
||||
// setting our custom mockWebServer search URL
|
||||
val searchString =
|
||||
"http://localhost:${searchMockServer.port}/pages/searchResults.html?search={searchTerms}"
|
||||
val searchString = "http://localhost:${searchMockServer.port}/searchResults.html?search={searchTerms}"
|
||||
val customSearchEngine = createSearchEngine(
|
||||
name = "TestSearchEngine",
|
||||
url = searchString,
|
||||
icon = DefaultIconGenerator().generate(appContext, IconRequest(searchString)).bitmap,
|
||||
icon = DefaultIconGenerator().generate(appContext, IconRequest(searchString)).bitmap
|
||||
)
|
||||
setCustomSearchEngine(customSearchEngine)
|
||||
|
||||
// Performs a search and opens 2 dummy search results links to create a search group
|
||||
homeScreen {
|
||||
}.togglePrivateBrowsingMode()
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
}.submitQuery("test search") {
|
||||
longClickMatchingText("Link 1")
|
||||
clickContextOpenLinkInPrivateTab()
|
||||
longClickMatchingText("Link 2")
|
||||
clickContextOpenLinkInPrivateTab()
|
||||
}.openTabDrawer {
|
||||
}.openTab(firstPage) {
|
||||
}.openTabDrawer {
|
||||
}.openTab(secondPage) {
|
||||
}.openTabDrawer {
|
||||
}.openTabsListThreeDotMenu {
|
||||
}.closeAllTabs {
|
||||
homeScreen {
|
||||
}.togglePrivateBrowsingMode()
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(false, "test search", 3)
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Failure caused by bugs: https://github.com/mozilla-mobile/fenix/issues/23818")
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun deleteItemsFromSearchGroupsHistoryTest() {
|
||||
val firstPage = searchMockServer.url("generic1.html").toString()
|
||||
val secondPage = searchMockServer.url("generic2.html").toString()
|
||||
// setting our custom mockWebServer search URL
|
||||
val searchString = "http://localhost:${searchMockServer.port}/searchResults.html?search={searchTerms}"
|
||||
val customSearchEngine = createSearchEngine(
|
||||
name = "TestSearchEngine",
|
||||
url = searchString,
|
||||
icon = DefaultIconGenerator().generate(appContext, IconRequest(searchString)).bitmap
|
||||
)
|
||||
setCustomSearchEngine(customSearchEngine)
|
||||
|
||||
// Performs a search and opens 2 dummy search results links to create a search group
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
}.submitQuery(queryString) {
|
||||
longClickLink("Link 1")
|
||||
}.submitQuery("test search") {
|
||||
longClickMatchingText("Link 1")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
mDevice.pressBack()
|
||||
longClickLink("Link 2")
|
||||
longClickMatchingText("Link 2")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
}.openTabDrawer {
|
||||
}.openTabFromGroup(firstPage) {
|
||||
}.openTabDrawer {
|
||||
}.openTabFromGroup(secondPage) {
|
||||
}.openTabDrawer {
|
||||
}.openTabsListThreeDotMenu {
|
||||
}.closeAllTabs {
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(true, queryString, 3)
|
||||
}.openRecentlyVisitedSearchGroupHistoryList(queryString) {
|
||||
clickDeleteHistoryButton(firstPageUrl.toString())
|
||||
longTapSelectItem(secondPageUrl)
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(true, "test search", 3)
|
||||
}.openRecentlyVisitedSearchGroupHistoryList("test search") {
|
||||
clickDeleteHistoryButton(firstPage)
|
||||
longTapSelectItem(secondPage.toUri())
|
||||
multipleSelectionToolbar {
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
clickMultiSelectionDelete()
|
||||
|
@ -361,207 +284,7 @@ class SearchTest {
|
|||
}
|
||||
homeScreen {
|
||||
// checking that the group is removed when only 1 item is left
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(false, queryString, 1)
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
|
||||
@Test
|
||||
fun deleteSearchGroupFromHistoryTest() {
|
||||
queryString = "test search"
|
||||
val firstPageUrl = getGenericAsset(searchMockServer, 1).url
|
||||
// setting our custom mockWebServer search URL
|
||||
val searchString =
|
||||
"http://localhost:${searchMockServer.port}/pages/searchResults.html?search={searchTerms}"
|
||||
val customSearchEngine = createSearchEngine(
|
||||
name = "TestSearchEngine",
|
||||
url = searchString,
|
||||
icon = DefaultIconGenerator().generate(appContext, IconRequest(searchString)).bitmap,
|
||||
)
|
||||
setCustomSearchEngine(customSearchEngine)
|
||||
|
||||
// Performs a search and opens 2 dummy search results links to create a search group
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
}.submitQuery(queryString) {
|
||||
longClickLink("Link 1")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
mDevice.pressBack()
|
||||
longClickLink("Link 2")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
}.openTabDrawer {
|
||||
}.openTabsListThreeDotMenu {
|
||||
}.closeAllTabs {
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(true, queryString, 3)
|
||||
}.openRecentlyVisitedSearchGroupHistoryList(queryString) {
|
||||
clickDeleteAllHistoryButton()
|
||||
confirmDeleteAllHistory()
|
||||
verifyDeleteSnackbarText("Group deleted")
|
||||
verifyHistoryItemExists(false, firstPageUrl.toString())
|
||||
}.goBack {}
|
||||
homeScreen {
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(false, queryString, 3)
|
||||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifySearchGroupDisplayed(false, queryString, 3)
|
||||
verifyEmptyHistoryView()
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
|
||||
@Test
|
||||
fun reopenTabsFromSearchGroupTest() {
|
||||
val firstPageUrl = getGenericAsset(searchMockServer, 1).url
|
||||
val secondPageUrl = getGenericAsset(searchMockServer, 2).url
|
||||
queryString = "test search"
|
||||
// setting our custom mockWebServer search URL
|
||||
val searchString =
|
||||
"http://localhost:${searchMockServer.port}/pages/searchResults.html?search={searchTerms}"
|
||||
val customSearchEngine = createSearchEngine(
|
||||
name = "TestSearchEngine",
|
||||
url = searchString,
|
||||
icon = DefaultIconGenerator().generate(appContext, IconRequest(searchString)).bitmap,
|
||||
)
|
||||
setCustomSearchEngine(customSearchEngine)
|
||||
|
||||
// Performs a search and opens 2 dummy search results links to create a search group
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
}.submitQuery(queryString) {
|
||||
longClickLink("Link 1")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
mDevice.pressBack()
|
||||
longClickLink("Link 2")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
}.openTabDrawer {
|
||||
}.openTabsListThreeDotMenu {
|
||||
}.closeAllTabs {
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(true, queryString, 3)
|
||||
}.openRecentlyVisitedSearchGroupHistoryList(queryString) {
|
||||
}.openWebsite(firstPageUrl) {
|
||||
verifyUrl(firstPageUrl.toString())
|
||||
}.goToHomescreen {
|
||||
}.openRecentlyVisitedSearchGroupHistoryList(queryString) {
|
||||
longTapSelectItem(firstPageUrl)
|
||||
longTapSelectItem(secondPageUrl)
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
}
|
||||
|
||||
multipleSelectionToolbar {
|
||||
}.clickOpenNewTab {
|
||||
verifyNormalModeSelected()
|
||||
}.closeTabDrawer {}
|
||||
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
|
||||
multipleSelectionToolbar {
|
||||
}.clickOpenPrivateTab {
|
||||
verifyPrivateModeSelected()
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
|
||||
@Test
|
||||
fun sharePageFromASearchGroupTest() {
|
||||
val firstPageUrl = getGenericAsset(searchMockServer, 1).url
|
||||
queryString = "test search"
|
||||
// setting our custom mockWebServer search URL
|
||||
val searchString =
|
||||
"http://localhost:${searchMockServer.port}/pages/searchResults.html?search={searchTerms}"
|
||||
val customSearchEngine = createSearchEngine(
|
||||
name = "TestSearchEngine",
|
||||
url = searchString,
|
||||
icon = DefaultIconGenerator().generate(appContext, IconRequest(searchString)).bitmap,
|
||||
)
|
||||
setCustomSearchEngine(customSearchEngine)
|
||||
|
||||
// Performs a search and opens 2 dummy search results links to create a search group
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
}.submitQuery(queryString) {
|
||||
longClickLink("Link 1")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
mDevice.pressBack()
|
||||
longClickLink("Link 2")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
waitForPageToLoad()
|
||||
}.openTabDrawer {
|
||||
}.openTabsListThreeDotMenu {
|
||||
}.closeAllTabs {
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(true, queryString, 3)
|
||||
}.openRecentlyVisitedSearchGroupHistoryList(queryString) {
|
||||
longTapSelectItem(firstPageUrl)
|
||||
}
|
||||
|
||||
multipleSelectionToolbar {
|
||||
clickShareHistoryButton()
|
||||
verifyShareOverlay()
|
||||
verifyShareTabFavicon()
|
||||
verifyShareTabTitle()
|
||||
verifyShareTabUrl()
|
||||
}
|
||||
}
|
||||
|
||||
// Default search code for Google-US
|
||||
@Test
|
||||
fun defaultSearchCodeGoogleUS() {
|
||||
queryString = "firefox"
|
||||
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
}.submitQuery(queryString) {
|
||||
verifyUrl(searchEngineCodes["Google"]!!)
|
||||
}
|
||||
}
|
||||
|
||||
// Default search code for Bing-US
|
||||
@Test
|
||||
fun defaultSearchCodeBingUS() {
|
||||
queryString = "firefox"
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
changeDefaultSearchEngine("Bing")
|
||||
}
|
||||
|
||||
exitMenu()
|
||||
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
}.submitQuery(queryString) {
|
||||
verifyUrl(searchEngineCodes["Bing"]!!)
|
||||
}
|
||||
}
|
||||
|
||||
// Default search code for DuckDuckGo-US
|
||||
@Test
|
||||
fun defaultSearchCodeDuckDuckGoUS() {
|
||||
queryString = "firefox"
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
changeDefaultSearchEngine("DuckDuckGo")
|
||||
}
|
||||
|
||||
exitMenu()
|
||||
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
}.submitQuery(queryString) {
|
||||
verifyUrl(searchEngineCodes["DuckDuckGo"]!!)
|
||||
verifyRecentlyVisitedSearchGroupDisplayed(false, "test search", 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,16 @@ import androidx.test.uiautomator.UiSelector
|
|||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.ui.robots.clickRateButtonGooglePlay
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.mDevice
|
||||
|
||||
/**
|
||||
* Tests for verifying the main three dot menu options
|
||||
|
@ -27,7 +29,7 @@ import org.mozilla.fenix.ui.robots.homeScreen
|
|||
class SettingsAboutTest {
|
||||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
|
||||
private lateinit var mDevice: UiDevice
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
@get:Rule
|
||||
|
@ -39,7 +41,6 @@ class SettingsAboutTest {
|
|||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -51,8 +52,8 @@ class SettingsAboutTest {
|
|||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
// Walks through settings menu and sub-menus to ensure all items are present
|
||||
@Test
|
||||
// Walks through settings menu and sub-menus to ensure all items are present
|
||||
fun settingsAboutItemsTest() {
|
||||
// ABOUT
|
||||
homeScreen {
|
||||
|
@ -68,10 +69,6 @@ class SettingsAboutTest {
|
|||
// ABOUT
|
||||
@Test
|
||||
fun verifyRateOnGooglePlayRedirect() {
|
||||
activityIntentTestRule.applySettingsExceptions {
|
||||
it.isTCPCFREnabled = false
|
||||
}
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
|
@ -83,12 +80,11 @@ class SettingsAboutTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/25355")
|
||||
@Test
|
||||
fun verifyAboutFirefoxPreview() {
|
||||
activityIntentTestRule.applySettingsExceptions {
|
||||
it.isJumpBackInCFREnabled = false
|
||||
it.isTCPCFREnabled = false
|
||||
}
|
||||
val settings = activityIntentTestRule.activity.settings()
|
||||
settings.shouldShowJumpBackInCFR = false
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import android.view.View
|
||||
import androidx.test.espresso.IdlingRegistry
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
|
@ -18,7 +19,6 @@ import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
|||
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.getEnhancedTrackingProtectionAsset
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
|
||||
import org.mozilla.fenix.helpers.TestHelper.registerAndCleanupIdlingResources
|
||||
import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource
|
||||
import org.mozilla.fenix.ui.robots.addonsMenu
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
@ -30,9 +30,11 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
|
|||
*/
|
||||
class SettingsAddonsTest {
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private var addonsListIdlingResource: RecyclerViewIdlingResource? = null
|
||||
private var addonContainerIdlingResource: ViewVisibilityIdlingResource? = null
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
|
||||
val activityTestRule = HomeActivityIntentTestRule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
|
@ -45,6 +47,14 @@ class SettingsAddonsTest {
|
|||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
|
||||
if (addonsListIdlingResource != null) {
|
||||
IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!)
|
||||
}
|
||||
|
||||
if (addonContainerIdlingResource != null) {
|
||||
IdlingRegistry.getInstance().unregister(addonContainerIdlingResource!!)
|
||||
}
|
||||
}
|
||||
|
||||
// Walks through settings add-ons menu to ensure all items are present
|
||||
|
@ -56,11 +66,10 @@ class SettingsAddonsTest {
|
|||
verifyAdvancedHeading()
|
||||
verifyAddons()
|
||||
}.openAddonsManagerMenu {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.add_ons_list), 1),
|
||||
) {
|
||||
verifyAddonsItems()
|
||||
}
|
||||
addonsListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.add_ons_list), 1)
|
||||
IdlingRegistry.getInstance().register(addonsListIdlingResource!!)
|
||||
verifyAddonsItems()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,14 +81,14 @@ class SettingsAddonsTest {
|
|||
homeScreen {}
|
||||
.openThreeDotMenu {}
|
||||
.openAddonsManagerMenu {
|
||||
registerAndCleanupIdlingResources(
|
||||
addonsListIdlingResource =
|
||||
RecyclerViewIdlingResource(
|
||||
activityTestRule.activity.findViewById(R.id.add_ons_list),
|
||||
1,
|
||||
),
|
||||
) {
|
||||
clickInstallAddon(addonName)
|
||||
}
|
||||
1
|
||||
)
|
||||
IdlingRegistry.getInstance().register(addonsListIdlingResource!!)
|
||||
clickInstallAddon(addonName)
|
||||
IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!)
|
||||
verifyAddonPermissionPrompt(addonName)
|
||||
cancelInstallAddon()
|
||||
clickInstallAddon(addonName)
|
||||
|
@ -102,20 +111,20 @@ class SettingsAddonsTest {
|
|||
verifyAddonInstallCompleted(addonName, activityTestRule)
|
||||
closeAddonInstallCompletePrompt()
|
||||
}.openDetailedMenuForAddon(addonName) {
|
||||
registerAndCleanupIdlingResources(
|
||||
ViewVisibilityIdlingResource(
|
||||
activityTestRule.activity.findViewById(R.id.addon_container),
|
||||
View.VISIBLE,
|
||||
),
|
||||
) {}
|
||||
addonContainerIdlingResource = ViewVisibilityIdlingResource(
|
||||
activityTestRule.activity.findViewById(R.id.addon_container),
|
||||
View.VISIBLE
|
||||
)
|
||||
IdlingRegistry.getInstance().register(addonContainerIdlingResource!!)
|
||||
}.removeAddon {
|
||||
IdlingRegistry.getInstance().unregister(addonContainerIdlingResource!!)
|
||||
verifyAddonCanBeInstalled(addonName)
|
||||
}
|
||||
}
|
||||
|
||||
// Installs uBlock add-on and checks that the app doesn't crash while loading pages with trackers
|
||||
@SmokeTest
|
||||
@Test
|
||||
// Installs uBlock add-on and checks that the app doesn't crash while loading pages with trackers
|
||||
fun noCrashWithAddonInstalledTest() {
|
||||
// setting ETP to Strict mode to test it works with add-ons
|
||||
activityTestRule.activity.settings().setStrictETP()
|
||||
|
|
|
@ -9,13 +9,17 @@ import androidx.test.uiautomator.UiDevice
|
|||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_PLAY_SERVICES
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.assertNativeAppOpens
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
|
@ -27,31 +31,35 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
|
|||
class SettingsAdvancedTest {
|
||||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
|
||||
private lateinit var mDevice: UiDevice
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
|
||||
@get:Rule
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule(
|
||||
isPocketEnabled = false,
|
||||
isTCPCFREnabled = false,
|
||||
)
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val retryTestRule = RetryTestRule(3)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
featureSettingsHelper.setPocketEnabled(false)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
// Walks through settings menu and sub-menus to ensure all items are present
|
||||
@Test
|
||||
// Walks through settings menu and sub-menus to ensure all items are present
|
||||
fun settingsAboutItemsTest() {
|
||||
// ADVANCED
|
||||
homeScreen {
|
||||
|
@ -67,11 +75,13 @@ class SettingsAdvancedTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Assumes Play Store is installed and enabled
|
||||
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/25551")
|
||||
@SmokeTest
|
||||
@Test
|
||||
// Assumes Play Store is installed and enabled
|
||||
fun openLinkInAppTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3)
|
||||
val playStoreUrl = "play.google.com/store/apps/details?id=org.mozilla.fenix"
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
|
@ -86,7 +96,7 @@ class SettingsAdvancedTest {
|
|||
mDevice.waitForIdle()
|
||||
clickLinkMatchingText("Mozilla Playstore link")
|
||||
mDevice.waitForIdle()
|
||||
TestHelper.assertPlayStoreOpens()
|
||||
assertNativeAppOpens(GOOGLE_PLAY_SERVICES, playStoreUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,39 +4,19 @@
|
|||
|
||||
package org.mozilla.fenix.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.FenixApplication
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.getLoremIpsumAsset
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong
|
||||
import org.mozilla.fenix.helpers.TestHelper.getStringResource
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestHelper.registerAndCleanupIdlingResources
|
||||
import org.mozilla.fenix.helpers.TestHelper.runWithSystemLocaleChanged
|
||||
import org.mozilla.fenix.ui.SettingsBasicsTest.CreditCard.MOCK_CREDIT_CARD_NUMBER
|
||||
import org.mozilla.fenix.ui.SettingsBasicsTest.CreditCard.MOCK_EXPIRATION_MONTH
|
||||
import org.mozilla.fenix.ui.SettingsBasicsTest.CreditCard.MOCK_EXPIRATION_YEAR
|
||||
import org.mozilla.fenix.ui.SettingsBasicsTest.CreditCard.MOCK_LAST_CARD_DIGITS
|
||||
import org.mozilla.fenix.ui.SettingsBasicsTest.CreditCard.MOCK_NAME_ON_CARD
|
||||
import org.mozilla.fenix.ui.robots.checkTextSizeOnWebsite
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
import org.mozilla.fenix.ui.util.FRENCH_LANGUAGE_HEADER
|
||||
import org.mozilla.fenix.ui.util.FRENCH_SYSTEM_LOCALE_OPTION
|
||||
import org.mozilla.fenix.ui.util.FR_SETTINGS
|
||||
import org.mozilla.fenix.ui.util.ROMANIAN_LANGUAGE_HEADER
|
||||
import java.time.LocalDate
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* Tests for verifying the General section of the Settings menu
|
||||
|
@ -45,17 +25,10 @@ import java.util.Locale
|
|||
class SettingsBasicsTest {
|
||||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
object CreditCard {
|
||||
const val MOCK_CREDIT_CARD_NUMBER = "5555555555554444"
|
||||
const val MOCK_LAST_CARD_DIGITS = "4444"
|
||||
const val MOCK_NAME_ON_CARD = "Mastercard"
|
||||
const val MOCK_EXPIRATION_MONTH = "February"
|
||||
val MOCK_EXPIRATION_YEAR = (LocalDate.now().year + 1).toString()
|
||||
}
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
|
||||
@get:Rule
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
|
@ -63,11 +36,27 @@ class SettingsBasicsTest {
|
|||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
|
||||
// resetting modified features enabled setting to default
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
private fun getUiTheme(): Boolean {
|
||||
val mode =
|
||||
activityIntentTestRule.activity.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK)
|
||||
|
||||
return when (mode) {
|
||||
Configuration.UI_MODE_NIGHT_YES -> true // dark theme is set
|
||||
Configuration.UI_MODE_NIGHT_NO -> false // dark theme is not set, using light theme
|
||||
else -> false // default option is light theme
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -82,13 +71,28 @@ class SettingsBasicsTest {
|
|||
verifyHomepageButton()
|
||||
verifyCustomizeButton()
|
||||
verifyLoginsAndPasswordsButton()
|
||||
verifyAutofillButton()
|
||||
verifyCreditCardsButton()
|
||||
verifyAccessibilityButton()
|
||||
verifyLanguageButton()
|
||||
verifySetAsDefaultBrowserButton()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun changeThemeSetting() {
|
||||
// Goes through the settings and changes the default search engine, then verifies it changes.
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openCustomizeSubMenu {
|
||||
verifyThemes()
|
||||
selectDarkMode()
|
||||
verifyDarkThemeApplied(getUiTheme())
|
||||
selectLightMode()
|
||||
verifyLightThemeApplied(getUiTheme())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun changeAccessibiltySettings() {
|
||||
// Goes through the settings and changes the default text on a webpage, then verifies if the text has changed.
|
||||
|
@ -118,179 +122,4 @@ class SettingsBasicsTest {
|
|||
verifyMenuItemsAreDisabled()
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun verifyAddressAutofillTest() {
|
||||
val addressFormPage =
|
||||
TestAssetHelper.getAddressFormAsset(mockWebServer)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openAutofillSubMenu {
|
||||
clickAddAddressButton()
|
||||
fillAndSaveAddress(
|
||||
"Mozilla",
|
||||
"Fenix",
|
||||
"Firefox",
|
||||
"Harrison Street",
|
||||
"San Francisco",
|
||||
"Alaska",
|
||||
"94105",
|
||||
"United States",
|
||||
"555-5555",
|
||||
"foo@bar.com",
|
||||
)
|
||||
}.goBack {
|
||||
}.goBack {
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(addressFormPage.url) {
|
||||
clickStreetAddressTextBox()
|
||||
clickSelectAddressButton()
|
||||
clickAddressSuggestion("Harrison Street")
|
||||
verifyAutofilledAddress("Harrison Street")
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun deleteSavedAddressTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openAutofillSubMenu {
|
||||
clickAddAddressButton()
|
||||
fillAndSaveAddress(
|
||||
"Mozilla",
|
||||
"Fenix",
|
||||
"Firefox",
|
||||
"Harrison Street",
|
||||
"San Francisco",
|
||||
"Alaska",
|
||||
"94105",
|
||||
"United States",
|
||||
"555-5555",
|
||||
"foo@bar.com",
|
||||
)
|
||||
clickManageAddressesButton()
|
||||
clickSavedAddress("Mozilla")
|
||||
clickDeleteAddressButton()
|
||||
clickCancelDeleteAddressButton()
|
||||
clickDeleteAddressButton()
|
||||
clickConfirmDeleteAddressButton()
|
||||
verifyAddAddressButton()
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun verifyCreditCardAutofillTest() {
|
||||
val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openAutofillSubMenu {
|
||||
clickAddCreditCardButton()
|
||||
fillAndSaveCreditCard(MOCK_CREDIT_CARD_NUMBER, MOCK_NAME_ON_CARD, MOCK_EXPIRATION_MONTH, MOCK_EXPIRATION_YEAR)
|
||||
// Opening Manage saved cards to dismiss here the Secure your credit prompt
|
||||
clickManageSavedCardsButton()
|
||||
clickSecuredCreditCardsLaterButton()
|
||||
}.goBackToAutofillSettings {
|
||||
}.goBack {
|
||||
}.goBack {
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(creditCardFormPage.url) {
|
||||
clickCardNumberTextBox()
|
||||
clickSelectCreditCardButton()
|
||||
clickCreditCardSuggestion(MOCK_LAST_CARD_DIGITS)
|
||||
verifyAutofilledCreditCard(MOCK_CREDIT_CARD_NUMBER)
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun deleteSavedCreditCardTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openAutofillSubMenu {
|
||||
clickAddCreditCardButton()
|
||||
fillAndSaveCreditCard(MOCK_CREDIT_CARD_NUMBER, MOCK_NAME_ON_CARD, MOCK_EXPIRATION_MONTH, MOCK_EXPIRATION_YEAR)
|
||||
clickManageSavedCardsButton()
|
||||
clickSecuredCreditCardsLaterButton()
|
||||
clickSavedCreditCard()
|
||||
clickDeleteCreditCardButton()
|
||||
clickConfirmDeleteCreditCardButton()
|
||||
verifyAddCreditCardsButton()
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun switchLanguageTest() {
|
||||
val enLanguageHeaderText = getStringResource(R.string.preferences_language)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openLanguageSubMenu {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(
|
||||
activityIntentTestRule.activity.findViewById(R.id.locale_list),
|
||||
2,
|
||||
),
|
||||
) {
|
||||
selectLanguage("Romanian")
|
||||
verifyLanguageHeaderIsTranslated(ROMANIAN_LANGUAGE_HEADER)
|
||||
selectLanguage("Français")
|
||||
verifyLanguageHeaderIsTranslated(FRENCH_LANGUAGE_HEADER)
|
||||
selectLanguage(FRENCH_SYSTEM_LOCALE_OPTION)
|
||||
verifyLanguageHeaderIsTranslated(enLanguageHeaderText)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun searchInLanguagesListTest() {
|
||||
val systemLocaleDefault = getStringResource(R.string.default_locale_text)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openLanguageSubMenu {
|
||||
verifyLanguageListIsDisplayed()
|
||||
openSearchBar()
|
||||
typeInSearchBar("French")
|
||||
verifySearchResultsContains(systemLocaleDefault)
|
||||
clearSearchBar()
|
||||
typeInSearchBar("French")
|
||||
selectLanguageSearchResult("Français")
|
||||
verifyLanguageHeaderIsTranslated(FRENCH_LANGUAGE_HEADER)
|
||||
// Add this step when https://github.com/mozilla-mobile/fenix/issues/26733 is fixed
|
||||
// verifyLanguageListIsDisplayed()
|
||||
}
|
||||
}
|
||||
|
||||
// Because it requires changing system prefs, this test will run only on Debug builds
|
||||
@Ignore("Failing due to app translation bug, see: https://github.com/mozilla-mobile/fenix/issues/26729")
|
||||
@Test
|
||||
fun frenchSystemLocaleTest() {
|
||||
val frenchLocale = Locale("fr", "FR")
|
||||
|
||||
runWithSystemLocaleChanged(frenchLocale, activityIntentTestRule) {
|
||||
mDevice.waitForIdle(waitingTimeLong)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings(localizedText = FR_SETTINGS) {
|
||||
}.openLanguageSubMenu(localizedText = FRENCH_LANGUAGE_HEADER) {
|
||||
verifyLanguageHeaderIsTranslated(FRENCH_LANGUAGE_HEADER)
|
||||
verifySelectedLanguage(FRENCH_SYSTEM_LOCALE_OPTION)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,122 +0,0 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
class SettingsCustomizeTest {
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
@get:Rule
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
private fun getUiTheme(): Boolean {
|
||||
val mode =
|
||||
activityIntentTestRule.activity.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK)
|
||||
|
||||
return when (mode) {
|
||||
Configuration.UI_MODE_NIGHT_YES -> true // dark theme is set
|
||||
Configuration.UI_MODE_NIGHT_NO -> false // dark theme is not set, using light theme
|
||||
else -> false // default option is light theme
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun changeThemeSettingTest() {
|
||||
// Goes through the settings and changes the default search engine, then verifies it changes.
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openCustomizeSubMenu {
|
||||
verifyThemes()
|
||||
selectDarkMode()
|
||||
verifyDarkThemeApplied(getUiTheme())
|
||||
selectLightMode()
|
||||
verifyLightThemeApplied(getUiTheme())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setToolbarPositionTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openCustomizeSubMenu {
|
||||
verifyToolbarPositionPreference("Bottom")
|
||||
clickTopToolbarToggle()
|
||||
verifyToolbarPositionPreference("Top")
|
||||
}.goBack {
|
||||
}.goBack {
|
||||
verifyToolbarPosition(defaultPosition = false)
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openCustomizeSubMenu {
|
||||
clickBottomToolbarToggle()
|
||||
verifyToolbarPositionPreference("Bottom")
|
||||
exitMenu()
|
||||
}
|
||||
homeScreen {
|
||||
verifyToolbarPosition(defaultPosition = true)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun swipeToolbarGesturePreferenceOffTest() {
|
||||
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openCustomizeSubMenu {
|
||||
verifySwipeToolbarGesturePrefState(true)
|
||||
clickSwipeToolbarToSwitchTabToggle()
|
||||
verifySwipeToolbarGesturePrefState(false)
|
||||
exitMenu()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(firstWebPage.url) {
|
||||
}.openTabDrawer {
|
||||
}.openNewTab {
|
||||
}.submitQuery(secondWebPage.url.toString()) {
|
||||
swipeNavBarRight(secondWebPage.url.toString())
|
||||
verifyUrl(secondWebPage.url.toString())
|
||||
swipeNavBarLeft(secondWebPage.url.toString())
|
||||
verifyUrl(secondWebPage.url.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun pullToRefreshPreferenceTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openCustomizeSubMenu {
|
||||
verifyPullToRefreshGesturePrefState(isEnabled = true)
|
||||
clickPullToRefreshToggle()
|
||||
verifyPullToRefreshGesturePrefState(isEnabled = false)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,10 +7,10 @@ package org.mozilla.fenix.ui
|
|||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Before
|
||||
import org.junit.After
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
|
@ -24,7 +24,7 @@ import org.mozilla.fenix.ui.robots.homeScreen
|
|||
class SettingsDeveloperToolsTest {
|
||||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
|
||||
private lateinit var mDevice: UiDevice
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
@get:Rule
|
||||
|
@ -32,7 +32,6 @@ class SettingsDeveloperToolsTest {
|
|||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -44,8 +43,8 @@ class SettingsDeveloperToolsTest {
|
|||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
// Walks through settings developer tools menu and sub-menus to ensure all items are present
|
||||
@Test
|
||||
// Walks through settings developer tools menu and sub-menus to ensure all items are present
|
||||
fun settingsDeveloperToolsItemsTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
|
|
|
@ -7,16 +7,14 @@ package org.mozilla.fenix.ui
|
|||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestHelper.openAppFromExternalLink
|
||||
import org.mozilla.fenix.helpers.TestHelper.restartApp
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
@ -28,9 +26,10 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
|
|||
*/
|
||||
class SettingsHomepageTest {
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
|
||||
@get:Rule
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule(skipOnboarding = true)
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
|
@ -42,83 +41,15 @@ class SettingsHomepageTest {
|
|||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyHomepageSettingsTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openHomepageSubMenu {
|
||||
verifyHomePageView()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyShortcutOptionTest() {
|
||||
// en-US defaults
|
||||
val defaultTopSites = arrayOf(
|
||||
"Top Articles",
|
||||
"Wikipedia",
|
||||
"Google",
|
||||
)
|
||||
|
||||
homeScreen {
|
||||
defaultTopSites.forEach { item ->
|
||||
verifyExistingTopSitesTabs(item)
|
||||
}
|
||||
}.openThreeDotMenu {
|
||||
}.openCustomizeHome {
|
||||
clickShortcutsButton()
|
||||
}.goBack {
|
||||
defaultTopSites.forEach { item ->
|
||||
verifyNotExistingTopSitesList(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyRecentlyVisitedOptionTest() {
|
||||
activityIntentTestRule.applySettingsExceptions {
|
||||
it.isRecentTabsFeatureEnabled = false
|
||||
}
|
||||
val genericURL = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(genericURL.url) {
|
||||
}.goToHomescreen {
|
||||
verifyRecentlyVisitedSectionIsDisplayed()
|
||||
}.openThreeDotMenu {
|
||||
}.openCustomizeHome {
|
||||
clickRecentlyVisited()
|
||||
}.goBack {
|
||||
verifyRecentlyVisitedSectionIsNotDisplayed()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyPocketOptionTest() {
|
||||
activityIntentTestRule.applySettingsExceptions {
|
||||
it.isRecentTabsFeatureEnabled = false
|
||||
it.isRecentlyVisitedFeatureEnabled = false
|
||||
}
|
||||
val genericURL = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(genericURL.url) {
|
||||
}.goToHomescreen {
|
||||
verifyPocketSectionIsDisplayed()
|
||||
}.openThreeDotMenu {
|
||||
}.openCustomizeHome {
|
||||
clickPocketButton()
|
||||
}.goBack {
|
||||
verifyPocketSectionIsNotDisplayed()
|
||||
}
|
||||
// resetting modified features enabled setting to default
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
|
@ -182,6 +113,19 @@ class SettingsHomepageTest {
|
|||
fun startOnLastTabTest() {
|
||||
val firstWebPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openHomepageSubMenu {
|
||||
clickStartOnHomepageButton()
|
||||
}
|
||||
|
||||
restartApp(activityIntentTestRule)
|
||||
|
||||
homeScreen {
|
||||
verifyHomeScreen()
|
||||
}
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(firstWebPage.url) {
|
||||
}.goToHomescreen {
|
||||
|
@ -197,39 +141,13 @@ class SettingsHomepageTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ignoreStartOnHomeWhenLaunchedByExternalLinkTest() {
|
||||
val genericPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openHomepageSubMenu {
|
||||
clickStartOnHomepageButton()
|
||||
}.goBack {}
|
||||
|
||||
with(activityIntentTestRule) {
|
||||
finishActivity()
|
||||
mDevice.waitForIdle()
|
||||
this.applySettingsExceptions {
|
||||
it.isTCPCFREnabled = false
|
||||
}
|
||||
openAppFromExternalLink(genericPage.url.toString())
|
||||
}
|
||||
|
||||
browserScreen {
|
||||
verifyPageContent(genericPage.content)
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
@Ignore("Intermittent test: https://github.com/mozilla-mobile/fenix/issues/26559")
|
||||
fun setWallpaperTest() {
|
||||
val wallpapers = listOf(
|
||||
"Wallpaper Item: amethyst",
|
||||
"Wallpaper Item: cerulean",
|
||||
"Wallpaper Item: sunrise",
|
||||
"Wallpaper Item: sunrise"
|
||||
)
|
||||
|
||||
for (wallpaper in wallpapers) {
|
||||
|
|
|
@ -7,29 +7,24 @@ package org.mozilla.fenix.ui
|
|||
import android.os.Build
|
||||
import android.view.autofill.AutofillManager
|
||||
import androidx.core.net.toUri
|
||||
import androidx.test.filters.SdkSuppress
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.getStorageTestAsset
|
||||
import org.mozilla.fenix.helpers.TestHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.helpers.TestHelper.generateRandomString
|
||||
import org.mozilla.fenix.helpers.TestHelper.getStringResource
|
||||
import org.mozilla.fenix.helpers.TestHelper.openAppFromExternalLink
|
||||
import org.mozilla.fenix.helpers.TestHelper.restartApp
|
||||
import org.mozilla.fenix.helpers.TestHelper.setNetworkEnabled
|
||||
import org.mozilla.fenix.ui.robots.addToHomeScreen
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
@ -44,22 +39,24 @@ import org.mozilla.fenix.ui.robots.settingsScreen
|
|||
class SettingsPrivacyTest {
|
||||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
|
||||
private lateinit var mDevice: UiDevice
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private val pageShortcutName = generateRandomString(5)
|
||||
private val pageShortcutName = "TestShortcut"
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
|
||||
val activityTestRule = HomeActivityIntentTestRule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
appContext.settings().userOptOutOfReEngageCookieBannerDialog = true
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
featureSettingsHelper.disablePwaCFR(true)
|
||||
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
|
||||
val autofillManager: AutofillManager =
|
||||
appContext.getSystemService(AutofillManager::class.java)
|
||||
|
@ -72,8 +69,8 @@ class SettingsPrivacyTest {
|
|||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
// Walks through settings privacy menu and sub-menus to ensure all items are present
|
||||
@Test
|
||||
// Walks through settings privacy menu and sub-menus to ensure all items are present
|
||||
fun settingsPrivacyItemsTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
|
@ -103,6 +100,7 @@ class SettingsPrivacyTest {
|
|||
verifyEnhancedTrackingProtectionProtectionExceptionsSubMenuItems()
|
||||
}.goBack {
|
||||
}.goBack {
|
||||
|
||||
// SITE PERMISSIONS
|
||||
verifySitePermissionsButton()
|
||||
}.openSettingsSubMenuSitePermissions {
|
||||
|
@ -114,46 +112,54 @@ class SettingsPrivacyTest {
|
|||
verifyNavigationToolBarHeader("Autoplay")
|
||||
verifySitePermissionsAutoPlaySubMenuItems()
|
||||
}.goBack {
|
||||
|
||||
// SITE PERMISSIONS CAMERA
|
||||
}.openCamera {
|
||||
verifyNavigationToolBarHeader("Camera")
|
||||
verifySitePermissionsCommonSubMenuItems()
|
||||
verifyToggleNameToON("3. Toggle Camera to ON")
|
||||
}.goBack {
|
||||
|
||||
// SITE PERMISSIONS LOCATION
|
||||
}.openLocation {
|
||||
verifyNavigationToolBarHeader("Location")
|
||||
verifySitePermissionsCommonSubMenuItems()
|
||||
verifyToggleNameToON("3. Toggle Location to ON")
|
||||
}.goBack {
|
||||
|
||||
// SITE PERMISSIONS MICROPHONE
|
||||
}.openMicrophone {
|
||||
verifyNavigationToolBarHeader("Microphone")
|
||||
verifySitePermissionsCommonSubMenuItems()
|
||||
verifyToggleNameToON("3. Toggle Microphone to ON")
|
||||
}.goBack {
|
||||
|
||||
// SITE PERMISSIONS NOTIFICATION
|
||||
}.openNotification {
|
||||
verifyNavigationToolBarHeader("Notification")
|
||||
verifySitePermissionsNotificationSubMenuItems()
|
||||
}.goBack {
|
||||
|
||||
// SITE PERMISSIONS PERSISTENT STORAGE
|
||||
}.openPersistentStorage {
|
||||
verifyNavigationToolBarHeader("Persistent Storage")
|
||||
verifySitePermissionsPersistentStorageSubMenuItems()
|
||||
}.goBack {
|
||||
|
||||
// SITE PERMISSIONS EXCEPTIONS
|
||||
}.openExceptions {
|
||||
verifyNavigationToolBarHeader()
|
||||
verifySitePermissionsExceptionSubMenuItems()
|
||||
}.goBack {
|
||||
}.goBack {
|
||||
|
||||
// DELETE BROWSING DATA
|
||||
verifyDeleteBrowsingDataButton()
|
||||
}.openSettingsSubMenuDeleteBrowsingData {
|
||||
verifyNavigationToolBarHeader()
|
||||
verifyDeleteBrowsingDataSubMenuItems()
|
||||
}.goBack {
|
||||
|
||||
// DELETE BROWSING DATA ON QUIT
|
||||
verifyDeleteBrowsingDataOnQuitButton()
|
||||
verifyDeleteBrowsingDataOnQuitState("Off")
|
||||
|
@ -161,11 +167,13 @@ class SettingsPrivacyTest {
|
|||
verifyNavigationToolBarHeader()
|
||||
verifyDeleteBrowsingDataOnQuitSubMenuItems()
|
||||
}.goBack {
|
||||
|
||||
// NOTIFICATIONS
|
||||
verifyNotificationsButton()
|
||||
}.openSettingsSubMenuNotifications {
|
||||
verifySystemNotificationsView()
|
||||
}.goBack {
|
||||
|
||||
// DATA COLLECTION
|
||||
verifyDataCollectionButton()
|
||||
}.openSettingsSubMenuDataCollection {
|
||||
|
@ -231,6 +239,8 @@ class SettingsPrivacyTest {
|
|||
@Test
|
||||
fun neverSaveLoginFromPromptTest() {
|
||||
val saveLoginTest = TestAssetHelper.getSaveLoginAsset(mockWebServer)
|
||||
val settings = activityTestRule.activity.settings()
|
||||
settings.shouldShowJumpBackInCFR = false
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(saveLoginTest.url) {
|
||||
|
@ -322,6 +332,7 @@ class SettingsPrivacyTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/24573")
|
||||
@Test
|
||||
fun openExternalLinksInPrivateTest() {
|
||||
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
@ -332,7 +343,6 @@ class SettingsPrivacyTest {
|
|||
openAppFromExternalLink(firstWebPage.url.toString())
|
||||
|
||||
browserScreen {
|
||||
verifyUrl(firstWebPage.url.toString())
|
||||
}.openTabDrawer {
|
||||
verifyPrivateModeSelected()
|
||||
}.closeTabDrawer {
|
||||
|
@ -344,7 +354,6 @@ class SettingsPrivacyTest {
|
|||
openAppFromExternalLink(secondWebPage.url.toString())
|
||||
|
||||
browserScreen {
|
||||
verifyUrl(secondWebPage.url.toString())
|
||||
}.openTabDrawer {
|
||||
verifyNormalModeSelected()
|
||||
}
|
||||
|
@ -381,8 +390,11 @@ class SettingsPrivacyTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Failing with frequent ANR: https://bugzilla.mozilla.org/show_bug.cgi?id=1764605")
|
||||
@Test
|
||||
fun launchLinksInPrivateToggleOffStateDoesntChangeTest() {
|
||||
val settings = activityTestRule.activity.applicationContext.settings()
|
||||
settings.shouldShowJumpBackInCFR = false
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
setOpenLinksInPrivateOn()
|
||||
|
@ -431,45 +443,6 @@ class SettingsPrivacyTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Verifies that you can go to System settings and change app's permissions from inside the app
|
||||
@SmokeTest
|
||||
@Test
|
||||
@SdkSuppress(minSdkVersion = 29)
|
||||
fun redirectToAppPermissionsSystemSettingsTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSettingsSubMenuSitePermissions {
|
||||
}.openCamera {
|
||||
verifyBlockedByAndroid()
|
||||
}.goBack {
|
||||
}.openLocation {
|
||||
verifyBlockedByAndroid()
|
||||
}.goBack {
|
||||
}.openMicrophone {
|
||||
verifyBlockedByAndroid()
|
||||
clickGoToSettingsButton()
|
||||
openAppSystemPermissionsSettings()
|
||||
switchAppPermissionSystemSetting("Camera", "Allow")
|
||||
goBackToSystemAppPermissionSettings()
|
||||
verifySystemGrantedPermission("Camera")
|
||||
switchAppPermissionSystemSetting("Location", "Allow")
|
||||
goBackToSystemAppPermissionSettings()
|
||||
verifySystemGrantedPermission("Location")
|
||||
switchAppPermissionSystemSetting("Microphone", "Allow")
|
||||
goBackToSystemAppPermissionSettings()
|
||||
verifySystemGrantedPermission("Microphone")
|
||||
goBackToPermissionsSettingsSubMenu()
|
||||
verifyUnblockedByAndroid()
|
||||
}.goBack {
|
||||
}.openLocation {
|
||||
verifyUnblockedByAndroid()
|
||||
}.goBack {
|
||||
}.openCamera {
|
||||
verifyUnblockedByAndroid()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun deleteBrowsingDataOptionStatesTest() {
|
||||
homeScreen {
|
||||
|
@ -576,16 +549,16 @@ class SettingsPrivacyTest {
|
|||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun deleteBrowsingHistoryAndSiteDataTest() {
|
||||
val storageWritePage = getStorageTestAsset(mockWebServer, "storage_write.html").url
|
||||
val storageCheckPage = getStorageTestAsset(mockWebServer, "storage_check.html").url
|
||||
fun deleteDeleteBrowsingHistoryDataTest() {
|
||||
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(storageWritePage) {
|
||||
}.enterURLAndEnterToBrowser(firstWebPage.url) {
|
||||
mDevice.waitForIdle()
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(storageCheckPage) {
|
||||
verifyPageContent("Session storage has value")
|
||||
verifyPageContent("Local storage has value")
|
||||
}.enterURLAndEnterToBrowser(secondWebPage.url) {
|
||||
mDevice.waitForIdle()
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSettingsSubMenuDeleteBrowsingData {
|
||||
|
@ -597,79 +570,15 @@ class SettingsPrivacyTest {
|
|||
clickDeleteBrowsingDataButton()
|
||||
confirmDeletionAndAssertSnackbar()
|
||||
verifyBrowsingHistoryDetails("0")
|
||||
exitMenu()
|
||||
}.goBack {
|
||||
verifyGeneralHeading()
|
||||
}.goBack {
|
||||
}
|
||||
navigationToolbar {
|
||||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyEmptyHistoryView()
|
||||
mDevice.pressBack()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(storageCheckPage) {
|
||||
verifyPageContent("Session storage empty")
|
||||
verifyPageContent("Local storage empty")
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun deleteCookiesTest() {
|
||||
val genericPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val cookiesTestPage = getStorageTestAsset(mockWebServer, "storage_write.html").url
|
||||
|
||||
// Browsing a generic page to allow GV to load on a fresh run
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(genericPage.url) {
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(cookiesTestPage) {
|
||||
verifyPageContent("No cookies set")
|
||||
clickSetCookiesButton()
|
||||
verifyPageContent("user=android")
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSettingsSubMenuDeleteBrowsingData {
|
||||
selectOnlyCookiesCheckBox()
|
||||
clickDeleteBrowsingDataButton()
|
||||
confirmDeletionAndAssertSnackbar()
|
||||
exitMenu()
|
||||
}
|
||||
browserScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.refreshPage {
|
||||
verifyPageContent("No cookies set")
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun deleteCachedFilesTest() {
|
||||
val pocketTopArticles = getStringResource(R.string.pocket_pinned_top_articles)
|
||||
|
||||
homeScreen {
|
||||
verifyExistingTopSitesTabs(pocketTopArticles)
|
||||
}.openTopSiteTabWithTitle(pocketTopArticles) {
|
||||
waitForPageToLoad()
|
||||
}.openTabDrawer {
|
||||
}.openNewTab {
|
||||
}.submitQuery("about:cache") {
|
||||
// disabling wifi to prevent downloads in the background
|
||||
setNetworkEnabled(enabled = false)
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSettingsSubMenuDeleteBrowsingData {
|
||||
selectOnlyCachedFilesCheckBox()
|
||||
clickDeleteBrowsingDataButton()
|
||||
confirmDeletionAndAssertSnackbar()
|
||||
exitMenu()
|
||||
}
|
||||
browserScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.refreshPage {
|
||||
verifyNetworkCacheIsEmpty("memory")
|
||||
verifyNetworkCacheIsEmpty("disk")
|
||||
}
|
||||
setNetworkEnabled(enabled = true)
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
|
|
|
@ -7,28 +7,24 @@ import org.junit.Before
|
|||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
|
||||
import org.mozilla.fenix.helpers.SearchDispatcher
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
|
||||
import org.mozilla.fenix.helpers.TestHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.helpers.TestHelper.setTextToClipBoard
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
import org.mozilla.fenix.ui.util.ARABIC_LANGUAGE_HEADER
|
||||
|
||||
class SettingsSearchTest {
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private lateinit var searchMockServer: MockWebServer
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = AndroidComposeTestRule(
|
||||
HomeActivityIntentTestRule.withDefaultSettingsOverrides(),
|
||||
HomeActivityIntentTestRule()
|
||||
) { it.activity }
|
||||
|
||||
@Before
|
||||
|
@ -37,11 +33,15 @@ class SettingsSearchTest {
|
|||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
|
||||
// resetting modified features enabled setting to default
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -53,11 +53,6 @@ class SettingsSearchTest {
|
|||
verifySearchToolbar()
|
||||
verifyDefaultSearchEngineHeader()
|
||||
verifySearchEngineList()
|
||||
verifyShowSearchSuggestions()
|
||||
verifyShowSearchShortcuts()
|
||||
verifySearchBrowsingHistory()
|
||||
verifySearchBookmarks()
|
||||
verifyShowClipboardSuggestionsDefault()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,27 +70,6 @@ class SettingsSearchTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toggleSearchAutocomplete() {
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
typeSearch("mo")
|
||||
verifyTypedToolbarText("monster.com")
|
||||
typeSearch("moz")
|
||||
verifyTypedToolbarText("mozilla.org")
|
||||
}.dismissSearchBar {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
toggleAutocomplete()
|
||||
}.goBack {
|
||||
}.goBack {
|
||||
}.openSearch {
|
||||
typeSearch("moz")
|
||||
verifyTypedToolbarText("moz")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toggleSearchBookmarksAndHistoryTest() {
|
||||
// Bookmarks 2 websites, toggles the bookmarks and history search settings off,
|
||||
|
@ -124,9 +98,8 @@ class SettingsSearchTest {
|
|||
}.openSearch {
|
||||
typeSearch("test")
|
||||
expandSearchSuggestionsList()
|
||||
verifyFirefoxSuggestResults(activityTestRule, "Firefox Suggest")
|
||||
verifyFirefoxSuggestResults(activityTestRule, "Test_Page_1")
|
||||
verifyFirefoxSuggestResults(activityTestRule, "Test_Page_2")
|
||||
verifySearchEngineSuggestionResults(activityTestRule, "Test_Page_1")
|
||||
verifySearchEngineSuggestionResults(activityTestRule, "Test_Page_2")
|
||||
}.dismissSearchBar {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
|
@ -142,15 +115,14 @@ class SettingsSearchTest {
|
|||
}.openSearch {
|
||||
typeSearch("test")
|
||||
expandSearchSuggestionsList()
|
||||
verifyNoSuggestionsAreDisplayed(activityTestRule, "Firefox Suggest")
|
||||
verifyNoSuggestionsAreDisplayed(activityTestRule, "Test_Page_1")
|
||||
verifyNoSuggestionsAreDisplayed(activityTestRule, "Test_Page_2")
|
||||
}
|
||||
}
|
||||
|
||||
// Ads a new search engine from the list of custom engines
|
||||
@SmokeTest
|
||||
@Test
|
||||
// Ads a new search engine from the list of custom engines
|
||||
fun addPredefinedSearchEngineTest() {
|
||||
val searchEngine = "Reddit"
|
||||
|
||||
|
@ -174,9 +146,9 @@ class SettingsSearchTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Verifies setting as default a customized search engine name and URL
|
||||
@SmokeTest
|
||||
@Test
|
||||
// Verifies setting as default a customized search engine name and URL
|
||||
fun editCustomSearchEngineTest() {
|
||||
searchMockServer = MockWebServer().apply {
|
||||
dispatcher = SearchDispatcher()
|
||||
|
@ -210,13 +182,14 @@ class SettingsSearchTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Test running on beta/release builds in CI:
|
||||
// caution when making changes to it, so they don't block the builds
|
||||
// Goes through the settings and changes the search suggestion toggle, then verifies it changes.
|
||||
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/23817")
|
||||
@SmokeTest
|
||||
@Test
|
||||
// Test running on beta/release builds in CI:
|
||||
// caution when making changes to it, so they don't block the builds
|
||||
// Goes through the settings and changes the search suggestion toggle, then verifies it changes.
|
||||
fun toggleSearchSuggestionsTest() {
|
||||
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
typeSearch("mozilla")
|
||||
|
@ -225,48 +198,7 @@ class SettingsSearchTest {
|
|||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
toggleShowSearchSuggestions()
|
||||
}.goBack {
|
||||
}.goBack {
|
||||
}.openSearch {
|
||||
typeSearch("mozilla")
|
||||
verifyNoSuggestionsAreDisplayed(activityTestRule, "mozilla firefox")
|
||||
}
|
||||
}
|
||||
|
||||
// Tests the "Don't allow" option from private mode search suggestions onboarding dialog
|
||||
@Test
|
||||
fun blockSearchSuggestionsInPrivateModeOnboardingTest() {
|
||||
homeScreen {
|
||||
togglePrivateBrowsingModeOnOff()
|
||||
}.openSearch {
|
||||
typeSearch("mozilla")
|
||||
verifyAllowSuggestionsInPrivateModeDialog()
|
||||
denySuggestionsInPrivateMode()
|
||||
verifyNoSuggestionsAreDisplayed(activityTestRule, "mozilla firefox")
|
||||
}.dismissSearchBar {
|
||||
togglePrivateBrowsingModeOnOff()
|
||||
}.openSearch {
|
||||
typeSearch("mozilla")
|
||||
verifySearchEngineSuggestionResults(activityTestRule, "mozilla firefox")
|
||||
}
|
||||
}
|
||||
|
||||
// Tests the "Allow" option from private mode search suggestions onboarding dialog
|
||||
@Test
|
||||
fun allowSearchSuggestionsInPrivateModeOnboardingTest() {
|
||||
homeScreen {
|
||||
togglePrivateBrowsingModeOnOff()
|
||||
}.openSearch {
|
||||
typeSearch("mozilla")
|
||||
verifyAllowSuggestionsInPrivateModeDialog()
|
||||
allowSuggestionsInPrivateMode()
|
||||
verifySearchEngineSuggestionResults(activityTestRule, "mozilla firefox")
|
||||
}.dismissSearchBar {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
toggleShowSuggestionsInPrivateSessions()
|
||||
disableShowSearchSuggestions()
|
||||
}.goBack {
|
||||
}.goBack {
|
||||
}.openSearch {
|
||||
|
@ -294,194 +226,4 @@ class SettingsSearchTest {
|
|||
verifyVoiceSearchButtonVisibility(false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toggleShowClipboardSuggestionsTest() {
|
||||
val link = "https://www.mozilla.org/en-US/"
|
||||
setTextToClipBoard(appContext, link)
|
||||
|
||||
homeScreen {
|
||||
}.openNavigationToolbar {
|
||||
verifyClipboardSuggestionsAreDisplayed(link, true)
|
||||
}.visitLinkFromClipboard {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
verifyShowClipboardSuggestionsDefault()
|
||||
toggleClipboardSuggestion()
|
||||
exitMenu()
|
||||
}
|
||||
homeScreen {
|
||||
}.openNavigationToolbar {
|
||||
verifyClipboardSuggestionsAreDisplayed(link, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Expected for en-us defaults
|
||||
@Test
|
||||
fun undoDeleteSearchEngineTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
verifyEngineListContains("Bing")
|
||||
openEngineOverflowMenu("Bing")
|
||||
clickDeleteSearchEngine()
|
||||
clickUndoSnackBarButton()
|
||||
verifyEngineListContains("Bing")
|
||||
}
|
||||
}
|
||||
|
||||
// Expected for en-us defaults
|
||||
@Test
|
||||
fun deleteDefaultSearchEngineTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
verifyEngineListContains("Google")
|
||||
verifyDefaultSearchEngine("Google")
|
||||
openEngineOverflowMenu("Google")
|
||||
clickDeleteSearchEngine()
|
||||
verifyEngineListDoesNotContain("Google")
|
||||
verifyDefaultSearchEngine("Bing")
|
||||
}
|
||||
}
|
||||
|
||||
// Expected for en-us defaults
|
||||
@Test
|
||||
fun deleteAllSearchEnginesTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
deleteMultipleSearchEngines(
|
||||
"Google",
|
||||
"Bing",
|
||||
"Amazon.com",
|
||||
"DuckDuckGo",
|
||||
"eBay",
|
||||
)
|
||||
verifyDefaultSearchEngine("Wikipedia")
|
||||
verifyThreeDotButtonIsNotDisplayed("Wikipedia")
|
||||
openAddSearchEngineMenu()
|
||||
verifyAddSearchEngineListContains(
|
||||
"Google",
|
||||
"Bing",
|
||||
"Amazon.com",
|
||||
"DuckDuckGo",
|
||||
"eBay",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Expected for en-us defaults
|
||||
@Test
|
||||
fun changeSearchEnginesBasedOnTextTest() {
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
typeSearch("D")
|
||||
verifySearchEnginePrompt(activityTestRule, "DuckDuckGo")
|
||||
clickSearchEnginePrompt(activityTestRule, "DuckDuckGo")
|
||||
}.submitQuery("firefox") {
|
||||
verifyUrl("duckduckgo.com/?q=firefox")
|
||||
}
|
||||
}
|
||||
|
||||
// Expected for app language set to Arabic
|
||||
@Test
|
||||
fun verifySearchEnginesWithRTLLocale() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
toggleShowSearchShortcuts()
|
||||
}.goBack {
|
||||
}.openLanguageSubMenu {
|
||||
TestHelper.registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(
|
||||
activityTestRule.activity.findViewById(R.id.locale_list),
|
||||
2,
|
||||
),
|
||||
) {
|
||||
selectLanguage("Arabic")
|
||||
verifyLanguageHeaderIsTranslated(ARABIC_LANGUAGE_HEADER)
|
||||
}
|
||||
}
|
||||
|
||||
exitMenu()
|
||||
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
verifyTranslatedFocusedNavigationToolbar("ابحث أو أدخِل عنوانا")
|
||||
verifySearchEngineShortcuts(
|
||||
activityTestRule,
|
||||
"Google",
|
||||
"Bing",
|
||||
"Amazon.com",
|
||||
"DuckDuckGo",
|
||||
"ويكيبيديا (ar)",
|
||||
)
|
||||
changeDefaultSearchEngine(activityTestRule, "ويكيبيديا (ar)")
|
||||
}.submitQuery("firefox") {
|
||||
verifyUrl("ar.m.wikipedia.org")
|
||||
}
|
||||
}
|
||||
|
||||
// Expected for en-us defaults
|
||||
@Test
|
||||
fun toggleSearchEnginesShortcutListTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
verifyShowSearchEnginesToggleState(false)
|
||||
toggleShowSearchShortcuts()
|
||||
verifyShowSearchEnginesToggleState(true)
|
||||
}
|
||||
|
||||
exitMenu()
|
||||
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
verifySearchEngineShortcuts(
|
||||
activityTestRule,
|
||||
"Google",
|
||||
"Bing",
|
||||
"Amazon.com",
|
||||
"DuckDuckGo",
|
||||
"eBay",
|
||||
"Wikipedia",
|
||||
)
|
||||
scrollToSearchEngineSettings(activityTestRule)
|
||||
}.clickSearchEngineSettings(activityTestRule) {
|
||||
toggleShowSearchShortcuts()
|
||||
verifyShowSearchEnginesToggleState(false)
|
||||
}
|
||||
|
||||
exitMenu()
|
||||
|
||||
homeScreen {
|
||||
}.openSearch {
|
||||
verifySearchEngineShortcutsAreNotDisplayed(
|
||||
activityTestRule,
|
||||
"Google",
|
||||
"Bing",
|
||||
"Amazon.com",
|
||||
"DuckDuckGo",
|
||||
"eBay",
|
||||
"Wikipedia",
|
||||
)
|
||||
clickSearchEngineShortcutButton()
|
||||
verifySearchEngineShortcuts(
|
||||
activityTestRule,
|
||||
"Google",
|
||||
"Bing",
|
||||
"Amazon.com",
|
||||
"DuckDuckGo",
|
||||
"eBay",
|
||||
"Wikipedia",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@ package org.mozilla.fenix.ui
|
|||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Before
|
||||
import org.junit.After
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
|
@ -23,7 +23,7 @@ import org.mozilla.fenix.helpers.HomeActivityTestRule
|
|||
class SettingsSyncTest {
|
||||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
|
||||
private lateinit var mDevice: UiDevice
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
@get:Rule
|
||||
|
@ -31,7 +31,6 @@ class SettingsSyncTest {
|
|||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -43,9 +42,9 @@ class SettingsSyncTest {
|
|||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
// Walks through settings sync menu and sub-menus to ensure all items are present
|
||||
@Ignore("This is a stub test, ignore for now")
|
||||
@Test
|
||||
// Walks through settings sync menu and sub-menus to ensure all items are present
|
||||
fun settingsSyncItemsTest() {
|
||||
// SYNC
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@ package org.mozilla.fenix.ui
|
|||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Before
|
||||
import org.junit.After
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
|
@ -23,7 +23,7 @@ import org.mozilla.fenix.helpers.HomeActivityTestRule
|
|||
class SettingsTest {
|
||||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
|
||||
private lateinit var mDevice: UiDevice
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
@get:Rule
|
||||
|
@ -31,7 +31,6 @@ class SettingsTest {
|
|||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -43,9 +42,9 @@ class SettingsTest {
|
|||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
// Walks through settings menu and sub-menus to ensure all items are present
|
||||
@Ignore("This is a stub test, ignore for now")
|
||||
@Test
|
||||
// Walks through settings menu and sub-menus to ensure all items are present
|
||||
fun settingsMenusItemsTest() {
|
||||
// SYNC
|
||||
|
||||
|
|
|
@ -6,20 +6,18 @@ package org.mozilla.fenix.ui
|
|||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.hardware.camera2.CameraManager
|
||||
import android.media.AudioManager
|
||||
import android.os.Build
|
||||
import androidx.core.net.toUri
|
||||
import androidx.test.filters.SdkSuppress
|
||||
import androidx.test.rule.GrantPermissionRule
|
||||
import org.junit.Assume.assumeTrue
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.components.PermissionStorage
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.MockLocationUpdatesRule
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
|
@ -31,36 +29,39 @@ class SitePermissionsTest {
|
|||
/* Test page created and handled by the Mozilla mobile test-eng team */
|
||||
private val testPage = "https://mozilla-mobile.github.io/testapp/permissions"
|
||||
private val testPageSubstring = "https://mozilla-mobile.github.io:443"
|
||||
private val cameraManager = appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager
|
||||
private val micManager = appContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityTestRule(
|
||||
isJumpBackInCFREnabled = false,
|
||||
isPWAsPromptEnabled = false,
|
||||
isTCPCFREnabled = false,
|
||||
isDeleteSitePermissionsEnabled = true,
|
||||
)
|
||||
val activityTestRule = HomeActivityTestRule()
|
||||
|
||||
@get:Rule
|
||||
val grantPermissionRule: GrantPermissionRule = GrantPermissionRule.grant(
|
||||
Manifest.permission.RECORD_AUDIO,
|
||||
Manifest.permission.CAMERA,
|
||||
Manifest.permission.ACCESS_COARSE_LOCATION,
|
||||
Manifest.permission.CAMERA
|
||||
)
|
||||
|
||||
@get: Rule
|
||||
val mockLocationUpdatesRule = MockLocationUpdatesRule()
|
||||
@Before
|
||||
fun setUp() {
|
||||
// disabling the new homepage pop-up that interferes with the tests.
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
featureSettingsHelper.deleteSitePermissions(true)
|
||||
}
|
||||
|
||||
@get: Rule
|
||||
val retryTestRule = RetryTestRule(3)
|
||||
@After
|
||||
fun tearDown() {
|
||||
// Clearing all permission data after each test to avoid overlapping data
|
||||
val applicationContext: Context = activityTestRule.activity.applicationContext
|
||||
val permissionStorage = PermissionStorage(applicationContext)
|
||||
|
||||
runBlocking {
|
||||
permissionStorage.deleteAllSitePermissions()
|
||||
}
|
||||
}
|
||||
|
||||
@SdkSuppress(maxSdkVersion = Build.VERSION_CODES.P, codeName = "P")
|
||||
@SmokeTest
|
||||
@Test
|
||||
@Ignore("Firebase - No camera and microphone on AVD")
|
||||
fun audioVideoPermissionChoiceOnEachRequestTest() {
|
||||
assumeTrue(cameraManager.cameraIdList.isNotEmpty())
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(testPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
|
@ -76,10 +77,8 @@ class SitePermissionsTest {
|
|||
|
||||
@SmokeTest
|
||||
@Test
|
||||
@Ignore("Firebase - No camera and microphone on AVD, see also https://github.com/mozilla-mobile/fenix/issues/23298")
|
||||
fun rememberBlockAudioVideoPermissionChoiceTest() {
|
||||
assumeTrue(cameraManager.cameraIdList.isNotEmpty())
|
||||
assumeTrue(micManager.microphones.isNotEmpty())
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(testPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
|
@ -97,12 +96,10 @@ class SitePermissionsTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Firebase - No camera and microphone on AVD, see also https://github.com/mozilla-mobile/fenix/issues/23298")
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun rememberAllowAudioVideoPermissionChoiceTest() {
|
||||
assumeTrue(cameraManager.cameraIdList.isNotEmpty())
|
||||
assumeTrue(micManager.microphones.isNotEmpty())
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(testPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
|
@ -121,9 +118,8 @@ class SitePermissionsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Firebase - No camera and microphone on AVD")
|
||||
fun microphonePermissionChoiceOnEachRequestTest() {
|
||||
assumeTrue(micManager.microphones.isNotEmpty())
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(testPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
|
@ -138,9 +134,8 @@ class SitePermissionsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Firebase - No camera and microphone on AVD")
|
||||
fun rememberBlockMicrophonePermissionChoiceTest() {
|
||||
assumeTrue(micManager.microphones.isNotEmpty())
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(testPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
|
@ -158,10 +153,9 @@ class SitePermissionsTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Flaky, needs investigation: https://github.com/mozilla-mobile/fenix/issues/23298")
|
||||
@Test
|
||||
fun rememberAllowMicrophonePermissionChoiceTest() {
|
||||
assumeTrue(micManager.microphones.isNotEmpty())
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(testPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
|
@ -180,9 +174,8 @@ class SitePermissionsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Firebase - No camera and microphone on AVD")
|
||||
fun cameraPermissionChoiceOnEachRequestTest() {
|
||||
assumeTrue(cameraManager.cameraIdList.isNotEmpty())
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(testPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
|
@ -197,9 +190,8 @@ class SitePermissionsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Firebase - No camera and microphone on AVD")
|
||||
fun rememberBlockCameraPermissionChoiceTest() {
|
||||
assumeTrue(cameraManager.cameraIdList.isNotEmpty())
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(testPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
|
@ -218,9 +210,8 @@ class SitePermissionsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Firebase - No camera and microphone on AVD")
|
||||
fun rememberAllowCameraPermissionChoiceTest() {
|
||||
assumeTrue(cameraManager.cameraIdList.isNotEmpty())
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(testPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
|
@ -265,20 +256,20 @@ class SitePermissionsTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Needs mocking location for Firebase - to do: https://github.com/mozilla-mobile/mobile-test-eng/issues/585")
|
||||
@Test
|
||||
fun allowLocationPermissionsTest() {
|
||||
mockLocationUpdatesRule.setMockLocation()
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(testPage.toUri()) {
|
||||
}.clickGetLocationButton {
|
||||
verifyLocationPermissionPrompt(testPageSubstring)
|
||||
}.clickPagePermissionButton(true) {
|
||||
verifyPageContent("${mockLocationUpdatesRule.latitude}")
|
||||
verifyPageContent("${mockLocationUpdatesRule.longitude}")
|
||||
verifyPageContent("longitude")
|
||||
verifyPageContent("latitude")
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Needs mocking location for Firebase - to do: https://github.com/mozilla-mobile/mobile-test-eng/issues/585")
|
||||
@Test
|
||||
fun blockLocationPermissionsTest() {
|
||||
navigationToolbar {
|
||||
|
|
|
@ -9,6 +9,8 @@ package org.mozilla.fenix.ui
|
|||
import android.view.View
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.core.net.toUri
|
||||
import androidx.test.espresso.IdlingRegistry
|
||||
import androidx.test.filters.SdkSuppress
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
|
@ -17,6 +19,7 @@ import mozilla.components.concept.engine.mediasession.MediaSession
|
|||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.IntentReceiverActivity
|
||||
|
@ -24,8 +27,8 @@ import org.mozilla.fenix.R
|
|||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.Constants.PackageName.YOUTUBE_APP
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelperDelegate
|
||||
import org.mozilla.fenix.helpers.Constants
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
|
@ -34,16 +37,20 @@ import org.mozilla.fenix.helpers.TestHelper
|
|||
import org.mozilla.fenix.helpers.TestHelper.appName
|
||||
import org.mozilla.fenix.helpers.TestHelper.assertNativeAppOpens
|
||||
import org.mozilla.fenix.helpers.TestHelper.createCustomTabIntent
|
||||
import org.mozilla.fenix.helpers.TestHelper.generateRandomString
|
||||
import org.mozilla.fenix.helpers.TestHelper.registerAndCleanupIdlingResources
|
||||
import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText
|
||||
import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.customTabScreen
|
||||
import org.mozilla.fenix.ui.robots.enhancedTrackingProtection
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
import org.mozilla.fenix.ui.robots.notificationShade
|
||||
import org.mozilla.fenix.ui.robots.openEditURLView
|
||||
import org.mozilla.fenix.ui.robots.searchScreen
|
||||
import org.mozilla.fenix.ui.util.FRENCH_LANGUAGE_HEADER
|
||||
import org.mozilla.fenix.ui.util.FRENCH_SYSTEM_LOCALE_OPTION
|
||||
import org.mozilla.fenix.ui.util.ROMANIAN_LANGUAGE_HEADER
|
||||
import org.mozilla.fenix.ui.util.STRING_ONBOARDING_TRACKING_PROTECTION_HEADER
|
||||
|
||||
/**
|
||||
* Test Suite that contains a part of the Smoke and Sanity tests defined in TestRail:
|
||||
|
@ -54,26 +61,30 @@ import org.mozilla.fenix.ui.robots.searchScreen
|
|||
@Suppress("ForbiddenComment")
|
||||
@SmokeTest
|
||||
class SmokeTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private var awesomeBar: ViewVisibilityIdlingResource? = null
|
||||
private var addonsListIdlingResource: RecyclerViewIdlingResource? = null
|
||||
private var recentlyClosedTabsListIdlingResource: RecyclerViewIdlingResource? = null
|
||||
private var readerViewNotification: ViewVisibilityIdlingResource? = null
|
||||
private var bookmarksListIdlingResource: RecyclerViewIdlingResource? = null
|
||||
private var localeListIdlingResource: RecyclerViewIdlingResource? = null
|
||||
private val customMenuItem = "TestMenuItem"
|
||||
private lateinit var browserStore: BrowserStore
|
||||
private val featureSettingsHelper = FeatureSettingsHelperDelegate()
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
|
||||
@get:Rule(order = 0)
|
||||
@get:Rule
|
||||
val activityTestRule = AndroidComposeTestRule(
|
||||
HomeActivityIntentTestRule(),
|
||||
{ it.activity },
|
||||
{ it.activity }
|
||||
)
|
||||
|
||||
@get: Rule(order = 1)
|
||||
@get: Rule
|
||||
val intentReceiverActivityTestRule = ActivityTestRule(
|
||||
IntentReceiverActivity::class.java,
|
||||
true,
|
||||
false,
|
||||
IntentReceiverActivity::class.java, true, false
|
||||
)
|
||||
|
||||
@Rule(order = 2)
|
||||
@Rule
|
||||
@JvmField
|
||||
val retryTestRule = RetryTestRule(3)
|
||||
|
||||
|
@ -84,13 +95,8 @@ class SmokeTest {
|
|||
browserStore = activityTestRule.activity.components.core.store
|
||||
|
||||
// disabling the new homepage pop-up that interferes with the tests.
|
||||
featureSettingsHelper.apply {
|
||||
isJumpBackInCFREnabled = false
|
||||
isTCPCFREnabled = false
|
||||
isWallpaperOnboardingEnabled = false
|
||||
}.applyFlagUpdates()
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -101,6 +107,30 @@ class SmokeTest {
|
|||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
|
||||
if (awesomeBar != null) {
|
||||
IdlingRegistry.getInstance().unregister(awesomeBar!!)
|
||||
}
|
||||
|
||||
if (addonsListIdlingResource != null) {
|
||||
IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!)
|
||||
}
|
||||
|
||||
if (recentlyClosedTabsListIdlingResource != null) {
|
||||
IdlingRegistry.getInstance().unregister(recentlyClosedTabsListIdlingResource!!)
|
||||
}
|
||||
|
||||
if (bookmarksListIdlingResource != null) {
|
||||
IdlingRegistry.getInstance().unregister(bookmarksListIdlingResource!!)
|
||||
}
|
||||
|
||||
if (readerViewNotification != null) {
|
||||
IdlingRegistry.getInstance().unregister(readerViewNotification)
|
||||
}
|
||||
|
||||
if (localeListIdlingResource != null) {
|
||||
IdlingRegistry.getInstance().unregister(localeListIdlingResource)
|
||||
}
|
||||
|
||||
// resetting modified features enabled setting to default
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
@ -109,24 +139,46 @@ class SmokeTest {
|
|||
@Test
|
||||
fun firstRunScreenTest() {
|
||||
homeScreen {
|
||||
verifyHomeScreenAppBarItems()
|
||||
verifyHomeScreenWelcomeItems()
|
||||
verifyChooseYourThemeCard(
|
||||
isDarkThemeChecked = false,
|
||||
isLightThemeChecked = false,
|
||||
isAutomaticThemeChecked = true,
|
||||
)
|
||||
verifyToolbarPlacementCard(isBottomChecked = true, isTopChecked = false)
|
||||
verifySignInToSyncCard()
|
||||
verifyPrivacyProtectionCard(isStandardChecked = true, isStrictChecked = false)
|
||||
verifyPrivacyNoticeCard()
|
||||
verifyStartBrowsingSection()
|
||||
verifyNavigationToolbarItems("0")
|
||||
verifyHomeScreen()
|
||||
verifyNavigationToolbar()
|
||||
verifyHomePrivateBrowsingButton()
|
||||
verifyHomeMenu()
|
||||
verifyHomeWordmark()
|
||||
|
||||
verifyWelcomeHeader()
|
||||
// Sign in to Firefox
|
||||
verifyStartSyncHeader()
|
||||
verifyAccountsSignInButton()
|
||||
|
||||
// Always-on privacy
|
||||
scrollToElementByText(STRING_ONBOARDING_TRACKING_PROTECTION_HEADER)
|
||||
verifyAutomaticPrivacyHeader()
|
||||
verifyAutomaticPrivacyText()
|
||||
|
||||
// Choose your theme
|
||||
verifyChooseThemeHeader()
|
||||
verifyChooseThemeText()
|
||||
verifyDarkThemeDescription()
|
||||
verifyDarkThemeToggle()
|
||||
verifyLightThemeDescription()
|
||||
verifyLightThemeToggle()
|
||||
|
||||
// Pick your toolbar placement
|
||||
verifyTakePositionHeader()
|
||||
verifyTakePositionElements()
|
||||
|
||||
// Your privacy
|
||||
verifyYourPrivacyHeader()
|
||||
verifyYourPrivacyText()
|
||||
verifyPrivacyNoticeButton()
|
||||
|
||||
// Start Browsing
|
||||
verifyStartBrowsingButton()
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies the functionality of the onboarding Start Browsing button
|
||||
@Test
|
||||
// Verifies the functionality of the onboarding Start Browsing button
|
||||
fun startBrowsingButtonTest() {
|
||||
homeScreen {
|
||||
verifyStartBrowsingButton()
|
||||
|
@ -135,6 +187,7 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
/* Verifies the nav bar:
|
||||
- opening a web page
|
||||
- the existence of nav bar items
|
||||
|
@ -142,7 +195,6 @@ class SmokeTest {
|
|||
- the tab drawer button
|
||||
- opening a new search and dismissing the nav bar
|
||||
*/
|
||||
@Test
|
||||
fun verifyBasicNavigationToolbarFunctionality() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -162,22 +214,21 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Verifies the list of items in a tab's 3 dot menu
|
||||
@Test
|
||||
// Verifies the list of items in a tab's 3 dot menu
|
||||
fun verifyPageMainMenuItemsTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
waitForPageToLoad()
|
||||
}.openThreeDotMenu {
|
||||
verifyPageThreeDotMainMenuItems(isRequestDesktopSiteEnabled = false)
|
||||
verifyPageThreeDotMainMenuItems()
|
||||
}
|
||||
}
|
||||
|
||||
// Could be removed when more smoke tests from the History category are added
|
||||
// Verifies the History menu opens from a tab's 3 dot menu
|
||||
@Test
|
||||
// Verifies the History menu opens from a tab's 3 dot menu
|
||||
fun openMainMenuHistoryItemTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -190,8 +241,8 @@ class SmokeTest {
|
|||
}
|
||||
|
||||
// Could be removed when more smoke tests from the Bookmarks category are added
|
||||
// Verifies the Bookmarks menu opens from a tab's 3 dot menu
|
||||
@Test
|
||||
// Verifies the Bookmarks menu opens from a tab's 3 dot menu
|
||||
fun openMainMenuBookmarksItemTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -203,8 +254,8 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Verifies the Add-ons menu opens from a tab's 3 dot menu
|
||||
@Test
|
||||
// Verifies the Add-ons menu opens from a tab's 3 dot menu
|
||||
fun openMainMenuAddonsTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -212,17 +263,20 @@ class SmokeTest {
|
|||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
}.openThreeDotMenu {
|
||||
}.openAddonsManagerMenu {
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.add_ons_list), 1),
|
||||
) {
|
||||
verifyAddonsItems()
|
||||
}
|
||||
addonsListIdlingResource =
|
||||
RecyclerViewIdlingResource(
|
||||
activityTestRule.activity.findViewById(R.id.add_ons_list),
|
||||
1
|
||||
)
|
||||
IdlingRegistry.getInstance().register(addonsListIdlingResource!!)
|
||||
verifyAddonsItems()
|
||||
IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
// Verifies the Synced tabs menu or Sync Sign In menu opens from a tab's 3 dot menu.
|
||||
// The test is assuming we are NOT signed in.
|
||||
@Test
|
||||
fun openMainMenuSyncItemTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -235,10 +289,10 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
// Test running on beta/release builds in CI:
|
||||
// caution when making changes to it, so they don't block the builds
|
||||
// Verifies the Settings menu opens from a tab's 3 dot menu
|
||||
@Test
|
||||
fun openMainMenuSettingsItemTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -250,8 +304,8 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Verifies the Find in page option in a tab's 3 dot menu
|
||||
@Test
|
||||
// Verifies the Find in page option in a tab's 3 dot menu
|
||||
fun openMainMenuFindInPageTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -263,11 +317,10 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Verifies the Add to home screen option in a tab's 3 dot menu
|
||||
@Test
|
||||
// Verifies the Add to home screen option in a tab's 3 dot menu
|
||||
fun mainMenuAddToHomeScreenTest() {
|
||||
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val shortcutTitle = generateRandomString(5)
|
||||
|
||||
homeScreen {
|
||||
}.openNavigationToolbar {
|
||||
|
@ -282,18 +335,18 @@ class SmokeTest {
|
|||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
}.openAddToHomeScreen {
|
||||
verifyShortcutTextFieldTitle("Test_Page_1")
|
||||
addShortcutName(shortcutTitle)
|
||||
verifyShortcutNameField("Test_Page_1")
|
||||
addShortcutName("Test Page")
|
||||
clickAddShortcutButton()
|
||||
clickAddAutomaticallyButton()
|
||||
}.openHomeScreenShortcut(shortcutTitle) {
|
||||
}.openHomeScreenShortcut("Test Page") {
|
||||
verifyUrl(website.url.toString())
|
||||
verifyTabCounter("1")
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies the Add to collection option in a tab's 3 dot menu
|
||||
@Test
|
||||
// Verifies the Add to collection option in a tab's 3 dot menu
|
||||
fun openMainMenuAddToCollectionTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -305,8 +358,8 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Verifies the Bookmark button in a tab's 3 dot menu
|
||||
@Test
|
||||
// Verifies the Bookmark button in a tab's 3 dot menu
|
||||
fun mainMenuBookmarkButtonTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -318,23 +371,23 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
// Device or AVD requires a Google Services Android OS installation with Play Store installed
|
||||
// Verifies the Open in app button when an app is installed
|
||||
@Test
|
||||
fun mainMenuOpenInAppTest() {
|
||||
val youtubeURL = "https://m.youtube.com/user/mozilla?cbrd=1"
|
||||
val playStoreUrl = "play.google.com/store/apps/details?id=org.mozilla.fenix"
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(youtubeURL.toUri()) {
|
||||
}.enterURLAndEnterToBrowser(playStoreUrl.toUri()) {
|
||||
verifyNotificationDotOnMainMenu()
|
||||
}.openThreeDotMenu {
|
||||
}.clickOpenInApp {
|
||||
assertNativeAppOpens(YOUTUBE_APP, youtubeURL)
|
||||
assertNativeAppOpens(Constants.PackageName.GOOGLE_PLAY_SERVICES, playStoreUrl)
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies the Desktop site toggle in a tab's 3 dot menu
|
||||
@Test
|
||||
// Verifies the Desktop site toggle in a tab's 3 dot menu
|
||||
fun mainMenuDesktopSiteTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -347,8 +400,8 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Verifies the Share button in a tab's 3 dot menu
|
||||
@Test
|
||||
// Verifies the Share button in a tab's 3 dot menu
|
||||
fun mainMenuShareButtonTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -362,8 +415,8 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Verifies the refresh button in a tab's 3 dot menu
|
||||
@Test
|
||||
// Verifies the refresh button in a tab's 3 dot menu
|
||||
fun mainMenuRefreshButtonTest() {
|
||||
val refreshWebPage = TestAssetHelper.getRefreshAsset(mockWebServer)
|
||||
|
||||
|
@ -377,8 +430,40 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Verifies changing the default engine from the Search Shortcut menu
|
||||
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/25345")
|
||||
@Test
|
||||
fun customTrackingProtectionSettingsTest() {
|
||||
val genericWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val trackingPage = TestAssetHelper.getEnhancedTrackingProtectionAsset(mockWebServer)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openEnhancedTrackingProtectionSubMenu {
|
||||
verifyEnhancedTrackingProtectionOptionsEnabled()
|
||||
selectTrackingProtectionOption("Custom")
|
||||
verifyCustomTrackingProtectionSettings()
|
||||
}.goBackToHomeScreen {}
|
||||
|
||||
navigationToolbar {
|
||||
// browsing a basic page to allow GV to load on a fresh run
|
||||
}.enterURLAndEnterToBrowser(genericWebPage.url) {
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(trackingPage.url) {}
|
||||
|
||||
enhancedTrackingProtection {
|
||||
}.openEnhancedTrackingProtectionSheet {
|
||||
}.openDetails {
|
||||
verifyTrackingCookiesBlocked()
|
||||
verifyCryptominersBlocked()
|
||||
verifyFingerprintersBlocked()
|
||||
verifyTrackingContentBlocked()
|
||||
viewTrackingContentBlockList()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
// Verifies changing the default engine from the Search Shortcut menu
|
||||
fun selectSearchEnginesShortcutTest() {
|
||||
val enginesList = listOf("DuckDuckGo", "Google", "Amazon.com", "Wikipedia", "Bing", "eBay")
|
||||
|
||||
|
@ -396,8 +481,26 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Saves a login, then changes it and verifies the update
|
||||
@Test
|
||||
// Swipes the nav bar left/right to switch between tabs
|
||||
fun swipeToSwitchTabTest() {
|
||||
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(firstWebPage.url) {
|
||||
}.openTabDrawer {
|
||||
}.openNewTab {
|
||||
}.submitQuery(secondWebPage.url.toString()) {
|
||||
swipeNavBarRight(secondWebPage.url.toString())
|
||||
verifyUrl(firstWebPage.url.toString())
|
||||
swipeNavBarLeft(firstWebPage.url.toString())
|
||||
verifyUrl(secondWebPage.url.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
// Saves a login, then changes it and verifies the update
|
||||
fun updateSavedLoginTest() {
|
||||
val saveLoginTest =
|
||||
TestAssetHelper.getSaveLoginAsset(mockWebServer)
|
||||
|
@ -428,8 +531,45 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Verifies that a recently closed item is properly opened
|
||||
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/25034")
|
||||
@Test
|
||||
@SdkSuppress(minSdkVersion = 29)
|
||||
// Verifies that you can go to System settings and change app's permissions from inside the app
|
||||
fun redirectToAppPermissionsSystemSettingsTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSettingsSubMenuSitePermissions {
|
||||
}.openCamera {
|
||||
verifyBlockedByAndroid()
|
||||
}.goBack {
|
||||
}.openLocation {
|
||||
verifyBlockedByAndroid()
|
||||
}.goBack {
|
||||
}.openMicrophone {
|
||||
verifyBlockedByAndroid()
|
||||
clickGoToSettingsButton()
|
||||
openAppSystemPermissionsSettings()
|
||||
switchAppPermissionSystemSetting("Camera", "Allow")
|
||||
mDevice.pressBack()
|
||||
switchAppPermissionSystemSetting("Location", "Allow")
|
||||
mDevice.pressBack()
|
||||
switchAppPermissionSystemSetting("Microphone", "Allow")
|
||||
mDevice.pressBack()
|
||||
mDevice.pressBack()
|
||||
mDevice.pressBack()
|
||||
verifyUnblockedByAndroid()
|
||||
}.goBack {
|
||||
}.openLocation {
|
||||
verifyUnblockedByAndroid()
|
||||
}.goBack {
|
||||
}.openCamera {
|
||||
verifyUnblockedByAndroid()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
// Verifies that a recently closed item is properly opened
|
||||
fun openRecentlyClosedItemTest() {
|
||||
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -442,18 +582,18 @@ class SmokeTest {
|
|||
}.openTabDrawer {
|
||||
}.openRecentlyClosedTabs {
|
||||
waitForListToExist()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.recently_closed_list), 1),
|
||||
) {
|
||||
verifyRecentlyClosedTabsMenuView()
|
||||
}
|
||||
recentlyClosedTabsListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.recently_closed_list), 1)
|
||||
IdlingRegistry.getInstance().register(recentlyClosedTabsListIdlingResource!!)
|
||||
verifyRecentlyClosedTabsMenuView()
|
||||
IdlingRegistry.getInstance().unregister(recentlyClosedTabsListIdlingResource!!)
|
||||
}.clickRecentlyClosedItem("Test_Page_1") {
|
||||
verifyUrl(website.url.toString())
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies that tapping the "x" button removes a recently closed item from the list
|
||||
@Test
|
||||
// Verifies that tapping the "x" button removes a recently closed item from the list
|
||||
fun deleteRecentlyClosedTabsItemTest() {
|
||||
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -466,18 +606,18 @@ class SmokeTest {
|
|||
}.openTabDrawer {
|
||||
}.openRecentlyClosedTabs {
|
||||
waitForListToExist()
|
||||
registerAndCleanupIdlingResources(
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.recently_closed_list), 1),
|
||||
) {
|
||||
verifyRecentlyClosedTabsMenuView()
|
||||
}
|
||||
recentlyClosedTabsListIdlingResource =
|
||||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.recently_closed_list), 1)
|
||||
IdlingRegistry.getInstance().register(recentlyClosedTabsListIdlingResource!!)
|
||||
verifyRecentlyClosedTabsMenuView()
|
||||
IdlingRegistry.getInstance().unregister(recentlyClosedTabsListIdlingResource!!)
|
||||
clickDeleteRecentlyClosedTabs()
|
||||
verifyEmptyRecentlyClosedTabsList()
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies that deleting a Bookmarks folder also removes the item from inside it.
|
||||
@Test
|
||||
// Verifies that deleting a Bookmarks folder also removes the item from inside it.
|
||||
fun deleteNonEmptyBookmarkFolderTest() {
|
||||
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -547,9 +687,8 @@ class SmokeTest {
|
|||
}.clickShareAllTabsButton {
|
||||
verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle)
|
||||
verifySharingWithSelectedApp(
|
||||
sharingApp,
|
||||
sharedUrlsString,
|
||||
"$firstWebsiteTitle, $secondWebsiteTitle",
|
||||
sharingApp, sharedUrlsString,
|
||||
"$firstWebsiteTitle, $secondWebsiteTitle"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -579,6 +718,7 @@ class SmokeTest {
|
|||
homeScreen {
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(website.url) {
|
||||
mDevice.waitForIdle()
|
||||
}.openTabDrawer {
|
||||
verifyNormalBrowsingButtonIsSelected(false)
|
||||
verifyPrivateBrowsingButtonIsSelected(true)
|
||||
|
@ -588,15 +728,17 @@ class SmokeTest {
|
|||
verifyExistingTabList()
|
||||
verifyExistingOpenTabs(website.title)
|
||||
verifyCloseTabsButton(website.title)
|
||||
// Disabled step due to ongoing tabs tray compose refactoring, see: https://github.com/mozilla-mobile/fenix/issues/21318
|
||||
// verifyOpenedTabThumbnail()
|
||||
verifyOpenedTabThumbnail()
|
||||
verifyPrivateBrowsingNewTabButton()
|
||||
}.openTab(website.title) {
|
||||
verifyUrl(website.url.toString())
|
||||
verifyTabCounter("1")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
// Test running on beta/release builds in CI:
|
||||
// caution when making changes to it, so they don't block the builds
|
||||
@Test
|
||||
fun noHistoryInPrivateBrowsingTest() {
|
||||
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -648,8 +790,8 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Verifies that reader mode is detected and the custom appearance controls are displayed
|
||||
@Test
|
||||
// Verifies that reader mode is detected and the custom appearance controls are displayed
|
||||
fun verifyReaderViewAppearanceUI() {
|
||||
val readerViewPage =
|
||||
TestAssetHelper.getLoremIpsumAsset(mockWebServer)
|
||||
|
@ -657,15 +799,15 @@ class SmokeTest {
|
|||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(readerViewPage.url) {
|
||||
mDevice.waitForIdle()
|
||||
org.mozilla.fenix.ui.robots.mDevice.waitForIdle()
|
||||
}
|
||||
|
||||
registerAndCleanupIdlingResources(
|
||||
ViewVisibilityIdlingResource(
|
||||
activityTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
|
||||
View.VISIBLE,
|
||||
),
|
||||
) {}
|
||||
readerViewNotification = ViewVisibilityIdlingResource(
|
||||
activityTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
|
||||
View.VISIBLE
|
||||
)
|
||||
|
||||
IdlingRegistry.getInstance().register(readerViewNotification)
|
||||
|
||||
navigationToolbar {
|
||||
verifyReaderViewDetected(true)
|
||||
|
@ -690,16 +832,16 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
// Verifies the main menu of a custom tab with a custom menu item
|
||||
@Test
|
||||
// Verifies the main menu of a custom tab with a custom menu item
|
||||
fun customTabMenuItemsTest() {
|
||||
val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
intentReceiverActivityTestRule.launchActivity(
|
||||
createCustomTabIntent(
|
||||
customTabPage.url.toString(),
|
||||
customMenuItem,
|
||||
),
|
||||
customMenuItem
|
||||
)
|
||||
)
|
||||
|
||||
customTabScreen {
|
||||
|
@ -716,15 +858,15 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
// The test opens a link in a custom tab then sends it to the browser
|
||||
@Test
|
||||
// The test opens a link in a custom tab then sends it to the browser
|
||||
fun openCustomTabInBrowserTest() {
|
||||
val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
intentReceiverActivityTestRule.launchActivity(
|
||||
createCustomTabIntent(
|
||||
customTabPage.url.toString(),
|
||||
),
|
||||
customTabPage.url.toString()
|
||||
)
|
||||
)
|
||||
|
||||
customTabScreen {
|
||||
|
@ -735,6 +877,7 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Failing with frequent ANR: https://bugzilla.mozilla.org/show_bug.cgi?id=1764605")
|
||||
@Test
|
||||
fun audioPlaybackSystemNotificationTest() {
|
||||
val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
|
||||
|
@ -786,9 +929,9 @@ class SmokeTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
// For API>23
|
||||
// Verifies the default browser switch opens the system default apps menu.
|
||||
@Test
|
||||
fun changeDefaultBrowserSetting() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
|
@ -816,7 +959,7 @@ class SmokeTest {
|
|||
clickClearButton()
|
||||
longClickToolbar()
|
||||
clickPasteText()
|
||||
verifyTypedToolbarText("content")
|
||||
verifyPastedToolbarText("content")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -835,8 +978,29 @@ class SmokeTest {
|
|||
clickClearButton()
|
||||
longClickToolbar()
|
||||
clickPasteText()
|
||||
// with Select all, some white space is copied over, so we need to include that too
|
||||
verifyTypedToolbarText(" Page content: 1 ")
|
||||
verifyPastedToolbarText("Page content: 1")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun switchLanguageTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openLanguageSubMenu {
|
||||
localeListIdlingResource =
|
||||
RecyclerViewIdlingResource(
|
||||
activityTestRule.activity.findViewById(R.id.locale_list),
|
||||
2
|
||||
)
|
||||
IdlingRegistry.getInstance().register(localeListIdlingResource)
|
||||
selectLanguage("Romanian")
|
||||
verifyLanguageHeaderIsTranslated(ROMANIAN_LANGUAGE_HEADER)
|
||||
selectLanguage("Français")
|
||||
verifyLanguageHeaderIsTranslated(FRENCH_LANGUAGE_HEADER)
|
||||
selectLanguage(FRENCH_SYSTEM_LOCALE_OPTION)
|
||||
verifyLanguageHeaderIsTranslated("Language")
|
||||
IdlingRegistry.getInstance().unregister(localeListIdlingResource)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,252 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.Constants.defaultTopSitesList
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.helpers.TestHelper.getSponsoredShortcutTitle
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
||||
/**
|
||||
* Tests Sponsored shortcuts functionality
|
||||
*/
|
||||
|
||||
class SponsoredShortcutsTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private val defaultSearchEngine = "Amazon.com"
|
||||
private lateinit var sponsoredShortcutTitle: String
|
||||
private lateinit var sponsoredShortcutTitle2: String
|
||||
|
||||
@get:Rule
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
TestHelper.appContext.settings().userOptOutOfReEngageCookieBannerDialog = true
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
// Expected for en-us defaults
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun verifySponsoredShortcutsListTest() {
|
||||
homeScreen {
|
||||
defaultTopSitesList.values.forEach { value ->
|
||||
verifyExistingTopSitesTabs(value)
|
||||
}
|
||||
}.openThreeDotMenu {
|
||||
}.openCustomizeHome {
|
||||
verifySponsoredShortcutsCheckBox(true)
|
||||
clickSponsoredShortcuts()
|
||||
verifySponsoredShortcutsCheckBox(false)
|
||||
}.goBack {
|
||||
verifyNotExistingSponsoredTopSitesList()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun openSponsoredShortcutTest() {
|
||||
homeScreen {
|
||||
sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
|
||||
}.openSponsoredShortcut(sponsoredShortcutTitle) {
|
||||
verifyUrl(sponsoredShortcutTitle)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun openSponsoredShortcutInPrivateBrowsingTest() {
|
||||
homeScreen {
|
||||
sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
|
||||
}.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) {
|
||||
}.openTopSiteInPrivateTab {
|
||||
verifyUrl(sponsoredShortcutTitle)
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/25926")
|
||||
@Test
|
||||
fun verifySponsorsAndPrivacyLinkTest() {
|
||||
homeScreen {
|
||||
sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
|
||||
}.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) {
|
||||
}.clickSponsorsAndPrivacyButton {
|
||||
verifyUrl("support.mozilla.org/en-US/kb/sponsor-privacy")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifySponsoredShortcutsSettingsOptionTest() {
|
||||
homeScreen {
|
||||
sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
|
||||
}.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) {
|
||||
}.clickSponsoredShortcutsSettingsButton {
|
||||
verifyHomePageView()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifySponsoredShortcutsDetailsTest() {
|
||||
homeScreen {
|
||||
sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
|
||||
sponsoredShortcutTitle2 = getSponsoredShortcutTitle(3)
|
||||
|
||||
verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2)
|
||||
verifySponsoredShortcutDetails(sponsoredShortcutTitle2, 3)
|
||||
}
|
||||
}
|
||||
|
||||
// The default search engine should not be displayed as a sponsored shortcut
|
||||
@Test
|
||||
fun defaultSearchEngineIsNotDisplayedAsSponsoredShortcutTest() {
|
||||
val sponsoredShortcutTitle = "Amazon"
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openSearchSubMenu {
|
||||
changeDefaultSearchEngine(defaultSearchEngine)
|
||||
}
|
||||
|
||||
exitMenu()
|
||||
|
||||
homeScreen {
|
||||
verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle, 2)
|
||||
verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle, 3)
|
||||
}
|
||||
}
|
||||
|
||||
// 1 sponsored shortcut should be displayed if there are 7 pinned top sites
|
||||
@Test
|
||||
fun verifySponsoredShortcutsListWithSevenPinnedSitesTest() {
|
||||
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
|
||||
val thirdWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3)
|
||||
val fourthWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 4)
|
||||
|
||||
homeScreen {
|
||||
sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
|
||||
sponsoredShortcutTitle2 = getSponsoredShortcutTitle(3)
|
||||
|
||||
verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2)
|
||||
verifySponsoredShortcutDetails(sponsoredShortcutTitle2, 3)
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(firstWebPage.url) {
|
||||
verifyPageContent(firstWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
}.addToFirefoxHome {
|
||||
}.goToHomescreen {
|
||||
verifyExistingTopSitesTabs(firstWebPage.title)
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(secondWebPage.url) {
|
||||
verifyPageContent(secondWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
}.addToFirefoxHome {
|
||||
}.goToHomescreen {
|
||||
verifyExistingTopSitesTabs(secondWebPage.title)
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(thirdWebPage.url) {
|
||||
verifyPageContent(thirdWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
}.addToFirefoxHome {
|
||||
}.goToHomescreen {
|
||||
verifyExistingTopSitesTabs(thirdWebPage.title)
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(fourthWebPage.url) {
|
||||
verifyPageContent(fourthWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
}.addToFirefoxHome {
|
||||
}.goToHomescreen {
|
||||
verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2)
|
||||
verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle2, 3)
|
||||
}
|
||||
}
|
||||
|
||||
// No sponsored shortcuts should be displayed if there are 8 pinned top sites
|
||||
@Test
|
||||
fun verifySponsoredShortcutsListWithEightPinnedSitesTest() {
|
||||
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
|
||||
val thirdWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3)
|
||||
val fourthWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 4)
|
||||
val fifthWebPage = TestAssetHelper.getLoremIpsumAsset(mockWebServer)
|
||||
|
||||
homeScreen {
|
||||
sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
|
||||
sponsoredShortcutTitle2 = getSponsoredShortcutTitle(3)
|
||||
|
||||
verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2)
|
||||
verifySponsoredShortcutDetails(sponsoredShortcutTitle2, 3)
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(firstWebPage.url) {
|
||||
verifyPageContent(firstWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
}.addToFirefoxHome {
|
||||
}.goToHomescreen {
|
||||
verifyExistingTopSitesTabs(firstWebPage.title)
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(secondWebPage.url) {
|
||||
verifyPageContent(secondWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
}.addToFirefoxHome {
|
||||
}.goToHomescreen {
|
||||
verifyExistingTopSitesTabs(secondWebPage.title)
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(thirdWebPage.url) {
|
||||
verifyPageContent(thirdWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
}.addToFirefoxHome {
|
||||
}.goToHomescreen {
|
||||
verifyExistingTopSitesTabs(thirdWebPage.title)
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(fourthWebPage.url) {
|
||||
verifyPageContent(fourthWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
}.addToFirefoxHome {
|
||||
}.goToHomescreen {
|
||||
verifyExistingTopSitesTabs(fourthWebPage.title)
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(fifthWebPage.url) {
|
||||
verifyPageContent(fifthWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
}.addToFirefoxHome {
|
||||
}.goToHomescreen {
|
||||
verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle, 2)
|
||||
verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle2, 3)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,19 +4,17 @@
|
|||
|
||||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.ui.robots.enhancedTrackingProtection
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
@ -35,15 +33,12 @@ import org.mozilla.fenix.ui.robots.settingsSubMenuEnhancedTrackingProtection
|
|||
* - Verifying Enhanced Tracking Protection site exceptions
|
||||
*/
|
||||
|
||||
class EnhancedTrackingProtectionTest {
|
||||
class StrictEnhancedTrackingProtectionTest {
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityTestRule(
|
||||
isJumpBackInCFREnabled = false,
|
||||
isTCPCFREnabled = false,
|
||||
isWallpaperOnboardingEnabled = false,
|
||||
)
|
||||
val activityTestRule = HomeActivityTestRule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
|
@ -51,11 +46,14 @@ class EnhancedTrackingProtectionTest {
|
|||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
featureSettingsHelper.setStrictETPEnabled()
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -85,8 +83,8 @@ class EnhancedTrackingProtectionTest {
|
|||
}.openEnhancedTrackingProtectionSubMenu {
|
||||
switchEnhancedTrackingProtectionToggle()
|
||||
verifyEnhancedTrackingProtectionOptionsEnabled(false)
|
||||
exitMenu()
|
||||
}
|
||||
}.goBack {
|
||||
}.goBack { }
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(genericPage.url) { }
|
||||
|
@ -109,7 +107,6 @@ class EnhancedTrackingProtectionTest {
|
|||
|
||||
@Test
|
||||
fun testStrictVisitProtectionSheet() {
|
||||
appContext.settings().setStrictETP()
|
||||
val genericPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val trackingProtectionTest =
|
||||
TestAssetHelper.getEnhancedTrackingProtectionAsset(mockWebServer)
|
||||
|
@ -129,9 +126,9 @@ class EnhancedTrackingProtectionTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Failing with frequent ANR: https://bugzilla.mozilla.org/show_bug.cgi?id=1764605")
|
||||
@Test
|
||||
fun testStrictVisitDisableExceptionToggle() {
|
||||
appContext.settings().setStrictETP()
|
||||
val genericPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val trackingProtectionTest =
|
||||
TestAssetHelper.getEnhancedTrackingProtectionAsset(mockWebServer)
|
||||
|
@ -166,7 +163,6 @@ class EnhancedTrackingProtectionTest {
|
|||
|
||||
@Test
|
||||
fun testStrictVisitSheetDetails() {
|
||||
appContext.settings().setStrictETP()
|
||||
val genericPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val trackingProtectionTest =
|
||||
TestAssetHelper.getEnhancedTrackingProtectionAsset(mockWebServer)
|
||||
|
@ -180,11 +176,7 @@ class EnhancedTrackingProtectionTest {
|
|||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(trackingProtectionTest.url) {
|
||||
verifyTrackingProtectionWebContent("social blocked")
|
||||
verifyTrackingProtectionWebContent("ads blocked")
|
||||
verifyTrackingProtectionWebContent("analytics blocked")
|
||||
verifyTrackingProtectionWebContent("Fingerprinting blocked")
|
||||
verifyTrackingProtectionWebContent("Cryptomining blocked")
|
||||
verifyTrackingProtectionWebContent("blocked")
|
||||
}
|
||||
enhancedTrackingProtection {
|
||||
}.openEnhancedTrackingProtectionSheet {
|
||||
|
@ -198,76 +190,4 @@ class EnhancedTrackingProtectionTest {
|
|||
viewTrackingContentBlockList()
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun customTrackingProtectionSettingsTest() {
|
||||
val genericWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val trackingPage = TestAssetHelper.getEnhancedTrackingProtectionAsset(mockWebServer)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
}.openEnhancedTrackingProtectionSubMenu {
|
||||
verifyEnhancedTrackingProtectionOptionsEnabled()
|
||||
selectTrackingProtectionOption("Custom")
|
||||
verifyCustomTrackingProtectionSettings()
|
||||
}.goBackToHomeScreen {}
|
||||
|
||||
navigationToolbar {
|
||||
// browsing a basic page to allow GV to load on a fresh run
|
||||
}.enterURLAndEnterToBrowser(genericWebPage.url) {
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(trackingPage.url) {
|
||||
verifyTrackingProtectionWebContent("social blocked")
|
||||
verifyTrackingProtectionWebContent("ads blocked")
|
||||
verifyTrackingProtectionWebContent("analytics blocked")
|
||||
verifyTrackingProtectionWebContent("Fingerprinting blocked")
|
||||
verifyTrackingProtectionWebContent("Cryptomining blocked")
|
||||
}
|
||||
|
||||
enhancedTrackingProtection {
|
||||
}.openEnhancedTrackingProtectionSheet {
|
||||
}.openDetails {
|
||||
verifyTrackingCookiesBlocked()
|
||||
verifyCryptominersBlocked()
|
||||
verifyFingerprintersBlocked()
|
||||
verifyTrackingContentBlocked()
|
||||
viewTrackingContentBlockList()
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun blockCookiesStorageAccessTest() {
|
||||
// With Standard TrackingProtection settings
|
||||
val page = mockWebServer.url("pages/cross-site-cookies.html").toString().toUri()
|
||||
val originSite = "https://mozilla-mobile.github.io"
|
||||
val currentSite = "http://localhost:${mockWebServer.port}"
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(page) {
|
||||
}.clickRequestStorageAccessButton {
|
||||
verifyCrossOriginCookiesPermissionPrompt(originSite, currentSite)
|
||||
}.clickPagePermissionButton(allow = false) {
|
||||
verifyPageContent("access denied")
|
||||
}
|
||||
}
|
||||
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun allowCookiesStorageAccessTest() {
|
||||
// With Standard TrackingProtection settings
|
||||
val page = mockWebServer.url("pages/cross-site-cookies.html").toString().toUri()
|
||||
val originSite = "https://mozilla-mobile.github.io"
|
||||
val currentSite = "http://localhost:${mockWebServer.port}"
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(page) {
|
||||
}.clickRequestStorageAccessButton {
|
||||
verifyCrossOriginCookiesPermissionPrompt(originSite, currentSite)
|
||||
}.clickPagePermissionButton(allow = true) {
|
||||
verifyPageContent("access granted")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,10 +10,10 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelper
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
|
@ -40,12 +40,13 @@ import org.mozilla.fenix.ui.robots.notificationShade
|
|||
*/
|
||||
|
||||
class TabbedBrowsingTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private val featureSettingsHelper = FeatureSettingsHelper()
|
||||
|
||||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides()
|
||||
val activityTestRule = HomeActivityTestRule()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
|
@ -53,7 +54,9 @@ class TabbedBrowsingTest {
|
|||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
// disabling the new homepage pop-up that interferes with the tests.
|
||||
featureSettingsHelper.setJumpBackCFREnabled(false)
|
||||
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -63,6 +66,7 @@ class TabbedBrowsingTest {
|
|||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -122,7 +126,7 @@ class TabbedBrowsingTest {
|
|||
verifyShareTabButton()
|
||||
verifySelectTabs()
|
||||
}.closeAllTabs {
|
||||
verifyTabCounter("0")
|
||||
verifyNoTabsOpened()
|
||||
}
|
||||
|
||||
// Repeat for Private Tabs
|
||||
|
@ -137,12 +141,11 @@ class TabbedBrowsingTest {
|
|||
}.openTabsListThreeDotMenu {
|
||||
verifyCloseAllTabsButton()
|
||||
}.closeAllTabs {
|
||||
verifyTabCounter("0")
|
||||
verifyNoTabsOpened()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087")
|
||||
fun closeTabTest() {
|
||||
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -153,7 +156,7 @@ class TabbedBrowsingTest {
|
|||
closeTab()
|
||||
}
|
||||
homeScreen {
|
||||
verifyTabCounter("0")
|
||||
verifyNoTabsOpened()
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(genericURL.url) {
|
||||
}.openTabDrawer {
|
||||
|
@ -161,7 +164,7 @@ class TabbedBrowsingTest {
|
|||
swipeTabRight("Test_Page_1")
|
||||
}
|
||||
homeScreen {
|
||||
verifyTabCounter("0")
|
||||
verifyNoTabsOpened()
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(genericURL.url) {
|
||||
}.openTabDrawer {
|
||||
|
@ -169,17 +172,15 @@ class TabbedBrowsingTest {
|
|||
swipeTabLeft("Test_Page_1")
|
||||
}
|
||||
homeScreen {
|
||||
verifyTabCounter("0")
|
||||
verifyNoTabsOpened()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyUndoSnackBarTest() {
|
||||
// disabling these features because they interfere with the snackbar visibility
|
||||
activityTestRule.applySettingsExceptions {
|
||||
it.isPocketEnabled = false
|
||||
it.isRecentTabsFeatureEnabled = false
|
||||
}
|
||||
featureSettingsHelper.setPocketEnabled(false)
|
||||
featureSettingsHelper.setRecentTabsFeatureEnabled(false)
|
||||
|
||||
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -200,7 +201,6 @@ class TabbedBrowsingTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Failing after compose migration. See: https://github.com/mozilla-mobile/fenix/issues/26087")
|
||||
fun closePrivateTabTest() {
|
||||
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
@ -213,7 +213,7 @@ class TabbedBrowsingTest {
|
|||
closeTab()
|
||||
}
|
||||
homeScreen {
|
||||
verifyTabCounter("0")
|
||||
verifyNoTabsOpened()
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(genericURL.url) {
|
||||
}.openTabDrawer {
|
||||
|
@ -221,7 +221,7 @@ class TabbedBrowsingTest {
|
|||
swipeTabRight("Test_Page_1")
|
||||
}
|
||||
homeScreen {
|
||||
verifyTabCounter("0")
|
||||
verifyNoTabsOpened()
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(genericURL.url) {
|
||||
}.openTabDrawer {
|
||||
|
@ -229,7 +229,7 @@ class TabbedBrowsingTest {
|
|||
swipeTabLeft("Test_Page_1")
|
||||
}
|
||||
homeScreen {
|
||||
verifyTabCounter("0")
|
||||
verifyNoTabsOpened()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,6 +277,7 @@ class TabbedBrowsingTest {
|
|||
|
||||
@Test
|
||||
fun verifyTabTrayNotShowingStateHalfExpanded() {
|
||||
|
||||
navigationToolbar {
|
||||
}.openTabTray {
|
||||
verifyNoOpenTabsInNormalBrowsing()
|
||||
|
@ -326,8 +327,7 @@ class TabbedBrowsingTest {
|
|||
verifyTabsTrayCounter()
|
||||
verifyExistingTabList()
|
||||
verifyNormalBrowsingNewTabButton()
|
||||
// Disabled step due to ongoing tabs tray compose refactoring, see: https://github.com/mozilla-mobile/fenix/issues/21318
|
||||
// verifyOpenedTabThumbnail()
|
||||
verifyOpenedTabThumbnail()
|
||||
verifyExistingOpenTabs(defaultWebPage.title)
|
||||
verifyCloseTabsButton(defaultWebPage.title)
|
||||
}.openTab(defaultWebPage.title) {
|
||||
|
@ -353,7 +353,7 @@ class TabbedBrowsingTest {
|
|||
// dismiss search dialog
|
||||
homeScreen { }.pressBack()
|
||||
verifyPrivateSessionMessage()
|
||||
verifyNavigationToolbar()
|
||||
verifyHomeToolbar()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
|
@ -364,7 +364,7 @@ class TabbedBrowsingTest {
|
|||
// dismiss search dialog
|
||||
homeScreen { }.pressBack()
|
||||
verifyHomeWordmark()
|
||||
verifyNavigationToolbar()
|
||||
verifyHomeToolbar()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,12 @@ package org.mozilla.fenix.ui
|
|||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
||||
/**
|
||||
|
@ -25,10 +26,11 @@ class ThreeDotMenuMainTest {
|
|||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides()
|
||||
val activityTestRule = HomeActivityTestRule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
activityTestRule.activity.applicationContext.settings().shouldShowJumpBackInCFR = false
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
|
@ -41,159 +43,54 @@ class ThreeDotMenuMainTest {
|
|||
}
|
||||
|
||||
// Verifies the list of items in the homescreen's 3 dot main menu
|
||||
@Ignore("Failing with frequent ANR: https://bugzilla.mozilla.org/show_bug.cgi?id=1764605")
|
||||
@Test
|
||||
fun homeThreeDotMenuItemsTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
verifyHomeThreeDotMainMenuItems(isRequestDesktopSiteEnabled = false)
|
||||
}.openBookmarks {
|
||||
verifyBookmarksMenuView()
|
||||
verifyBookmarksButton()
|
||||
verifyHistoryButton()
|
||||
verifyDownloadsButton()
|
||||
verifyAddOnsButton()
|
||||
verifySyncSignInButton()
|
||||
verifyDesktopSite()
|
||||
verifyWhatsNewButton()
|
||||
verifyHelpButton()
|
||||
verifyCustomizeHomeButton()
|
||||
verifySettingsButton()
|
||||
}.openSettings {
|
||||
verifySettingsView()
|
||||
}.goBack {
|
||||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyHistoryMenuView()
|
||||
}.goBack {
|
||||
}.openThreeDotMenu {
|
||||
}.openDownloadsManager {
|
||||
verifyEmptyDownloadsList()
|
||||
}.goBack {
|
||||
}.openThreeDotMenu {
|
||||
}.openAddonsManagerMenu {
|
||||
verifyAddonsItems()
|
||||
}.goBack {
|
||||
}.openThreeDotMenu {
|
||||
}.openSyncSignIn {
|
||||
verifyTurnOnSyncMenu()
|
||||
}.goBack {
|
||||
// Desktop toggle
|
||||
}.openThreeDotMenu {
|
||||
}.switchDesktopSiteMode {
|
||||
}
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
verifyDesktopSiteModeEnabled(isRequestDesktopSiteEnabled = true)
|
||||
}.openWhatsNew {
|
||||
verifyWhatsNewURL()
|
||||
}.goToHomescreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openHelp {
|
||||
verifyHelpUrl()
|
||||
}.goToHomescreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openCustomizeHome {
|
||||
verifyHomePageView()
|
||||
}.goBack {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
verifySettingsView()
|
||||
}.openHelp {
|
||||
verifyHelpUrl()
|
||||
}.openTabDrawer {
|
||||
closeTab()
|
||||
}
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openWhatsNew {
|
||||
verifyWhatsNewURL()
|
||||
}.openTabDrawer {
|
||||
closeTab()
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies the list of items in the homescreen's 3 dot main menu in private browsing
|
||||
@Test
|
||||
fun privateHomeThreeDotMenuItemsTest() {
|
||||
homeScreen {
|
||||
}.togglePrivateBrowsingMode()
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
verifyHomeThreeDotMainMenuItems(isRequestDesktopSiteEnabled = false)
|
||||
}.openBookmarks {
|
||||
verifyBookmarksMenuView()
|
||||
}.goBack {
|
||||
}.closeMenu {
|
||||
}
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyHistoryMenuView()
|
||||
}.goBack {
|
||||
}.openThreeDotMenu {
|
||||
}.openDownloadsManager {
|
||||
verifyEmptyDownloadsList()
|
||||
}.goBack {
|
||||
}.openThreeDotMenu {
|
||||
}.openAddonsManagerMenu {
|
||||
verifyAddonsItems()
|
||||
}.goBack {
|
||||
}.openThreeDotMenu {
|
||||
}.openSyncSignIn {
|
||||
verifyTurnOnSyncMenu()
|
||||
}.goBack {
|
||||
// Desktop toggle
|
||||
}.openThreeDotMenu {
|
||||
}.switchDesktopSiteMode {
|
||||
}
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
verifyDesktopSiteModeEnabled(isRequestDesktopSiteEnabled = true)
|
||||
}.openWhatsNew {
|
||||
verifyWhatsNewURL()
|
||||
}.goToHomescreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openHelp {
|
||||
verifyHelpUrl()
|
||||
}.goToHomescreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openCustomizeHome {
|
||||
verifyHomePageView()
|
||||
}.goBack {
|
||||
}.openThreeDotMenu {
|
||||
}.openSettings {
|
||||
verifySettingsView()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setDesktopSiteBeforePageLoadTest() {
|
||||
val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 4)
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
verifyDesktopSiteModeEnabled(false)
|
||||
}.switchDesktopSiteMode {
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(webPage.url) {
|
||||
}.openThreeDotMenu {
|
||||
verifyDesktopSiteModeEnabled(true)
|
||||
}.closeBrowserMenuToBrowser {
|
||||
clickLinkMatchingText("Link 1")
|
||||
}.openThreeDotMenu {
|
||||
verifyDesktopSiteModeEnabled(true)
|
||||
}.closeBrowserMenuToBrowser {
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(webPage.url) {
|
||||
longClickLink("Link 2")
|
||||
clickContextOpenLinkInNewTab()
|
||||
snackBarButtonClick()
|
||||
}.openThreeDotMenu {
|
||||
verifyDesktopSiteModeEnabled(false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun privateBrowsingSetDesktopSiteBeforePageLoadTest() {
|
||||
val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 4)
|
||||
|
||||
homeScreen {
|
||||
}.togglePrivateBrowsingMode()
|
||||
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
verifyDesktopSiteModeEnabled(false)
|
||||
}.switchDesktopSiteMode {
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(webPage.url) {
|
||||
}.openThreeDotMenu {
|
||||
verifyDesktopSiteModeEnabled(true)
|
||||
}.closeBrowserMenuToBrowser {
|
||||
clickLinkMatchingText("Link 1")
|
||||
}.openThreeDotMenu {
|
||||
verifyDesktopSiteModeEnabled(true)
|
||||
}.closeBrowserMenuToBrowser {
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(webPage.url) {
|
||||
longClickLink("Link 2")
|
||||
clickContextOpenLinkInPrivateTab()
|
||||
snackBarButtonClick()
|
||||
}.openThreeDotMenu {
|
||||
verifyDesktopSiteModeEnabled(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue