Merge remote-tracking branch 'origin/fenix/120.0' into iceraven

pull/700/head
akliuxingyuan 7 months ago
commit dd9f0b7833

@ -78,6 +78,7 @@ projects:
- support-images - support-images
- support-ktx - support-ktx
- support-locale - support-locale
- support-remotesettings
- support-rusterrors - support-rusterrors
- support-rusthttp - support-rusthttp
- support-rustlog - support-rustlog

@ -28,6 +28,9 @@ glean:
hasExposure: true hasExposure: true
exposureDescription: "" exposureDescription: ""
variables: variables:
enable-event-timestamps:
type: boolean
description: Enables precise event timestamps for Glean events
metrics-enabled: metrics-enabled:
type: json type: json
description: "A map of metric base-identifiers to booleans representing the state of the 'enabled' flag for that metric." description: "A map of metric base-identifiers to booleans representing the state of the 'enabled' flag for that metric."

@ -247,6 +247,14 @@ android {
targetCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17
} }
bundle {
language {
// Because we have runtime language selection we will keep all strings and languages
// in the base APKs.
enableSplit = false
}
}
lint { lint {
lintConfig file("lint.xml") lintConfig file("lint.xml")
baseline file("lint-baseline.xml") baseline file("lint-baseline.xml")
@ -313,9 +321,10 @@ android.applicationVariants.configureEach { variant ->
def abi = output.getFilter(FilterConfiguration.FilterType.ABI.name()) def abi = output.getFilter(FilterConfiguration.FilterType.ABI.name())
// If it is a Mozilla Online build, use a unified version code of armeabi-v7a // If it is a Mozilla Online build, use a unified version code of armeabi-v7a
def arch = (isMozillaOnline) ? "armeabi-v7a" : abi def arch = (isMozillaOnline) ? "armeabi-v7a" : abi
def aab = project.hasProperty("aab")
// We use the same version code generator, that we inherited from Fennec, across all channels - even on // We use the same version code generator, that we inherited from Fennec, across all channels - even on
// channels that never shipped a Fennec build. // channels that never shipped a Fennec build.
def versionCodeOverride = Config.generateFennecVersionCode(arch) def versionCodeOverride = Config.generateFennecVersionCode(arch, aab)
println("versionCode for $abi = $versionCodeOverride, isMozillaOnline = $isMozillaOnline") println("versionCode for $abi = $versionCodeOverride, isMozillaOnline = $isMozillaOnline")
@ -477,6 +486,23 @@ android.applicationVariants.configureEach { variant ->
buildConfigField 'String', 'POCKET_CONSUMER_KEY', '""' buildConfigField 'String', 'POCKET_CONSUMER_KEY', '""'
println("--") println("--")
} }
// -------------------------------------------------------------------------------------------------
// BuildConfig: Set flag to disable LeakCanary in debug (on CI builds)
// -------------------------------------------------------------------------------------------------
if (isDebug) {
if (project.hasProperty("disableLeakCanary") || gradle.hasProperty("localProperties.disableLeakCanary")) {
buildConfigField "boolean", "LEAKCANARY", "false"
println("LeakCanary enabled in debug: false")
} else {
buildConfigField "boolean", "LEAKCANARY", "true"
println("LeakCanary enabled in debug: true")
}
} else {
buildConfigField "boolean", "LEAKCANARY", "false"
}
} }
// Generate Kotlin code for the Fenix Glean metrics. // Generate Kotlin code for the Fenix Glean metrics.
@ -503,6 +529,8 @@ nimbus {
// It will be fetched by Experimenter (the Nimbus experiment website) // It will be fetched by Experimenter (the Nimbus experiment website)
// and used to inform experiment configuration. // and used to inform experiment configuration.
experimenterManifest = ".experimenter.yaml" experimenterManifest = ".experimenter.yaml"
applicationServicesDir = gradle.hasProperty('localProperties.autoPublish.application-services.dir')
? gradle.getProperty('localProperties.autoPublish.application-services.dir') : null
} }
tasks.withType(KotlinCompile).configureEach { tasks.withType(KotlinCompile).configureEach {
@ -681,7 +709,7 @@ dependencies {
androidTestImplementation ComponentsDependencies.androidx_test_junit androidTestImplementation ComponentsDependencies.androidx_test_junit
androidTestImplementation ComponentsDependencies.androidx_work_testing androidTestImplementation ComponentsDependencies.androidx_work_testing
androidTestImplementation FenixDependencies.androidx_benchmark_junit4 androidTestImplementation FenixDependencies.androidx_benchmark_junit4
androidTestImplementation FenixDependencies.mockwebserver androidTestImplementation ComponentsDependencies.testing_mockwebserver
testImplementation project(':support-test') testImplementation project(':support-test')
testImplementation project(':support-test-libstate') testImplementation project(':support-test-libstate')
testImplementation ComponentsDependencies.androidx_test_junit testImplementation ComponentsDependencies.androidx_test_junit

File diff suppressed because it is too large Load Diff

@ -245,7 +245,8 @@ features:
{ {
"feature-ui": 0, "feature-ui": 0,
"feature-setting-value": 0, "feature-setting-value": 0,
"dialog-re-engage-time": 4 "dialog-re-engage-time": 4,
"feature-setting-value-pbm": 0
} }
defaults: defaults:
- channel: developer - channel: developer
@ -253,7 +254,8 @@ features:
"sections-enabled": { "sections-enabled": {
"feature-ui": 1, "feature-ui": 1,
"feature-setting-value": 0, "feature-setting-value": 0,
"dialog-re-engage-time": 4 "dialog-re-engage-time": 4,
"feature-setting-value-pbm": 0
} }
} }
- channel: nightly - channel: nightly
@ -261,7 +263,8 @@ features:
"sections-enabled": { "sections-enabled": {
"feature-ui": 1, "feature-ui": 1,
"feature-setting-value": 0, "feature-setting-value": 0,
"dialog-re-engage-time": 4 "dialog-re-engage-time": 4,
"feature-setting-value-pbm": 0
} }
} }
unified-search: unified-search:
@ -278,7 +281,7 @@ features:
enabled: enabled:
description: If true, the extensions process is enabled. description: If true, the extensions process is enabled.
type: Boolean type: Boolean
default: false default: true
growth-data: growth-data:
description: A feature measuring campaign growth data description: A feature measuring campaign growth data
@ -328,6 +331,10 @@ features:
description: "A map of metric base-identifiers to booleans representing the state of the 'enabled' flag for that metric." description: "A map of metric base-identifiers to booleans representing the state of the 'enabled' flag for that metric."
type: Map<String, Boolean> type: Map<String, Boolean>
default: {} default: {}
enable-event-timestamps:
description: "Enables precise event timestamps for Glean events"
type: Boolean
default: false
splash-screen: splash-screen:
description: "A feature that extends splash screen duration, allowing additional data fetching time for the app's initial run." description: "A feature that extends splash screen duration, allowing additional data fetching time for the app's initial run."
@ -406,6 +413,9 @@ features:
- channel: developer - channel: developer
value: value:
enabled: true enabled: true
- channel: nightly
value:
enabled: true
types: types:
objects: {} objects: {}
@ -455,6 +465,9 @@ types:
description: An integer indicating the number of hours that needs to happen before description: An integer indicating the number of hours that needs to happen before
the re-engagement dialog shows again since the last seen, for example if set to 4 the re-engagement dialog shows again since the last seen, for example if set to 4
that means if the users has seen the dialog, it will see it 4 hours later. that means if the users has seen the dialog, it will see it 4 hours later.
feature-setting-value-pbm:
description: An integer either 0 or 1 indicating if cookie banner setting should be enabled or disabled,
0 for setting the value to disabled, 1 for enabling the setting with the value reject_all.
OnboardingPanel: OnboardingPanel:
description: The types of onboarding panels in the onboarding page description: The types of onboarding panels in the onboarding page
variants: variants:

@ -11,9 +11,9 @@ features:
default: default:
default-browser: default-browser:
card-type: default-browser card-type: default-browser
title: juno_onboarding_default_browser_title_nimbus title: juno_onboarding_default_browser_title_nimbus_2
ordering: 10 ordering: 10
body: juno_onboarding_default_browser_description_nimbus body: juno_onboarding_default_browser_description_nimbus_2
link-text: juno_onboarding_default_browser_description_link_text link-text: juno_onboarding_default_browser_description_link_text
image-res: ic_onboarding_welcome image-res: ic_onboarding_welcome
primary-button-label: juno_onboarding_default_browser_positive_button primary-button-label: juno_onboarding_default_browser_positive_button
@ -31,8 +31,8 @@ features:
sync-sign-in: sync-sign-in:
card-type: sync-sign-in card-type: sync-sign-in
title: juno_onboarding_sign_in_title title: juno_onboarding_sign_in_title_2
body: juno_onboarding_sign_in_description body: juno_onboarding_sign_in_description_2
image-res: ic_onboarding_sync image-res: ic_onboarding_sync
ordering: 20 ordering: 20
primary-button-label: juno_onboarding_sign_in_positive_button primary-button-label: juno_onboarding_sign_in_positive_button
@ -40,8 +40,8 @@ features:
notification-permission: notification-permission:
card-type: notification-permission card-type: notification-permission
title: juno_onboarding_enable_notifications_title_nimbus title: juno_onboarding_enable_notifications_title_nimbus_2
body: juno_onboarding_enable_notifications_description_nimbus body: juno_onboarding_enable_notifications_description_nimbus_2
image-res: ic_notification_permission image-res: ic_notification_permission
ordering: 30 ordering: 30
primary-button-label: juno_onboarding_enable_notifications_positive_button primary-button-label: juno_onboarding_enable_notifications_positive_button

@ -77,3 +77,17 @@ cookie-banner-report-site:
- https://github.com/mozilla-mobile/firefox-android/pull/1298#pullrequestreview-1350344223 - https://github.com/mozilla-mobile/firefox-android/pull/1298#pullrequestreview-1350344223
notification_emails: notification_emails:
- android-probes@mozilla.com - android-probes@mozilla.com
fx-suggest:
description: |
A ping representing a single event occurring with or to a Firefox Suggestion.
Distinguishable by its `ping_type`.
Does not contain a `client_id`, preferring a `context_id` instead.
include_client_id: false
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1857092
data_reviews:
- https://github.com/mozilla-mobile/firefox-android/pull/3958#issuecomment-1758607927
notification_emails:
- lina@mozilla.com
- ttran@mozilla.com
- najiang@mozilla.com

@ -55,11 +55,6 @@ class AppRequestInterceptor(
)?.let { response -> )?.let { response ->
return response return response
} }
interceptAmoRequest(uri, isSameDomain, hasUserGesture)?.let { response ->
return response
}
return context.components.services.appLinksInterceptor return context.components.services.appLinksInterceptor
.onLoadRequest( .onLoadRequest(
engineSession, engineSession,
@ -95,40 +90,6 @@ class AppRequestInterceptor(
return RequestInterceptor.ErrorResponse(errorPageUri) return RequestInterceptor.ErrorResponse(errorPageUri)
} }
/**
* Checks if the provided [uri] is a request to install an add-on from addons.mozilla.org and
* redirects to Add-ons Manager to trigger installation if needed.
*
* @return [RequestInterceptor.InterceptionResponse.Deny] when installation was triggered and
* the original request can be skipped, otherwise null to continue loading the page.
*/
private fun interceptAmoRequest(
uri: String,
isSameDomain: 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),
)
// We've redirected to the add-ons management fragment, skip original request.
return RequestInterceptor.InterceptionResponse.Deny
}
}
}
// In all other case we let the original request proceed.
return null
}
// This method is the only difference from the production code. // This method is the only difference from the production code.
// Otherwise the code should be kept identical // Otherwise the code should be kept identical
@Suppress("LongParameterList") @Suppress("LongParameterList")
@ -236,7 +197,5 @@ class AppRequestInterceptor(
companion object { companion object {
internal const val LOW_AND_MEDIUM_RISK_ERROR_PAGES = "low_and_medium_risk_error_pages.html" internal const val LOW_AND_MEDIUM_RISK_ERROR_PAGES = "low_and_medium_risk_error_pages.html"
internal const val HIGH_RISK_ERROR_PAGES = "high_risk_error_pages.html" internal const val HIGH_RISK_ERROR_PAGES = "high_risk_error_pages.html"
internal const val AMO_BASE_URL = BuildConfig.AMO_BASE_URL
internal const val AMO_INSTALL_URL_REGEX = "$AMO_BASE_URL/android/downloads/file/([^\\s]+)/([^\\s]+\\.xpi)"
} }
} }

@ -0,0 +1,74 @@
/* 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.experimentintegration
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.TestHelper
import org.mozilla.fenix.ui.robots.homeScreen
class GenericExperimentIntegrationTest {
private val experimentName = "Viewpoint"
@get:Rule
val activityTestRule = HomeActivityTestRule(
isJumpBackInCFREnabled = false,
isPWAsPromptEnabled = false,
isTCPCFREnabled = false,
)
@Before
fun setUp() {
TestHelper.appContext.settings().showSecretDebugMenuThisSession = true
}
@After
fun tearDown() {
TestHelper.appContext.settings().showSecretDebugMenuThisSession = false
}
private fun disableStudiesViaStudiesToggle() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openExperimentsMenu {
verifyExperimentEnrolled(experimentName)
}.goBack {
}.openSettingsSubMenuDataCollection {
clickStudiesOption()
verifyStudiesToggle(true)
clickStudiesToggle()
clickStudiesDialogOkButton()
}
}
@Test
fun testExperimentUnenrolled() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openExperimentsMenu {
verifyExperimentExists(experimentName)
verifyExperimentNotEnrolled(experimentName)
}
}
@Test
fun testExperimentUnenrolledViaSecretMenu() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openExperimentsMenu {
verifyExperimentExists(experimentName)
verifyExperimentEnrolled(experimentName)
unenrollfromExperiment(experimentName)
verifyExperimentNotEnrolled(experimentName)
}
}
}

@ -26,84 +26,99 @@
}, },
"charset-normalizer": { "charset-normalizer": {
"hashes": [ "hashes": [
"sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96", "sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843",
"sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c", "sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786",
"sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710", "sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e",
"sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706", "sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8",
"sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020", "sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4",
"sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252", "sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa",
"sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad", "sha256:1063da2c85b95f2d1a430f1c33b55c9c17ffaf5e612e10aeaad641c55a9e2b9d",
"sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329", "sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82",
"sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a", "sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7",
"sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f", "sha256:15b26ddf78d57f1d143bdf32e820fd8935d36abe8a25eb9ec0b5a71c82eb3895",
"sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6", "sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d",
"sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4", "sha256:187d18082694a29005ba2944c882344b6748d5be69e3a89bf3cc9d878e548d5a",
"sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a", "sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382",
"sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46", "sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678",
"sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2", "sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b",
"sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23", "sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e",
"sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace", "sha256:249c6470a2b60935bafd1d1d13cd613f8cd8388d53461c67397ee6a0f5dce741",
"sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd", "sha256:24a91a981f185721542a0b7c92e9054b7ab4fea0508a795846bc5b0abf8118d4",
"sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982", "sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596",
"sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10", "sha256:250c9eb0f4600361dd80d46112213dff2286231d92d3e52af1e5a6083d10cad9",
"sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2", "sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69",
"sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea", "sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c",
"sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09", "sha256:2f4a0033ce9a76e391542c182f0d48d084855b5fcba5010f707c8e8c34663d77",
"sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5", "sha256:30a85aed0b864ac88309b7d94be09f6046c834ef60762a8833b660139cfbad13",
"sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149", "sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459",
"sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489", "sha256:3ae38d325b512f63f8da31f826e6cb6c367336f95e418137286ba362925c877e",
"sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9", "sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7",
"sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80", "sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908",
"sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592", "sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a",
"sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3", "sha256:468d2a840567b13a590e67dd276c570f8de00ed767ecc611994c301d0f8c014f",
"sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6", "sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8",
"sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed", "sha256:542da1178c1c6af8873e143910e2269add130a299c9106eef2594e15dae5e482",
"sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c", "sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d",
"sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200", "sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d",
"sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a", "sha256:588245972aca710b5b68802c8cad9edaa98589b1b42ad2b53accd6910dad3545",
"sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e", "sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34",
"sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d", "sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86",
"sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6", "sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6",
"sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623", "sha256:67b8cc9574bb518ec76dc8e705d4c39ae78bb96237cb533edac149352c1f39fe",
"sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669", "sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e",
"sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3", "sha256:70f1d09c0d7748b73290b29219e854b3207aea922f839437870d8cc2168e31cc",
"sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa", "sha256:750b446b2ffce1739e8578576092179160f6d26bd5e23eb1789c4d64d5af7dc7",
"sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9", "sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd",
"sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2", "sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c",
"sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f", "sha256:7f5d10bae5d78e4551b7be7a9b29643a95aded9d0f602aa2ba584f0388e7a557",
"sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1", "sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a",
"sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4", "sha256:81bf654678e575403736b85ba3a7867e31c2c30a69bc57fe88e3ace52fb17b89",
"sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a", "sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078",
"sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8", "sha256:85a32721ddde63c9df9ebb0d2045b9691d9750cb139c161c80e500d210f5e26e",
"sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3", "sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4",
"sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029", "sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403",
"sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f", "sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0",
"sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959", "sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89",
"sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22", "sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115",
"sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7", "sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9",
"sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952", "sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05",
"sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346", "sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a",
"sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e", "sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec",
"sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d", "sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56",
"sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299", "sha256:aae32c93e0f64469f74ccc730a7cb21c7610af3a775157e50bbd38f816536b38",
"sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd", "sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479",
"sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a", "sha256:abecce40dfebbfa6abf8e324e1860092eeca6f7375c8c4e655a8afb61af58f2c",
"sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3", "sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e",
"sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037", "sha256:ac71b2977fb90c35d41c9453116e283fac47bb9096ad917b8819ca8b943abecd",
"sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94", "sha256:ada214c6fa40f8d800e575de6b91a40d0548139e5dc457d2ebb61470abf50186",
"sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c", "sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455",
"sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858", "sha256:b1121de0e9d6e6ca08289583d7491e7fcb18a439305b34a30b20d8215922d43c",
"sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a", "sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65",
"sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449", "sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78",
"sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c", "sha256:b5bcf60a228acae568e9911f410f9d9e0d43197d030ae5799e20dca8df588287",
"sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918", "sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df",
"sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1", "sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43",
"sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c", "sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1",
"sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", "sha256:c5a74c359b2d47d26cdbbc7845e9662d6b08a1e915eb015d044729e92e7050b7",
"sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" "sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989",
"sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a",
"sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63",
"sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884",
"sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649",
"sha256:dc45229747b67ffc441b3de2f3ae5e62877a282ea828a5bdb67883c4ee4a8810",
"sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828",
"sha256:e39c7eb31e3f5b1f88caff88bcff1b7f8334975b46f6ac6e9fc725d829bc35d4",
"sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2",
"sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd",
"sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5",
"sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe",
"sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293",
"sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e",
"sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e",
"sha256:fc52b79d83a3fe3a360902d3f5d79073a993597d48114c29485e9431092905d8"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_full_version >= '3.7.0'",
"version": "==3.2.0" "version": "==3.3.0"
}, },
"idna": { "idna": {
"hashes": [ "hashes": [
@ -135,8 +150,11 @@
"sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e",
"sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431",
"sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686",
"sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c",
"sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559",
"sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc",
"sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb",
"sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939",
"sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c",
"sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0",
"sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4",
@ -144,6 +162,7 @@
"sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575",
"sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba",
"sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d",
"sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd",
"sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3",
"sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00",
"sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155",
@ -152,6 +171,7 @@
"sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f",
"sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8",
"sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b",
"sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007",
"sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24",
"sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea",
"sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198",
@ -159,9 +179,12 @@
"sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee",
"sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be",
"sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2",
"sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1",
"sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707",
"sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6",
"sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c",
"sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58",
"sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823",
"sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779",
"sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636",
"sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c",
@ -180,18 +203,20 @@
"sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9",
"sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57",
"sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc",
"sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2" "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc",
"sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2",
"sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==2.1.3" "version": "==2.1.3"
}, },
"packaging": { "packaging": {
"hashes": [ "hashes": [
"sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5",
"sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==23.1" "version": "==23.2"
}, },
"pluggy": { "pluggy": {
"hashes": [ "hashes": [
@ -207,6 +232,7 @@
"sha256:460c9a59b14e27c602eb5ece2e47bec99dc5fc5f6513cf924a7d03a578991b1f" "sha256:460c9a59b14e27c602eb5ece2e47bec99dc5fc5f6513cf924a7d03a578991b1f"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==7.4.1" "version": "==7.4.1"
}, },
"pytest-html": { "pytest-html": {
@ -215,6 +241,7 @@
"sha256:79c4677ed6196417bf290d8b81f706342ae49f726f623728efa3f7dfff09f8eb" "sha256:79c4677ed6196417bf290d8b81f706342ae49f726f623728efa3f7dfff09f8eb"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==4.0.0" "version": "==4.0.0"
}, },
"pytest-metadata": { "pytest-metadata": {
@ -223,6 +250,7 @@
"sha256:a17b1e40080401dc23177599208c52228df463db191c1a573ccdffacd885e190" "sha256:a17b1e40080401dc23177599208c52228df463db191c1a573ccdffacd885e190"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==3.0.0" "version": "==3.0.0"
}, },
"pytest-variables": { "pytest-variables": {
@ -231,6 +259,7 @@
"sha256:ab84235417afac5a0a7dd4c3918287d9c7329d2e16d570d6e943f8d8e02533b9" "sha256:ab84235417afac5a0a7dd4c3918287d9c7329d2e16d570d6e943f8d8e02533b9"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==3.0.0" "version": "==3.0.0"
}, },
"pyyaml": { "pyyaml": {
@ -287,6 +316,7 @@
"sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.6'",
"version": "==6.0.1" "version": "==6.0.1"
}, },
"requests": { "requests": {
@ -295,15 +325,17 @@
"sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==2.31.0" "version": "==2.31.0"
}, },
"urllib3": { "urllib3": {
"hashes": [ "hashes": [
"sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11", "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84",
"sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4" "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"
], ],
"index": "pypi",
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==2.0.4" "version": "==2.0.7"
} }
}, },
"develop": { "develop": {
@ -333,6 +365,7 @@
"sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995" "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==23.7.0" "version": "==23.7.0"
}, },
"click": { "click": {
@ -349,6 +382,7 @@
"sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5" "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_full_version >= '3.8.1'",
"version": "==6.1.0" "version": "==6.1.0"
}, },
"mccabe": { "mccabe": {
@ -369,11 +403,11 @@
}, },
"packaging": { "packaging": {
"hashes": [ "hashes": [
"sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5",
"sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==23.1" "version": "==23.2"
}, },
"pathspec": { "pathspec": {
"hashes": [ "hashes": [
@ -385,19 +419,19 @@
}, },
"platformdirs": { "platformdirs": {
"hashes": [ "hashes": [
"sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d", "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3",
"sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d" "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==3.10.0" "version": "==3.11.0"
}, },
"pycodestyle": { "pycodestyle": {
"hashes": [ "hashes": [
"sha256:259bcc17857d8a8b3b4a2327324b79e5f020a13c16074670f9c8c8f872ea76d0", "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f",
"sha256:5d1013ba8dc7895b548be5afb05740ca82454fd899971563d2ef625d090326f8" "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.11.0" "version": "==2.11.1"
}, },
"pyflakes": { "pyflakes": {
"hashes": [ "hashes": [

@ -4,6 +4,7 @@
package org.mozilla.fenix.experimentintegration package org.mozilla.fenix.experimentintegration
import android.content.pm.ActivityInfo
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
@ -26,6 +27,7 @@ class SurveyExperimentIntegrationTest {
isJumpBackInCFREnabled = false, isJumpBackInCFREnabled = false,
isPWAsPromptEnabled = false, isPWAsPromptEnabled = false,
isTCPCFREnabled = false, isTCPCFREnabled = false,
isDeleteSitePermissionsEnabled = true,
) )
@Before @Before
@ -38,6 +40,15 @@ class SurveyExperimentIntegrationTest {
TestHelper.appContext.settings().showSecretDebugMenuThisSession = false TestHelper.appContext.settings().showSecretDebugMenuThisSession = false
} }
fun checkExperimentExists() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openExperimentsMenu {
verifyExperimentExists(experimentName)
}
}
@Test @Test
fun checkSurveyNavigatesCorrectly() { fun checkSurveyNavigatesCorrectly() {
browserScreen { browserScreen {
@ -46,12 +57,7 @@ class SurveyExperimentIntegrationTest {
verifyUrl(surveyURL) verifyUrl(surveyURL)
} }
homeScreen { checkExperimentExists()
}.openThreeDotMenu {
}.openSettings {
}.openExperimentsMenu {
verifyExperimentExists(experimentName)
}
} }
@Test @Test
@ -62,11 +68,29 @@ class SurveyExperimentIntegrationTest {
verifyTabCounter("0") verifyTabCounter("0")
} }
homeScreen { checkExperimentExists()
}.openThreeDotMenu { }
}.openSettings {
}.openExperimentsMenu { @Test
verifyExperimentExists(experimentName) fun checkHomescreenSurveyDismissesCorrectly() {
browserScreen {
verifyHomeScreenSurveyCloseButton()
}.clickHomeScreenSurveyCloseButton {
verifyTabCounter("0")
verifySurveyButtonDoesNotExist()
}
checkExperimentExists()
}
@Test
fun checkSurveyLandscapeLooksCorrect() {
activityTestRule.activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
browserScreen {
verifySurveyNoThanksButton()
verifySurveyButton()
} }
checkExperimentExists()
} }
} }

@ -64,6 +64,8 @@ def gradlewbuild(gradlewbuild_log):
def fixture_experiment_data(experiment_url): def fixture_experiment_data(experiment_url):
data = requests.get(experiment_url).json() data = requests.get(experiment_url).json()
for item in data["branches"][0]["features"][0]["value"]["messages"].values(): for item in data["branches"][0]["features"][0]["value"]["messages"].values():
item["surface"] = "homescreen"
item["style"] = "URGENT"
for count, trigger in enumerate(item["trigger"]): for count, trigger in enumerate(item["trigger"]):
if "USER_EN_SPEAKER" not in trigger: if "USER_EN_SPEAKER" not in trigger:
del(item["trigger"][count]) del(item["trigger"][count])
@ -160,6 +162,7 @@ def fixture_setup_experiment(experiment_slug, json_data, gradlewbuild_log):
def _(branch): def _(branch):
logging.info(f"Testing experiment {experiment_slug}, BRANCH: {branch[0]}") logging.info(f"Testing experiment {experiment_slug}, BRANCH: {branch[0]}")
command = f"nimbus-cli --app fenix --channel developer enroll {experiment_slug} --branch {branch[0]} --file {json_data} --reset-app" command = f"nimbus-cli --app fenix --channel developer enroll {experiment_slug} --branch {branch[0]} --file {json_data} --reset-app"
logging.info(f"Running command {command}")
try: try:
out = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT) out = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:

@ -0,0 +1,12 @@
import pytest
@pytest.mark.parametrize("load_branches", [("branch")], indirect=True)
def test_experiment_unenrolls_via_studies_toggle(setup_experiment, gradlewbuild, load_branches):
setup_experiment(load_branches)
gradlewbuild.test("GenericExperimentIntegrationTest#disableStudiesViaStudiesToggle")
gradlewbuild.test("GenericExperimentIntegrationTest#testExperimentUnenrolls")
@pytest.mark.parametrize("load_branches", [("branch")], indirect=True)
def test_experiment_unenrolls_via_secret_menu(setup_experiment, gradlewbuild, load_branches):
setup_experiment(load_branches)
gradlewbuild.test("GenericExperimentIntegrationTest#testExperimentUnenrollsViaSecretMenu")

@ -10,3 +10,13 @@ def test_survey_navigates_correctly(setup_experiment, gradlewbuild, load_branche
def test_survey_no_thanks_navigates_correctly(setup_experiment, gradlewbuild, load_branches): def test_survey_no_thanks_navigates_correctly(setup_experiment, gradlewbuild, load_branches):
setup_experiment(load_branches) setup_experiment(load_branches)
gradlewbuild.test("SurveyExperimentIntegrationTest#checkSurveyNoThanksNavigatesCorrectly") gradlewbuild.test("SurveyExperimentIntegrationTest#checkSurveyNoThanksNavigatesCorrectly")
@pytest.mark.parametrize("load_branches", [("branch")], indirect=True)
def test_homescreen_survey_dismisses_correctly(setup_experiment, gradlewbuild, load_branches):
setup_experiment(load_branches)
gradlewbuild.test("SurveyExperimentIntegrationTest#checkHomescreenSurveyDismissesCorrectly")
@pytest.mark.parametrize("load_branches", [("branch")], indirect=True)
def test_survey_landscape_looks_correct(setup_experiment, gradlewbuild, load_branches):
setup_experiment(load_branches)
gradlewbuild.test("SurveyExperimentIntegrationTest#checkSurveyLandscapeLooksCorrect")

@ -32,13 +32,13 @@ class ExtensionProcessTest {
} }
@Test @Test
fun test_extension_process_can_be_controlled_by_nimbus() { fun test_extension_process_can_be_enabled_by_nimbus() {
val hardcodedNimbus = HardcodedNimbusFeatures( val hardcodedNimbus = HardcodedNimbusFeatures(
context, context,
"extensions-process" to JSONObject( "extensions-process" to JSONObject(
""" """
{ {
"enabled":true "enabled": true
} }
""".trimIndent(), """.trimIndent(),
), ),
@ -53,7 +53,20 @@ class ExtensionProcessTest {
} }
@Test @Test
fun test_extension_process_must_be_disabled_by_default() { fun test_extension_process_can_be_disabled_by_nimbus() {
val hardcodedNimbus = HardcodedNimbusFeatures(
context,
"extensions-process" to JSONObject(
"""
{
"enabled": false
}
""".trimIndent(),
),
)
hardcodedNimbus.connectWith(FxNimbus)
val runtime = GeckoProvider.createRuntimeSettings(context, policy) val runtime = GeckoProvider.createRuntimeSettings(context, policy)
assertFalse(FxNimbus.features.extensionsProcess.value().enabled) assertFalse(FxNimbus.features.extensionsProcess.value().enabled)

@ -42,182 +42,186 @@
}, },
"cffi": { "cffi": {
"hashes": [ "hashes": [
"sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc",
"sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef", "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a",
"sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104", "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417",
"sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426", "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab",
"sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405", "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520",
"sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375", "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36",
"sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a", "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743",
"sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e", "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8",
"sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc", "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed",
"sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf", "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684",
"sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185", "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56",
"sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497", "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324",
"sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3", "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d",
"sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35", "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235",
"sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c", "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e",
"sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83", "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088",
"sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21", "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000",
"sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca", "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7",
"sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984", "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e",
"sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac", "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673",
"sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd", "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c",
"sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee", "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe",
"sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a", "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2",
"sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2", "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098",
"sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192", "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8",
"sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7", "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a",
"sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585", "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0",
"sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f", "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b",
"sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e", "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896",
"sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27", "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e",
"sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b", "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9",
"sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e", "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2",
"sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e", "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b",
"sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d", "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6",
"sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c", "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404",
"sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415", "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f",
"sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82", "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0",
"sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02", "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4",
"sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314", "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc",
"sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325", "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936",
"sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c", "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba",
"sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3", "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872",
"sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914", "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb",
"sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045", "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614",
"sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d", "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1",
"sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9", "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d",
"sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5", "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969",
"sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2", "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b",
"sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c", "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4",
"sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3", "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627",
"sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2", "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956",
"sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8", "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"
"sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d", ],
"sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d", "markers": "python_version >= '3.8'",
"sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9", "version": "==1.16.0"
"sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162",
"sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76",
"sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4",
"sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e",
"sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9",
"sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6",
"sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b",
"sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01",
"sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"
],
"version": "==1.15.1"
}, },
"charset-normalizer": { "charset-normalizer": {
"hashes": [ "hashes": [
"sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96", "sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843",
"sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c", "sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786",
"sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710", "sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e",
"sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706", "sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8",
"sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020", "sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4",
"sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252", "sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa",
"sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad", "sha256:1063da2c85b95f2d1a430f1c33b55c9c17ffaf5e612e10aeaad641c55a9e2b9d",
"sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329", "sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82",
"sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a", "sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7",
"sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f", "sha256:15b26ddf78d57f1d143bdf32e820fd8935d36abe8a25eb9ec0b5a71c82eb3895",
"sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6", "sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d",
"sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4", "sha256:187d18082694a29005ba2944c882344b6748d5be69e3a89bf3cc9d878e548d5a",
"sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a", "sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382",
"sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46", "sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678",
"sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2", "sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b",
"sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23", "sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e",
"sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace", "sha256:249c6470a2b60935bafd1d1d13cd613f8cd8388d53461c67397ee6a0f5dce741",
"sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd", "sha256:24a91a981f185721542a0b7c92e9054b7ab4fea0508a795846bc5b0abf8118d4",
"sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982", "sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596",
"sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10", "sha256:250c9eb0f4600361dd80d46112213dff2286231d92d3e52af1e5a6083d10cad9",
"sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2", "sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69",
"sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea", "sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c",
"sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09", "sha256:2f4a0033ce9a76e391542c182f0d48d084855b5fcba5010f707c8e8c34663d77",
"sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5", "sha256:30a85aed0b864ac88309b7d94be09f6046c834ef60762a8833b660139cfbad13",
"sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149", "sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459",
"sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489", "sha256:3ae38d325b512f63f8da31f826e6cb6c367336f95e418137286ba362925c877e",
"sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9", "sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7",
"sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80", "sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908",
"sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592", "sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a",
"sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3", "sha256:468d2a840567b13a590e67dd276c570f8de00ed767ecc611994c301d0f8c014f",
"sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6", "sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8",
"sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed", "sha256:542da1178c1c6af8873e143910e2269add130a299c9106eef2594e15dae5e482",
"sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c", "sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d",
"sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200", "sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d",
"sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a", "sha256:588245972aca710b5b68802c8cad9edaa98589b1b42ad2b53accd6910dad3545",
"sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e", "sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34",
"sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d", "sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86",
"sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6", "sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6",
"sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623", "sha256:67b8cc9574bb518ec76dc8e705d4c39ae78bb96237cb533edac149352c1f39fe",
"sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669", "sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e",
"sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3", "sha256:70f1d09c0d7748b73290b29219e854b3207aea922f839437870d8cc2168e31cc",
"sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa", "sha256:750b446b2ffce1739e8578576092179160f6d26bd5e23eb1789c4d64d5af7dc7",
"sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9", "sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd",
"sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2", "sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c",
"sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f", "sha256:7f5d10bae5d78e4551b7be7a9b29643a95aded9d0f602aa2ba584f0388e7a557",
"sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1", "sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a",
"sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4", "sha256:81bf654678e575403736b85ba3a7867e31c2c30a69bc57fe88e3ace52fb17b89",
"sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a", "sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078",
"sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8", "sha256:85a32721ddde63c9df9ebb0d2045b9691d9750cb139c161c80e500d210f5e26e",
"sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3", "sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4",
"sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029", "sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403",
"sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f", "sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0",
"sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959", "sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89",
"sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22", "sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115",
"sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7", "sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9",
"sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952", "sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05",
"sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346", "sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a",
"sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e", "sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec",
"sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d", "sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56",
"sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299", "sha256:aae32c93e0f64469f74ccc730a7cb21c7610af3a775157e50bbd38f816536b38",
"sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd", "sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479",
"sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a", "sha256:abecce40dfebbfa6abf8e324e1860092eeca6f7375c8c4e655a8afb61af58f2c",
"sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3", "sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e",
"sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037", "sha256:ac71b2977fb90c35d41c9453116e283fac47bb9096ad917b8819ca8b943abecd",
"sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94", "sha256:ada214c6fa40f8d800e575de6b91a40d0548139e5dc457d2ebb61470abf50186",
"sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c", "sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455",
"sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858", "sha256:b1121de0e9d6e6ca08289583d7491e7fcb18a439305b34a30b20d8215922d43c",
"sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a", "sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65",
"sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449", "sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78",
"sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c", "sha256:b5bcf60a228acae568e9911f410f9d9e0d43197d030ae5799e20dca8df588287",
"sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918", "sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df",
"sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1", "sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43",
"sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c", "sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1",
"sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", "sha256:c5a74c359b2d47d26cdbbc7845e9662d6b08a1e915eb015d044729e92e7050b7",
"sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" "sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989",
], "sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a",
"markers": "python_version >= '3.7'", "sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63",
"version": "==3.2.0" "sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884",
"sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649",
"sha256:dc45229747b67ffc441b3de2f3ae5e62877a282ea828a5bdb67883c4ee4a8810",
"sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828",
"sha256:e39c7eb31e3f5b1f88caff88bcff1b7f8334975b46f6ac6e9fc725d829bc35d4",
"sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2",
"sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd",
"sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5",
"sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe",
"sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293",
"sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e",
"sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e",
"sha256:fc52b79d83a3fe3a360902d3f5d79073a993597d48114c29485e9431092905d8"
],
"markers": "python_full_version >= '3.7.0'",
"version": "==3.3.0"
}, },
"cryptography": { "cryptography": {
"hashes": [ "hashes": [
"sha256:0d09fb5356f975974dbcb595ad2d178305e5050656affb7890a1583f5e02a306", "sha256:004b6ccc95943f6a9ad3142cfabcc769d7ee38a3f60fb0dddbfb431f818c3a67",
"sha256:23c2d778cf829f7d0ae180600b17e9fceea3c2ef8b31a99e3c694cbbf3a24b84", "sha256:047c4603aeb4bbd8db2756e38f5b8bd7e94318c047cfe4efeb5d715e08b49311",
"sha256:3fb248989b6363906827284cd20cca63bb1a757e0a2864d4c1682a985e3dca47", "sha256:0d9409894f495d465fe6fda92cb70e8323e9648af912d5b9141d616df40a87b8",
"sha256:41d7aa7cdfded09b3d73a47f429c298e80796c8e825ddfadc84c8a7f12df212d", "sha256:23a25c09dfd0d9f28da2352503b23e086f8e78096b9fd585d1d14eca01613e13",
"sha256:42cb413e01a5d36da9929baa9d70ca90d90b969269e5a12d39c1e0d475010116", "sha256:2ed09183922d66c4ec5fdaa59b4d14e105c084dd0febd27452de8f6f74704143",
"sha256:4c2f0d35703d61002a2bbdcf15548ebb701cfdd83cdc12471d2bae80878a4207", "sha256:35c00f637cd0b9d5b6c6bd11b6c3359194a8eba9c46d4e875a3660e3b400005f",
"sha256:4fd871184321100fb400d759ad0cddddf284c4b696568204d281c902fc7b0d81", "sha256:37480760ae08065437e6573d14be973112c9e6dcaf5f11d00147ee74f37a3829",
"sha256:5259cb659aa43005eb55a0e4ff2c825ca111a0da1814202c64d28a985d33b087", "sha256:3b224890962a2d7b57cf5eeb16ccaafba6083f7b811829f00476309bce2fe0fd",
"sha256:57a51b89f954f216a81c9d057bf1a24e2f36e764a1ca9a501a6964eb4a6800dd", "sha256:5a0f09cefded00e648a127048119f77bc2b2ec61e736660b5789e638f43cc397",
"sha256:652627a055cb52a84f8c448185922241dd5217443ca194d5739b44612c5e6507", "sha256:5b72205a360f3b6176485a333256b9bcd48700fc755fef51c8e7e67c4b63e3ac",
"sha256:67e120e9a577c64fe1f611e53b30b3e69744e5910ff3b6e97e935aeb96005858", "sha256:7e53db173370dea832190870e975a1e09c86a879b613948f09eb49324218c14d",
"sha256:6af1c6387c531cd364b72c28daa29232162010d952ceb7e5ca8e2827526aceae", "sha256:7febc3094125fc126a7f6fb1f420d0da639f3f32cb15c8ff0dc3997c4549f51a",
"sha256:6d192741113ef5e30d89dcb5b956ef4e1578f304708701b8b73d38e3e1461f34", "sha256:80907d3faa55dc5434a16579952ac6da800935cd98d14dbd62f6f042c7f5e839",
"sha256:7efe8041897fe7a50863e51b77789b657a133c75c3b094e51b5e4b5cec7bf906", "sha256:86defa8d248c3fa029da68ce61fe735432b047e32179883bdb1e79ed9bb8195e",
"sha256:84537453d57f55a50a5b6835622ee405816999a7113267739a1b4581f83535bd", "sha256:8ac4f9ead4bbd0bc8ab2d318f97d85147167a488be0e08814a37eb2f439d5cf6",
"sha256:8f09daa483aedea50d249ef98ed500569841d6498aa9c9f4b0531b9964658922", "sha256:93530900d14c37a46ce3d6c9e6fd35dbe5f5601bf6b3a5c325c7bffc030344d9",
"sha256:95dd7f261bb76948b52a5330ba5202b91a26fbac13ad0e9fc8a3ac04752058c7", "sha256:9eeb77214afae972a00dee47382d2591abe77bdae166bda672fb1e24702a3860",
"sha256:a74fbcdb2a0d46fe00504f571a2a540532f4c188e6ccf26f1f178480117b33c4", "sha256:b5f4dfe950ff0479f1f00eda09c18798d4f49b98f4e2006d644b3301682ebdca",
"sha256:a983e441a00a9d57a4d7c91b3116a37ae602907a7618b882c8013b5762e80574", "sha256:c3391bd8e6de35f6f1140e50aaeb3e2b3d6a9012536ca23ab0d9c35ec18c8a91",
"sha256:ab8de0d091acbf778f74286f4989cf3d1528336af1b59f3e5d2ebca8b5fe49e1", "sha256:c880eba5175f4307129784eca96f4e70b88e57aa3f680aeba3bab0e980b0f37d",
"sha256:aeb57c421b34af8f9fe830e1955bf493a86a7996cc1338fe41b30047d16e962c", "sha256:cecfefa17042941f94ab54f769c8ce0fe14beff2694e9ac684176a2535bf9714",
"sha256:ce785cf81a7bdade534297ef9e490ddff800d956625020ab2ec2780a556c313e", "sha256:e40211b4923ba5a6dc9769eab704bdb3fbb58d56c5b336d30996c24fcf12aadb",
"sha256:d0d651aa754ef58d75cec6edfbd21259d93810b73f6ec246436a21b7841908de" "sha256:efc8ad4e6fc4f1752ebfb58aefece8b4e3c4cae940b0994d43649bdfce8d0d4f"
], ],
"index": "pypi", "markers": "python_version >= '3.7'",
"version": "==41.0.3" "version": "==41.0.4"
}, },
"distro": { "distro": {
"hashes": [ "hashes": [
@ -357,19 +361,19 @@
}, },
"outcome": { "outcome": {
"hashes": [ "hashes": [
"sha256:6f82bd3de45da303cf1f771ecafa1633750a358436a8bb60e06a1ceb745d2672", "sha256:588ef4dc10b64e8df160d8d1310c44e1927129a66d6d2ef86845cef512c5f24c",
"sha256:c4ab89a56575d6d38a05aa16daeaa333109c1f96167aba8901ab18b6b5e0f7f5" "sha256:7b688fd82db72f4b0bc9e883a00359d4d4179cd97d27f09c9644d0c842ba7786"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==1.2.0" "version": "==1.3.0"
}, },
"packaging": { "packaging": {
"hashes": [ "hashes": [
"sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5",
"sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==23.1" "version": "==23.2"
}, },
"pluggy": { "pluggy": {
"hashes": [ "hashes": [
@ -384,7 +388,7 @@
"sha256:1393922fcb64598944ad457569fbeb4b3ac189ef50b5adb9cef3284e87e394ce", "sha256:1393922fcb64598944ad457569fbeb4b3ac189ef50b5adb9cef3284e87e394ce",
"sha256:1a8e201211f99a85df55f720b3b6da7fb5c8cdef56792c4547205be2de5ea606" "sha256:1a8e201211f99a85df55f720b3b6da7fb5c8cdef56792c4547205be2de5ea606"
], ],
"markers": "python_version >= '3.7'", "markers": "python_full_version >= '3.7.0'",
"version": "==4.2.0" "version": "==4.2.0"
}, },
"py": { "py": {
@ -444,6 +448,7 @@
"sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45" "sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==7.1.2" "version": "==7.1.2"
}, },
"pytest-fxa": { "pytest-fxa": {
@ -460,6 +465,7 @@
"sha256:b7f82f123936a3f4d2950bc993c2c1ca09ce262c9ae12f9ac763a2401380b455" "sha256:b7f82f123936a3f4d2950bc993c2c1ca09ce262c9ae12f9ac763a2401380b455"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.6'",
"version": "==3.1.1" "version": "==3.1.1"
}, },
"pytest-metadata": { "pytest-metadata": {
@ -468,15 +474,16 @@
"sha256:fcd2f416f15be295943527b3c8ba16a44ae5a7141939c90c3dc5ce9d167cf2a5" "sha256:fcd2f416f15be295943527b3c8ba16a44ae5a7141939c90c3dc5ce9d167cf2a5"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7' and python_version < '4.0'",
"version": "==2.0.2" "version": "==2.0.2"
}, },
"python-utils": { "python-utils": {
"hashes": [ "hashes": [
"sha256:1970468fff1c0adbd60b9a751e6a786223a9f0373c954571912d9cf4be49b552", "sha256:ec3a672465efb6c673845a43afcfafaa23d2594c24324a40ec18a0c59478dc0b",
"sha256:e31c1187168c314c984932e99c2d3f973465443493869ae041dd9e2e18e998aa" "sha256:efdf31c8154667d7dc0317547c8e6d3b506c5d4b6e360e0c89662306262fc0ab"
], ],
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.9'",
"version": "==3.7.0" "version": "==3.8.1"
}, },
"redo": { "redo": {
"hashes": [ "hashes": [
@ -491,23 +498,24 @@
"sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==2.31.0" "version": "==2.31.0"
}, },
"selenium": { "selenium": {
"hashes": [ "hashes": [
"sha256:95be6aa449a0ab4ac1198bb9de71bbe9170405e04b9752f4b450dc7292a21828", "sha256:0d14b0d9842366f38fb5f8f842cf7c042bcfa062affc6a0a86e4d634bdd0fe54",
"sha256:b2c48b1440db54a0653300d9955f5421390723d53b36ec835e18de8e13bbd401" "sha256:be9824a9354a7fe288e3fad9ceb6a9c65ddc7c44545d23ad0ebf4ce202b19893"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==4.12.0" "version": "==4.14.0"
}, },
"setuptools": { "setuptools": {
"hashes": [ "hashes": [
"sha256:00478ca80aeebeecb2f288d3206b0de568df5cd2b8fada1209843cc9a8d88a48", "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87",
"sha256:af3d5949030c3f493f550876b2fd1dd5ec66689c4ee5d5344f009746f71fd5a8" "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==68.2.0" "version": "==68.2.2"
}, },
"six": { "six": {
"hashes": [ "hashes": [
@ -557,34 +565,35 @@
}, },
"trio-websocket": { "trio-websocket": {
"hashes": [ "hashes": [
"sha256:c7a620c4013c34b7e4477d89fe76695da1e455e4510a8d7ae13f81c632bdce1d", "sha256:18c11793647703c158b1f6e62de638acada927344d534e3c7628eedcb746839f",
"sha256:e66b3db3e2453017431dfbd352081006654e1241c2a6800dc2f43d7df54d55c5" "sha256:520d046b0d030cf970b8b2b2e00c4c2245b3807853ecd44214acd33d74581638"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==0.10.4" "version": "==0.11.1"
}, },
"typing-extensions": { "typing-extensions": {
"hashes": [ "hashes": [
"sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0",
"sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.8'",
"version": "==4.7.1" "version": "==4.8.0"
}, },
"urllib3": { "urllib3": {
"hashes": [ "hashes": [
"sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11", "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84",
"sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4" "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"
], ],
"index": "pypi",
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==2.0.4" "version": "==2.0.7"
}, },
"wcwidth": { "wcwidth": {
"hashes": [ "hashes": [
"sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e", "sha256:77f719e01648ed600dfa5402c347481c0992263b81a027344f3e1ba25493a704",
"sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0" "sha256:8705c569999ffbb4f6a87c6d1b80f324bd6db952f5eb0b95bc07517f4c1813d4"
], ],
"version": "==0.2.6" "version": "==0.2.8"
}, },
"webob": { "webob": {
"hashes": [ "hashes": [
@ -599,7 +608,7 @@
"sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065", "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065",
"sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736" "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736"
], ],
"markers": "python_version >= '3.7'", "markers": "python_full_version >= '3.7.0'",
"version": "==1.2.0" "version": "==1.2.0"
}, },
"zope.component": { "zope.component": {
@ -620,81 +629,87 @@
}, },
"zope.hookable": { "zope.hookable": {
"hashes": [ "hashes": [
"sha256:0054539ed839751b7f511193912cba393f0b8b5f7dfe9f3601c65b2d3b74e731", "sha256:070776c9f36b99fb0df5af2a762a4d4f77e568df36637797e2e8a41c9d8d290d",
"sha256:049ef54de127236e555d0864ad3b950b2b6e5048cdf1098cf340c6fb108104c7", "sha256:12959a3d70c35a6b835e69d9f70008d3a31e324d2f2d13536c8533f648fa8a96",
"sha256:06570ed57b22624c7673ff203801bbdece14d2d42dc5d9879c24ef5612c53456", "sha256:1668993d40a7cfdc867843dd5725929e7f83a5b0c195c709af1daef8274f43cb",
"sha256:0e9e5adc24954e157e084bee97362346470a06d0305cb095118367a8a776dce4", "sha256:1a97f4a46d87ee726d48f3058062e2a1570f136ba9aa788e9c0bcdd5e511609d",
"sha256:2e8fd79437c2007020d3faac41e13c49bcbaa6a0738e4142b996c656dcb5bb69", "sha256:20936873c8b17f903bc8b63ca13ec6c492665b48067988e4359ddd5d1c5b6f2f",
"sha256:4313b3d282c1c26fcb69569b7988bc2de0b6dc59238ae7189b6b7b29503d47cb", "sha256:2968b37457079678a9d1bd9ef09ff1a224d4234e02120792a9e4e00117193df3",
"sha256:448ca90d78bd3aef75fe5d55d19f5d05a217193738b7a8d5fd9e93ecf2c02c84", "sha256:2d7bfcb11356e4dbb3e24943f0055819ff264dada4dc0b68ca012e5a1ff5b474",
"sha256:4b2fd781571336b0b7655826d9a052379a06b62af138085409b2e3fef1e6fb3d", "sha256:2d7c782bbfed7aa4846af2a67269718563daa904b33077d97665e5644b08ce2b",
"sha256:5215355203b9583b7f2a8f06fa7df272562cc12bf5be1a960a45ea49c3294426", "sha256:351cc91c0bc4c9a6d537c033179be22b613e3a60be42ba08f863490c32f736cf",
"sha256:5cb0e4a23588435c6911bde300158d31e47c73c469fbf59d927e801e1cb457ef", "sha256:3875bfb6d113ecb41c07dee67be16f5a0bbbae13199b9979e2bbeec97d97ec4b",
"sha256:71bff8f7c2e223f92a218b0909ccc6f612c075cc3b5ed164cf152f1537cae2ca", "sha256:4d3200d955c4182223f04593fef4add9771d4156d4ba6f034e65396f3b132139",
"sha256:7241ab28df7288d9a8bf49339a0aabfbf035b93d6a2a843af13d13dfa735c46a", "sha256:55a0a9d62ea907861fd79ae39e86f1d9e755064543e46c5430aa586c1b5a4854",
"sha256:7269a0fbcd7c5901e255679f8dac835b628eab58d5490c38cf2b15508f181e64", "sha256:5efffb4417604561ff0bae5c80ad3aa2ecd2145c5a8c3a4b0a4a1f55017e95a2",
"sha256:7401bd6138e58231aef751c63718726259a7aa6875d746d8a87bba70271b9cff", "sha256:6cd064359ba8c356b1bdb6c84df028ce2f6402f3703a930c4e1bab25d3ff7fff",
"sha256:761c9bf1b8df6e2b2d5ae87cda27b8e82c33e2f328750e039de4f6f7f35b73cd", "sha256:6d5f83e626caa7ed2814609b446dcc6a3abb19db729bc67671c3eef2265006fd",
"sha256:78c51f04aabd3b77ba8d3b2c2abaff8b7598376fea7bd1af9929e90549f6dd4c", "sha256:6f4d8b99c1d52e3da1b122e42e7c07eb02f6468cd315f0b6811f426586b7aa8c",
"sha256:93cfda0663d4d3db6b1818619fbc14e3df2e703454983c841b3b95894d559f86", "sha256:6ff30e7b24859974f2ff3f00b4564c4c8692730690c4c46f0019ef9b42b1f795",
"sha256:9af06ca83ff1ef9f94a98d08095dd8960fc5b71ffc7ed7db05988dc493e148a1", "sha256:7761c5fdf97a274ce8576002a2444ff45645327179ee1bafde5d5d743d0d3556",
"sha256:9cffa01d8ef1172492fd6df0113ff5432006129b9bd6e8265e1e4985362b973d", "sha256:78e4953334592c42aefa3e74f74d4c5b168a70d2c2d8cd945eb1a2f442eebee5",
"sha256:9d398b1de407a5908c8e5f55fb7a26fa177916b1203e697ef0b4c3389dd28e14", "sha256:7c5a8204992fe677bffa0e5e190cb031aef74994c658a0402a338eed7b58fe8d",
"sha256:9f447ecaf7741257333f4b1cc215de633daaf147dbc87133638142ed88492617", "sha256:7ca296b1fb0c5f69e8c0e5a90a5a953e456931016fd1f8c513b3baa3751b0640",
"sha256:9f5d425eb57dee785e4d32703e45c5d6cf2b9fa7ad37c10214593b5f62daa60b", "sha256:86bc17b6b3d1d9274168318cf171d509cbe6c8a8bdd8be0282291dac4a768de0",
"sha256:9f7dd1b45cd13976f49ad21f48a8253628c74ad5eefe3f6e14d50f38cc45f613", "sha256:968f196347fa1bd9ffc15e1d1c9d250f46137d36b75bdd2a482c51c5fc314402",
"sha256:9fd11381ec66a8569f999dbe11c94870ddf8aecd591300f203a927f18e938a24", "sha256:aaac43ac9bf9359db5170627f645c6442e9cf74414f8299ee217e4cfb259bc5c",
"sha256:acec917178af910959205f98f48bcd0a165bdcd6b4d8b3f4baf06fa393ac5ff5", "sha256:ad48a4db8d12701759b93f3cec55aff9f53626dff12ec415144c2d0ee719b965",
"sha256:b65e86a5cb8244d83eabd021f70968d4a80fac01edc99f6e35d29e5458a128bb", "sha256:b99ddae52522dce614a0323812df944b1835d97f254f81c46b33c3bcf82dadf5",
"sha256:bad033b8adfe71f650fef2d4fc33452b3310a0e53139a530dbffbcf9fe08c8c8", "sha256:ba0e86642d5b33b5edf39d28da26ed34545780a2720aa79e6dda94402c3fc457",
"sha256:c39ffe1b1ef7543e8efafdc6472d7b9ece8ed1ebe20be261522346463aa2c8c0", "sha256:c0db442d2e78d5ea1afa5f1c2537bf7201155ec8963abc8d0f3b9257b52caffb",
"sha256:c79da9673a7d704f6ea2a4bbef6e5e161adbba9d8371476de28a0e3416510cc1", "sha256:c2cf62d40f689d4bfbe733e3ed41ed2b557d011d9050185abb2bc3e96130677d",
"sha256:d06da931ac88ebb4c02ac89d0b6fdb2e4fff130901edf9c6e7ea0338a2edf6bd", "sha256:cd6fb03c174a4e20f4faec9ff22bace922bb59adb44078aebec862605bbcee92",
"sha256:d44229a0aa8d3587491f359d7326c55b5db6379f68656785dece792afbcfcbae", "sha256:e21dc34ba2453d798cf3cab92efb4994e55659c19a1f77d4cf0c2a0067e78583",
"sha256:d5e50bfbcde1afe32f9cf7fa5e8ea42e218090ecb989c31164d708d0491134b7", "sha256:ee1e32f54db69abfb6c7e227e65452d2b92e1cefae93a51106419ec623a845ff",
"sha256:d822b7ec71ebb5c96df000e2180127e94ba49258335ae796dc4b6201259b2502", "sha256:ee7ff109b2b4793137b6bd82ddc3516cbd643e67813e11e31e0bf613b387d2ec",
"sha256:eeb4042f9b1771a1dd8377cb1cb307c4a4f5821d1491becbdc69bc9de66d3918", "sha256:f2eeba6e2fd69e9e72a003edcceed7ce4614ad1c1e866bf168c92540c3658343",
"sha256:fb601f00ac87e5aa582a81315ed96768ce3513280729d3f51f79312e2b8b94ac", "sha256:f58a129a63289c44ba84ae951019f8a60d34c4d948350be7fa2abda5106f8498",
"sha256:fd49da3340339b8aeef31153ce898e93867ee5a7ffcf685e903ceae6717f0cc2" "sha256:ff5ee2df0dc3ccc524772e00d5a1991c3b8d942cc12fd503a7bf9dc35a040779"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "markers": "python_version >= '3.7'",
"version": "==5.4" "version": "==6.0"
}, },
"zope.interface": { "zope.interface": {
"hashes": [ "hashes": [
"sha256:042f2381118b093714081fd82c98e3b189b68db38ee7d35b63c327c470ef8373", "sha256:0c8cf55261e15590065039696607f6c9c1aeda700ceee40c70478552d323b3ff",
"sha256:0ec9653825f837fbddc4e4b603d90269b501486c11800d7c761eee7ce46d1bbb", "sha256:13b7d0f2a67eb83c385880489dbb80145e9d344427b4262c49fbf2581677c11c",
"sha256:12175ca6b4db7621aedd7c30aa7cfa0a2d65ea3a0105393e05482d7a2d367446", "sha256:1f294a15f7723fc0d3b40701ca9b446133ec713eafc1cc6afa7b3d98666ee1ac",
"sha256:1592f68ae11e557b9ff2bc96ac8fc30b187e77c45a3c9cd876e3368c53dc5ba8", "sha256:239a4a08525c080ff833560171d23b249f7f4d17fcbf9316ef4159f44997616f",
"sha256:23ac41d52fd15dd8be77e3257bc51bbb82469cf7f5e9a30b75e903e21439d16c", "sha256:2f8d89721834524a813f37fa174bac074ec3d179858e4ad1b7efd4401f8ac45d",
"sha256:424d23b97fa1542d7be882eae0c0fc3d6827784105264a8169a26ce16db260d8", "sha256:2fdc7ccbd6eb6b7df5353012fbed6c3c5d04ceaca0038f75e601060e95345309",
"sha256:4407b1435572e3e1610797c9203ad2753666c62883b921318c5403fb7139dec2", "sha256:34c15ca9248f2e095ef2e93af2d633358c5f048c49fbfddf5fdfc47d5e263736",
"sha256:48f4d38cf4b462e75fac78b6f11ad47b06b1c568eb59896db5b6ec1094eb467f", "sha256:387545206c56b0315fbadb0431d5129c797f92dc59e276b3ce82db07ac1c6179",
"sha256:4c3d7dfd897a588ec27e391edbe3dd320a03684457470415870254e714126b1f", "sha256:43b576c34ef0c1f5a4981163b551a8781896f2a37f71b8655fd20b5af0386abb",
"sha256:5171eb073474a5038321409a630904fd61f12dd1856dd7e9d19cd6fe092cbbc5", "sha256:57d0a8ce40ce440f96a2c77824ee94bf0d0925e6089df7366c2272ccefcb7941",
"sha256:5a158846d0fca0a908c1afb281ddba88744d403f2550dc34405c3691769cdd85", "sha256:5a804abc126b33824a44a7aa94f06cd211a18bbf31898ba04bd0924fbe9d282d",
"sha256:6ee934f023f875ec2cfd2b05a937bd817efcc6c4c3f55c5778cbf78e58362ddc", "sha256:67be3ca75012c6e9b109860820a8b6c9a84bfb036fbd1076246b98e56951ca92",
"sha256:790c1d9d8f9c92819c31ea660cd43c3d5451df1df61e2e814a6f99cebb292788", "sha256:6af47f10cfc54c2ba2d825220f180cc1e2d4914d783d6fc0cd93d43d7bc1c78b",
"sha256:809fe3bf1a91393abc7e92d607976bbb8586512913a79f2bf7d7ec15bd8ea518", "sha256:6dc998f6de015723196a904045e5a2217f3590b62ea31990672e31fbc5370b41",
"sha256:87b690bbee9876163210fd3f500ee59f5803e4a6607d1b1238833b8885ebd410", "sha256:70d2cef1bf529bff41559be2de9d44d47b002f65e17f43c73ddefc92f32bf00f",
"sha256:89086c9d3490a0f265a3c4b794037a84541ff5ffa28bb9c24cc9f66566968464", "sha256:7ebc4d34e7620c4f0da7bf162c81978fce0ea820e4fa1e8fc40ee763839805f3",
"sha256:99856d6c98a326abbcc2363827e16bd6044f70f2ef42f453c0bd5440c4ce24e5", "sha256:964a7af27379ff4357dad1256d9f215047e70e93009e532d36dcb8909036033d",
"sha256:aab584725afd10c710b8f1e6e208dbee2d0ad009f57d674cb9d1b3964037275d", "sha256:97806e9ca3651588c1baaebb8d0c5ee3db95430b612db354c199b57378312ee8",
"sha256:af169ba897692e9cd984a81cb0f02e46dacdc07d6cf9fd5c91e81f8efaf93d52", "sha256:9b9bc671626281f6045ad61d93a60f52fd5e8209b1610972cf0ef1bbe6d808e3",
"sha256:b39b8711578dcfd45fc0140993403b8a81e879ec25d53189f3faa1f006087dca", "sha256:9ffdaa5290422ac0f1688cb8adb1b94ca56cee3ad11f29f2ae301df8aecba7d1",
"sha256:b3f543ae9d3408549a9900720f18c0194ac0fe810cecda2a584fd4dca2eb3bb8", "sha256:a0da79117952a9a41253696ed3e8b560a425197d4e41634a23b1507efe3273f1",
"sha256:d0583b75f2e70ec93f100931660328965bb9ff65ae54695fb3fa0a1255daa6f2", "sha256:a41f87bb93b8048fe866fa9e3d0c51e27fe55149035dcf5f43da4b56732c0a40",
"sha256:dfbbbf0809a3606046a41f8561c3eada9db811be94138f42d9135a5c47e75f6f", "sha256:aa6fd016e9644406d0a61313e50348c706e911dca29736a3266fc9e28ec4ca6d",
"sha256:e538f2d4a6ffb6edfb303ce70ae7e88629ac6e5581870e66c306d9ad7b564a58", "sha256:ad54ed57bdfa3254d23ae04a4b1ce405954969c1b0550cc2d1d2990e8b439de1",
"sha256:eba51599370c87088d8882ab74f637de0c4f04a6d08a312dce49368ba9ed5c2a", "sha256:b012d023b4fb59183909b45d7f97fb493ef7a46d2838a5e716e3155081894605",
"sha256:ee4b43f35f5dc15e1fec55ccb53c130adb1d11e8ad8263d68b1284b66a04190d", "sha256:b51b64432eed4c0744241e9ce5c70dcfecac866dff720e746d0a9c82f371dfa7",
"sha256:f2363e5fd81afb650085c6686f2ee3706975c54f331b426800b53531191fdf28", "sha256:bbe81def9cf3e46f16ce01d9bfd8bea595e06505e51b7baf45115c77352675fd",
"sha256:f299c020c6679cb389814a3b81200fe55d428012c5e76da7e722491f5d205990", "sha256:c9559138690e1bd4ea6cd0954d22d1e9251e8025ce9ede5d0af0ceae4a401e43",
"sha256:f72f23bab1848edb7472309e9898603141644faec9fd57a823ea6b4d1c4c8995", "sha256:e30506bcb03de8983f78884807e4fd95d8db6e65b69257eea05d13d519b83ac0",
"sha256:fa90bac61c9dc3e1a563e5babb3fd2c0c1c80567e815442ddbe561eadc803b30" "sha256:e33e86fd65f369f10608b08729c8f1c92ec7e0e485964670b4d2633a4812d36b",
"sha256:e441e8b7d587af0414d25e8d05e27040d78581388eed4c54c30c0c91aad3a379",
"sha256:e8bb9c990ca9027b4214fa543fd4025818dc95f8b7abce79d61dc8a2112b561a",
"sha256:ef43ee91c193f827e49599e824385ec7c7f3cd152d74cb1dfe02cb135f264d83",
"sha256:ef467d86d3cfde8b39ea1b35090208b0447caaabd38405420830f7fd85fbdd56",
"sha256:f89b28772fc2562ed9ad871c865f5320ef761a7fcc188a935e21fe8b31a38ca9",
"sha256:fddbab55a2473f1d3b8833ec6b7ac31e8211b0aa608df5ab09ce07f3727326de"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==6.0" "version": "==6.1"
} }
}, },
"develop": {} "develop": {}

@ -70,10 +70,11 @@ class AddToHomeScreenTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/414970
@Ignore("Failure, more details at: https://bugzilla.mozilla.org/show_bug.cgi?id=1830005") @Ignore("Failure, more details at: https://bugzilla.mozilla.org/show_bug.cgi?id=1830005")
@SmokeTest @SmokeTest
@Test @Test
fun addPrivateBrowsingShortcutTest() { fun addPrivateBrowsingShortcutFromHomeScreenCFRTest() {
homeScreen { homeScreen {
}.triggerPrivateBrowsingShortcutPrompt { }.triggerPrivateBrowsingShortcutPrompt {
verifyNoThanksPrivateBrowsingShortcutButton(composeTestRule) verifyNoThanksPrivateBrowsingShortcutButton(composeTestRule)

@ -56,9 +56,10 @@ class BrowsingErrorPagesTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326774
@SmokeTest @SmokeTest
@Test @Test
fun blockMalwarePageTest() { fun verifyMalwareWebsiteWarningMessageTest() {
val malwareURl = "http://itisatrap.org/firefox/its-an-attack.html" val malwareURl = "http://itisatrap.org/firefox/its-an-attack.html"
navigationToolbar { navigationToolbar {
@ -67,9 +68,10 @@ class BrowsingErrorPagesTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326773
@SmokeTest @SmokeTest
@Test @Test
fun blockPhishingPageTest() { fun verifyPhishingWebsiteWarningMessageTest() {
val phishingURl = "http://itisatrap.org/firefox/its-a-trap.html" val phishingURl = "http://itisatrap.org/firefox/its-a-trap.html"
navigationToolbar { navigationToolbar {
@ -78,9 +80,10 @@ class BrowsingErrorPagesTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326772
@SmokeTest @SmokeTest
@Test @Test
fun blockUnwantedSoftwarePageTest() { fun verifyUnwantedSoftwareWebsiteWarningMessageTest() {
val unwantedURl = "http://itisatrap.org/firefox/unwanted.html" val unwantedURl = "http://itisatrap.org/firefox/unwanted.html"
navigationToolbar { navigationToolbar {
@ -89,9 +92,10 @@ class BrowsingErrorPagesTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/329877
@SmokeTest @SmokeTest
@Test @Test
fun blockHarmfulPageTest() { fun verifyHarmfulWebsiteWarningMessageTest() {
val harmfulURl = "https://itisatrap.org/firefox/harmful.html" val harmfulURl = "https://itisatrap.org/firefox/harmful.html"
navigationToolbar { navigationToolbar {
@ -100,10 +104,11 @@ class BrowsingErrorPagesTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/329882
// Failing with network interruption, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1833874 // Failing with network interruption, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1833874
// This tests the server ERROR_CONNECTION_REFUSED // This tests the server ERROR_CONNECTION_REFUSED
@Test @Test
fun connectionRefusedErrorMessageTest() { fun verifyConnectionInterruptedErrorMessageTest() {
val testUrl = getGenericAsset(mockWebServer, 1) val testUrl = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -119,8 +124,9 @@ class BrowsingErrorPagesTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/329881
@Test @Test
fun addressNotFoundErrorMessageTest() { fun verifyAddressNotFoundErrorMessageTest() {
val url = "ww.example.com" val url = "ww.example.com"
navigationToolbar { navigationToolbar {
@ -132,8 +138,9 @@ class BrowsingErrorPagesTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2140588
@Test @Test
fun noInternetConnectionErrorMessageTest() { fun verifyNoInternetConnectionErrorMessageTest() {
val url = "www.example.com" val url = "www.example.com"
setNetworkEnabled(false) setNetworkEnabled(false)

@ -64,9 +64,10 @@ class CollectionTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/353823
@SmokeTest @SmokeTest
@Test @Test
fun createFirstCollectionTest() { fun createFirstCollectionUsingHomeScreenButtonTest() {
val firstWebPage = getGenericAsset(mockWebServer, 1) val firstWebPage = getGenericAsset(mockWebServer, 1)
val secondWebPage = getGenericAsset(mockWebServer, 2) val secondWebPage = getGenericAsset(mockWebServer, 2)
@ -108,6 +109,7 @@ class CollectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/343422
@SmokeTest @SmokeTest
@Test @Test
fun verifyExpandedCollectionItemsTest() { fun verifyExpandedCollectionItemsTest() {
@ -158,9 +160,10 @@ class CollectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/343425
@SmokeTest @SmokeTest
@Test @Test
fun openAllTabsInCollectionTest() { fun openAllTabsFromACollectionTest() {
val firstTestPage = getGenericAsset(mockWebServer, 1) val firstTestPage = getGenericAsset(mockWebServer, 1)
val secondTestPage = getGenericAsset(mockWebServer, 2) val secondTestPage = getGenericAsset(mockWebServer, 2)
@ -191,9 +194,10 @@ class CollectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/343426
@SmokeTest @SmokeTest
@Test @Test
fun shareCollectionTest() { fun shareAllTabsFromACollectionTest() {
val firstWebsite = getGenericAsset(mockWebServer, 1) val firstWebsite = getGenericAsset(mockWebServer, 1)
val secondWebsite = getGenericAsset(mockWebServer, 2) val secondWebsite = getGenericAsset(mockWebServer, 2)
val sharingApp = "Gmail" val sharingApp = "Gmail"
@ -218,6 +222,7 @@ class CollectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/343428
// Test running on beta/release builds in CI: // Test running on beta/release builds in CI:
// caution when making changes to it, so they don't block the builds // caution when making changes to it, so they don't block the builds
@SmokeTest @SmokeTest
@ -239,15 +244,29 @@ class CollectionTest {
selectDeleteCollection(composeTestRule) selectDeleteCollection(composeTestRule)
} }
homeScreen {
verifySnackBarText("Collection deleted")
clickSnackbarButton("UNDO")
verifyCollectionIsDisplayed(collectionName, true)
}
homeScreen {
verifyCollectionIsDisplayed(collectionName)
}.expandCollection(collectionName) {
clickCollectionThreeDotButton(composeTestRule)
selectDeleteCollection(composeTestRule)
}
homeScreen { homeScreen {
verifySnackBarText("Collection deleted") verifySnackBarText("Collection deleted")
verifyNoCollectionsText() verifyNoCollectionsText()
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2319453
// open a webpage, and add currently opened tab to existing collection // open a webpage, and add currently opened tab to existing collection
@Test @Test
fun mainMenuSaveToExistingCollection() { fun saveTabToExistingCollectionFromMainMenuTest() {
val firstWebPage = getGenericAsset(mockWebServer, 1) val firstWebPage = getGenericAsset(mockWebServer, 1)
val secondWebPage = getGenericAsset(mockWebServer, 2) val secondWebPage = getGenericAsset(mockWebServer, 2)
@ -273,8 +292,9 @@ class CollectionTest {
} }
} }
// Testrail link: https://testrail.stage.mozaws.net/index.php?/cases/view/343423
@Test @Test
fun verifyAddTabButtonOfCollectionMenu() { fun saveTabToExistingCollectionUsingTheAddTabButtonTest() {
val firstWebPage = getGenericAsset(mockWebServer, 1) val firstWebPage = getGenericAsset(mockWebServer, 1)
val secondWebPage = getGenericAsset(mockWebServer, 2) val secondWebPage = getGenericAsset(mockWebServer, 2)
@ -300,6 +320,7 @@ class CollectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/343424
@Test @Test
fun renameCollectionTest() { fun renameCollectionTest() {
val webPage = getGenericAsset(mockWebServer, 1) val webPage = getGenericAsset(mockWebServer, 1)
@ -322,30 +343,32 @@ class CollectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/991248
@Test @Test
fun createSecondCollectionTest() { fun createCollectionUsingSelectTabsButtonTest() {
val webPage = getGenericAsset(mockWebServer, 1) val firstWebPage = getGenericAsset(mockWebServer, 1)
val secondWebPage = getGenericAsset(mockWebServer, 2)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(webPage.url) { }.enterURLAndEnterToBrowser(firstWebPage.url) {
}.openTabDrawer {
}.openNewTab {
}.submitQuery(secondWebPage.url.toString()) {
}.openTabDrawer { }.openTabDrawer {
createCollection(webPage.title, collectionName = firstCollectionName)
verifySnackBarText("Collection saved!")
createCollection( createCollection(
webPage.title, tabTitles = arrayOf(firstWebPage.title, secondWebPage.title),
collectionName = secondCollectionName, collectionName = firstCollectionName,
firstCollection = false,
) )
verifySnackBarText("Collection saved!") verifySnackBarText("Collection saved!")
}.closeTabDrawer { }.closeTabDrawer {
}.goToHomescreen { }.goToHomescreen {
verifyCollectionIsDisplayed(firstCollectionName) verifyCollectionIsDisplayed(firstCollectionName)
verifyCollectionIsDisplayed(secondCollectionName)
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2319455
@Test @Test
fun removeTabFromCollectionTest() { fun removeTabFromCollectionUsingTheCloseButtonTest() {
val webPage = getGenericAsset(mockWebServer, 1) val webPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -360,40 +383,24 @@ class CollectionTest {
}.expandCollection(collectionName) { }.expandCollection(collectionName) {
verifyTabSavedInCollection(webPage.title, true) verifyTabSavedInCollection(webPage.title, true)
removeTabFromCollection(webPage.title) removeTabFromCollection(webPage.title)
verifyTabSavedInCollection(webPage.title, false)
}
homeScreen {
verifyCollectionIsDisplayed(collectionName, false)
}
}
@Test
fun undoTabRemovalFromCollectionTest() {
val webPage = getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(webPage.url) {
}.openTabDrawer {
createCollection(webPage.title, collectionName = collectionName)
closeTab()
} }
homeScreen { homeScreen {
verifySnackBarText("Collection deleted")
clickSnackbarButton("UNDO")
verifyCollectionIsDisplayed(collectionName) verifyCollectionIsDisplayed(collectionName)
}.expandCollection(collectionName) { }.expandCollection(collectionName) {
verifyTabSavedInCollection(webPage.title, true) verifyTabSavedInCollection(webPage.title, true)
removeTabFromCollection(webPage.title) removeTabFromCollection(webPage.title)
verifyTabSavedInCollection(webPage.title, false)
} }
homeScreen { homeScreen {
verifySnackBarText("Collection deleted") verifyCollectionIsDisplayed(collectionName, false)
clickSnackbarButton("UNDO")
verifyCollectionIsDisplayed(collectionName, true)
verifyCollectionIsDisplayed(collectionName, true)
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/343427
@Test @Test
fun swipeLeftToRemoveTabFromCollectionTest() { fun removeTabFromCollectionUsingSwipeLeftActionTest() {
val testPage = getGenericAsset(mockWebServer, 1) val testPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -415,13 +422,21 @@ class CollectionTest {
} }
homeScreen { homeScreen {
verifySnackBarText("Collection deleted") verifySnackBarText("Collection deleted")
verifySnackBarText("UNDO") clickSnackbarButton("UNDO")
verifyCollectionIsDisplayed(collectionName)
}.expandCollection(collectionName) {
verifyTabSavedInCollection(testPage.title, true)
swipeTabLeft(testPage.title, composeTestRule)
verifyTabSavedInCollection(testPage.title, false)
}
homeScreen {
verifyCollectionIsDisplayed(collectionName, false) verifyCollectionIsDisplayed(collectionName, false)
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/991278
@Test @Test
fun swipeRightToRemoveTabFromCollectionTest() { fun removeTabFromCollectionUsingSwipeRightActionTest() {
val testPage = getGenericAsset(mockWebServer, 1) val testPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -443,13 +458,21 @@ class CollectionTest {
} }
homeScreen { homeScreen {
verifySnackBarText("Collection deleted") verifySnackBarText("Collection deleted")
verifySnackBarText("UNDO") clickSnackbarButton("UNDO")
verifyCollectionIsDisplayed(collectionName)
}.expandCollection(collectionName) {
verifyTabSavedInCollection(testPage.title, true)
swipeTabRight(testPage.title, composeTestRule)
verifyTabSavedInCollection(testPage.title, false)
}
homeScreen {
verifyCollectionIsDisplayed(collectionName, false) verifyCollectionIsDisplayed(collectionName, false)
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/991276
@Test @Test
fun selectTabOnLongTapTest() { fun createCollectionByLongPressingOpenTabsTest() {
val firstWebPage = getGenericAsset(mockWebServer, 1) val firstWebPage = getGenericAsset(mockWebServer, 1)
val secondWebPage = getGenericAsset(mockWebServer, 2) val secondWebPage = getGenericAsset(mockWebServer, 2)
@ -479,6 +502,7 @@ class CollectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/344897
@Test @Test
fun navigateBackInCollectionFlowTest() { fun navigateBackInCollectionFlowTest() {
val webPage = getGenericAsset(mockWebServer, 1) val webPage = getGenericAsset(mockWebServer, 1)
@ -510,30 +534,4 @@ class CollectionTest {
verifyMenuButton() verifyMenuButton()
} }
} }
@SmokeTest
@Test
fun undoDeleteCollectionTest() {
val webPage = getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(webPage.url) {
}.openTabDrawer {
createCollection(webPage.title, collectionName = collectionName)
snackBarButtonClick("VIEW")
}
homeScreen {
verifyCollectionIsDisplayed(collectionName)
}.expandCollection(collectionName) {
clickCollectionThreeDotButton(composeTestRule)
selectDeleteCollection(composeTestRule)
}
homeScreen {
verifySnackBarText("Collection deleted")
clickSnackbarButton("UNDO")
verifyCollectionIsDisplayed(collectionName, true)
}
}
} }

@ -67,7 +67,7 @@ class ComposeCollectionTest {
@SmokeTest @SmokeTest
@Test @Test
fun createFirstCollectionTest() { fun createFirstCollectionUsingHomeScreenButtonTest() {
val firstWebPage = getGenericAsset(mockWebServer, 1) val firstWebPage = getGenericAsset(mockWebServer, 1)
val secondWebPage = getGenericAsset(mockWebServer, 2) val secondWebPage = getGenericAsset(mockWebServer, 2)
@ -149,7 +149,7 @@ class ComposeCollectionTest {
@SmokeTest @SmokeTest
@Test @Test
fun openAllTabsInCollectionTest() { fun openAllTabsFromACollectionTest() {
val firstTestPage = getGenericAsset(mockWebServer, 1) val firstTestPage = getGenericAsset(mockWebServer, 1)
val secondTestPage = getGenericAsset(mockWebServer, 2) val secondTestPage = getGenericAsset(mockWebServer, 2)
@ -183,7 +183,7 @@ class ComposeCollectionTest {
@SmokeTest @SmokeTest
@Test @Test
fun shareCollectionTest() { fun shareAllTabsFromACollectionTest() {
val firstWebsite = getGenericAsset(mockWebServer, 1) val firstWebsite = getGenericAsset(mockWebServer, 1)
val secondWebsite = getGenericAsset(mockWebServer, 2) val secondWebsite = getGenericAsset(mockWebServer, 2)
val sharingApp = "Gmail" val sharingApp = "Gmail"
@ -229,6 +229,19 @@ class ComposeCollectionTest {
selectDeleteCollection(composeTestRule) selectDeleteCollection(composeTestRule)
} }
homeScreen {
verifySnackBarText("Collection deleted")
clickSnackbarButton("UNDO")
verifyCollectionIsDisplayed(collectionName, true)
}
homeScreen {
verifyCollectionIsDisplayed(collectionName)
}.expandCollection(collectionName) {
clickCollectionThreeDotButton(composeTestRule)
selectDeleteCollection(composeTestRule)
}
homeScreen { homeScreen {
verifySnackBarText("Collection deleted") verifySnackBarText("Collection deleted")
verifyNoCollectionsText() verifyNoCollectionsText()
@ -237,7 +250,7 @@ class ComposeCollectionTest {
// open a webpage, and add currently opened tab to existing collection // open a webpage, and add currently opened tab to existing collection
@Test @Test
fun mainMenuSaveToExistingCollection() { fun saveTabToExistingCollectionFromMainMenuTest() {
val firstWebPage = getGenericAsset(mockWebServer, 1) val firstWebPage = getGenericAsset(mockWebServer, 1)
val secondWebPage = getGenericAsset(mockWebServer, 2) val secondWebPage = getGenericAsset(mockWebServer, 2)
@ -313,29 +326,29 @@ class ComposeCollectionTest {
} }
@Test @Test
fun createSecondCollectionTest() { fun createCollectionUsingSelectTabsButtonTest() {
val webPage = getGenericAsset(mockWebServer, 1) val firstWebPage = getGenericAsset(mockWebServer, 1)
val secondWebPage = getGenericAsset(mockWebServer, 2)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(webPage.url) { }.enterURLAndEnterToBrowser(firstWebPage.url) {
}.openComposeTabDrawer(composeTestRule) {
}.openNewTab {
}.submitQuery(secondWebPage.url.toString()) {
}.openComposeTabDrawer(composeTestRule) { }.openComposeTabDrawer(composeTestRule) {
createCollection(webPage.title, collectionName = firstCollectionName)
verifySnackBarText("Collection saved!")
createCollection( createCollection(
webPage.title, tabTitles = arrayOf(firstWebPage.title, secondWebPage.title),
collectionName = secondCollectionName, collectionName = firstCollectionName,
firstCollection = false,
) )
verifySnackBarText("Collection saved!") verifySnackBarText("Collection saved!")
}.closeTabDrawer { }.closeTabDrawer {
}.goToHomescreen { }.goToHomescreen {
verifyCollectionIsDisplayed(firstCollectionName) verifyCollectionIsDisplayed(firstCollectionName)
verifyCollectionIsDisplayed(secondCollectionName)
} }
} }
@Test @Test
fun removeTabFromCollectionTest() { fun removeTabFromCollectionUsingTheCloseButtonTest() {
val webPage = getGenericAsset(mockWebServer, 1) val webPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -350,40 +363,23 @@ class ComposeCollectionTest {
}.expandCollection(collectionName) { }.expandCollection(collectionName) {
verifyTabSavedInCollection(webPage.title, true) verifyTabSavedInCollection(webPage.title, true)
removeTabFromCollection(webPage.title) removeTabFromCollection(webPage.title)
verifyTabSavedInCollection(webPage.title, false)
} }
homeScreen { homeScreen {
verifyCollectionIsDisplayed(collectionName, false) verifySnackBarText("Collection deleted")
} clickSnackbarButton("UNDO")
}
@Test
fun undoTabRemovalFromCollectionTest() {
val webPage = getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(webPage.url) {
}.openComposeTabDrawer(composeTestRule) {
createCollection(webPage.title, collectionName = collectionName)
closeTab()
}
homeScreen {
verifyCollectionIsDisplayed(collectionName) verifyCollectionIsDisplayed(collectionName)
}.expandCollection(collectionName) { }.expandCollection(collectionName) {
verifyTabSavedInCollection(webPage.title, true) verifyTabSavedInCollection(webPage.title, true)
removeTabFromCollection(webPage.title) removeTabFromCollection(webPage.title)
verifyTabSavedInCollection(webPage.title, false)
} }
homeScreen { homeScreen {
verifySnackBarText("Collection deleted") verifyCollectionIsDisplayed(collectionName, false)
clickSnackbarButton("UNDO")
verifyCollectionIsDisplayed(collectionName, true)
verifyCollectionIsDisplayed(collectionName, true)
} }
} }
@Test @Test
fun swipeLeftToRemoveTabFromCollectionTest() { fun removeTabFromCollectionUsingSwipeLeftActionTest() {
val testPage = getGenericAsset(mockWebServer, 1) val testPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -405,13 +401,17 @@ class ComposeCollectionTest {
} }
homeScreen { homeScreen {
verifySnackBarText("Collection deleted") verifySnackBarText("Collection deleted")
verifySnackBarText("UNDO") clickSnackbarButton("UNDO")
verifyCollectionIsDisplayed(collectionName, false) verifyCollectionIsDisplayed(collectionName)
}.expandCollection(collectionName) {
verifyTabSavedInCollection(testPage.title, true)
swipeTabLeft(testPage.title, composeTestRule)
verifyTabSavedInCollection(testPage.title, false)
} }
} }
@Test @Test
fun swipeRightToRemoveTabFromCollectionTest() { fun removeTabFromCollectionUsingSwipeRightActionTest() {
val testPage = getGenericAsset(mockWebServer, 1) val testPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -433,13 +433,17 @@ class ComposeCollectionTest {
} }
homeScreen { homeScreen {
verifySnackBarText("Collection deleted") verifySnackBarText("Collection deleted")
verifySnackBarText("UNDO") clickSnackbarButton("UNDO")
verifyCollectionIsDisplayed(collectionName, false) verifyCollectionIsDisplayed(collectionName)
}.expandCollection(collectionName) {
verifyTabSavedInCollection(testPage.title, true)
swipeTabRight(testPage.title, composeTestRule)
verifyTabSavedInCollection(testPage.title, false)
} }
} }
@Test @Test
fun selectTabOnLongTapTest() { fun createCollectionByLongPressingOpenTabsTest() {
val firstWebPage = getGenericAsset(mockWebServer, 1) val firstWebPage = getGenericAsset(mockWebServer, 1)
val secondWebPage = getGenericAsset(mockWebServer, 2) val secondWebPage = getGenericAsset(mockWebServer, 2)
@ -501,30 +505,4 @@ class ComposeCollectionTest {
verifyMenuButton() verifyMenuButton()
} }
} }
@SmokeTest
@Test
fun undoDeleteCollectionTest() {
val webPage = getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(webPage.url) {
}.openComposeTabDrawer(composeTestRule) {
createCollection(webPage.title, collectionName = collectionName)
clickSnackbarButton("VIEW")
}
homeScreen {
verifyCollectionIsDisplayed(collectionName)
}.expandCollection(collectionName) {
clickCollectionThreeDotButton(composeTestRule)
selectDeleteCollection(composeTestRule)
}
homeScreen {
verifySnackBarText("Collection deleted")
clickSnackbarButton("UNDO")
verifyCollectionIsDisplayed(collectionName, true)
}
}
} }

@ -76,7 +76,7 @@ class ComposeContextMenusTest {
} }
@Test @Test
fun verifyContextOpenLinkNewTab() { fun verifyOpenLinkNewTabContextMenuOptionTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val genericURL = val genericURL =
@ -99,7 +99,7 @@ class ComposeContextMenusTest {
} }
@Test @Test
fun verifyContextOpenLinkPrivateTab() { fun verifyOpenLinkInNewPrivateTabContextMenuOptionTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val genericURL = val genericURL =
@ -121,7 +121,7 @@ class ComposeContextMenusTest {
} }
@Test @Test
fun verifyContextCopyLink() { fun verifyCopyLinkContextMenuOptionTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val genericURL = val genericURL =
@ -141,29 +141,7 @@ class ComposeContextMenusTest {
} }
@Test @Test
fun verifyContextCopyLinkNotDisplayedAfterApplied() { fun verifyShareLinkContextMenuOptionTest() {
val pageLinks = TestAssetHelper.getGenericAsset(mockWebServer, 4)
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 3)
navigationToolbar {
}.enterURLAndEnterToBrowser(pageLinks.url) {
longClickPageObject(itemWithText("Link 3"))
verifyContextMenuForLocalHostLinks(genericURL.url)
clickContextMenuItem("Copy link")
verifySnackBarText("Link copied to clipboard")
}.openNavigationToolbar {
}.visitLinkFromClipboard {
verifyUrl(genericURL.url.toString())
}.openComposeTabDrawer(composeTestRule) {
}.openNewTab {
}
navigationToolbar {
verifyClipboardSuggestionsAreDisplayed(shouldBeDisplayed = false)
}
}
@Test
fun verifyContextShareLink() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val genericURL = val genericURL =
@ -182,7 +160,7 @@ class ComposeContextMenusTest {
} }
@Test @Test
fun verifyContextOpenImageNewTab() { fun verifyOpenImageNewTabContextMenuOptionTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val imageResource = val imageResource =
@ -201,7 +179,7 @@ class ComposeContextMenusTest {
} }
@Test @Test
fun verifyContextCopyImageLocation() { fun verifyCopyImageLocationContextMenuOptionTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val imageResource = val imageResource =
@ -221,7 +199,7 @@ class ComposeContextMenusTest {
} }
@Test @Test
fun verifyContextSaveImage() { fun verifySaveImageContextMenuOptionTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val imageResource = val imageResource =
@ -244,7 +222,7 @@ class ComposeContextMenusTest {
} }
@Test @Test
fun verifyContextMixedVariations() { fun verifyContextMenuLinkVariationsTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val genericURL = val genericURL =
@ -267,7 +245,7 @@ class ComposeContextMenusTest {
} }
@Test @Test
fun verifyContextMixedVariationsInPDFTest() { fun verifyPDFContextMenuLinkVariationsTest() {
val genericURL = val genericURL =
TestAssetHelper.getGenericAsset(mockWebServer, 3) TestAssetHelper.getGenericAsset(mockWebServer, 3)
@ -287,7 +265,7 @@ class ComposeContextMenusTest {
} }
@Test @Test
fun verifyContextOpenLinkInAppTest() { fun verifyOpenLinkInAppContextMenuOptionTest() {
val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer)
navigationToolbar { navigationToolbar {

@ -417,4 +417,24 @@ class ComposeHistoryTest {
verifySuggestionsAreNotDisplayed(activityTestRule, thirdWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, thirdWebPage.url.toString())
} }
} }
// Test running on beta/release builds in CI:
// caution when making changes to it, so they don't block the builds
@SmokeTest
@Test
fun noHistoryInPrivateBrowsingTest() {
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
}.togglePrivateBrowsingMode()
homeScreen {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(website.url) {
mDevice.waitForIdle()
}.openThreeDotMenu {
}.openHistory {
verifyEmptyHistoryView()
}
}
} }

@ -88,7 +88,7 @@ class ComposeHomeScreenTest {
homeScreen { }.togglePrivateBrowsingMode() homeScreen { }.togglePrivateBrowsingMode()
homeScreen { homeScreen {
verifyPrivateBrowsingHomeScreen() verifyPrivateBrowsingHomeScreenItems()
}.openCommonMythsLink { }.openCommonMythsLink {
verifyUrl("common-myths-about-private-browsing") verifyUrl("common-myths-about-private-browsing")
} }

@ -69,9 +69,10 @@ class ComposeMediaNotificationTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1347033
@SmokeTest @SmokeTest
@Test @Test
fun videoPlaybackSystemNotificationTest() { fun verifyVideoPlaybackSystemNotificationTest() {
val videoTestPage = TestAssetHelper.getVideoPageAsset(mockWebServer) val videoTestPage = TestAssetHelper.getVideoPageAsset(mockWebServer)
navigationToolbar { navigationToolbar {
@ -103,9 +104,10 @@ class ComposeMediaNotificationTest {
mDevice.pressBack() mDevice.pressBack()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2316010
@SmokeTest @SmokeTest
@Test @Test
fun audioPlaybackSystemNotificationTest() { fun verifyAudioPlaybackSystemNotificationTest() {
val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer) val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
navigationToolbar { navigationToolbar {
@ -137,6 +139,7 @@ class ComposeMediaNotificationTest {
mDevice.pressBack() mDevice.pressBack()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903595
@Test @Test
fun mediaSystemNotificationInPrivateModeTest() { fun mediaSystemNotificationInPrivateModeTest() {
val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer) val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)

@ -80,7 +80,7 @@ class ComposeSearchTest {
} }
@Test @Test
fun searchBarItemsTest() { fun verifySearchBarItemsTest() {
navigationToolbar { navigationToolbar {
verifyDefaultSearchEngine("Google") verifyDefaultSearchEngine("Google")
verifySearchBarPlaceholder("Search or enter address") verifySearchBarPlaceholder("Search or enter address")
@ -96,7 +96,7 @@ class ComposeSearchTest {
} }
@Test @Test
fun searchSelectorMenuItemsTest() { fun verifySearchSelectorMenuItemsTest() {
homeScreen { homeScreen {
}.openSearch { }.openSearch {
verifySearchView() verifySearchView()
@ -110,7 +110,7 @@ class ComposeSearchTest {
} }
@Test @Test
fun searchPlaceholderForDefaultEnginesTest() { fun verifySearchPlaceholderForGeneralDefaultSearchEnginesTest() {
generalEnginesList.forEach { generalEnginesList.forEach {
homeScreen { homeScreen {
}.openSearch { }.openSearch {
@ -127,7 +127,7 @@ class ComposeSearchTest {
} }
@Test @Test
fun searchPlaceholderForOtherGeneralSearchEnginesTest() { fun verifySearchPlaceholderForNotDefaultGeneralSearchEnginesTest() {
val generalEnginesList = listOf("DuckDuckGo", "Bing") val generalEnginesList = listOf("DuckDuckGo", "Bing")
generalEnginesList.forEach { generalEnginesList.forEach {
@ -141,7 +141,7 @@ class ComposeSearchTest {
} }
@Test @Test
fun searchPlaceholderForTopicSearchEngineTest() { fun verifySearchPlaceholderForTopicSpecificSearchEnginesTest() {
val topicEnginesList = listOf("Amazon.com", "Wikipedia", "eBay") val topicEnginesList = listOf("Amazon.com", "Wikipedia", "eBay")
topicEnginesList.forEach { topicEnginesList.forEach {
@ -156,7 +156,7 @@ class ComposeSearchTest {
@SmokeTest @SmokeTest
@Test @Test
fun scanButtonDenyPermissionTest() { fun verifyQRScanningCameraAccessDialogTest() {
val cameraManager = TestHelper.appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager val cameraManager = TestHelper.appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager
Assume.assumeTrue(cameraManager.cameraIdList.isNotEmpty()) Assume.assumeTrue(cameraManager.cameraIdList.isNotEmpty())
@ -177,7 +177,7 @@ class ComposeSearchTest {
@SmokeTest @SmokeTest
@Test @Test
fun scanButtonAllowPermissionTest() { fun scanQRCodeToOpenAWebpageTest() {
val cameraManager = TestHelper.appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager val cameraManager = TestHelper.appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager
Assume.assumeTrue(cameraManager.cameraIdList.isNotEmpty()) Assume.assumeTrue(cameraManager.cameraIdList.isNotEmpty())
@ -190,7 +190,7 @@ class ComposeSearchTest {
} }
@Test @Test
fun scanButtonAvailableOnlyForGeneralSearchEnginesTest() { fun verifyScanButtonAvailableOnlyForGeneralSearchEnginesTest() {
generalEnginesList.forEach { generalEnginesList.forEach {
homeScreen { homeScreen {
}.openSearch { }.openSearch {
@ -213,7 +213,7 @@ class ComposeSearchTest {
// Verifies a temporary change of search engine from the Search shortcut menu // Verifies a temporary change of search engine from the Search shortcut menu
@SmokeTest @SmokeTest
@Test @Test
fun selectSearchEnginesShortcutTest() { fun searchEnginesCanBeChangedTemporarilyFromSearchSelectorMenuTest() {
val enginesList = listOf("DuckDuckGo", "Google", "Amazon.com", "Wikipedia", "Bing", "eBay") val enginesList = listOf("DuckDuckGo", "Google", "Amazon.com", "Wikipedia", "Bing", "eBay")
enginesList.forEach { enginesList.forEach {
@ -230,7 +230,7 @@ class ComposeSearchTest {
} }
@Test @Test
fun accessSearchSettingFromSearchSelectorMenuTest() { fun defaultSearchEnginesCanBeSetFromSearchSelectorMenuTest() {
searchScreen { searchScreen {
clickSearchSelectorButton() clickSearchSelectorButton()
}.clickSearchEngineSettings { }.clickSearchEngineSettings {
@ -247,7 +247,7 @@ class ComposeSearchTest {
} }
@Test @Test
fun clearSearchTest() { fun verifyClearSearchButtonTest() {
homeScreen { homeScreen {
}.openSearch { }.openSearch {
typeSearch(queryString) typeSearch(queryString)
@ -259,7 +259,7 @@ class ComposeSearchTest {
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704") @Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
@SmokeTest @SmokeTest
@Test @Test
fun searchGroupShowsInRecentlyVisitedTest() { fun searchResultsOpenedInNewTabsGenerateSearchGroupsTest() {
val searchEngineName = "TestSearchEngine" val searchEngineName = "TestSearchEngine"
// setting our custom mockWebServer search URL // setting our custom mockWebServer search URL
setCustomSearchEngine(searchMockServer, searchEngineName) setCustomSearchEngine(searchMockServer, searchEngineName)
@ -286,7 +286,7 @@ class ComposeSearchTest {
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704") @Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
@Test @Test
fun verifySearchGroupHistoryWithNoDuplicatesTest() { fun verifyAPageIsAddedToASearchGroupOnlyOnceTest() {
val firstPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 1).url val firstPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 1).url
val secondPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 2).url val secondPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 2).url
val originPageUrl = val originPageUrl =
@ -331,7 +331,7 @@ class ComposeSearchTest {
@Ignore("Failing due to known bug, see https://github.com/mozilla-mobile/fenix/issues/23818") @Ignore("Failing due to known bug, see https://github.com/mozilla-mobile/fenix/issues/23818")
@Test @Test
fun searchGroupGeneratedInTheSameTabTest() { fun searchGroupIsGeneratedWhenNavigatingInTheSameTabTest() {
// setting our custom mockWebServer search URL // setting our custom mockWebServer search URL
val searchEngineName = "TestSearchEngine" val searchEngineName = "TestSearchEngine"
setCustomSearchEngine(searchMockServer, searchEngineName) setCustomSearchEngine(searchMockServer, searchEngineName)
@ -354,7 +354,7 @@ class ComposeSearchTest {
@SmokeTest @SmokeTest
@Test @Test
fun noSearchGroupFromPrivateBrowsingTest() { fun searchGroupIsNotGeneratedForLinksOpenedInPrivateTabsTest() {
// setting our custom mockWebServer search URL // setting our custom mockWebServer search URL
val searchEngineName = "TestSearchEngine" val searchEngineName = "TestSearchEngine"
setCustomSearchEngine(searchMockServer, searchEngineName) setCustomSearchEngine(searchMockServer, searchEngineName)
@ -386,7 +386,7 @@ class ComposeSearchTest {
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704") @Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
@SmokeTest @SmokeTest
@Test @Test
fun deleteItemsFromSearchGroupHistoryTest() { fun deleteIndividualHistoryItemsFromSearchGroupTest() {
val firstPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 1).url val firstPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 1).url
val secondPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 2).url val secondPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 2).url
// setting our custom mockWebServer search URL // setting our custom mockWebServer search URL
@ -427,7 +427,7 @@ class ComposeSearchTest {
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704") @Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
@Test @Test
fun deleteSearchGroupFromHistoryTest() { fun deleteSearchGroupFromHomeScreenTest() {
val firstPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 1).url val firstPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 1).url
// setting our custom mockWebServer search URL // setting our custom mockWebServer search URL
val searchEngineName = "TestSearchEngine" val searchEngineName = "TestSearchEngine"
@ -467,7 +467,7 @@ class ComposeSearchTest {
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704") @Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
@Test @Test
fun reopenTabsFromSearchGroupTest() { fun openAPageFromHomeScreenSearchGroupTest() {
val firstPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 1).url val firstPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 1).url
val secondPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 2).url val secondPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 2).url
@ -515,7 +515,7 @@ class ComposeSearchTest {
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704") @Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
@Test @Test
fun sharePageFromASearchGroupTest() { fun shareAPageFromHomeScreenSearchGroupTest() {
val firstPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 1).url val firstPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 1).url
// setting our custom mockWebServer search URL // setting our custom mockWebServer search URL
val searchEngineName = "TestSearchEngine" val searchEngineName = "TestSearchEngine"
@ -590,7 +590,13 @@ class ComposeSearchTest {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openHistory { }.openHistory {
// Full URL no longer visible in the nav bar, so we'll check the history record // Full URL no longer visible in the nav bar, so we'll check the history record
verifyHistoryItemExists(shouldExist = true, Constants.searchEngineCodes["Bing"]!!) // A search group is sometimes created when searching with Bing (probably redirects)
try {
verifyHistoryItemExists(shouldExist = true, Constants.searchEngineCodes["Bing"]!!)
} catch (e: AssertionError) {
openSearchGroup(queryString)
verifyHistoryItemExists(shouldExist = true, Constants.searchEngineCodes["Bing"]!!)
}
} }
} }
@ -622,9 +628,10 @@ class ComposeSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1850517
// Test that verifies the Firefox Suggest results in a general search context // Test that verifies the Firefox Suggest results in a general search context
@Test @Test
fun firefoxSuggestHeaderForBrowsingDataSuggestionsTest() { fun verifyFirefoxSuggestHeaderForBrowsingDataSuggestionsTest() {
val firstPage = TestAssetHelper.getGenericAsset(searchMockServer, 1) val firstPage = TestAssetHelper.getGenericAsset(searchMockServer, 1)
val secondPage = TestAssetHelper.getGenericAsset(searchMockServer, 2) val secondPage = TestAssetHelper.getGenericAsset(searchMockServer, 2)
@ -646,8 +653,9 @@ class ComposeSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154197
@Test @Test
fun verifySearchTabsItemsTest() { fun verifyTabsSearchItemsTest() {
navigationToolbar { navigationToolbar {
}.clickUrlbar { }.clickUrlbar {
clickSearchSelectorButton() clickSearchSelectorButton()
@ -659,8 +667,9 @@ class ComposeSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154198
@Test @Test
fun verifySearchTabsWithoutOpenTabsTest() { fun verifyTabsSearchWithoutOpenTabsTest() {
navigationToolbar { navigationToolbar {
}.clickUrlbar { }.clickUrlbar {
clickSearchSelectorButton() clickSearchSelectorButton()
@ -672,9 +681,10 @@ class ComposeSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154199
@SmokeTest @SmokeTest
@Test @Test
fun verifySearchTabsWithOpenTabsTest() { fun verifyTabsSearchWithOpenTabsTest() {
val firstPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 1) val firstPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 1)
val secondPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 2) val secondPageUrl = TestAssetHelper.getGenericAsset(searchMockServer, 2)
@ -707,8 +717,9 @@ class ComposeSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154203
@Test @Test
fun verifySearchForBookmarksUITest() { fun verifyBookmarksSearchItemsTest() {
navigationToolbar { navigationToolbar {
}.clickSearchSelectorButton { }.clickSearchSelectorButton {
selectTemporarySearchMethod("Bookmarks") selectTemporarySearchMethod("Bookmarks")
@ -719,8 +730,9 @@ class ComposeSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154204
@Test @Test
fun bookmarkSearchWithNoBookmarksTest() { fun verifyBookmarkSearchWithNoBookmarksTest() {
navigationToolbar { navigationToolbar {
}.clickSearchSelectorButton { }.clickSearchSelectorButton {
selectTemporarySearchMethod("Bookmarks") selectTemporarySearchMethod("Bookmarks")
@ -729,8 +741,9 @@ class ComposeSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154206
@Test @Test
fun bookmarkSearchWhenBookmarksExistTest() { fun verifyBookmarksSearchForBookmarkedItemsTest() {
createBookmarkItem(url = "https://bookmarktest1.com", title = "Test1", position = 1u) createBookmarkItem(url = "https://bookmarktest1.com", title = "Test1", position = 1u)
createBookmarkItem(url = "https://bookmarktest2.com", title = "Test2", position = 2u) createBookmarkItem(url = "https://bookmarktest2.com", title = "Test2", position = 2u)
@ -756,8 +769,9 @@ class ComposeSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154212
@Test @Test
fun verifySearchHistoryItemsTest() { fun verifyHistorySearchItemsTest() {
navigationToolbar { navigationToolbar {
}.clickUrlbar { }.clickUrlbar {
clickSearchSelectorButton() clickSearchSelectorButton()
@ -769,8 +783,9 @@ class ComposeSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154213
@Test @Test
fun verifySearchHistoryWithoutBrowsingDataTest() { fun verifyHistorySearchWithoutBrowsingHistoryTest() {
navigationToolbar { navigationToolbar {
}.clickUrlbar { }.clickUrlbar {
clickSearchSelectorButton() clickSearchSelectorButton()

@ -1,238 +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/. */
@file:Suppress("DEPRECATION")
package org.mozilla.fenix.ui
import android.view.View
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.core.net.toUri
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.ActivityTestRule
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.Rule
import org.junit.Test
import org.mozilla.fenix.IntentReceiverActivity
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.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
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.clickPageObject
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
/**
* Test Suite that contains a part of the Smoke and Sanity tests defined in TestRail:
* https://testrail.stage.mozaws.net/index.php?/suites/view/3192
* Other smoke tests have been marked with the @SmokeTest annotation throughout the ui package in order to limit this class expansion.
* These tests will verify different functionalities of the app as a way to quickly detect regressions in main areas
*/
@Suppress("ForbiddenComment")
@SmokeTest
class ComposeSmokeTest {
private lateinit var mDevice: UiDevice
private lateinit var mockWebServer: MockWebServer
private val customMenuItem = "TestMenuItem"
private lateinit var browserStore: BrowserStore
@get:Rule(order = 0)
val activityTestRule = AndroidComposeTestRule(
HomeActivityIntentTestRule.withDefaultSettingsOverrides(
tabsTrayRewriteEnabled = true,
),
) { it.activity }
@get: Rule(order = 1)
val intentReceiverActivityTestRule = ActivityTestRule(
IntentReceiverActivity::class.java,
true,
false,
)
@Rule(order = 2)
@JvmField
val retryTestRule = RetryTestRule(3)
@Before
fun setUp() {
// Initializing this as part of class construction, below the rule would throw a NPE
// So we are initializing this here instead of in all related tests.
browserStore = activityTestRule.activity.components.core.store
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher()
start()
}
}
@After
fun tearDown() {
mockWebServer.shutdown()
}
@Test
fun shareTabsFromTabsTrayTest() {
val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2)
val firstWebsiteTitle = firstWebsite.title
val secondWebsiteTitle = secondWebsite.title
val sharingApp = "Gmail"
val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}"
homeScreen {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(firstWebsite.url) {
verifyPageContent(firstWebsite.content)
}.openComposeTabDrawer(activityTestRule) {
}.openNewTab {
}.submitQuery(secondWebsite.url.toString()) {
verifyPageContent(secondWebsite.content)
}.openComposeTabDrawer(activityTestRule) {
verifyExistingOpenTabs("Test_Page_1")
verifyExistingOpenTabs("Test_Page_2")
}.openThreeDotMenu {
verifyShareAllTabsButton()
}.clickShareAllTabsButton {
verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle)
verifySharingWithSelectedApp(
sharingApp,
sharedUrlsString,
"$firstWebsiteTitle, $secondWebsiteTitle",
)
}
}
@Test
fun privateTabsTrayWithOpenedTabTest() {
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
}.togglePrivateBrowsingMode()
homeScreen {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(website.url) {
}.openComposeTabDrawer(activityTestRule) {
verifyNormalBrowsingButtonIsSelected(false)
verifyPrivateBrowsingButtonIsSelected(true)
verifySyncedTabsButtonIsSelected(false)
verifyThreeDotButton()
verifyNormalTabCounter()
verifyPrivateTabsList()
verifyExistingOpenTabs(website.title)
verifyTabCloseButton()
verifyTabThumbnail()
verifyFab()
}
}
// 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)
homeScreen {
}.togglePrivateBrowsingMode()
homeScreen {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(website.url) {
mDevice.waitForIdle()
}.openThreeDotMenu {
}.openHistory {
verifyEmptyHistoryView()
}
}
@Test
fun mainMenuInstallPWATest() {
val pwaPage = "https://mozilla-mobile.github.io/testapp/"
navigationToolbar {
}.enterURLAndEnterToBrowser(pwaPage.toUri()) {
verifyNotificationDotOnMainMenu()
}.openThreeDotMenu {
}.clickInstall {
clickAddAutomaticallyButton()
}.openHomeScreenShortcut("TEST_APP") {
mDevice.waitForIdle()
verifyNavURLBarHidden()
}
}
// Verifies that reader mode is detected and the custom appearance controls are displayed
@Test
fun verifyReaderViewAppearanceUI() {
val readerViewPage =
TestAssetHelper.getLoremIpsumAsset(mockWebServer)
val estimatedReadingTime = "1 - 2 minutes"
navigationToolbar {
}.enterURLAndEnterToBrowser(readerViewPage.url) {
mDevice.waitForIdle()
}
registerAndCleanupIdlingResources(
ViewVisibilityIdlingResource(
activityTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
View.VISIBLE,
),
) {}
navigationToolbar {
verifyReaderViewDetected(true)
toggleReaderView()
}
browserScreen {
waitForPageToLoad()
verifyPageContent(estimatedReadingTime)
}.openThreeDotMenu {
verifyReaderViewAppearance(true)
}.openReaderViewAppearance {
verifyAppearanceFontGroup(true)
verifyAppearanceFontSansSerif(true)
verifyAppearanceFontSerif(true)
verifyAppearanceFontIncrease(true)
verifyAppearanceFontDecrease(true)
verifyAppearanceColorGroup(true)
verifyAppearanceColorDark(true)
verifyAppearanceColorLight(true)
verifyAppearanceColorSepia(true)
}
}
@Test
fun tabMediaControlButtonTest() {
val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
navigationToolbar {
}.enterURLAndEnterToBrowser(audioTestPage.url) {
mDevice.waitForIdle()
clickPageObject(itemWithText("Play"))
assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING)
}.openComposeTabDrawer(activityTestRule) {
verifyTabMediaControlButtonState("Pause")
clickTabMediaControlButton("Pause")
verifyTabMediaControlButtonState("Play")
}.openTab(audioTestPage.title) {
assertPlaybackState(browserStore, MediaSession.PlaybackState.PAUSED)
}
}
}

@ -8,14 +8,18 @@ import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.mediasession.MediaSession
import okhttp3.mockwebserver.MockWebServer import okhttp3.mockwebserver.MockWebServer
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper
import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.RetryTestRule
import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
@ -24,6 +28,7 @@ import org.mozilla.fenix.helpers.TestHelper.restartApp
import org.mozilla.fenix.helpers.TestHelper.verifyKeyboardVisibility import org.mozilla.fenix.helpers.TestHelper.verifyKeyboardVisibility
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.navigationToolbar
import org.mozilla.fenix.ui.robots.notificationShade import org.mozilla.fenix.ui.robots.notificationShade
@ -48,6 +53,7 @@ import org.mozilla.fenix.ui.robots.notificationShade
class ComposeTabbedBrowsingTest { class ComposeTabbedBrowsingTest {
private lateinit var mDevice: UiDevice private lateinit var mDevice: UiDevice
private lateinit var mockWebServer: MockWebServer private lateinit var mockWebServer: MockWebServer
private lateinit var browserStore: BrowserStore
@get:Rule(order = 0) @get:Rule(order = 0)
val composeTestRule = val composeTestRule =
@ -64,6 +70,10 @@ class ComposeTabbedBrowsingTest {
@Before @Before
fun setUp() { fun setUp() {
// Initializing this as part of class construction, below the rule would throw a NPE
// So we are initializing this here instead of in all related tests.
browserStore = composeTestRule.activity.components.core.store
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
mockWebServer = MockWebServer().apply { mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher() dispatcher = AndroidAssetDispatcher()
@ -76,52 +86,7 @@ class ComposeTabbedBrowsingTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
@Test // TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903599
fun openNewTabTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.waitForIdle()
verifyTabCounter("1")
}.openComposeTabDrawer(composeTestRule) {
verifyNormalBrowsingButtonIsSelected()
verifyExistingOpenTabs("Test_Page_1")
closeTab()
}
homeScreen {
}.openComposeTabDrawer(composeTestRule) {
verifyNoOpenTabsInNormalBrowsing()
}.openNewTab {
}.submitQuery(defaultWebPage.url.toString()) {
verifyPageContent(defaultWebPage.content)
verifyTabCounter("1")
}.openComposeTabDrawer(composeTestRule) {
verifyNormalBrowsingButtonIsSelected()
verifyExistingOpenTabs("Test_Page_1")
}
}
@Test
fun openNewPrivateTabTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
}.togglePrivateBrowsingMode()
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.waitForIdle()
verifyTabCounter("1")
}.openComposeTabDrawer(composeTestRule) {
verifyPrivateTabsList()
verifyPrivateBrowsingButtonIsSelected()
}.toggleToNormalTabs {
verifyNoOpenTabsInNormalBrowsing()
}.toggleToPrivateTabs {
verifyPrivateTabsList()
}
}
@Test @Test
fun closeAllTabsTest() { fun closeAllTabsTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -153,8 +118,9 @@ class ComposeTabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903604
@Test @Test
fun closeTabTest() { fun closingTabsMethodsTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -162,6 +128,13 @@ class ComposeTabbedBrowsingTest {
}.openComposeTabDrawer(composeTestRule) { }.openComposeTabDrawer(composeTestRule) {
verifyExistingOpenTabs("Test_Page_1") verifyExistingOpenTabs("Test_Page_1")
closeTab() closeTab()
verifySnackBarText("Tab closed")
clickSnackbarButton("UNDO")
}
browserScreen {
verifyTabCounter("1")
}.openComposeTabDrawer(composeTestRule) {
closeTab()
} }
homeScreen { homeScreen {
verifyTabCounter("0") verifyTabCounter("0")
@ -184,42 +157,23 @@ class ComposeTabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903591
@Test @Test
fun verifyUndoSnackBarTest() { fun closingPrivateTabsMethodsTest() {
// disabling these features because they interfere with the snackbar visibility
composeTestRule.activityRule.applySettingsExceptions {
it.isPocketEnabled = false
it.isRecentTabsFeatureEnabled = false
it.isRecentlyVisitedFeatureEnabled = false
}
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen { }.togglePrivateBrowsingMode()
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) { }.enterURLAndEnterToBrowser(genericURL.url) {
}.openComposeTabDrawer(composeTestRule) { }.openComposeTabDrawer(composeTestRule) {
verifyExistingOpenTabs("Test_Page_1") verifyExistingOpenTabs("Test_Page_1")
closeTab() closeTab()
verifySnackBarText("Tab closed") verifySnackBarText("Private tab closed")
clickSnackbarButton("UNDO") clickSnackbarButton("UNDO")
} }
browserScreen { browserScreen {
verifyTabCounter("1") verifyTabCounter("1")
}.openComposeTabDrawer(composeTestRule) { }.openComposeTabDrawer(composeTestRule) {
verifyExistingOpenTabs("Test_Page_1")
}
}
@Test
fun closePrivateTabTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen { }.togglePrivateBrowsingMode()
navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
}.openComposeTabDrawer(composeTestRule) {
verifyExistingOpenTabs("Test_Page_1")
closeTab() closeTab()
} }
homeScreen { homeScreen {
@ -229,6 +183,7 @@ class ComposeTabbedBrowsingTest {
}.openComposeTabDrawer(composeTestRule) { }.openComposeTabDrawer(composeTestRule) {
verifyExistingOpenTabs("Test_Page_1") verifyExistingOpenTabs("Test_Page_1")
swipeTabRight("Test_Page_1") swipeTabRight("Test_Page_1")
verifySnackBarText("Private tab closed")
} }
homeScreen { homeScreen {
verifyTabCounter("0") verifyTabCounter("0")
@ -237,39 +192,37 @@ class ComposeTabbedBrowsingTest {
}.openComposeTabDrawer(composeTestRule) { }.openComposeTabDrawer(composeTestRule) {
verifyExistingOpenTabs("Test_Page_1") verifyExistingOpenTabs("Test_Page_1")
swipeTabLeft("Test_Page_1") swipeTabLeft("Test_Page_1")
verifySnackBarText("Private tab closed")
} }
homeScreen { homeScreen {
verifyTabCounter("0") verifyTabCounter("0")
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903606
@SmokeTest
@Test @Test
fun verifyPrivateTabUndoSnackBarTest() { fun tabMediaControlButtonTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
homeScreen { }.togglePrivateBrowsingMode()
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) { }.enterURLAndEnterToBrowser(audioTestPage.url) {
verifyPageContent(genericURL.content) mDevice.waitForIdle()
}.openComposeTabDrawer(composeTestRule) { clickPageObject(MatcherHelper.itemWithText("Play"))
verifyExistingOpenTabs("Test_Page_1") assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING)
closeTab()
verifySnackBarText("Private tab closed")
clickSnackbarButton("UNDO")
}
browserScreen {
verifyPageContent(genericURL.content)
verifyTabCounter("1")
}.openComposeTabDrawer(composeTestRule) { }.openComposeTabDrawer(composeTestRule) {
verifyExistingOpenTabs("Test_Page_1") verifyTabMediaControlButtonState("Pause")
verifyPrivateBrowsingButtonIsSelected() clickTabMediaControlButton("Pause")
verifyTabMediaControlButtonState("Play")
}.openTab(audioTestPage.title) {
assertPlaybackState(browserStore, MediaSession.PlaybackState.PAUSED)
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903592
@SmokeTest @SmokeTest
@Test @Test
fun closePrivateTabsNotificationTest() { fun verifyCloseAllPrivateTabsNotificationTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen { homeScreen {
@ -310,6 +263,7 @@ class ComposeTabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903600
@Test @Test
fun verifyEmptyTabTray() { fun verifyEmptyTabTray() {
homeScreen { homeScreen {
@ -326,8 +280,9 @@ class ComposeTabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903585
@Test @Test
fun emptyTabsTrayViewPrivateBrowsingTest() { fun verifyEmptyPrivateTabsTrayTest() {
homeScreen { homeScreen {
}.openComposeTabDrawer(composeTestRule) { }.openComposeTabDrawer(composeTestRule) {
}.toggleToPrivateTabs { }.toggleToPrivateTabs {
@ -343,8 +298,9 @@ class ComposeTabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903601
@Test @Test
fun verifyOpenTabDetails() { fun verifyTabsTrayWithOpenTabTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -366,29 +322,57 @@ class ComposeTabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903587
@SmokeTest
@Test
fun verifyPrivateTabsTrayWithOpenTabTest() {
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
}.openComposeTabDrawer(composeTestRule) {
}.toggleToPrivateTabs {
}.openNewTab {
}.submitQuery(website.url.toString()) {
}.openComposeTabDrawer(composeTestRule) {
verifyNormalBrowsingButtonIsSelected(false)
verifyPrivateBrowsingButtonIsSelected(true)
verifySyncedTabsButtonIsSelected(false)
verifyThreeDotButton()
verifyNormalTabCounter()
verifyPrivateTabsList()
verifyExistingOpenTabs(website.title)
verifyTabCloseButton()
verifyTabThumbnail()
verifyFab()
}
}
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/927314
@Test @Test
fun verifyContextMenuShortcuts() { fun tabsCounterShortcutMenuTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {}
navigationToolbar {
}.openTabButtonShortcutsMenu { }.openTabButtonShortcutsMenu {
verifyTabButtonShortcutMenuItems() verifyTabButtonShortcutMenuItems()
}.closeTabFromShortcutsMenu { }.closeTabFromShortcutsMenu {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {}
navigationToolbar {
}.openTabButtonShortcutsMenu { }.openTabButtonShortcutsMenu {
}.openNewPrivateTabFromShortcutsMenu { }.openNewPrivateTabFromShortcutsMenu {
verifyKeyboardVisibility() verifyKeyboardVisibility()
verifySearchBarPlaceholder("Search or enter address") verifySearchBarPlaceholder("Search or enter address")
// dismiss search dialog // dismiss search dialog
}.dismissSearchBar { }.dismissSearchBar {
verifyCommonMythsLink() verifyPrivateBrowsingHomeScreenItems()
verifyNavigationToolbar()
} }
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {}
navigationToolbar {
}.openTabButtonShortcutsMenu { }.openTabButtonShortcutsMenu {
}.openTabFromShortcutsMenu { }.openNewTabFromShortcutsMenu {
verifyKeyboardVisibility() verifyKeyboardVisibility()
verifySearchBarPlaceholder("Search or enter address") verifySearchBarPlaceholder("Search or enter address")
// dismiss search dialog // dismiss search dialog
@ -398,6 +382,43 @@ class ComposeTabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/927314
@Test
fun privateTabsCounterShortcutMenuTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {}.togglePrivateBrowsingMode()
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {}
navigationToolbar {
}.openTabButtonShortcutsMenu {
verifyTabButtonShortcutMenuItems()
}.closeTabFromShortcutsMenu {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {}
navigationToolbar {
}.openTabButtonShortcutsMenu {
}.openNewPrivateTabFromShortcutsMenu {
verifyKeyboardVisibility()
verifySearchBarPlaceholder("Search or enter address")
// dismiss search dialog
}.dismissSearchBar {
verifyCommonMythsLink()
}
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {}
navigationToolbar {
}.openTabButtonShortcutsMenu {
}.openNewTabFromShortcutsMenu {
verifyKeyboardVisibility()
verifySearchBarPlaceholder("Search or enter address")
// dismiss search dialog
}.dismissSearchBar {
// Verify normal browsing homescreen
verifyExistingTopSitesList()
}
}
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/1046683
@Test @Test
fun verifySyncedTabsWhenUserIsNotSignedInTest() { fun verifySyncedTabsWhenUserIsNotSignedInTest() {
navigationToolbar { navigationToolbar {
@ -411,6 +432,41 @@ class ComposeTabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903598
@SmokeTest
@Test
fun shareTabsFromTabsTrayTest() {
val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2)
val firstWebsiteTitle = firstWebsite.title
val secondWebsiteTitle = secondWebsite.title
val sharingApp = "Gmail"
val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}"
homeScreen {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(firstWebsite.url) {
verifyPageContent(firstWebsite.content)
}.openComposeTabDrawer(composeTestRule) {
}.openNewTab {
}.submitQuery(secondWebsite.url.toString()) {
verifyPageContent(secondWebsite.content)
}.openComposeTabDrawer(composeTestRule) {
verifyExistingOpenTabs("Test_Page_1")
verifyExistingOpenTabs("Test_Page_2")
}.openThreeDotMenu {
verifyShareAllTabsButton()
}.clickShareAllTabsButton {
verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle)
verifySharingWithSelectedApp(
sharingApp,
sharedUrlsString,
"$firstWebsiteTitle, $secondWebsiteTitle",
)
}
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/526244
@Test @Test
fun privateModeStaysAsDefaultAfterRestartTest() { fun privateModeStaysAsDefaultAfterRestartTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -424,13 +480,14 @@ class ComposeTabbedBrowsingTest {
restartApp(composeTestRule.activityRule) restartApp(composeTestRule.activityRule)
homeScreen { homeScreen {
verifyPrivateBrowsingHomeScreen() verifyPrivateBrowsingHomeScreenItems()
}.openComposeTabDrawer(composeTestRule) { }.openComposeTabDrawer(composeTestRule) {
}.toggleToNormalTabs { }.toggleToNormalTabs {
verifyExistingOpenTabs(defaultWebPage.title) verifyExistingOpenTabs(defaultWebPage.title)
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2228470
@SmokeTest @SmokeTest
@Test @Test
fun privateTabsDoNotPersistAfterClosingAppTest() { fun privateTabsDoNotPersistAfterClosingAppTest() {
@ -449,7 +506,7 @@ class ComposeTabbedBrowsingTest {
closeApp(composeTestRule.activityRule) closeApp(composeTestRule.activityRule)
restartApp(composeTestRule.activityRule) restartApp(composeTestRule.activityRule)
homeScreen { homeScreen {
verifyPrivateBrowsingHomeScreen() verifyPrivateBrowsingHomeScreenItems()
}.openComposeTabDrawer(composeTestRule) { }.openComposeTabDrawer(composeTestRule) {
verifyNoOpenTabsInPrivateBrowsing() verifyNoOpenTabsInPrivateBrowsing()
} }

@ -62,7 +62,7 @@ class ComposeTopSitesTest {
@SmokeTest @SmokeTest
@Test @Test
fun verifyAddToFirefoxHome() { fun addAWebsiteAsATopSiteTest() {
val defaultWebPage = getGenericAsset(mockWebServer, 1) val defaultWebPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -79,7 +79,7 @@ class ComposeTopSitesTest {
} }
@Test @Test
fun verifyOpenTopSiteNormalTab() { fun openTopSiteInANewTabTest() {
val defaultWebPage = getGenericAsset(mockWebServer, 1) val defaultWebPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -106,7 +106,7 @@ class ComposeTopSitesTest {
} }
@Test @Test
fun verifyOpenTopSitePrivateTab() { fun openTopSiteInANewPrivateTabTest() {
val defaultWebPage = getGenericAsset(mockWebServer, 1) val defaultWebPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -127,7 +127,7 @@ class ComposeTopSitesTest {
} }
@Test @Test
fun verifyRenameTopSite() { fun renameATopSiteTest() {
val defaultWebPage = getGenericAsset(mockWebServer, 1) val defaultWebPage = getGenericAsset(mockWebServer, 1)
val newPageTitle = generateRandomString(5) val newPageTitle = generateRandomString(5)
@ -151,7 +151,7 @@ class ComposeTopSitesTest {
} }
@Test @Test
fun verifyRemoveTopSite() { fun removeTopSiteUsingMenuButtonTest() {
val defaultWebPage = getGenericAsset(mockWebServer, 1) val defaultWebPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -167,34 +167,17 @@ class ComposeTopSitesTest {
}.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) { }.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) {
verifyTopSiteContextMenuItems() verifyTopSiteContextMenuItems()
}.removeTopSite { }.removeTopSite {
verifyNotExistingTopSiteItem(defaultWebPage.title) clickSnackbarButton("UNDO")
}
}
@Test
fun verifyUndoRemoveTopSite() {
val defaultWebPage = getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
}.openThreeDotMenu {
expandMenu()
verifyAddToShortcutsButton(true)
}.addToFirefoxHome {
verifySnackBarText(getStringResource(R.string.snackbar_added_to_shortcuts))
}.goToHomescreenWithComposeTopSites(composeTestRule) {
verifyExistingTopSitesList()
verifyExistingTopSiteItem(defaultWebPage.title) verifyExistingTopSiteItem(defaultWebPage.title)
}.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) { }.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) {
verifyTopSiteContextMenuItems() verifyTopSiteContextMenuItems()
}.removeTopSite { }.removeTopSite {
clickSnackbarButton("UNDO") verifyNotExistingTopSiteItem(defaultWebPage.title)
verifyExistingTopSiteItem(defaultWebPage.title)
} }
} }
@Test @Test
fun verifyRemoveTopSiteFromMainMenu() { fun removeTopSiteFromMainMenuTest() {
val defaultWebPage = getGenericAsset(mockWebServer, 1) val defaultWebPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -218,7 +201,7 @@ class ComposeTopSitesTest {
// Expected for en-us defaults // Expected for en-us defaults
@Test @Test
fun verifyDefaultTopSitesList() { fun verifyENLocalesDefaultTopSitesListTest() {
homeScreenWithComposeTopSites(composeTestRule) { homeScreenWithComposeTopSites(composeTestRule) {
verifyExistingTopSitesList() verifyExistingTopSitesList()
val topSitesTitles = arrayListOf("Google", "Top Articles", "Wikipedia") val topSitesTitles = arrayListOf("Google", "Top Articles", "Wikipedia")

@ -10,7 +10,6 @@ import androidx.test.uiautomator.UiDevice
import okhttp3.mockwebserver.MockWebServer import okhttp3.mockwebserver.MockWebServer
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Ignore
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
@ -70,8 +69,9 @@ class ContextMenusTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243837
@Test @Test
fun verifyContextOpenLinkNewTab() { fun verifyOpenLinkNewTabContextMenuOptionTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val genericURL = val genericURL =
@ -93,8 +93,9 @@ class ContextMenusTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/244655
@Test @Test
fun verifyContextOpenLinkPrivateTab() { fun verifyOpenLinkInNewPrivateTabContextMenuOptionTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val genericURL = val genericURL =
@ -115,8 +116,9 @@ class ContextMenusTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243832
@Test @Test
fun verifyContextCopyLink() { fun verifyCopyLinkContextMenuOptionTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val genericURL = val genericURL =
@ -135,31 +137,9 @@ class ContextMenusTest {
} }
} }
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268") // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243838
@Test @Test
fun verifyContextCopyLinkNotDisplayedAfterApplied() { fun verifyShareLinkContextMenuOptionTest() {
val pageLinks = TestAssetHelper.getGenericAsset(mockWebServer, 4)
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 3)
navigationToolbar {
}.enterURLAndEnterToBrowser(pageLinks.url) {
longClickPageObject(itemWithText("Link 3"))
verifyContextMenuForLocalHostLinks(genericURL.url)
clickContextMenuItem("Copy link")
verifySnackBarText("Link copied to clipboard")
}.openNavigationToolbar {
}.visitLinkFromClipboard {
verifyUrl(genericURL.url.toString())
}.openTabDrawer {
}.openNewTab {
}
navigationToolbar {
verifyClipboardSuggestionsAreDisplayed(shouldBeDisplayed = false)
}
}
@Test
fun verifyContextShareLink() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val genericURL = val genericURL =
@ -177,8 +157,9 @@ class ContextMenusTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243833
@Test @Test
fun verifyContextOpenImageNewTab() { fun verifyOpenImageNewTabContextMenuOptionTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val imageResource = val imageResource =
@ -196,8 +177,9 @@ class ContextMenusTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243834
@Test @Test
fun verifyContextCopyImageLocation() { fun verifyCopyImageLocationContextMenuOptionTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val imageResource = val imageResource =
@ -216,8 +198,9 @@ class ContextMenusTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243835
@Test @Test
fun verifyContextSaveImage() { fun verifySaveImageContextMenuOptionTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val imageResource = val imageResource =
@ -239,8 +222,9 @@ class ContextMenusTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/352050
@Test @Test
fun verifyContextMixedVariations() { fun verifyContextMenuLinkVariationsTest() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
val genericURL = val genericURL =
@ -262,8 +246,9 @@ class ContextMenusTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2333840
@Test @Test
fun verifyContextMixedVariationsInPDFTest() { fun verifyPDFContextMenuLinkVariationsTest() {
val genericURL = val genericURL =
TestAssetHelper.getGenericAsset(mockWebServer, 3) TestAssetHelper.getGenericAsset(mockWebServer, 3)
@ -282,8 +267,9 @@ class ContextMenusTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/832094
@Test @Test
fun verifyContextOpenLinkInAppTest() { fun verifyOpenLinkInAppContextMenuOptionTest() {
val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer)
navigationToolbar { navigationToolbar {

@ -54,8 +54,9 @@ class CrashReportingTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/308906
@Test @Test
fun closeTabCrashedReporterTest() { fun closeTabFromCrashedTabReporterTest() {
homeScreen { homeScreen {
}.openNavigationToolbar { }.openNavigationToolbar {
}.openTabCrashReporter { }.openTabCrashReporter {
@ -65,9 +66,10 @@ class CrashReportingTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2336134
@Ignore("Test failure caused by: https://github.com/mozilla-mobile/fenix/issues/19964") @Ignore("Test failure caused by: https://github.com/mozilla-mobile/fenix/issues/19964")
@Test @Test
fun restoreTabCrashedReporterTest() { fun restoreTabFromTabCrashedReporterTest() {
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen { homeScreen {
@ -81,6 +83,7 @@ class CrashReportingTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1681928
@SmokeTest @SmokeTest
@Test @Test
fun useAppWhileTabIsCrashedTest() { fun useAppWhileTabIsCrashedTest() {
@ -110,35 +113,4 @@ class CrashReportingTest {
verifySettingsButton() verifySettingsButton()
} }
} }
@SmokeTest
@Test
fun privateBrowsingUseAppWhileTabIsCrashedTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
homeScreen {
togglePrivateBrowsingModeOnOff()
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(firstWebPage.url) {
mDevice.waitForIdle()
}.openTabDrawer {
}.openNewTab {
}.submitQuery(secondWebPage.url.toString()) {
waitForPageToLoad()
}
navigationToolbar {
}.openTabCrashReporter {
verifyPageContent(tabCrashMessage)
}.openTabDrawer {
verifyExistingOpenTabs(firstWebPage.title)
verifyExistingOpenTabs(secondWebPage.title)
}.closeTabDrawer {
}.goToHomescreen {
verifyCommonMythsLink()
}.openThreeDotMenu {
verifySettingsButton()
}
}
} }

@ -88,7 +88,7 @@ class CreditCardAutofillTest {
} }
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(creditCardFormPage.url) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) {
clickPageObject(itemWithResId("cardNumber")) clickCreditCardNumberTextBox()
clickPageObject(itemWithResId("$packageName:id/select_credit_card_header")) clickPageObject(itemWithResId("$packageName:id/select_credit_card_header"))
clickPageObject( clickPageObject(
itemWithResIdContainingText( itemWithResIdContainingText(
@ -200,7 +200,7 @@ class CreditCardAutofillTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(creditCardFormPage.url) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) {
clickPageObject(itemWithResId("cardNumber")) clickCreditCardNumberTextBox()
clickPageObject(itemWithResId("$packageName:id/select_credit_card_header")) clickPageObject(itemWithResId("$packageName:id/select_credit_card_header"))
}.clickManageCreditCardsButton { }.clickManageCreditCardsButton {
}.goBackToBrowser { }.goBackToBrowser {
@ -231,7 +231,7 @@ class CreditCardAutofillTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(creditCardFormPage.url) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) {
clickPageObject(itemWithResId("cardNumber")) clickCreditCardNumberTextBox()
verifySelectCreditCardPromptExists(true) verifySelectCreditCardPromptExists(true)
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -244,7 +244,7 @@ class CreditCardAutofillTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(creditCardFormPage.url) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) {
clickPageObject(itemWithResId("cardNumber")) clickCreditCardNumberTextBox()
verifySelectCreditCardPromptExists(false) verifySelectCreditCardPromptExists(false)
} }
} }
@ -321,7 +321,7 @@ class CreditCardAutofillTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(creditCardFormPage.url) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) {
clickPageObject(itemWithResId("cardNumber")) clickCreditCardNumberTextBox()
clickPageObject(itemWithResId("$packageName:id/select_credit_card_header")) clickPageObject(itemWithResId("$packageName:id/select_credit_card_header"))
clickPageObject( clickPageObject(
itemWithResIdContainingText( itemWithResIdContainingText(
@ -408,7 +408,7 @@ class CreditCardAutofillTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(creditCardFormPage.url) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) {
clickPageObject(itemWithResId("cardNumber")) clickCreditCardNumberTextBox()
clickPageObject(itemWithResId("$packageName:id/select_credit_card_header")) clickPageObject(itemWithResId("$packageName:id/select_credit_card_header"))
verifyCreditCardSuggestion( verifyCreditCardSuggestion(
MockCreditCard1.MOCK_LAST_CARD_DIGITS, MockCreditCard1.MOCK_LAST_CARD_DIGITS,
@ -498,7 +498,7 @@ class CreditCardAutofillTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(creditCardFormPage.url) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) {
clickPageObject(itemWithResId("cardNumber")) clickCreditCardNumberTextBox()
clickPageObject(itemWithResId("$packageName:id/select_credit_card_header")) clickPageObject(itemWithResId("$packageName:id/select_credit_card_header"))
clickPageObject( clickPageObject(
itemWithResIdContainingText( itemWithResIdContainingText(
@ -549,7 +549,7 @@ class CreditCardAutofillTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(creditCardFormPage.url) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) {
clickPageObject(itemWithResId("cardNumber")) clickCreditCardNumberTextBox()
clickPageObject(itemWithResId("$packageName:id/select_credit_card_header")) clickPageObject(itemWithResId("$packageName:id/select_credit_card_header"))
clickPageObject( clickPageObject(
itemWithResIdContainingText( itemWithResIdContainingText(

@ -21,7 +21,6 @@ import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.FeatureSettingsHelperDelegate import org.mozilla.fenix.helpers.FeatureSettingsHelperDelegate
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper
@ -33,7 +32,6 @@ import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.customTabScreen import org.mozilla.fenix.ui.robots.customTabScreen
import org.mozilla.fenix.ui.robots.enhancedTrackingProtection import org.mozilla.fenix.ui.robots.enhancedTrackingProtection
import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.longClickPageObject
import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.navigationToolbar
import org.mozilla.fenix.ui.robots.notificationShade import org.mozilla.fenix.ui.robots.notificationShade
import org.mozilla.fenix.ui.robots.openEditURLView import org.mozilla.fenix.ui.robots.openEditURLView
@ -78,29 +76,10 @@ class CustomTabsTest {
featureSettingsHelper.resetAllFeatureFlags() featureSettingsHelper.resetAllFeatureFlags()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/249659
@SmokeTest @SmokeTest
@Test @Test
fun customTabsOpenExternalLinkTest() { fun verifyLoginSaveInCustomTabTest() {
val externalLinkURL = "https://mozilla-mobile.github.io/testapp/downloads"
intentReceiverActivityTestRule.launchActivity(
createCustomTabIntent(
externalLinksPWAPage.toUri().toString(),
customMenuItem,
),
)
customTabScreen {
waitForPageToLoad()
clickPageObject(itemContainingText("External link"))
waitForPageToLoad()
verifyCustomTabToolbarTitle(externalLinkURL)
}
}
@SmokeTest
@Test
fun customTabsSaveLoginTest() {
intentReceiverActivityTestRule.launchActivity( intentReceiverActivityTestRule.launchActivity(
createCustomTabIntent( createCustomTabIntent(
loginPage.toUri().toString(), loginPage.toUri().toString(),
@ -131,9 +110,9 @@ class CustomTabsTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2334762
@Test @Test
fun customTabCopyToolbarUrlTest() { fun copyCustomTabToolbarUrlTest() {
val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
intentReceiverActivityTestRule.launchActivity( intentReceiverActivityTestRule.launchActivity(
@ -161,33 +140,11 @@ class CustomTabsTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2334761
@Test
fun customTabShareTextTest() {
val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
intentReceiverActivityTestRule.launchActivity(
createCustomTabIntent(
customTabPage.url.toString(),
customMenuItem,
),
)
customTabScreen {
waitForPageToLoad()
}
browserScreen {
longClickPageObject(itemContainingText("content"))
}.clickShareSelectedText {
verifyAndroidShareLayout()
}
}
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807289") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807289")
@SmokeTest @SmokeTest
@Test @Test
fun customTabDownloadTest() { fun verifyDownloadInACustomTabTest() {
val customTabPage = "https://storage.googleapis.com/mobile_test_assets/test_app/downloads.html" val customTabPage = "https://storage.googleapis.com/mobile_test_assets/test_app/downloads.html"
val downloadFile = "web_icon.png" val downloadFile = "web_icon.png"
@ -214,10 +171,11 @@ class CustomTabsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/249644
// Verifies the main menu of a custom tab with a custom menu item // Verifies the main menu of a custom tab with a custom menu item
@SmokeTest @SmokeTest
@Test @Test
fun customTabMenuItemsTest() { fun verifyCustomTabMenuItemsTest() {
val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
intentReceiverActivityTestRule.launchActivity( intentReceiverActivityTestRule.launchActivity(
@ -241,9 +199,11 @@ class CustomTabsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/249645
// The test opens a link in a custom tab then sends it to the browser // The test opens a link in a custom tab then sends it to the browser
@SmokeTest
@Test @Test
fun openCustomTabInBrowserTest() { fun openCustomTabInFirefoxTest() {
val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
intentReceiverActivityTestRule.launchActivity( intentReceiverActivityTestRule.launchActivity(
@ -260,8 +220,9 @@ class CustomTabsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2239548
@Test @Test
fun shareCustomTabTest() { fun shareCustomTabUsingToolbarButtonTest() {
val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
intentReceiverActivityTestRule.launchActivity( intentReceiverActivityTestRule.launchActivity(
@ -276,8 +237,9 @@ class CustomTabsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/249643
@Test @Test
fun verifyCustomTabViewTest() { fun verifyCustomTabViewItemsTest() {
val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
intentReceiverActivityTestRule.launchActivity( intentReceiverActivityTestRule.launchActivity(
@ -302,8 +264,9 @@ class CustomTabsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2239544
@Test @Test
fun verifyPdfCustomTabViewTest() { fun verifyPDFViewerInACustomTabTest() {
val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 3) val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 3)
val pdfFormResource = TestAssetHelper.getPdfFormAsset(mockWebServer) val pdfFormResource = TestAssetHelper.getPdfFormAsset(mockWebServer)
@ -331,8 +294,9 @@ class CustomTabsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2239117
@Test @Test
fun verifyETPSheetAndToggleTest() { fun verifyCustomTabETPSheetAndToggleTest() {
val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val customTabPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
intentReceiverActivityTestRule.launchActivity( intentReceiverActivityTestRule.launchActivity(

@ -138,6 +138,7 @@ class DownloadTest {
assertExternalAppOpens(GOOGLE_APPS_PHOTOS) assertExternalAppOpens(GOOGLE_APPS_PHOTOS)
mDevice.pressBack() mDevice.pressBack()
mDevice.openNotification() mDevice.openNotification()
verifySystemNotificationExists("Download completed")
swipeDownloadNotification( swipeDownloadNotification(
direction = "Left", direction = "Left",
shouldDismissNotification = true, shouldDismissNotification = true,

@ -445,4 +445,25 @@ class HistoryTest {
verifySuggestionsAreNotDisplayed(activityTestRule, thirdWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, thirdWebPage.url.toString())
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903590
// Test running on beta/release builds in CI:
// caution when making changes to it, so they don't block the builds
@SmokeTest
@Test
fun noHistoryInPrivateBrowsingTest() {
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
}.togglePrivateBrowsingMode()
homeScreen {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(website.url) {
mDevice.waitForIdle()
}.openThreeDotMenu {
}.openHistory {
verifyEmptyHistoryView()
}
}
} }

@ -86,7 +86,7 @@ class HomeScreenTest {
homeScreen { }.togglePrivateBrowsingMode() homeScreen { }.togglePrivateBrowsingMode()
homeScreen { homeScreen {
verifyPrivateBrowsingHomeScreen() verifyPrivateBrowsingHomeScreenItems()
}.openCommonMythsLink { }.openCommonMythsLink {
verifyUrl("common-myths-about-private-browsing") verifyUrl("common-myths-about-private-browsing")
} }

@ -62,9 +62,10 @@ class MediaNotificationTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1347033
@SmokeTest @SmokeTest
@Test @Test
fun videoPlaybackSystemNotificationTest() { fun verifyVideoPlaybackSystemNotificationTest() {
val videoTestPage = TestAssetHelper.getVideoPageAsset(mockWebServer) val videoTestPage = TestAssetHelper.getVideoPageAsset(mockWebServer)
navigationToolbar { navigationToolbar {
@ -96,9 +97,10 @@ class MediaNotificationTest {
mDevice.pressBack() mDevice.pressBack()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2316010
@SmokeTest @SmokeTest
@Test @Test
fun audioPlaybackSystemNotificationTest() { fun verifyAudioPlaybackSystemNotificationTest() {
val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer) val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
navigationToolbar { navigationToolbar {
@ -130,6 +132,7 @@ class MediaNotificationTest {
mDevice.pressBack() mDevice.pressBack()
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903595
@Test @Test
fun mediaSystemNotificationInPrivateModeTest() { fun mediaSystemNotificationInPrivateModeTest() {
val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer) val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)

@ -103,6 +103,7 @@ class NavigationToolbarTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.toUri()) { }.enterURLAndEnterToBrowser(defaultWebPage.toUri()) {
waitForPageToLoad()
}.openSiteSecuritySheet { }.openSiteSecuritySheet {
verifyQuickActionSheet(defaultWebPage, true) verifyQuickActionSheet(defaultWebPage, true)
openSecureConnectionSubMenu(true) openSecureConnectionSubMenu(true)

@ -56,7 +56,7 @@ class NimbusMessagingHomescreenTest {
@Before @Before
fun setUp() { fun setUp() {
// Set up nimbus message // Set up nimbus message
FxNimbusMessaging.features.messaging.withInitializer { FxNimbusMessaging.features.messaging.withInitializer { _, _ ->
// FML generated objects. // FML generated objects.
Messaging( Messaging(
messages = mapOf( messages = mapOf(
@ -82,7 +82,7 @@ class NimbusMessagingHomescreenTest {
} }
// Remove some homescreen features not needed for testing // Remove some homescreen features not needed for testing
FxNimbus.features.homescreen.withInitializer { FxNimbus.features.homescreen.withInitializer { _, _ ->
// These are FML generated objects and enums // These are FML generated objects and enums
Homescreen( Homescreen(
sectionsEnabled = mapOf( sectionsEnabled = mapOf(

@ -37,6 +37,7 @@ class NoNetworkAccessStartupTests {
// Test running on beta/release builds in CI: // Test running on beta/release builds in CI:
// caution when making changes to it, so they don't block the builds // 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 // Based on STR from https://github.com/mozilla-mobile/fenix/issues/16886
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2240542
@Test @Test
fun noNetworkConnectionStartupTest() { fun noNetworkConnectionStartupTest() {
setNetworkEnabled(false) setNetworkEnabled(false)
@ -49,6 +50,7 @@ class NoNetworkAccessStartupTests {
} }
// Based on STR from https://github.com/mozilla-mobile/fenix/issues/16886 // Based on STR from https://github.com/mozilla-mobile/fenix/issues/16886
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2240722
@Test @Test
fun networkInterruptedFromBrowserToHomeTest() { fun networkInterruptedFromBrowserToHomeTest() {
val url = "example.com" val url = "example.com"
@ -66,6 +68,7 @@ class NoNetworkAccessStartupTests {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2240723
@Test @Test
fun testPageReloadAfterNetworkInterrupted() { fun testPageReloadAfterNetworkInterrupted() {
val url = "example.com" val url = "example.com"
@ -82,6 +85,7 @@ class NoNetworkAccessStartupTests {
}.refreshPage { } }.refreshPage { }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2240721
@SmokeTest @SmokeTest
@Test @Test
fun testSignInPageWithNoNetworkConnection() { fun testSignInPageWithNoNetworkConnection() {

@ -52,9 +52,10 @@ class PDFViewerTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2048140
@SmokeTest @SmokeTest
@Test @Test
fun openPDFInBrowserTest() { fun verifyPDFFileIsOpenedInTheSameTabTest() {
val genericURL = val genericURL =
getGenericAsset(mockWebServer, 3) getGenericAsset(mockWebServer, 3)
@ -62,11 +63,13 @@ class PDFViewerTest {
}.enterURLAndEnterToBrowser(genericURL.url) { }.enterURLAndEnterToBrowser(genericURL.url) {
clickPageObject(itemContainingText("PDF form file")) clickPageObject(itemContainingText("PDF form file"))
verifyPageContent("Washington Crossing the Delaware") verifyPageContent("Washington Crossing the Delaware")
verifyTabCounter("1")
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2159718
@Test @Test
fun pdfViewerOpenInAppTest() { fun verifyPDFViewerOpenInAppButtonTest() {
val genericURL = getGenericAsset(mockWebServer, 3) val genericURL = getGenericAsset(mockWebServer, 3)
navigationToolbar { navigationToolbar {
@ -78,9 +81,10 @@ class PDFViewerTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2145448
// Download PDF file using the download toolbar button // Download PDF file using the download toolbar button
@Test @Test
fun pdfViewerDownloadButtonTest() { fun verifyPDFViewerDownloadButtonTest() {
val genericURL = getGenericAsset(mockWebServer, 3) val genericURL = getGenericAsset(mockWebServer, 3)
val downloadFile = "pdfForm.pdf" val downloadFile = "pdfForm.pdf"

@ -5,27 +5,16 @@
package org.mozilla.fenix.ui package org.mozilla.fenix.ui
import androidx.core.net.toUri import androidx.core.net.toUri
import org.junit.Ignore
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.mozilla.fenix.helpers.Constants.PackageName.GMAIL_APP import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.Constants.PackageName.PHONE_APP
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.TestHelper
import org.mozilla.fenix.helpers.TestHelper.assertExternalAppOpens
import org.mozilla.fenix.helpers.TestHelper.assertNativeAppOpens
import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.ui.robots.addToHomeScreen
import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.customTabScreen import org.mozilla.fenix.ui.robots.customTabScreen
import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.navigationToolbar
import org.mozilla.fenix.ui.robots.pwaScreen import org.mozilla.fenix.ui.robots.pwaScreen
import org.mozilla.fenix.ui.robots.setPageObjectText
class PwaTest { class PwaTest {
/* Updated externalLinks.html to v2.0, /* Updated externalLinks.html to v2.0,
@ -39,6 +28,7 @@ class PwaTest {
@get:Rule @get:Rule
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/845695
@Test @Test
fun externalLinkPWATest() { fun externalLinkPWATest() {
val externalLinkURL = "https://mozilla-mobile.github.io/testapp/downloads" val externalLinkURL = "https://mozilla-mobile.github.io/testapp/downloads"
@ -59,38 +49,7 @@ class PwaTest {
} }
} }
@Test // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/845694
fun emailLinkPWATest() {
navigationToolbar {
}.enterURLAndEnterToBrowser(externalLinksPWAPage.toUri()) {
waitForPageToLoad()
verifyNotificationDotOnMainMenu()
}.openThreeDotMenu {
}.clickInstall {
clickAddAutomaticallyButton()
}.openHomeScreenShortcut(shortcutTitle) {
clickPageObject(itemContainingText("Email link"))
clickPageObject(itemWithResIdAndText("android:id/button1", "OPEN"))
assertExternalAppOpens(GMAIL_APP)
}
}
@Test
fun telephoneLinkPWATest() {
navigationToolbar {
}.enterURLAndEnterToBrowser(externalLinksPWAPage.toUri()) {
waitForPageToLoad()
verifyNotificationDotOnMainMenu()
}.openThreeDotMenu {
}.clickInstall {
clickAddAutomaticallyButton()
}.openHomeScreenShortcut(shortcutTitle) {
clickPageObject(itemContainingText("Telephone link"))
clickPageObject(itemWithResIdAndText("android:id/button1", "OPEN"))
assertNativeAppOpens(PHONE_APP, phoneLink)
}
}
@Test @Test
fun appLikeExperiencePWATest() { fun appLikeExperiencePWATest() {
navigationToolbar { navigationToolbar {
@ -109,11 +68,11 @@ class PwaTest {
} }
} }
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807273") // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/834200
@SmokeTest
@Test @Test
fun saveLoginsInPWATest() { fun installPWAFromTheMainMenuTest() {
val pwaPage = "https://mozilla-mobile.github.io/testapp/loginForm" val pwaPage = "https://mozilla-mobile.github.io/testapp/"
val shortcutTitle = "TEST_APP"
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(pwaPage.toUri()) { }.enterURLAndEnterToBrowser(pwaPage.toUri()) {
@ -121,29 +80,9 @@ class PwaTest {
}.openThreeDotMenu { }.openThreeDotMenu {
}.clickInstall { }.clickInstall {
clickAddAutomaticallyButton() clickAddAutomaticallyButton()
}.openHomeScreenShortcut(shortcutTitle) { }.openHomeScreenShortcut("TEST_APP") {
mDevice.waitForIdle() mDevice.waitForIdle()
setPageObjectText(itemWithResId("username"), "mozilla") verifyNavURLBarHidden()
setPageObjectText(itemWithResId("password"), "firefox")
clickPageObject(itemWithResId("submit"))
verifySaveLoginPromptIsDisplayed()
clickPageObject(itemWithText("Save"))
TestHelper.openAppFromExternalLink(pwaPage)
browserScreen {
}.openThreeDotMenu {
}.openSettings {
}.openLoginsAndPasswordSubMenu {
}.openSavedLogins {
verifySecurityPromptForLogins()
tapSetupLater()
verifySavedLoginsSectionUsername("mozilla")
}
addToHomeScreen {
}.searchAndOpenHomeScreenShortcut(shortcutTitle) {
verifyPrefilledPWALoginCredentials("mozilla", shortcutTitle)
}
} }
} }
} }

@ -13,6 +13,7 @@ import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.RetryTestRule
@ -63,10 +64,13 @@ class ReaderViewTest {
* - Show the toggle button in the navigation bar * - Show the toggle button in the navigation bar
* *
*/ */
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/250592
@Test @Test
fun verifyReaderViewPageMenuDetection() { fun verifyReaderModePageDetectionTest() {
val readerViewPage = val readerViewPage =
TestAssetHelper.getLoremIpsumAsset(mockWebServer) TestAssetHelper.getLoremIpsumAsset(mockWebServer)
val genericPage =
TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(readerViewPage.url) { }.enterURLAndEnterToBrowser(readerViewPage.url) {
@ -82,70 +86,17 @@ class ReaderViewTest {
navigationToolbar { navigationToolbar {
verifyReaderViewDetected(true) verifyReaderViewDetected(true)
}
}
/**
* Verify that non Reader View capable pages
*
* - Reader View toggle should not be visible in the navigation toolbar
*
*/
@Test
fun verifyNonReaderViewPageMenuNoDetection() {
var genericPage =
TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(genericPage.url) { }.enterURLAndEnterToBrowser(genericPage.url) {
mDevice.waitForIdle()
} }
navigationToolbar { navigationToolbar {
verifyReaderViewDetected(false) verifyReaderViewDetected(false)
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/250585
@SmokeTest
@Test @Test
fun verifyReaderViewToggle() { fun verifyReaderModeControlsTest() {
val readerViewPage =
TestAssetHelper.getLoremIpsumAsset(mockWebServer)
navigationToolbar {
}.enterURLAndEnterToBrowser(readerViewPage.url) {
mDevice.waitForIdle()
}
registerAndCleanupIdlingResources(
ViewVisibilityIdlingResource(
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
View.VISIBLE,
),
) {}
navigationToolbar {
verifyReaderViewDetected(true)
toggleReaderView()
mDevice.waitForIdle()
}
browserScreen {
verifyPageContent(estimatedReadingTime)
}.openThreeDotMenu {
verifyReaderViewAppearance(true)
}.closeBrowserMenuToBrowser { }
navigationToolbar {
verifyCloseReaderViewDetected(true)
toggleReaderView()
mDevice.waitForIdle()
verifyReaderViewDetected(true)
}.openThreeDotMenu {
verifyReaderViewAppearance(false)
}.closeBrowserMenuToBrowser { }
}
@Test
fun verifyReaderViewAppearanceFontToggle() {
val readerViewPage = val readerViewPage =
TestAssetHelper.getLoremIpsumAsset(mockWebServer) TestAssetHelper.getLoremIpsumAsset(mockWebServer)
@ -177,44 +128,15 @@ class ReaderViewTest {
verifyAppearanceFontSerif(true) verifyAppearanceFontSerif(true)
verifyAppearanceFontIncrease(true) verifyAppearanceFontIncrease(true)
verifyAppearanceFontDecrease(true) verifyAppearanceFontDecrease(true)
verifyAppearanceFontSize(3)
verifyAppearanceColorGroup(true)
verifyAppearanceColorDark(true)
verifyAppearanceColorLight(true)
verifyAppearanceColorSepia(true)
}.toggleSansSerif { }.toggleSansSerif {
verifyAppearanceFontIsActive("SANSSERIF") verifyAppearanceFontIsActive("SANSSERIF")
}.toggleSerif { }.toggleSerif {
verifyAppearanceFontIsActive("SERIF") verifyAppearanceFontIsActive("SERIF")
}
}
@Test
fun verifyReaderViewAppearanceFontSizeToggle() {
val readerViewPage =
TestAssetHelper.getLoremIpsumAsset(mockWebServer)
navigationToolbar {
}.enterURLAndEnterToBrowser(readerViewPage.url) {
mDevice.waitForIdle()
}
registerAndCleanupIdlingResources(
ViewVisibilityIdlingResource(
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
View.VISIBLE,
),
) {}
navigationToolbar {
verifyReaderViewDetected(true)
toggleReaderView()
mDevice.waitForIdle()
}
browserScreen {
verifyPageContent(estimatedReadingTime)
}.openThreeDotMenu {
verifyReaderViewAppearance(true)
}.openReaderViewAppearance {
verifyAppearanceFontIncrease(true)
verifyAppearanceFontDecrease(true)
verifyAppearanceFontSize(3)
}.toggleFontSizeIncrease { }.toggleFontSizeIncrease {
verifyAppearanceFontSize(4) verifyAppearanceFontSize(4)
}.toggleFontSizeIncrease { }.toggleFontSizeIncrease {
@ -227,46 +149,20 @@ class ReaderViewTest {
verifyAppearanceFontSize(4) verifyAppearanceFontSize(4)
}.toggleFontSizeDecrease { }.toggleFontSizeDecrease {
verifyAppearanceFontSize(3) verifyAppearanceFontSize(3)
}
}
@Test
fun verifyReaderViewAppearanceColorSchemeChange() {
val readerViewPage =
TestAssetHelper.getLoremIpsumAsset(mockWebServer)
navigationToolbar {
}.enterURLAndEnterToBrowser(readerViewPage.url) {
mDevice.waitForIdle()
}
registerAndCleanupIdlingResources(
ViewVisibilityIdlingResource(
activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
View.VISIBLE,
),
) {}
navigationToolbar {
verifyReaderViewDetected(true)
toggleReaderView()
mDevice.waitForIdle()
}
browserScreen {
verifyPageContent(estimatedReadingTime)
}.openThreeDotMenu {
verifyReaderViewAppearance(true)
}.openReaderViewAppearance {
verifyAppearanceColorDark(true)
verifyAppearanceColorLight(true)
verifyAppearanceColorSepia(true)
}.toggleColorSchemeChangeDark { }.toggleColorSchemeChangeDark {
verifyAppearanceColorSchemeChange("DARK") verifyAppearanceColorSchemeChange("DARK")
}.toggleColorSchemeChangeSepia { }.toggleColorSchemeChangeSepia {
verifyAppearanceColorSchemeChange("SEPIA") verifyAppearanceColorSchemeChange("SEPIA")
}.toggleColorSchemeChangeLight { }.toggleColorSchemeChangeLight {
verifyAppearanceColorSchemeChange("LIGHT") verifyAppearanceColorSchemeChange("LIGHT")
}.closeAppearanceMenu {
}
navigationToolbar {
toggleReaderView()
mDevice.waitForIdle()
verifyReaderViewDetected(true)
}.openThreeDotMenu {
verifyReaderViewAppearance(false)
} }
} }
} }

@ -54,36 +54,7 @@ class RecentlyClosedTabsTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// This test verifies the Recently Closed Tabs List and items // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1065414
@Test
fun verifyRecentlyClosedTabsListTest() {
val website = getGenericAsset(mockWebServer, 1)
homeScreen {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(website.url) {
mDevice.waitForIdle()
}.openComposeTabDrawer(activityTestRule) {
closeTab()
}
homeScreen {
}.openThreeDotMenu {
}.openHistory {
}.openRecentlyClosedTabs {
waitForListToExist()
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(
activityTestRule.activity.findViewById(R.id.recently_closed_list),
1,
),
) {
verifyRecentlyClosedTabsMenuView()
}
verifyRecentlyClosedTabsPageTitle("Test_Page_1")
verifyRecentlyClosedTabsUrl(website.url)
}
}
// Verifies that a recently closed item is properly opened // Verifies that a recently closed item is properly opened
@SmokeTest @SmokeTest
@Test @Test
@ -106,12 +77,15 @@ class RecentlyClosedTabsTest {
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.recently_closed_list), 1), RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.recently_closed_list), 1),
) { ) {
verifyRecentlyClosedTabsMenuView() verifyRecentlyClosedTabsMenuView()
verifyRecentlyClosedTabsPageTitle("Test_Page_1")
verifyRecentlyClosedTabsUrl(website.url)
} }
}.clickRecentlyClosedItem("Test_Page_1") { }.clickRecentlyClosedItem("Test_Page_1") {
verifyUrl(website.url.toString()) verifyUrl(website.url.toString())
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2195812
// Verifies that tapping the "x" button removes a recently closed item from the list // Verifies that tapping the "x" button removes a recently closed item from the list
@SmokeTest @SmokeTest
@Test @Test
@ -140,8 +114,9 @@ class RecentlyClosedTabsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1605515
@Test @Test
fun openInNewTabRecentlyClosedTabsTest() { fun openMultipleRecentlyClosedTabsTest() {
val firstPage = getGenericAsset(mockWebServer, 1) val firstPage = getGenericAsset(mockWebServer, 1)
val secondPage = getGenericAsset(mockWebServer, 2) val secondPage = getGenericAsset(mockWebServer, 2)
@ -174,8 +149,9 @@ class RecentlyClosedTabsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2198690
@Test @Test
fun openInPrivateTabRecentlyClosedTabsTest() { fun openRecentlyClosedTabsInPrivateBrowsingTest() {
val firstPage = getGenericAsset(mockWebServer, 1) val firstPage = getGenericAsset(mockWebServer, 1)
val secondPage = getGenericAsset(mockWebServer, 2) val secondPage = getGenericAsset(mockWebServer, 2)
@ -208,6 +184,7 @@ class RecentlyClosedTabsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1605514
@Test @Test
fun shareMultipleRecentlyClosedTabsTest() { fun shareMultipleRecentlyClosedTabsTest() {
val firstPage = getGenericAsset(mockWebServer, 1) val firstPage = getGenericAsset(mockWebServer, 1)
@ -237,8 +214,9 @@ class RecentlyClosedTabsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1065438
@Test @Test
fun privateBrowsingNotSavedInRecentlyClosedTabsTest() { fun closedPrivateTabsAreNotSavedInRecentlyClosedTabsTest() {
val firstPage = getGenericAsset(mockWebServer, 1) val firstPage = getGenericAsset(mockWebServer, 1)
val secondPage = getGenericAsset(mockWebServer, 2) val secondPage = getGenericAsset(mockWebServer, 2)
@ -260,8 +238,9 @@ class RecentlyClosedTabsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1065439
@Test @Test
fun deleteHistoryClearsRecentlyClosedTabsListTest() { fun deletingBrowserHistoryClearsRecentlyClosedTabsListTest() {
val firstPage = getGenericAsset(mockWebServer, 1) val firstPage = getGenericAsset(mockWebServer, 1)
val secondPage = getGenericAsset(mockWebServer, 2) val secondPage = getGenericAsset(mockWebServer, 2)

@ -32,6 +32,7 @@ import org.mozilla.fenix.helpers.MockBrowserDataHelper.createTabItem
import org.mozilla.fenix.helpers.MockBrowserDataHelper.setCustomSearchEngine import org.mozilla.fenix.helpers.MockBrowserDataHelper.setCustomSearchEngine
import org.mozilla.fenix.helpers.SearchDispatcher import org.mozilla.fenix.helpers.SearchDispatcher
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset 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.appContext
import org.mozilla.fenix.helpers.TestHelper.assertNativeAppOpens import org.mozilla.fenix.helpers.TestHelper.assertNativeAppOpens
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
@ -49,6 +50,7 @@ import org.mozilla.fenix.ui.robots.longClickPageObject
import org.mozilla.fenix.ui.robots.multipleSelectionToolbar import org.mozilla.fenix.ui.robots.multipleSelectionToolbar
import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.navigationToolbar
import org.mozilla.fenix.ui.robots.searchScreen import org.mozilla.fenix.ui.robots.searchScreen
import java.util.Locale
/** /**
* Tests for verifying the search fragment * Tests for verifying the search fragment
@ -93,8 +95,9 @@ class SearchTest {
searchMockServer.shutdown() searchMockServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154189
@Test @Test
fun searchBarItemsTest() { fun verifySearchBarItemsTest() {
navigationToolbar { navigationToolbar {
verifyDefaultSearchEngine("Google") verifyDefaultSearchEngine("Google")
verifySearchBarPlaceholder("Search or enter address") verifySearchBarPlaceholder("Search or enter address")
@ -109,8 +112,9 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154190
@Test @Test
fun searchSelectorMenuItemsTest() { fun verifySearchSelectorMenuItemsTest() {
homeScreen { homeScreen {
}.openSearch { }.openSearch {
verifySearchView() verifySearchView()
@ -123,8 +127,9 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154194
@Test @Test
fun searchPlaceholderForDefaultEnginesTest() { fun verifySearchPlaceholderForGeneralDefaultSearchEnginesTest() {
generalEnginesList.forEach { generalEnginesList.forEach {
homeScreen { homeScreen {
}.openSearch { }.openSearch {
@ -140,8 +145,9 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154195
@Test @Test
fun searchPlaceholderForOtherGeneralSearchEnginesTest() { fun verifySearchPlaceholderForNotDefaultGeneralSearchEnginesTest() {
val generalEnginesList = listOf("DuckDuckGo", "Bing") val generalEnginesList = listOf("DuckDuckGo", "Bing")
generalEnginesList.forEach { generalEnginesList.forEach {
@ -154,8 +160,9 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154196
@Test @Test
fun searchPlaceholderForTopicSearchEngineTest() { fun verifySearchPlaceholderForTopicSpecificSearchEnginesTest() {
val topicEnginesList = listOf("Amazon.com", "Wikipedia", "eBay") val topicEnginesList = listOf("Amazon.com", "Wikipedia", "eBay")
topicEnginesList.forEach { topicEnginesList.forEach {
@ -168,9 +175,10 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1059459
@SmokeTest @SmokeTest
@Test @Test
fun scanButtonDenyPermissionTest() { fun verifyQRScanningCameraAccessDialogTest() {
val cameraManager = appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager val cameraManager = appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager
assumeTrue(cameraManager.cameraIdList.isNotEmpty()) assumeTrue(cameraManager.cameraIdList.isNotEmpty())
@ -189,9 +197,10 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/235397
@SmokeTest @SmokeTest
@Test @Test
fun scanButtonAllowPermissionTest() { fun scanQRCodeToOpenAWebpageTest() {
val cameraManager = appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager val cameraManager = appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager
assumeTrue(cameraManager.cameraIdList.isNotEmpty()) assumeTrue(cameraManager.cameraIdList.isNotEmpty())
@ -203,8 +212,9 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154191
@Test @Test
fun scanButtonAvailableOnlyForGeneralSearchEnginesTest() { fun verifyScanButtonAvailableOnlyForGeneralSearchEnginesTest() {
generalEnginesList.forEach { generalEnginesList.forEach {
homeScreen { homeScreen {
}.openSearch { }.openSearch {
@ -224,10 +234,11 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/235395
// Verifies a temporary change of search engine from the Search shortcut menu // Verifies a temporary change of search engine from the Search shortcut menu
@SmokeTest @SmokeTest
@Test @Test
fun selectSearchEnginesShortcutTest() { fun searchEnginesCanBeChangedTemporarilyFromSearchSelectorMenuTest() {
val enginesList = listOf("DuckDuckGo", "Google", "Amazon.com", "Wikipedia", "Bing", "eBay") val enginesList = listOf("DuckDuckGo", "Google", "Amazon.com", "Wikipedia", "Bing", "eBay")
enginesList.forEach { enginesList.forEach {
@ -243,8 +254,9 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/233589
@Test @Test
fun accessSearchSettingFromSearchSelectorMenuTest() { fun defaultSearchEnginesCanBeSetFromSearchSelectorMenuTest() {
searchScreen { searchScreen {
clickSearchSelectorButton() clickSearchSelectorButton()
}.clickSearchEngineSettings { }.clickSearchEngineSettings {
@ -260,8 +272,9 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/522918
@Test @Test
fun clearSearchTest() { fun verifyClearSearchButtonTest() {
homeScreen { homeScreen {
}.openSearch { }.openSearch {
typeSearch(queryString) typeSearch(queryString)
@ -270,10 +283,11 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1623441
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704") @Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
@SmokeTest @SmokeTest
@Test @Test
fun searchGroupShowsInRecentlyVisitedTest() { fun searchResultsOpenedInNewTabsGenerateSearchGroupsTest() {
// setting our custom mockWebServer search URL // setting our custom mockWebServer search URL
val searchEngineName = "TestSearchEngine" val searchEngineName = "TestSearchEngine"
setCustomSearchEngine(searchMockServer, searchEngineName) setCustomSearchEngine(searchMockServer, searchEngineName)
@ -298,9 +312,10 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1592229
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704") @Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
@Test @Test
fun verifySearchGroupHistoryWithNoDuplicatesTest() { fun verifyAPageIsAddedToASearchGroupOnlyOnceTest() {
val firstPageUrl = getGenericAsset(searchMockServer, 1).url val firstPageUrl = getGenericAsset(searchMockServer, 1).url
val secondPageUrl = getGenericAsset(searchMockServer, 2).url val secondPageUrl = getGenericAsset(searchMockServer, 2).url
val originPageUrl = val originPageUrl =
@ -343,9 +358,10 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1591782
@Ignore("Failing due to known bug, see https://github.com/mozilla-mobile/fenix/issues/23818") @Ignore("Failing due to known bug, see https://github.com/mozilla-mobile/fenix/issues/23818")
@Test @Test
fun searchGroupGeneratedInTheSameTabTest() { fun searchGroupIsGeneratedWhenNavigatingInTheSameTabTest() {
// setting our custom mockWebServer search URL // setting our custom mockWebServer search URL
val searchEngineName = "TestSearchEngine" val searchEngineName = "TestSearchEngine"
setCustomSearchEngine(searchMockServer, searchEngineName) setCustomSearchEngine(searchMockServer, searchEngineName)
@ -366,9 +382,10 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1591781
@SmokeTest @SmokeTest
@Test @Test
fun noSearchGroupFromPrivateBrowsingTest() { fun searchGroupIsNotGeneratedForLinksOpenedInPrivateTabsTest() {
// setting our custom mockWebServer search URL // setting our custom mockWebServer search URL
val searchEngineName = "TestSearchEngine" val searchEngineName = "TestSearchEngine"
setCustomSearchEngine(searchMockServer, searchEngineName) setCustomSearchEngine(searchMockServer, searchEngineName)
@ -397,10 +414,11 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1592269
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704") @Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
@SmokeTest @SmokeTest
@Test @Test
fun deleteItemsFromSearchGroupHistoryTest() { fun deleteIndividualHistoryItemsFromSearchGroupTest() {
val firstPageUrl = getGenericAsset(searchMockServer, 1).url val firstPageUrl = getGenericAsset(searchMockServer, 1).url
val secondPageUrl = getGenericAsset(searchMockServer, 2).url val secondPageUrl = getGenericAsset(searchMockServer, 2).url
// setting our custom mockWebServer search URL // setting our custom mockWebServer search URL
@ -439,9 +457,10 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1592242
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704") @Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
@Test @Test
fun deleteSearchGroupFromHistoryTest() { fun deleteSearchGroupFromHomeScreenTest() {
val firstPageUrl = getGenericAsset(searchMockServer, 1).url val firstPageUrl = getGenericAsset(searchMockServer, 1).url
// setting our custom mockWebServer search URL // setting our custom mockWebServer search URL
val searchEngineName = "TestSearchEngine" val searchEngineName = "TestSearchEngine"
@ -479,9 +498,10 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1592235
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704") @Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
@Test @Test
fun reopenTabsFromSearchGroupTest() { fun openAPageFromHomeScreenSearchGroupTest() {
val firstPageUrl = getGenericAsset(searchMockServer, 1).url val firstPageUrl = getGenericAsset(searchMockServer, 1).url
val secondPageUrl = getGenericAsset(searchMockServer, 2).url val secondPageUrl = getGenericAsset(searchMockServer, 2).url
// setting our custom mockWebServer search URL // setting our custom mockWebServer search URL
@ -526,9 +546,10 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1592238
@Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704") @Ignore("Test run timing out: https://github.com/mozilla-mobile/fenix/issues/27704")
@Test @Test
fun sharePageFromASearchGroupTest() { fun shareAPageFromHomeScreenSearchGroupTest() {
val firstPageUrl = getGenericAsset(searchMockServer, 1).url val firstPageUrl = getGenericAsset(searchMockServer, 1).url
// setting our custom mockWebServer search URL // setting our custom mockWebServer search URL
val searchEngineName = "TestSearchEngine" val searchEngineName = "TestSearchEngine"
@ -564,6 +585,7 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1232633
// Default search code for Google-US // Default search code for Google-US
@Test @Test
fun defaultSearchCodeGoogleUS() { fun defaultSearchCodeGoogleUS() {
@ -584,6 +606,7 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1232637
// Default search code for Bing-US // Default search code for Bing-US
@Test @Test
fun defaultSearchCodeBingUS() { fun defaultSearchCodeBingUS() {
@ -603,10 +626,17 @@ class SearchTest {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openHistory { }.openHistory {
// Full URL no longer visible in the nav bar, so we'll check the history record // Full URL no longer visible in the nav bar, so we'll check the history record
verifyHistoryItemExists(shouldExist = true, searchEngineCodes["Bing"]!!) // A search group is sometimes created when searching with Bing (probably redirects)
try {
verifyHistoryItemExists(shouldExist = true, searchEngineCodes["Bing"]!!)
} catch (e: AssertionError) {
openSearchGroup(queryString)
verifyHistoryItemExists(shouldExist = true, searchEngineCodes["Bing"]!!)
}
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1232638
// Default search code for DuckDuckGo-US // Default search code for DuckDuckGo-US
@Test @Test
fun defaultSearchCodeDuckDuckGoUS() { fun defaultSearchCodeDuckDuckGoUS() {
@ -635,9 +665,10 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154215
@SmokeTest @SmokeTest
@Test @Test
fun verifySearchHistoryWithBrowsingDataTest() { fun verifyHistorySearchWithBrowsingHistoryTest() {
val firstPageUrl = getGenericAsset(searchMockServer, 1) val firstPageUrl = getGenericAsset(searchMockServer, 1)
val secondPageUrl = getGenericAsset(searchMockServer, 2) val secondPageUrl = getGenericAsset(searchMockServer, 2)
@ -708,6 +739,7 @@ class SearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2230212
@SmokeTest @SmokeTest
@Test @Test
fun searchHistoryNotRememberedInPrivateBrowsingTest() { fun searchHistoryNotRememberedInPrivateBrowsingTest() {
@ -753,4 +785,29 @@ class SearchTest {
) )
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1232631
// Expected for app language set to Arabic
@Test
fun verifySearchEnginesFunctionalityUsingRTLLocaleTest() {
val arabicLocale = Locale("ar", "AR")
TestHelper.runWithSystemLocaleChanged(arabicLocale, activityTestRule.activityRule) {
homeScreen {
}.openSearch {
verifyTranslatedFocusedNavigationToolbar("ابحث أو أدخِل عنوانا")
clickSearchSelectorButton()
verifySearchShortcutListContains(
"Google",
"Bing",
"Amazon.com",
"DuckDuckGo",
"ويكيبيديا (ar)",
)
selectTemporarySearchMethod("ويكيبيديا (ar)")
}.submitQuery("firefox") {
verifyUrl("firefox")
}
}
}
} }

@ -71,7 +71,9 @@ class SettingsAdvancedTest {
verifyExternalDownloadManagerButton() verifyExternalDownloadManagerButton()
verifyExternalDownloadManagerToggle(false) verifyExternalDownloadManagerToggle(false)
verifyLeakCanaryButton() verifyLeakCanaryButton()
verifyLeakCanaryToggle(true) // LeakCanary is disabled in UI tests.
// See BuildConfig.LEAKCANARY.
verifyLeakCanaryToggle(false)
verifyRemoteDebuggingButton() verifyRemoteDebuggingButton()
verifyRemoteDebuggingToggle(false) verifyRemoteDebuggingToggle(false)
} }
@ -222,7 +224,10 @@ class SettingsAdvancedTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(externalLinksPage.url) { }.enterURLAndEnterToBrowser(externalLinksPage.url) {
clickPageObject(youTubeFullLink) clickPageObject(youTubeFullLink)
verifyPrivateBrowsingOpenLinkInAnotherAppPrompt("youtube") verifyPrivateBrowsingOpenLinkInAnotherAppPrompt(
url = "youtube",
pageObject = youTubeFullLink,
)
clickPageObject(itemWithResIdAndText("android:id/button2", "CANCEL")) clickPageObject(itemWithResIdAndText("android:id/button2", "CANCEL"))
waitForPageToLoad() waitForPageToLoad()
verifyUrl("youtube") verifyUrl("youtube")
@ -256,7 +261,10 @@ class SettingsAdvancedTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(externalLinksPage.url) { }.enterURLAndEnterToBrowser(externalLinksPage.url) {
clickPageObject(youTubeSchemaLink) clickPageObject(youTubeSchemaLink)
verifyPrivateBrowsingOpenLinkInAnotherAppPrompt("youtube") verifyPrivateBrowsingOpenLinkInAnotherAppPrompt(
url = "youtube",
pageObject = youTubeSchemaLink,
)
clickPageObject(itemWithResIdAndText("android:id/button1", "OPEN")) clickPageObject(itemWithResIdAndText("android:id/button1", "OPEN"))
mDevice.waitForIdle() mDevice.waitForIdle()
assertYoutubeAppOpens() assertYoutubeAppOpens()

@ -14,6 +14,7 @@ import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestHelper import org.mozilla.fenix.helpers.TestHelper
import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.restartApp
import org.mozilla.fenix.ui.robots.addToHomeScreen import org.mozilla.fenix.ui.robots.addToHomeScreen
import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.homeScreen
@ -54,8 +55,9 @@ class SettingsPrivateBrowsingTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/420086
@Test @Test
fun openExternalLinksInPrivateTest() { fun launchLinksInAPrivateTabTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
@ -82,8 +84,9 @@ class SettingsPrivateBrowsingTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/555776
@Test @Test
fun launchPageShortcutInPrivateModeTest() { fun launchPageShortcutInPrivateBrowsingTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
setOpenLinksInPrivateOn() setOpenLinksInPrivateOn()
@ -100,9 +103,11 @@ class SettingsPrivateBrowsingTest {
mDevice.waitForIdle() mDevice.waitForIdle()
// We need to close the existing tab here, to open a different session // We need to close the existing tab here, to open a different session
TestHelper.restartApp(activityTestRule) restartApp(activityTestRule)
browserScreen { browserScreen {
}.openTabDrawer { }.openTabDrawer {
verifyNormalModeSelected()
closeTab() closeTab()
} }
@ -110,39 +115,15 @@ class SettingsPrivateBrowsingTest {
}.searchAndOpenHomeScreenShortcut(pageShortcutName) { }.searchAndOpenHomeScreenShortcut(pageShortcutName) {
}.openTabDrawer { }.openTabDrawer {
verifyPrivateModeSelected() verifyPrivateModeSelected()
closeTab()
} }
}
@Test
fun launchLinksInPrivateToggleOffStateDoesntChangeTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
setOpenLinksInPrivateOn()
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
}.openThreeDotMenu {
expandMenu()
}.openAddToHomeScreen {
addShortcutName(pageShortcutName)
clickAddShortcutButton()
clickAddAutomaticallyButton()
}.openHomeScreenShortcut(pageShortcutName) {
}.goToHomescreen { }
setOpenLinksInPrivateOff() setOpenLinksInPrivateOff()
TestHelper.restartApp(activityTestRule)
mDevice.waitForIdle()
addToHomeScreen { addToHomeScreen {
}.searchAndOpenHomeScreenShortcut(pageShortcutName) { }.searchAndOpenHomeScreenShortcut(pageShortcutName) {
}.openTabDrawer { }.openTabDrawer {
verifyNormalModeSelected() verifyNormalModeSelected()
}.closeTabDrawer {
}.openThreeDotMenu {
}.openSettings {
}.openPrivateBrowsingSubMenu {
verifyOpenLinksInPrivateTabOff()
} }
} }

@ -29,6 +29,7 @@ import org.mozilla.fenix.helpers.TestHelper.setTextToClipBoard
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
import org.mozilla.fenix.ui.robots.EngineShortcut import org.mozilla.fenix.ui.robots.EngineShortcut
import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
import org.mozilla.fenix.ui.robots.searchScreen import org.mozilla.fenix.ui.robots.searchScreen
import java.util.Locale import java.util.Locale
@ -65,8 +66,9 @@ class SettingsSearchTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2203333
@Test @Test
fun searchSettingsItemsTest() { fun verifySearchSettingsMenuItemsTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -89,8 +91,9 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2203307
@Test @Test
fun defaultSearchEnginesSettingsItemsTest() { fun verifyDefaultSearchEnginesSettingsItemsTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -103,9 +106,10 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2203308
@SmokeTest @SmokeTest
@Test @Test
fun selectNewDefaultSearchEngine() { fun verifyTheDefaultSearchEngineCanBeChangedTest() {
// Goes through the settings and changes the default search engine, then verifies it has changed. // Goes through the settings and changes the default search engine, then verifies it has changed.
defaultSearchEngineList.forEach { defaultSearchEngineList.forEach {
homeScreen { homeScreen {
@ -122,8 +126,9 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/233586
@Test @Test
fun toggleSearchAutocomplete() { fun verifyUrlAutocompleteToggleTest() {
homeScreen { homeScreen {
}.openSearch { }.openSearch {
typeSearch("mo") typeSearch("mo")
@ -143,8 +148,9 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/361817
@Test @Test
fun toggleOffHistorySearchSuggestionsTest() { fun disableSearchBrowsingHistorySuggestionsToggleTest() {
val websiteURL = getGenericAsset(mockWebServer, 1).url.toString() val websiteURL = getGenericAsset(mockWebServer, 1).url.toString()
createHistoryItem(websiteURL) createHistoryItem(websiteURL)
@ -168,8 +174,9 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/412926
@Test @Test
fun toggleOffBookmarksSearchSuggestionsTest() { fun disableSearchBookmarksToggleTest() {
val website = getGenericAsset(mockWebServer, 1) val website = getGenericAsset(mockWebServer, 1)
createBookmarkItem(website.url.toString(), website.title, 1u) createBookmarkItem(website.url.toString(), website.title, 1u)
@ -196,10 +203,11 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2203309
// Verifies setting as default a customized search engine name and URL // Verifies setting as default a customized search engine name and URL
@SmokeTest @SmokeTest
@Test @Test
fun addCustomDefaultSearchEngineTest() { fun verifyCustomSearchEngineCanBeAddedFromSearchEngineMenuTest() {
val customSearchEngine = object { val customSearchEngine = object {
val title = "TestSearchEngine" val title = "TestSearchEngine"
val url = "http://localhost:${searchMockServer.port}/searchResults.html?search=%s" val url = "http://localhost:${searchMockServer.port}/searchResults.html?search=%s"
@ -234,8 +242,9 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2203335
@Test @Test
fun addSearchEngineToManageShortcutsListTest() { fun addCustomSearchEngineToManageShortcutsListTest() {
val customSearchEngine = object { val customSearchEngine = object {
val title = "TestSearchEngine" val title = "TestSearchEngine"
val url = "http://localhost:${searchMockServer.port}/searchResults.html?search=%s" val url = "http://localhost:${searchMockServer.port}/searchResults.html?search=%s"
@ -256,8 +265,9 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2203343
@Test @Test
fun addSearchEngineLearnMoreLinksTest() { fun verifyLearnMoreLinksFromAddSearchEngineSectionTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -280,6 +290,7 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2203310
@Test @Test
fun editCustomSearchEngineTest() { fun editCustomSearchEngineTest() {
val customSearchEngine = object { val customSearchEngine = object {
@ -309,9 +320,10 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2203312
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1848623") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1848623")
@Test @Test
fun errorForInvalidSearchEngineStringsTest() { fun verifyErrorMessagesForInvalidSearchEngineUrlsTest() {
val customSearchEngine = object { val customSearchEngine = object {
val title = "TestSearchEngine" val title = "TestSearchEngine"
val badTemplateUrl = "http://localhost:${searchMockServer.port}/searchResults.html?search=" val badTemplateUrl = "http://localhost:${searchMockServer.port}/searchResults.html?search="
@ -341,6 +353,7 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2203313
@Test @Test
fun deleteCustomSearchEngineTest() { fun deleteCustomSearchEngineTest() {
val customSearchEngineTitle = "TestSearchEngine" val customSearchEngineTitle = "TestSearchEngine"
@ -375,6 +388,7 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2203339
@Test @Test
fun deleteCustomSearchShortcutTest() { fun deleteCustomSearchShortcutTest() {
val customSearchEngineTitle = "TestSearchEngine" val customSearchEngineTitle = "TestSearchEngine"
@ -402,13 +416,14 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/233588
// Test running on beta/release builds in CI: // Test running on beta/release builds in CI:
// caution when making changes to it, so they don't block the builds // 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. // 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") @Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/23817")
@SmokeTest @SmokeTest
@Test @Test
fun toggleSearchSuggestionsTest() { fun verifyShowSearchSuggestionsToggleTest() {
homeScreen { homeScreen {
}.openSearch { }.openSearch {
typeSearch("mozilla ") typeSearch("mozilla ")
@ -430,9 +445,10 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/464420
// Tests the "Don't allow" option from private mode search suggestions onboarding dialog // Tests the "Don't allow" option from private mode search suggestions onboarding dialog
@Test @Test
fun blockSearchSuggestionsInPrivateModeOnboardingTest() { fun doNotAllowSearchSuggestionsInPrivateBrowsingTest() {
homeScreen { homeScreen {
togglePrivateBrowsingModeOnOff() togglePrivateBrowsingModeOnOff()
}.openSearch { }.openSearch {
@ -443,9 +459,10 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1957063
// Tests the "Allow" option from private mode search suggestions onboarding dialog // Tests the "Allow" option from private mode search suggestions onboarding dialog
@Test @Test
fun allowSearchSuggestionsInPrivateModeOnboardingTest() { fun allowSearchSuggestionsInPrivateBrowsingTest() {
homeScreen { homeScreen {
togglePrivateBrowsingModeOnOff() togglePrivateBrowsingModeOnOff()
}.openSearch { }.openSearch {
@ -470,8 +487,9 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/888673
@Test @Test
fun toggleVoiceSearchTest() { fun verifyShowVoiceSearchToggleTest() {
homeScreen { homeScreen {
}.openSearch { }.openSearch {
verifyVoiceSearchButtonVisibility(true) verifyVoiceSearchButtonVisibility(true)
@ -489,8 +507,10 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/412927
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268")
@Test @Test
fun toggleShowClipboardSuggestionsTest() { fun verifyShowClipboardSuggestionsToggleTest() {
val link = "https://www.mozilla.org/en-US/" val link = "https://www.mozilla.org/en-US/"
setTextToClipBoard(appContext, link) setTextToClipBoard(appContext, link)
@ -498,6 +518,21 @@ class SettingsSearchTest {
}.openNavigationToolbar { }.openNavigationToolbar {
verifyClipboardSuggestionsAreDisplayed(link, true) verifyClipboardSuggestionsAreDisplayed(link, true)
}.visitLinkFromClipboard { }.visitLinkFromClipboard {
waitForPageToLoad()
}.openTabDrawer {
}.openNewTab {
}
navigationToolbar {
// After visiting the link from clipboard it shouldn't be displayed again
verifyClipboardSuggestionsAreDisplayed(shouldBeDisplayed = false)
}.goBackToHomeScreen {
setTextToClipBoard(appContext, link)
}.openTabDrawer {
}.openNewTab {
}
navigationToolbar {
verifyClipboardSuggestionsAreDisplayed(link, true)
}.goBackToHomeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
}.openSearchSubMenu { }.openSearchSubMenu {
@ -507,37 +542,17 @@ class SettingsSearchTest {
exitMenu() exitMenu()
} }
homeScreen { homeScreen {
}.openNavigationToolbar { }.openTabDrawer {
verifyClipboardSuggestionsAreDisplayed(link, false) }.openNewTab {
} }
} navigationToolbar {
verifyClipboardSuggestionsAreDisplayed(link, false)
// Expected for app language set to Arabic
@Test
fun verifySearchEnginesWithRTLLocale() {
val arabicLocale = Locale("ar", "AR")
runWithSystemLocaleChanged(arabicLocale, activityTestRule.activityRule) {
homeScreen {
}.openSearch {
verifyTranslatedFocusedNavigationToolbar("ابحث أو أدخِل عنوانا")
clickSearchSelectorButton()
verifySearchShortcutListContains(
"Google",
"Bing",
"Amazon.com",
"DuckDuckGo",
"ويكيبيديا (ar)",
)
selectTemporarySearchMethod("ويكيبيديا (ar)")
}.submitQuery("firefox") {
verifyUrl("firefox")
}
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2233337
@Test @Test
fun searchEnginesListRespectLocaleTest() { fun verifyTheSearchEnginesListsRespectTheLocaleTest() {
runWithSystemLocaleChanged(Locale.CHINA, activityTestRule.activityRule) { runWithSystemLocaleChanged(Locale.CHINA, activityTestRule.activityRule) {
// Checking search engines for CH locale // Checking search engines for CH locale
homeScreen { homeScreen {
@ -567,14 +582,15 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2203334
@Test @Test
fun manageSearchShortcutsSettingsItemsTest() { fun verifyManageSearchShortcutsSettingsItemsTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
}.openSearchSubMenu { }.openSearchSubMenu {
openManageShortcutsMenu() openManageShortcutsMenu()
verifyToolbarText("Manage search shortcuts") verifyToolbarText("Manage alternative search engines")
verifyEnginesShortcutsListHeader() verifyEnginesShortcutsListHeader()
verifyManageShortcutsList(activityTestRule) verifyManageShortcutsList(activityTestRule)
verifySearchShortcutChecked( verifySearchShortcutChecked(
@ -590,9 +606,10 @@ class SettingsSearchTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2203340
@SmokeTest @SmokeTest
@Test @Test
fun changeSearchShortcutsListTest() { fun verifySearchShortcutChangesAreReflectedInSearchSelectorMenuTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {

@ -78,9 +78,10 @@ class SitePermissionsTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2334295
@SmokeTest @SmokeTest
@Test @Test
fun audioVideoPermissionChoiceOnEachRequestTest() { fun audioVideoPermissionWithoutRememberingTheDecisionTest() {
assumeTrue(cameraManager.cameraIdList.isNotEmpty()) assumeTrue(cameraManager.cameraIdList.isNotEmpty())
navigationToolbar { navigationToolbar {
@ -96,10 +97,10 @@ class SitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2334294
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1815395") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1815395")
@SmokeTest
@Test @Test
fun rememberBlockAudioVideoPermissionChoiceTest() { fun blockAudioVideoPermissionRememberingTheDecisionTest() {
assumeTrue(cameraManager.cameraIdList.isNotEmpty()) assumeTrue(cameraManager.cameraIdList.isNotEmpty())
assumeTrue(micManager.microphones.isNotEmpty()) assumeTrue(micManager.microphones.isNotEmpty())
@ -120,10 +121,10 @@ class SitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/251388
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1815395") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1815395")
@SmokeTest
@Test @Test
fun rememberAllowAudioVideoPermissionChoiceTest() { fun allowAudioVideoPermissionRememberingTheDecisionTest() {
assumeTrue(cameraManager.cameraIdList.isNotEmpty()) assumeTrue(cameraManager.cameraIdList.isNotEmpty())
assumeTrue(micManager.microphones.isNotEmpty()) assumeTrue(micManager.microphones.isNotEmpty())
@ -144,8 +145,9 @@ class SitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2334189
@Test @Test
fun microphonePermissionChoiceOnEachRequestTest() { fun microphonePermissionWithoutRememberingTheDecisionTest() {
assumeTrue(micManager.microphones.isNotEmpty()) assumeTrue(micManager.microphones.isNotEmpty())
navigationToolbar { navigationToolbar {
@ -161,9 +163,10 @@ class SitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2334190
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1815395") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1815395")
@Test @Test
fun rememberBlockMicrophonePermissionChoiceTest() { fun blockMicrophonePermissionRememberingTheDecisionTest() {
assumeTrue(micManager.microphones.isNotEmpty()) assumeTrue(micManager.microphones.isNotEmpty())
navigationToolbar { navigationToolbar {
@ -183,9 +186,10 @@ class SitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/251387
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1815395") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1815395")
@Test @Test
fun rememberAllowMicrophonePermissionChoiceTest() { fun allowMicrophonePermissionRememberingTheDecisionTest() {
assumeTrue(micManager.microphones.isNotEmpty()) assumeTrue(micManager.microphones.isNotEmpty())
navigationToolbar { navigationToolbar {
@ -205,8 +209,9 @@ class SitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2334076
@Test @Test
fun cameraPermissionChoiceOnEachRequestTest() { fun cameraPermissionWithoutRememberingDecisionTest() {
assumeTrue(cameraManager.cameraIdList.isNotEmpty()) assumeTrue(cameraManager.cameraIdList.isNotEmpty())
navigationToolbar { navigationToolbar {
@ -222,9 +227,10 @@ class SitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2334077
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1815395") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1815395")
@Test @Test
fun rememberBlockCameraPermissionChoiceTest() { fun blockCameraPermissionRememberingTheDecisionTest() {
assumeTrue(cameraManager.cameraIdList.isNotEmpty()) assumeTrue(cameraManager.cameraIdList.isNotEmpty())
navigationToolbar { navigationToolbar {
@ -244,9 +250,10 @@ class SitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/251386
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1815395") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1815395")
@Test @Test
fun rememberAllowCameraPermissionChoiceTest() { fun allowCameraPermissionRememberingTheDecisionTest() {
assumeTrue(cameraManager.cameraIdList.isNotEmpty()) assumeTrue(cameraManager.cameraIdList.isNotEmpty())
navigationToolbar { navigationToolbar {
@ -266,8 +273,10 @@ class SitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2334074
@SmokeTest
@Test @Test
fun blockNotificationsPermissionPromptTest() { fun blockNotificationsPermissionTest() {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(testPage.toUri()) { }.enterURLAndEnterToBrowser(testPage.toUri()) {
}.clickOpenNotificationButton { }.clickOpenNotificationButton {
@ -282,8 +291,9 @@ class SitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/251380
@Test @Test
fun allowNotificationsPermissionPromptTest() { fun allowNotificationsPermissionTest() {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(testPage.toUri()) { }.enterURLAndEnterToBrowser(testPage.toUri()) {
}.clickOpenNotificationButton { }.clickOpenNotificationButton {
@ -293,6 +303,7 @@ class SitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/251385
@SmokeTest @SmokeTest
@Test @Test
fun allowLocationPermissionsTest() { fun allowLocationPermissionsTest() {
@ -308,7 +319,7 @@ class SitePermissionsTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2334075
@Test @Test
fun blockLocationPermissionsTest() { fun blockLocationPermissionsTest() {
navigationToolbar { navigationToolbar {
@ -320,6 +331,7 @@ class SitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2121537
@SmokeTest @SmokeTest
@Test @Test
fun fileUploadPermissionTest() { fun fileUploadPermissionTest() {

@ -1,236 +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/. */
@file:Suppress("DEPRECATION")
package org.mozilla.fenix.ui
import android.view.View
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.core.net.toUri
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.ActivityTestRule
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.Rule
import org.junit.Test
import org.mozilla.fenix.IntentReceiverActivity
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.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
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.clickPageObject
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
/**
* Test Suite that contains a part of the Smoke and Sanity tests defined in TestRail:
* https://testrail.stage.mozaws.net/index.php?/suites/view/3192
* Other smoke tests have been marked with the @SmokeTest annotation throughout the ui package in order to limit this class expansion.
* These tests will verify different functionalities of the app as a way to quickly detect regressions in main areas
*/
@Suppress("ForbiddenComment")
@SmokeTest
class SmokeTest {
private lateinit var mDevice: UiDevice
private lateinit var mockWebServer: MockWebServer
private lateinit var browserStore: BrowserStore
@get:Rule(order = 0)
val activityTestRule = AndroidComposeTestRule(
HomeActivityIntentTestRule.withDefaultSettingsOverrides(),
{ it.activity },
)
@get: Rule(order = 1)
val intentReceiverActivityTestRule = ActivityTestRule(
IntentReceiverActivity::class.java,
true,
false,
)
@Rule(order = 2)
@JvmField
val retryTestRule = RetryTestRule(3)
@Before
fun setUp() {
// Initializing this as part of class construction, below the rule would throw a NPE
// So we are initializing this here instead of in all related tests.
browserStore = activityTestRule.activity.components.core.store
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher()
start()
}
}
@After
fun tearDown() {
mockWebServer.shutdown()
}
@Test
fun shareTabsFromTabsTrayTest() {
val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2)
val firstWebsiteTitle = firstWebsite.title
val secondWebsiteTitle = secondWebsite.title
val sharingApp = "Gmail"
val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}"
homeScreen {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(firstWebsite.url) {
verifyPageContent(firstWebsite.content)
}.openTabDrawer {
}.openNewTab {
}.submitQuery(secondWebsite.url.toString()) {
verifyPageContent(secondWebsite.content)
}.openTabDrawer {
verifyExistingOpenTabs("Test_Page_1")
verifyExistingOpenTabs("Test_Page_2")
}.openTabsListThreeDotMenu {
verifyShareAllTabsButton()
}.clickShareAllTabsButton {
verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle)
verifySharingWithSelectedApp(
sharingApp,
sharedUrlsString,
"$firstWebsiteTitle, $secondWebsiteTitle",
)
}
}
@Test
fun privateTabsTrayWithOpenedTabTest() {
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
}.togglePrivateBrowsingMode()
homeScreen {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(website.url) {
}.openTabDrawer {
verifyNormalBrowsingButtonIsSelected(false)
verifyPrivateBrowsingButtonIsSelected(true)
verifySyncedTabsButtonIsSelected(false)
verifyTabTrayOverflowMenu(true)
verifyTabsTrayCounter()
verifyExistingTabList()
verifyExistingOpenTabs(website.title)
verifyCloseTabsButton(website.title)
verifyOpenedTabThumbnail()
verifyPrivateBrowsingNewTabButton()
}
}
// 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)
homeScreen {
}.togglePrivateBrowsingMode()
homeScreen {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(website.url) {
mDevice.waitForIdle()
}.openThreeDotMenu {
}.openHistory {
verifyEmptyHistoryView()
}
}
@Test
fun mainMenuInstallPWATest() {
val pwaPage = "https://mozilla-mobile.github.io/testapp/"
navigationToolbar {
}.enterURLAndEnterToBrowser(pwaPage.toUri()) {
verifyNotificationDotOnMainMenu()
}.openThreeDotMenu {
}.clickInstall {
clickAddAutomaticallyButton()
}.openHomeScreenShortcut("TEST_APP") {
mDevice.waitForIdle()
verifyNavURLBarHidden()
}
}
// Verifies that reader mode is detected and the custom appearance controls are displayed
@Test
fun verifyReaderViewAppearanceUI() {
val readerViewPage =
TestAssetHelper.getLoremIpsumAsset(mockWebServer)
val estimatedReadingTime = "1 - 2 minutes"
navigationToolbar {
}.enterURLAndEnterToBrowser(readerViewPage.url) {
mDevice.waitForIdle()
}
registerAndCleanupIdlingResources(
ViewVisibilityIdlingResource(
activityTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
View.VISIBLE,
),
) {}
navigationToolbar {
verifyReaderViewDetected(true)
toggleReaderView()
}
browserScreen {
waitForPageToLoad()
verifyPageContent(estimatedReadingTime)
}.openThreeDotMenu {
verifyReaderViewAppearance(true)
}.openReaderViewAppearance {
verifyAppearanceFontGroup(true)
verifyAppearanceFontSansSerif(true)
verifyAppearanceFontSerif(true)
verifyAppearanceFontIncrease(true)
verifyAppearanceFontDecrease(true)
verifyAppearanceColorGroup(true)
verifyAppearanceColorDark(true)
verifyAppearanceColorLight(true)
verifyAppearanceColorSepia(true)
}
}
@Test
fun tabMediaControlButtonTest() {
val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
navigationToolbar {
}.enterURLAndEnterToBrowser(audioTestPage.url) {
mDevice.waitForIdle()
clickPageObject(itemWithText("Play"))
assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING)
}.openTabDrawer {
verifyTabMediaControlButtonState("Pause")
clickTabMediaControlButton("Pause")
verifyTabMediaControlButtonState("Play")
}.openTab(audioTestPage.title) {
assertPlaybackState(browserStore, MediaSession.PlaybackState.PAUSED)
}
}
}

@ -7,20 +7,25 @@ package org.mozilla.fenix.ui
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.mediasession.MediaSession
import okhttp3.mockwebserver.MockWebServer import okhttp3.mockwebserver.MockWebServer
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper
import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.RetryTestRule
import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestHelper.closeApp import org.mozilla.fenix.helpers.TestHelper.closeApp
import org.mozilla.fenix.helpers.TestHelper.restartApp import org.mozilla.fenix.helpers.TestHelper.restartApp
import org.mozilla.fenix.helpers.TestHelper.verifyKeyboardVisibility import org.mozilla.fenix.helpers.TestHelper.verifyKeyboardVisibility
import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.navigationToolbar
import org.mozilla.fenix.ui.robots.notificationShade import org.mozilla.fenix.ui.robots.notificationShade
@ -45,6 +50,7 @@ import org.mozilla.fenix.ui.robots.notificationShade
class TabbedBrowsingTest { class TabbedBrowsingTest {
private lateinit var mDevice: UiDevice private lateinit var mDevice: UiDevice
private lateinit var mockWebServer: MockWebServer private lateinit var mockWebServer: MockWebServer
private lateinit var browserStore: BrowserStore
@get:Rule @get:Rule
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true) val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
@ -55,6 +61,10 @@ class TabbedBrowsingTest {
@Before @Before
fun setUp() { fun setUp() {
// Initializing this as part of class construction, below the rule would throw a NPE
// So we are initializing this here instead of in all related tests.
browserStore = activityTestRule.activity.components.core.store
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
mockWebServer = MockWebServer().apply { mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher() dispatcher = AndroidAssetDispatcher()
@ -67,50 +77,7 @@ class TabbedBrowsingTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
@Test // TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903599
fun openNewTabTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.waitForIdle()
verifyTabCounter("1")
}.openTabDrawer {
verifyNormalModeSelected()
verifyExistingOpenTabs("Test_Page_1")
closeTab()
}.openTabDrawer {
verifyNoOpenTabsInNormalBrowsing()
}.openNewTab {
}.submitQuery(defaultWebPage.url.toString()) {
mDevice.waitForIdle()
verifyTabCounter("1")
}.openTabDrawer {
verifyNormalModeSelected()
verifyExistingOpenTabs("Test_Page_1")
}
}
@Test
fun openNewPrivateTabTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {}.togglePrivateBrowsingMode()
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.waitForIdle()
verifyTabCounter("1")
}.openTabDrawer {
verifyExistingTabList()
verifyPrivateModeSelected()
}.toggleToNormalTabs {
verifyNoOpenTabsInNormalBrowsing()
}.toggleToPrivateTabs {
verifyExistingTabList()
}
}
@Test @Test
fun closeAllTabsTest() { fun closeAllTabsTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -143,8 +110,9 @@ class TabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903604
@Test @Test
fun closeTabTest() { fun closingTabsMethodsTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -152,6 +120,13 @@ class TabbedBrowsingTest {
}.openTabDrawer { }.openTabDrawer {
verifyExistingOpenTabs("Test_Page_1") verifyExistingOpenTabs("Test_Page_1")
closeTab() closeTab()
verifySnackBarText("Tab closed")
snackBarButtonClick("UNDO")
}
browserScreen {
verifyTabCounter("1")
}.openTabDrawer {
closeTab()
} }
homeScreen { homeScreen {
verifyTabCounter("0") verifyTabCounter("0")
@ -160,6 +135,7 @@ class TabbedBrowsingTest {
}.openTabDrawer { }.openTabDrawer {
verifyExistingOpenTabs("Test_Page_1") verifyExistingOpenTabs("Test_Page_1")
swipeTabRight("Test_Page_1") swipeTabRight("Test_Page_1")
verifySnackBarText("Tab closed")
} }
homeScreen { homeScreen {
verifyTabCounter("0") verifyTabCounter("0")
@ -168,48 +144,31 @@ class TabbedBrowsingTest {
}.openTabDrawer { }.openTabDrawer {
verifyExistingOpenTabs("Test_Page_1") verifyExistingOpenTabs("Test_Page_1")
swipeTabLeft("Test_Page_1") swipeTabLeft("Test_Page_1")
verifySnackBarText("Tab closed")
} }
homeScreen { homeScreen {
verifyTabCounter("0") verifyTabCounter("0")
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903591
@Test @Test
fun verifyUndoSnackBarTest() { fun closingPrivateTabsMethodsTest() {
// disabling these features because they interfere with the snackbar visibility
activityTestRule.applySettingsExceptions {
it.isPocketEnabled = false
it.isRecentTabsFeatureEnabled = false
}
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen { }.togglePrivateBrowsingMode()
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) { }.enterURLAndEnterToBrowser(genericURL.url) {
}.openTabDrawer { }.openTabDrawer {
verifyExistingOpenTabs("Test_Page_1") verifyExistingOpenTabs("Test_Page_1")
verifyCloseTabsButton("Test_Page_1")
closeTab() closeTab()
verifySnackBarText("Tab closed") verifySnackBarText("Private tab closed")
snackBarButtonClick("UNDO") snackBarButtonClick("UNDO")
} }
browserScreen { browserScreen {
verifyTabCounter("1") verifyTabCounter("1")
}.openTabDrawer { }.openTabDrawer {
verifyExistingOpenTabs("Test_Page_1")
}
}
@Test
fun closePrivateTabTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen { }.togglePrivateBrowsingMode()
navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
}.openTabDrawer {
verifyExistingOpenTabs("Test_Page_1")
verifyCloseTabsButton("Test_Page_1")
closeTab() closeTab()
} }
homeScreen { homeScreen {
@ -219,6 +178,7 @@ class TabbedBrowsingTest {
}.openTabDrawer { }.openTabDrawer {
verifyExistingOpenTabs("Test_Page_1") verifyExistingOpenTabs("Test_Page_1")
swipeTabRight("Test_Page_1") swipeTabRight("Test_Page_1")
verifySnackBarText("Private tab closed")
} }
homeScreen { homeScreen {
verifyTabCounter("0") verifyTabCounter("0")
@ -227,38 +187,37 @@ class TabbedBrowsingTest {
}.openTabDrawer { }.openTabDrawer {
verifyExistingOpenTabs("Test_Page_1") verifyExistingOpenTabs("Test_Page_1")
swipeTabLeft("Test_Page_1") swipeTabLeft("Test_Page_1")
verifySnackBarText("Private tab closed")
} }
homeScreen { homeScreen {
verifyTabCounter("0") verifyTabCounter("0")
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903606
@SmokeTest
@Test @Test
fun verifyPrivateTabUndoSnackBarTest() { fun tabMediaControlButtonTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
homeScreen { }.togglePrivateBrowsingMode()
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) { }.enterURLAndEnterToBrowser(audioTestPage.url) {
}.openTabDrawer { mDevice.waitForIdle()
verifyExistingOpenTabs("Test_Page_1") clickPageObject(MatcherHelper.itemWithText("Play"))
verifyCloseTabsButton("Test_Page_1") assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING)
closeTab()
verifySnackBarText("Private tab closed")
snackBarButtonClick("UNDO")
}
browserScreen {
verifyTabCounter("1")
}.openTabDrawer { }.openTabDrawer {
verifyExistingOpenTabs("Test_Page_1") verifyTabMediaControlButtonState("Pause")
verifyPrivateModeSelected() clickTabMediaControlButton("Pause")
verifyTabMediaControlButtonState("Play")
}.openTab(audioTestPage.title) {
assertPlaybackState(browserStore, MediaSession.PlaybackState.PAUSED)
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/903592
@SmokeTest @SmokeTest
@Test @Test
fun closePrivateTabsNotificationTest() { fun verifyCloseAllPrivateTabsNotificationTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen { homeScreen {
@ -276,6 +235,40 @@ class TabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903598
@SmokeTest
@Test
fun shareTabsFromTabsTrayTest() {
val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2)
val firstWebsiteTitle = firstWebsite.title
val secondWebsiteTitle = secondWebsite.title
val sharingApp = "Gmail"
val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}"
homeScreen {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(firstWebsite.url) {
verifyPageContent(firstWebsite.content)
}.openTabDrawer {
}.openNewTab {
}.submitQuery(secondWebsite.url.toString()) {
verifyPageContent(secondWebsite.content)
}.openTabDrawer {
verifyExistingOpenTabs("Test_Page_1")
verifyExistingOpenTabs("Test_Page_2")
}.openTabsListThreeDotMenu {
verifyShareAllTabsButton()
}.clickShareAllTabsButton {
verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle)
verifySharingWithSelectedApp(
sharingApp,
sharedUrlsString,
"$firstWebsiteTitle, $secondWebsiteTitle",
)
}
}
@Test @Test
fun verifyTabTrayNotShowingStateHalfExpanded() { fun verifyTabTrayNotShowingStateHalfExpanded() {
navigationToolbar { navigationToolbar {
@ -299,6 +292,7 @@ class TabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903600
@Test @Test
fun verifyEmptyTabTray() { fun verifyEmptyTabTray() {
navigationToolbar { navigationToolbar {
@ -313,8 +307,9 @@ class TabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903585
@Test @Test
fun emptyTabsTrayViewPrivateBrowsingTest() { fun verifyEmptyPrivateTabsTrayTest() {
navigationToolbar { navigationToolbar {
}.openTabTray { }.openTabTray {
}.toggleToPrivateTabs { }.toggleToPrivateTabs {
@ -328,12 +323,15 @@ class TabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903601
@Test @Test
fun verifyOpenTabDetails() { fun verifyTabsTrayWithOpenTabTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { homeScreen {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openTabDrawer {
}.openNewTab {
}.submitQuery(defaultWebPage.url.toString()) {
}.openTabDrawer { }.openTabDrawer {
verifyNormalBrowsingButtonIsSelected(true) verifyNormalBrowsingButtonIsSelected(true)
verifyPrivateBrowsingButtonIsSelected(false) verifyPrivateBrowsingButtonIsSelected(false)
@ -351,29 +349,57 @@ class TabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/903587
@SmokeTest
@Test
fun verifyPrivateTabsTrayWithOpenTabTest() {
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
}.openTabDrawer {
}.toggleToPrivateTabs {
}.openNewTab {
}.submitQuery(website.url.toString()) {
}.openTabDrawer {
verifyNormalBrowsingButtonIsSelected(false)
verifyPrivateBrowsingButtonIsSelected(true)
verifySyncedTabsButtonIsSelected(false)
verifyTabTrayOverflowMenu(true)
verifyTabsTrayCounter()
verifyExistingTabList()
verifyExistingOpenTabs(website.title)
verifyCloseTabsButton(website.title)
verifyOpenedTabThumbnail()
verifyPrivateBrowsingNewTabButton()
}
}
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/927315
@Test @Test
fun verifyContextMenuShortcuts() { fun tabsCounterShortcutMenuTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {}
navigationToolbar {
}.openTabButtonShortcutsMenu { }.openTabButtonShortcutsMenu {
verifyTabButtonShortcutMenuItems() verifyTabButtonShortcutMenuItems()
}.closeTabFromShortcutsMenu { }.closeTabFromShortcutsMenu {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {}
navigationToolbar {
}.openTabButtonShortcutsMenu { }.openTabButtonShortcutsMenu {
}.openNewPrivateTabFromShortcutsMenu { }.openNewPrivateTabFromShortcutsMenu {
verifyKeyboardVisibility() verifyKeyboardVisibility()
verifySearchBarPlaceholder("Search or enter address") verifySearchBarPlaceholder("Search or enter address")
// dismiss search dialog // dismiss search dialog
}.dismissSearchBar { }.dismissSearchBar {
verifyCommonMythsLink() verifyPrivateBrowsingHomeScreenItems()
verifyNavigationToolbar()
} }
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {}
navigationToolbar {
}.openTabButtonShortcutsMenu { }.openTabButtonShortcutsMenu {
}.openTabFromShortcutsMenu { }.openNewTabFromShortcutsMenu {
verifyKeyboardVisibility() verifyKeyboardVisibility()
verifySearchBarPlaceholder("Search or enter address") verifySearchBarPlaceholder("Search or enter address")
// dismiss search dialog // dismiss search dialog
@ -383,6 +409,45 @@ class TabbedBrowsingTest {
} }
} }
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/927314
@Test
fun privateTabsCounterShortcutMenuTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {}.togglePrivateBrowsingMode()
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
waitForPageToLoad()
}
navigationToolbar {
}.openTabButtonShortcutsMenu {
verifyTabButtonShortcutMenuItems()
}.closeTabFromShortcutsMenu {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {}
navigationToolbar {
}.openTabButtonShortcutsMenu {
}.openNewPrivateTabFromShortcutsMenu {
verifyKeyboardVisibility()
verifySearchBarPlaceholder("Search or enter address")
// dismiss search dialog
}.dismissSearchBar {
verifyCommonMythsLink()
}
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {}
navigationToolbar {
}.openTabButtonShortcutsMenu {
}.openNewTabFromShortcutsMenu {
verifyKeyboardVisibility()
verifySearchBarPlaceholder("Search or enter address")
// dismiss search dialog
}.dismissSearchBar {
// Verify normal browsing homescreen
verifyExistingTopSitesList()
}
}
// TestRail: https://testrail.stage.mozaws.net/index.php?/cases/view/1046683
@Test @Test
fun verifySyncedTabsWhenUserIsNotSignedInTest() { fun verifySyncedTabsWhenUserIsNotSignedInTest() {
navigationToolbar { navigationToolbar {
@ -397,6 +462,7 @@ class TabbedBrowsingTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/526244
@Test @Test
fun privateModeStaysAsDefaultAfterRestartTest() { fun privateModeStaysAsDefaultAfterRestartTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -408,13 +474,14 @@ class TabbedBrowsingTest {
closeApp(activityTestRule) closeApp(activityTestRule)
restartApp(activityTestRule) restartApp(activityTestRule)
homeScreen { homeScreen {
verifyPrivateBrowsingHomeScreen() verifyPrivateBrowsingHomeScreenItems()
}.openTabDrawer { }.openTabDrawer {
}.toggleToNormalTabs { }.toggleToNormalTabs {
verifyExistingOpenTabs(defaultWebPage.title) verifyExistingOpenTabs(defaultWebPage.title)
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2228470
@SmokeTest @SmokeTest
@Test @Test
fun privateTabsDoNotPersistAfterClosingAppTest() { fun privateTabsDoNotPersistAfterClosingAppTest() {
@ -435,7 +502,7 @@ class TabbedBrowsingTest {
restartApp(activityTestRule) restartApp(activityTestRule)
homeScreen { homeScreen {
verifyPrivateBrowsingHomeScreen() verifyPrivateBrowsingHomeScreenItems()
}.openTabDrawer { }.openTabDrawer {
verifyNoOpenTabsInPrivateBrowsing() verifyNoOpenTabsInPrivateBrowsing()
} }

@ -53,9 +53,10 @@ class TextSelectionTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326832
@SmokeTest @SmokeTest
@Test @Test
fun selectAllAndCopyTextTest() { fun verifySelectAllTextOptionTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -77,9 +78,9 @@ class TextSelectionTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326828
@Test @Test
fun copyTextTest() { fun verifyCopyTextOptionTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -98,9 +99,9 @@ class TextSelectionTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326829
@Test @Test
fun shareSelectedTextTest() { fun verifyShareSelectedTextOptionTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -111,9 +112,9 @@ class TextSelectionTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326830
@Test @Test
fun selectAndSearchTextTest() { fun verifySearchTextOptionTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -126,9 +127,10 @@ class TextSelectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326831
@SmokeTest @SmokeTest
@Test @Test
fun privateSelectAndSearchTextTest() { fun verifyPrivateSearchTextTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen { homeScreen {
@ -144,9 +146,9 @@ class TextSelectionTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326834
@Test @Test
fun selectAllAndCopyPDFTextTest() { fun verifySelectAllPDFTextOptionTest() {
val genericURL = val genericURL =
TestAssetHelper.getGenericAsset(mockWebServer, 3) TestAssetHelper.getGenericAsset(mockWebServer, 3)
@ -168,9 +170,10 @@ class TextSelectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243839
@SmokeTest @SmokeTest
@Test @Test
fun copyPDFTextTest() { fun verifyCopyPDFTextOptionTest() {
val genericURL = val genericURL =
TestAssetHelper.getGenericAsset(mockWebServer, 3) TestAssetHelper.getGenericAsset(mockWebServer, 3)
@ -191,9 +194,9 @@ class TextSelectionTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326835
@Test @Test
fun shareSelectedPDFTextTest() { fun verifyShareSelectedPDFTextOptionTest() {
val genericURL = val genericURL =
TestAssetHelper.getGenericAsset(mockWebServer, 3) TestAssetHelper.getGenericAsset(mockWebServer, 3)
@ -206,9 +209,10 @@ class TextSelectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326836
@SmokeTest @SmokeTest
@Test @Test
fun selectAndSearchPDFTextTest() { fun verifySearchPDFTextOptionTest() {
val genericURL = val genericURL =
TestAssetHelper.getGenericAsset(mockWebServer, 3) TestAssetHelper.getGenericAsset(mockWebServer, 3)
@ -222,9 +226,9 @@ class TextSelectionTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326837
@Test @Test
fun privateSelectAndSearchPDFTextTest() { fun verifyPrivateSearchPDFTextOptionTest() {
val genericURL = val genericURL =
TestAssetHelper.getGenericAsset(mockWebServer, 3) TestAssetHelper.getGenericAsset(mockWebServer, 3)
@ -241,6 +245,7 @@ class TextSelectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326813
@Test @Test
fun verifyUrlBarTextSelectionOptionsTest() { fun verifyUrlBarTextSelectionOptionsTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -253,8 +258,9 @@ class TextSelectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326814
@Test @Test
fun copyUrlBarTextTest() { fun verifyCopyUrlBarTextSelectionOptionTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -270,8 +276,9 @@ class TextSelectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326815
@Test @Test
fun cutUrlBarTextTest() { fun verifyCutUrlBarTextSelectionOptionTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -286,8 +293,10 @@ class TextSelectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243845
@SmokeTest
@Test @Test
fun shareUrlBarTextTest() { fun verifyShareUrlBarTextSelectionOptionTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1) val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -301,6 +310,7 @@ class TextSelectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/414316
@Test @Test
fun urlBarQuickActionsTest() { fun urlBarQuickActionsTest() {
val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1)

@ -55,9 +55,10 @@ class TopSitesTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/532598
@SmokeTest @SmokeTest
@Test @Test
fun verifyAddToFirefoxHome() { fun addAWebsiteAsATopSiteTest() {
val defaultWebPage = getGenericAsset(mockWebServer, 1) val defaultWebPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -73,8 +74,9 @@ class TopSitesTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/532599
@Test @Test
fun verifyOpenTopSiteNormalTab() { fun openTopSiteInANewTabTest() {
val defaultWebPage = getGenericAsset(mockWebServer, 1) val defaultWebPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -100,8 +102,9 @@ class TopSitesTest {
mDevice.pressBack() mDevice.pressBack()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/532600
@Test @Test
fun verifyOpenTopSitePrivateTab() { fun openTopSiteInANewPrivateTabTest() {
val defaultWebPage = getGenericAsset(mockWebServer, 1) val defaultWebPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -121,8 +124,9 @@ class TopSitesTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1110321
@Test @Test
fun verifyRenameTopSite() { fun renameATopSiteTest() {
val defaultWebPage = getGenericAsset(mockWebServer, 1) val defaultWebPage = getGenericAsset(mockWebServer, 1)
val newPageTitle = generateRandomString(5) val newPageTitle = generateRandomString(5)
@ -145,8 +149,9 @@ class TopSitesTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/532601
@Test @Test
fun verifyRemoveTopSite() { fun removeTopSiteUsingMenuButtonTest() {
val defaultWebPage = getGenericAsset(mockWebServer, 1) val defaultWebPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -162,34 +167,18 @@ class TopSitesTest {
}.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) { }.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) {
verifyTopSiteContextMenuItems() verifyTopSiteContextMenuItems()
}.removeTopSite { }.removeTopSite {
verifyNotExistingTopSitesList(defaultWebPage.title) clickSnackbarButton("UNDO")
}
}
@Test
fun verifyUndoRemoveTopSite() {
val defaultWebPage = getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
}.openThreeDotMenu {
expandMenu()
verifyAddToShortcutsButton(shouldExist = true)
}.addToFirefoxHome {
verifySnackBarText(getStringResource(R.string.snackbar_added_to_shortcuts))
}.goToHomescreen {
verifyExistingTopSitesList()
verifyExistingTopSitesTabs(defaultWebPage.title) verifyExistingTopSitesTabs(defaultWebPage.title)
}.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) { }.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) {
verifyTopSiteContextMenuItems() verifyTopSiteContextMenuItems()
}.removeTopSite { }.removeTopSite {
clickSnackbarButton("UNDO") verifyNotExistingTopSitesList(defaultWebPage.title)
verifyExistingTopSitesTabs(defaultWebPage.title)
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2323641
@Test @Test
fun verifyRemoveTopSiteFromMainMenu() { fun removeTopSiteFromMainMenuTest() {
val defaultWebPage = getGenericAsset(mockWebServer, 1) val defaultWebPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -211,9 +200,10 @@ class TopSitesTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/561582
// Expected for en-us defaults // Expected for en-us defaults
@Test @Test
fun verifyDefaultTopSitesList() { fun verifyENLocalesDefaultTopSitesListTest() {
homeScreen { homeScreen {
verifyExistingTopSitesList() verifyExistingTopSitesList()
defaultTopSitesList.values.forEach { value -> defaultTopSitesList.values.forEach { value ->
@ -222,6 +212,7 @@ class TopSitesTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1050642
@SmokeTest @SmokeTest
@Test @Test
fun addAndRemoveMostViewedTopSiteTest() { fun addAndRemoveMostViewedTopSiteTest() {

@ -56,21 +56,9 @@ class WebControlsTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2316067
@Test @Test
fun cancelCalendarFormTest() { fun verifyCalendarFormInteractionsTest() {
val htmlControlsPage = getHTMLControlsFormAsset(mockWebServer)
navigationToolbar {
}.enterURLAndEnterToBrowser(htmlControlsPage.url) {
clickPageObject(itemWithResId("calendar"))
clickPageObject(itemContainingText("CANCEL"))
clickPageObject(itemWithResId("submitDate"))
verifyNoDateIsSelected()
}
}
@Test
fun setAndClearCalendarFormTest() {
val currentDate = LocalDate.now() val currentDate = LocalDate.now()
val currentDay = currentDate.dayOfMonth val currentDay = currentDate.dayOfMonth
val currentMonth = currentDate.month val currentMonth = currentDate.month
@ -79,6 +67,10 @@ class WebControlsTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(htmlControlsPage.url) { }.enterURLAndEnterToBrowser(htmlControlsPage.url) {
clickPageObject(itemWithResId("calendar"))
clickPageObject(itemContainingText("CANCEL"))
clickPageObject(itemWithResId("submitDate"))
verifyNoDateIsSelected()
clickPageObject(itemWithResId("calendar")) clickPageObject(itemWithResId("calendar"))
clickPageObject(itemWithDescription("$currentDay $currentMonth $currentYear")) clickPageObject(itemWithDescription("$currentDay $currentMonth $currentYear"))
clickPageObject(itemContainingText("OK")) clickPageObject(itemContainingText("OK"))
@ -91,8 +83,9 @@ class WebControlsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2316069
@Test @Test
fun cancelClockFormTest() { fun verifyClockFormInteractionsTest() {
val htmlControlsPage = getHTMLControlsFormAsset(mockWebServer) val htmlControlsPage = getHTMLControlsFormAsset(mockWebServer)
navigationToolbar { navigationToolbar {
@ -101,15 +94,6 @@ class WebControlsTest {
clickPageObject(itemContainingText("CANCEL")) clickPageObject(itemContainingText("CANCEL"))
clickPageObject(itemWithResId("submitTime")) clickPageObject(itemWithResId("submitTime"))
verifyNoTimeIsSelected(hour, minute) verifyNoTimeIsSelected(hour, minute)
}
}
@Test
fun setAndClearClockFormTest() {
val htmlControlsPage = getHTMLControlsFormAsset(mockWebServer)
navigationToolbar {
}.enterURLAndEnterToBrowser(htmlControlsPage.url) {
clickPageObject(itemWithResId("clock")) clickPageObject(itemWithResId("clock"))
selectTime(hour, minute) selectTime(hour, minute)
clickPageObject(itemContainingText("OK")) clickPageObject(itemContainingText("OK"))
@ -122,8 +106,9 @@ class WebControlsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2316068
@Test @Test
fun cancelColorFormTest() { fun verifyColorPickerInteractionsTest() {
val htmlControlsPage = getHTMLControlsFormAsset(mockWebServer) val htmlControlsPage = getHTMLControlsFormAsset(mockWebServer)
navigationToolbar { navigationToolbar {
@ -133,15 +118,6 @@ class WebControlsTest {
clickPageObject(itemContainingText("CANCEL")) clickPageObject(itemContainingText("CANCEL"))
clickPageObject(itemWithResId("submitColor")) clickPageObject(itemWithResId("submitColor"))
verifyColorIsNotSelected(colorHexValue) verifyColorIsNotSelected(colorHexValue)
}
}
@Test
fun setColorFormTest() {
val htmlControlsPage = getHTMLControlsFormAsset(mockWebServer)
navigationToolbar {
}.enterURLAndEnterToBrowser(htmlControlsPage.url) {
clickPageObject(itemWithResId("colorPicker")) clickPageObject(itemWithResId("colorPicker"))
clickPageObject(itemWithDescription(colorHexValue)) clickPageObject(itemWithDescription(colorHexValue))
clickPageObject(itemContainingText("SET")) clickPageObject(itemContainingText("SET"))
@ -150,8 +126,9 @@ class WebControlsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2316070
@Test @Test
fun verifyDropdownMenuTest() { fun verifyDropdownMenuInteractionsTest() {
val htmlControlsPage = getHTMLControlsFormAsset(mockWebServer) val htmlControlsPage = getHTMLControlsFormAsset(mockWebServer)
navigationToolbar { navigationToolbar {
@ -163,8 +140,9 @@ class WebControlsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2316071
@Test @Test
fun emailLinkTest() { fun verifyEmailLinkTest() {
val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer)
navigationToolbar { navigationToolbar {
@ -175,8 +153,9 @@ class WebControlsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/834205
@Test @Test
fun telephoneLinkTest() { fun verifyTelephoneLinkTest() {
val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer)
navigationToolbar { navigationToolbar {

@ -55,6 +55,7 @@ import org.mozilla.fenix.helpers.SessionLoadedIdlingResource
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
import org.mozilla.fenix.helpers.TestHelper.appName
import org.mozilla.fenix.helpers.TestHelper.getStringResource import org.mozilla.fenix.helpers.TestHelper.getStringResource
import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.TestHelper.packageName
@ -428,6 +429,12 @@ class BrowserRobot {
fun changeCreditCardExpiryDate(expiryDate: String) = fun changeCreditCardExpiryDate(expiryDate: String) =
itemWithResId("expiryMonthAndYear").setText(expiryDate) itemWithResId("expiryMonthAndYear").setText(expiryDate)
fun clickCreditCardNumberTextBox() {
mDevice.wait(Until.findObject(By.res("cardNumber")), waitingTime)
mDevice.findObject(By.res("cardNumber")).click()
mDevice.waitForWindowUpdate(appName, waitingTimeShort)
}
fun clickCreditCardFormSubmitButton() = fun clickCreditCardFormSubmitButton() =
itemWithResId("submit").clickAndWaitForNewWindow(waitingTime) itemWithResId("submit").clickAndWaitForNewWindow(waitingTime)
@ -800,13 +807,31 @@ class BrowserRobot {
) )
} }
fun verifyPrivateBrowsingOpenLinkInAnotherAppPrompt(url: String) = fun verifyPrivateBrowsingOpenLinkInAnotherAppPrompt(url: String, pageObject: UiObject) {
assertItemContainingTextExists( for (i in 1..RETRY_COUNT) {
itemContainingText( try {
getStringResource(R.string.mozac_feature_applinks_confirm_dialog_title), assertItemContainingTextExists(
), itemContainingText(
itemContainingText(url), getStringResource(R.string.mozac_feature_applinks_confirm_dialog_title),
) ),
itemContainingText(url),
)
break
} catch (e: AssertionError) {
if (i == RETRY_COUNT) {
throw e
} else {
browserScreen {
}.openThreeDotMenu {
}.refreshPage {
waitForPageToLoad()
clickPageObject(pageObject)
}
}
}
}
}
fun verifyFindInPageBar(exists: Boolean) = fun verifyFindInPageBar(exists: Boolean) =
assertItemWithResIdExists( assertItemWithResIdExists(
@ -882,6 +907,17 @@ class BrowserRobot {
assertTrue(button.waitForExists(waitingTime)) assertTrue(button.waitForExists(waitingTime))
} }
fun verifySurveyButtonDoesNotExist() {
val button = mDevice.findObject(
UiSelector().text(
getStringResource(
R.string.preferences_take_survey,
),
),
)
assertTrue(button.waitUntilGone(waitingTime))
}
fun verifySurveyNoThanksButton() { fun verifySurveyNoThanksButton() {
val button = mDevice.findObject( val button = mDevice.findObject(
UiSelector().text( UiSelector().text(
@ -893,6 +929,15 @@ class BrowserRobot {
assertTrue(button.waitForExists(waitingTime)) assertTrue(button.waitForExists(waitingTime))
} }
fun verifyHomeScreenSurveyCloseButton() {
val button = mDevice.findObject(
UiSelector().descriptionContains(
"Close",
),
)
assertTrue(button.waitForExists(waitingTime))
}
fun clickOpenLinksInAppsDismissCFRButton() = fun clickOpenLinksInAppsDismissCFRButton() =
itemWithResIdContainingText( itemWithResIdContainingText(
"$packageName:id/dismiss", "$packageName:id/dismiss",
@ -910,7 +955,6 @@ class BrowserRobot {
button.waitForExists(waitingTime) button.waitForExists(waitingTime)
button.click() button.click()
} }
fun clickNoThanksSurveyButton() { fun clickNoThanksSurveyButton() {
val button = mDevice.findObject( val button = mDevice.findObject(
UiSelector().text( UiSelector().text(
@ -1068,14 +1112,6 @@ class BrowserRobot {
return ComposeTabDrawerRobot.Transition(composeTestRule) return ComposeTabDrawerRobot.Transition(composeTestRule)
} }
fun openTabButtonShortcutsMenu(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition {
mDevice.waitNotNull(Until.findObject(By.desc("Tabs")))
tabsCounter().click(LONG_CLICK_DURATION)
NavigationToolbarRobot().interact()
return NavigationToolbarRobot.Transition()
}
fun openNotificationShade(interact: NotificationRobot.() -> Unit): NotificationRobot.Transition { fun openNotificationShade(interact: NotificationRobot.() -> Unit): NotificationRobot.Transition {
mDevice.openNotification() mDevice.openNotification()
@ -1263,6 +1299,13 @@ class BrowserRobot {
surveyNoThanksButton.waitForExists(waitingTime) surveyNoThanksButton.waitForExists(waitingTime)
surveyNoThanksButton.click() surveyNoThanksButton.click()
BrowserRobot().interact()
return Transition()
}
fun clickHomeScreenSurveyCloseButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
homescreenSurveyCloseButton.waitForExists(waitingTime)
homescreenSurveyCloseButton.click()
BrowserRobot().interact() BrowserRobot().interact()
return Transition() return Transition()
} }
@ -1421,3 +1464,6 @@ private val surveyButton =
private val surveyNoThanksButton = private val surveyNoThanksButton =
itemContainingText(getStringResource(R.string.preferences_not_take_survey)) itemContainingText(getStringResource(R.string.preferences_not_take_survey))
private val homescreenSurveyCloseButton =
itemWithDescription("Close")

@ -17,12 +17,14 @@ import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollTo import androidx.compose.ui.test.performScrollTo
import androidx.compose.ui.test.performTouchInput import androidx.compose.ui.test.performTouchInput
import androidx.test.uiautomator.UiSelector
import org.mozilla.fenix.helpers.HomeActivityComposeTestRule import org.mozilla.fenix.helpers.HomeActivityComposeTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.TestHelper.packageName
import org.mozilla.fenix.home.topsites.TopSitesTestTag import org.mozilla.fenix.home.topsites.TopSitesTestTag
@ -37,7 +39,7 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR
@OptIn(ExperimentalTestApi::class) @OptIn(ExperimentalTestApi::class)
fun verifyExistingTopSiteItem(vararg titles: String) { fun verifyExistingTopSiteItem(vararg titles: String) {
titles.forEach { title -> titles.forEach { title ->
composeTestRule.waitUntilAtLeastOneExists(hasText(title), waitingTime) mDevice.findObject(UiSelector().textContains(title)).waitForExists(waitingTimeShort)
composeTestRule.topSiteItem(title).assertExists() composeTestRule.topSiteItem(title).assertExists()
} }
} }

@ -87,11 +87,10 @@ class HomeScreenRobot {
fun verifyHomeScreen() = assertItemWithResIdExists(homeScreen) fun verifyHomeScreen() = assertItemWithResIdExists(homeScreen)
fun verifyPrivateBrowsingHomeScreen() { fun verifyPrivateBrowsingHomeScreenItems() {
verifyHomeScreenAppBarItems() verifyHomeScreenAppBarItems()
assertItemContainingTextExists(itemContainingText(privateSessionMessage)) assertItemContainingTextExists(itemContainingText(privateSessionMessage))
verifyCommonMythsLink() verifyCommonMythsLink()
verifyNavigationToolbarItems()
} }
fun verifyHomeScreenAppBarItems() = fun verifyHomeScreenAppBarItems() =

@ -147,23 +147,6 @@ class NavigationToolbarRobot {
class Transition { class Transition {
private lateinit var sessionLoadedIdlingResource: SessionLoadedIdlingResource private lateinit var sessionLoadedIdlingResource: SessionLoadedIdlingResource
fun goBackToWebsite(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
openEditURLView()
clearAddressBarButton().click()
assertTrue(
mDevice.findObject(
UiSelector()
.resourceId("$packageName:id/mozac_browser_toolbar_edit_url_view")
.textContains(""),
).waitForExists(waitingTime),
)
goBackButton()
BrowserRobot().interact()
return BrowserRobot.Transition()
}
fun enterURLAndEnterToBrowser( fun enterURLAndEnterToBrowser(
url: Uri, url: Uri,
interact: BrowserRobot.() -> Unit, interact: BrowserRobot.() -> Unit,
@ -298,14 +281,23 @@ class NavigationToolbarRobot {
return BrowserRobot.Transition() return BrowserRobot.Transition()
} }
fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
goBackButton() mDevice.pressBack()
mDevice.waitForWindowUpdate(packageName, waitingTimeShort)
HomeScreenRobot().interact() HomeScreenRobot().interact()
return HomeScreenRobot.Transition() return HomeScreenRobot.Transition()
} }
fun closeTabFromShortcutsMenu(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition { fun openTabButtonShortcutsMenu(interact: NavigationToolbarRobot.() -> Unit): Transition {
mDevice.waitNotNull(Until.findObject(By.desc("Tabs")))
tabsCounter().click(LONG_CLICK_DURATION)
NavigationToolbarRobot().interact()
return Transition()
}
fun closeTabFromShortcutsMenu(interact: NavigationToolbarRobot.() -> Unit): Transition {
mDevice.waitForIdle(waitingTime) mDevice.waitForIdle(waitingTime)
onView(withId(R.id.mozac_browser_menu_recyclerView)) onView(withId(R.id.mozac_browser_menu_recyclerView))
@ -319,10 +311,10 @@ class NavigationToolbarRobot {
) )
NavigationToolbarRobot().interact() NavigationToolbarRobot().interact()
return NavigationToolbarRobot.Transition() return Transition()
} }
fun openTabFromShortcutsMenu(interact: SearchRobot.() -> Unit): SearchRobot.Transition { fun openNewTabFromShortcutsMenu(interact: SearchRobot.() -> Unit): SearchRobot.Transition {
mDevice.waitForIdle(waitingTime) mDevice.waitForIdle(waitingTime)
onView(withId(R.id.mozac_browser_menu_recyclerView)) onView(withId(R.id.mozac_browser_menu_recyclerView))
@ -413,9 +405,10 @@ private fun awesomeBar() =
mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_edit_url_view")) mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_edit_url_view"))
private fun threeDotButton() = onView(withId(R.id.mozac_browser_toolbar_menu)) private fun threeDotButton() = onView(withId(R.id.mozac_browser_toolbar_menu))
private fun tabTrayButton() = onView(withId(R.id.tab_button)) private fun tabTrayButton() = onView(withId(R.id.tab_button))
private fun tabsCounter() =
mDevice.findObject(By.res("$packageName:id/counter_root"))
private fun fillLinkButton() = onView(withId(R.id.fill_link_from_clipboard)) private fun fillLinkButton() = onView(withId(R.id.fill_link_from_clipboard))
private fun clearAddressBarButton() = itemWithResId("$packageName:id/mozac_browser_toolbar_clear_view") private fun clearAddressBarButton() = itemWithResId("$packageName:id/mozac_browser_toolbar_clear_view")
private fun goBackButton() = mDevice.pressBack()
private fun readerViewToggle() = private fun readerViewToggle() =
onView(withParent(withId(R.id.mozac_browser_toolbar_page_actions))) onView(withParent(withId(R.id.mozac_browser_toolbar_page_actions)))

@ -117,23 +117,26 @@ class NotificationRobot {
shouldDismissNotification: Boolean, shouldDismissNotification: Boolean,
canExpandNotification: Boolean = true, canExpandNotification: Boolean = true,
) { ) {
// In case it fails, retry max 6x the swipe action on download system notifications // In case it fails, retry max 3x the swipe action on download system notifications
for (i in 1..6) { for (i in 1..RETRY_COUNT) {
try { try {
// Swipe left the download system notification var retries = 0
if (direction == "Left") { while (itemContainingText(appName).exists() && retries++ < 3) {
itemContainingText(appName) // Swipe left the download system notification
.also { if (direction == "Left") {
it.waitForExists(waitingTime) itemContainingText(appName)
it.swipeLeft(3) .also {
} it.waitForExists(waitingTime)
} else { it.swipeLeft(3)
// Swipe right the download system notification }
itemContainingText(appName) } else {
.also { // Swipe right the download system notification
it.waitForExists(waitingTime) itemContainingText(appName)
it.swipeRight(3) .also {
} it.waitForExists(waitingTime)
it.swipeRight(3)
}
}
} }
// Not all download related system notifications can be dismissed // Not all download related system notifications can be dismissed
if (shouldDismissNotification) { if (shouldDismissNotification) {
@ -144,7 +147,7 @@ class NotificationRobot {
break break
} catch (e: AssertionError) { } catch (e: AssertionError) {
if (i == 6) { if (i == RETRY_COUNT) {
throw e throw e
} else { } else {
notificationShade { notificationShade {
@ -167,7 +170,7 @@ class NotificationRobot {
fun clickNotification(notificationMessage: String) { fun clickNotification(notificationMessage: String) {
mDevice.findObject(UiSelector().text(notificationMessage)).waitForExists(waitingTime) mDevice.findObject(UiSelector().text(notificationMessage)).waitForExists(waitingTime)
mDevice.findObject(UiSelector().text(notificationMessage)).click() mDevice.findObject(UiSelector().text(notificationMessage)).clickAndWaitForNewWindow(waitingTimeShort)
} }
class Transition { class Transition {

@ -16,6 +16,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.click
/** /**
@ -89,6 +90,14 @@ class ReaderViewRobot {
} }
class Transition { class Transition {
fun closeAppearanceMenu(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
mDevice.pressBack()
BrowserRobot().interact()
return BrowserRobot.Transition()
}
fun toggleSansSerif(interact: ReaderViewRobot.() -> Unit): Transition { fun toggleSansSerif(interact: ReaderViewRobot.() -> Unit): Transition {
fun sansSerifButton() = fun sansSerifButton() =
onView( onView(

@ -224,7 +224,7 @@ class SettingsSubMenuAddonsManagerRobot {
isDescendantOfA(withId(R.id.add_on_item)), isDescendantOfA(withId(R.id.add_on_item)),
hasSibling(hasDescendant(withText(addonName))), hasSibling(hasDescendant(withText(addonName))),
), ),
).check(matches(withEffectiveVisibility(Visibility.GONE))) ).check(matches(withEffectiveVisibility(Visibility.INVISIBLE)))
} }
private fun cancelInstall() { private fun cancelInstall() {
@ -267,7 +267,7 @@ class SettingsSubMenuAddonsManagerRobot {
hasDescendant(withText("uBlock Origin")), hasDescendant(withText("uBlock Origin")),
hasDescendant(withText("Finally, an efficient wide-spectrum content blocker. Easy on CPU and memory.")), hasDescendant(withText("Finally, an efficient wide-spectrum content blocker. Easy on CPU and memory.")),
hasDescendant(withId(R.id.rating)), hasDescendant(withId(R.id.rating)),
hasDescendant(withId(R.id.users_count)), hasDescendant(withId(R.id.review_count)),
), ),
), ),
hasDescendant(withId(R.id.add_button)), hasDescendant(withId(R.id.add_button)),

@ -7,7 +7,13 @@ package org.mozilla.fenix.ui.robots
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.UiSelector
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
import org.mozilla.fenix.helpers.TestHelper.packageName
import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.click
/** /**
@ -41,5 +47,35 @@ class SettingsSubMenuExperimentsRobot {
checkNotNull(experiment) checkNotNull(experiment)
} }
fun verifyExperimentEnrolled(title: String) {
itemContainingText(title).click()
assertTrue(
checkIcon().waitForExists(waitingTimeShort),
)
goBackButton().click()
}
fun verifyExperimentNotEnrolled(title: String) {
itemContainingText(title).click()
assertFalse(
checkIcon().waitForExists(waitingTimeShort),
)
goBackButton().click()
}
fun unenrollfromExperiment(title: String) {
val branch = itemWithResId("$packageName:id/nimbus_branch_name")
itemContainingText(title).click()
assertTrue(
checkIcon().waitForExists(waitingTimeShort),
)
branch.click()
assertFalse(
checkIcon().waitForExists(waitingTimeShort),
)
}
} }
private fun goBackButton() = onView(withContentDescription(R.string.action_bar_up_description)) private fun goBackButton() = onView(withContentDescription(R.string.action_bar_up_description))
private fun checkIcon() = itemWithResId("$packageName:id/selected_icon")

@ -96,7 +96,7 @@ class SettingsSubMenuSearchRobot {
} }
fun verifyAddressBarSectionHeader() { fun verifyAddressBarSectionHeader() {
onView(withText("Address bar")).check(matches(isDisplayed())) onView(withText("Address bar - Firefox Suggest")).check(matches(isDisplayed()))
} }
fun verifyDefaultSearchEngineList() { fun verifyDefaultSearchEngineList() {
@ -402,7 +402,7 @@ class EngineShortcut(
private val defaultSearchEngineHeader = onView(withText("Default search engine")) private val defaultSearchEngineHeader = onView(withText("Default search engine"))
private val manageSearchShortcutsHeader = onView(withText("Manage search shortcuts")) private val manageSearchShortcutsHeader = onView(withText("Manage alternative search engines"))
private fun searchHistorySwitchButton(): ViewInteraction { private fun searchHistorySwitchButton(): ViewInteraction {
onView(withId(androidx.preference.R.id.recycler_view)).perform( onView(withId(androidx.preference.R.id.recycler_view)).perform(

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save