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

pull/700/head
akliuxingyuan 7 months ago
commit 10defdb011

@ -35,6 +35,7 @@ projects:
- feature-customtabs - feature-customtabs
- feature-downloads - feature-downloads
- feature-findinpage - feature-findinpage
- feature-fxsuggest
- feature-intent - feature-intent
- feature-logins - feature-logins
- feature-media - feature-media

@ -15,6 +15,14 @@ extensions-process:
enabled: enabled:
type: boolean type: boolean
description: "If true, the extensions process is enabled." description: "If true, the extensions process is enabled."
fx-suggest:
description: A feature that provides Firefox Suggest search suggestions.
hasExposure: true
exposureDescription: ""
variables:
enabled:
type: boolean
description: "Whether the feature is enabled. When Firefox Suggest is enabled, Firefox will download and store new search suggestions in the background, and show additional Search settings to control which suggestions appear in the awesomebar. When Firefox Suggest is disabled, Firefox will not download new suggestions, and hide the additional Search settings.\n"
glean: glean:
description: A feature that provides server-side configurations for Glean metrics (aka Server Knobs). description: A feature that provides server-side configurations for Glean metrics (aka Server Knobs).
hasExposure: true hasExposure: true
@ -47,9 +55,6 @@ juno-onboarding:
cards: cards:
type: json type: json
description: Collection of user facing onboarding cards. description: Collection of user facing onboarding cards.
enabled:
type: boolean
description: "if true, juno onboarding is shown to the user."
messaging: messaging:
description: "The in-app messaging system.\n" description: "The in-app messaging system.\n"
hasExposure: true hasExposure: true
@ -199,6 +204,9 @@ shopping-experience:
enabled: enabled:
type: boolean type: boolean
description: "if true, the shopping experience feature is shown to the user." description: "if true, the shopping experience feature is shown to the user."
product-recommendations:
type: boolean
description: "if true, recommended products feature is enabled to be shown to the user based on their preference."
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."
hasExposure: true hasExposure: true

@ -1,3 +1,4 @@
import com.android.build.api.variant.FilterConfiguration
import org.apache.tools.ant.util.StringUtils import org.apache.tools.ant.util.StringUtils
plugins { plugins {
@ -12,18 +13,16 @@ apply plugin: 'jacoco'
apply plugin: 'androidx.navigation.safeargs.kotlin' apply plugin: 'androidx.navigation.safeargs.kotlin'
apply plugin: 'com.google.android.gms.oss-licenses-plugin' apply plugin: 'com.google.android.gms.oss-licenses-plugin'
import com.android.build.OutputFile
import groovy.json.JsonOutput import groovy.json.JsonOutput
import org.gradle.internal.logging.text.StyledTextOutput.Style import org.gradle.internal.logging.text.StyledTextOutput.Style
import org.gradle.internal.logging.text.StyledTextOutputFactory import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import static org.gradle.api.tasks.testing.TestResult.ResultType import static org.gradle.api.tasks.testing.TestResult.ResultType
apply from: 'benchmark.gradle' apply from: 'benchmark.gradle'
android { android {
compileSdkVersion config.compileSdkVersion
project.maybeConfigForJetpackBenchmark(it) project.maybeConfigForJetpackBenchmark(it)
if (project.hasProperty("testBuildType")) { if (project.hasProperty("testBuildType")) {
// Allowing to configure the test build type via command line flag (./gradlew -PtestBuildType=beta ..) // Allowing to configure the test build type via command line flag (./gradlew -PtestBuildType=beta ..)
@ -34,6 +33,7 @@ android {
defaultConfig { defaultConfig {
applicationId "io.github.forkmaintainers" applicationId "io.github.forkmaintainers"
minSdkVersion config.minSdkVersion minSdkVersion config.minSdkVersion
compileSdk config.compileSdkVersion
targetSdkVersion config.targetSdkVersion targetSdkVersion config.targetSdkVersion
versionCode 1 versionCode 1
versionName Config.generateDebugVersionName() versionName Config.generateDebugVersionName()
@ -218,9 +218,7 @@ android {
animationsDisabled = true animationsDisabled = true
} }
flavorDimensions "engine" flavorDimensions.add("product")
flavorDimensions "product"
productFlavors { productFlavors {
fenix { fenix {
@ -286,7 +284,7 @@ android {
namespace 'org.mozilla.fenix' namespace 'org.mozilla.fenix'
} }
android.applicationVariants.all { variant -> android.applicationVariants.configureEach { variant ->
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
// Generate version codes for builds // Generate version codes for builds
@ -312,7 +310,7 @@ android.applicationVariants.all { variant ->
variant.outputs.each { output -> variant.outputs.each { output ->
def isMozillaOnline = project.hasProperty("mozillaOnline") || gradle.hasProperty("localProperties.mozillaOnline") def isMozillaOnline = project.hasProperty("mozillaOnline") || gradle.hasProperty("localProperties.mozillaOnline")
def abi = output.getFilter(OutputFile.ABI) 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
// 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
@ -507,12 +505,8 @@ nimbus {
experimenterManifest = ".experimenter.yaml" experimenterManifest = ".experimenter.yaml"
} }
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { tasks.withType(KotlinCompile).configureEach {
kotlinOptions { kotlinOptions.freeCompilerArgs += "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi"
freeCompilerArgs += [
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
]
}
} }
dependencies { dependencies {
@ -559,6 +553,7 @@ dependencies {
implementation project(':feature-contextmenu') implementation project(':feature-contextmenu')
implementation project(':feature-customtabs') implementation project(':feature-customtabs')
implementation project(':feature-downloads') implementation project(':feature-downloads')
implementation project(':feature-fxsuggest')
implementation project(':feature-intent') implementation project(':feature-intent')
implementation project(':feature-media') implementation project(':feature-media')
implementation project(':feature-prompts') implementation project(':feature-prompts')
@ -635,7 +630,7 @@ dependencies {
implementation FenixDependencies.androidx_navigation_fragment implementation FenixDependencies.androidx_navigation_fragment
implementation FenixDependencies.androidx_navigation_ui implementation FenixDependencies.androidx_navigation_ui
implementation ComponentsDependencies.androidx_recyclerview implementation ComponentsDependencies.androidx_recyclerview
implementation FenixDependencies.androidx_lifecycle_common implementation ComponentsDependencies.androidx_lifecycle_common
implementation ComponentsDependencies.androidx_lifecycle_livedata implementation ComponentsDependencies.androidx_lifecycle_livedata
implementation ComponentsDependencies.androidx_lifecycle_process implementation ComponentsDependencies.androidx_lifecycle_process
implementation ComponentsDependencies.androidx_lifecycle_runtime implementation ComponentsDependencies.androidx_lifecycle_runtime
@ -737,13 +732,13 @@ if (project.hasProperty("coverage")) {
toolVersion = Versions.jacoco toolVersion = Versions.jacoco
} }
android.applicationVariants.all { variant -> android.applicationVariants.configureEach { variant ->
tasks.register("jacoco${variant.name.capitalize()}TestReport", JacocoReport) { tasks.register("jacoco${variant.name.capitalize()}TestReport", JacocoReport) {
dependsOn "test${variant.name.capitalize()}UnitTest" dependsOn "test${variant.name.capitalize()}UnitTest"
reports { reports {
xml.enabled = true xml.required = true
html.enabled = true html.required = true
} }
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*',
@ -782,7 +777,7 @@ tasks.register('printVariants') {
doLast { doLast {
def variants = android.applicationVariants.collect { variant -> [ def variants = android.applicationVariants.collect { variant -> [
apks: variant.outputs.collect { output -> [ apks: variant.outputs.collect { output -> [
abi: output.getFilter(com.android.build.VariantOutput.FilterType.ABI), abi: output.getFilter(FilterConfiguration.FilterType.ABI.name()),
fileName: output.outputFile.name fileName: output.outputFile.name
]}, ]},
build_type: variant.buildType.name, build_type: variant.buildType.name,
@ -801,22 +796,22 @@ tasks.register('printVariants') {
} }
} }
task buildTranslationArray { tasks.register('buildTranslationArray') {
// This isn't running as a task, instead the array is build when the gradle file is parsed. // This isn't running as a task, instead the array is build when the gradle file is parsed.
// https://github.com/mozilla-mobile/fenix/issues/14175 // https://github.com/mozilla-mobile/fenix/issues/14175
def foundLocales = new StringBuilder() def foundLocales = new StringBuilder()
foundLocales.append("new String[]{") foundLocales.append("new String[]{")
fileTree("src/main/res").visit { FileVisitDetails details -> fileTree("src/main/res").visit { FileVisitDetails details ->
if(details.file.path.endsWith("${File.separator}strings.xml")){ if (details.file.path.endsWith("${File.separator}strings.xml")) {
def languageCode = details.file.parent.tokenize(File.separator).last().replaceAll('values-','').replaceAll('-r','-') def languageCode = details.file.parent.tokenize(File.separator).last().replaceAll('values-', '').replaceAll('-r', '-')
languageCode = (languageCode == "values") ? "en-US" : languageCode languageCode = (languageCode == "values") ? "en-US" : languageCode
foundLocales.append("\"").append(languageCode).append("\"").append(",") foundLocales.append("\"").append(languageCode).append("\"").append(",")
} }
} }
foundLocales.append("}") foundLocales.append("}")
def foundLocalesString = foundLocales.toString().replaceAll(',}','}') def foundLocalesString = foundLocales.toString().replaceAll(',}', '}')
android.defaultConfig.buildConfigField "String[]", "SUPPORTED_LOCALE_ARRAY", foundLocalesString android.defaultConfig.buildConfigField "String[]", "SUPPORTED_LOCALE_ARRAY", foundLocalesString
} }
@ -878,7 +873,7 @@ if (gradle.hasProperty('localProperties.autoPublish.glean.dir')) {
apply from: "../${gleanSrcDir}/build-scripts/substitute-local-glean.gradle" apply from: "../${gleanSrcDir}/build-scripts/substitute-local-glean.gradle"
} }
android.applicationVariants.all { variant -> android.applicationVariants.configureEach { variant ->
tasks.register("apkSize${variant.name.capitalize()}", ApkSizeTask) { tasks.register("apkSize${variant.name.capitalize()}", ApkSizeTask) {
variantName = variant.name variantName = variant.name
apks = variant.outputs.collect { output -> output.outputFile.name } apks = variant.outputs.collect { output -> output.outputFile.name }

@ -2539,6 +2539,28 @@ metrics:
metadata: metadata:
tags: tags:
- Experiments - Experiments
device_total_ram:
type: quantity
lifetime: application
description: >
The total amount of memory this device in bytes, when available will be
MemoryInfo.advertisedMem otherwise it will be MemoryInfo.totalMem.
This doesn't represent memory available to the application however.
send_in_pings:
- metrics
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1853967
data_reviews:
- https://github.com/mozilla-mobile/firefox-android/pull/2620
data_sensitivity:
- technical
notification_emails:
- android-probes@mozilla.com
expires: never
unit: integer
metadata:
tags:
- Performance
search_page_load_time: search_page_load_time:
type: timing_distribution type: timing_distribution
time_unit: millisecond time_unit: millisecond

@ -348,6 +348,10 @@ features:
description: if true, the shopping experience feature is shown to the user. description: if true, the shopping experience feature is shown to the user.
type: Boolean type: Boolean
default: false default: false
product-recommendations:
description: if true, recommended products feature is enabled to be shown to the user based on their preference.
type: Boolean
default: false
defaults: defaults:
- channel: developer - channel: developer
value: value:
@ -384,6 +388,24 @@ features:
description: The channel Id param name with arg. description: The channel Id param name with arg.
type: Map<String, String> type: Map<String, String>
default: {} default: {}
fx-suggest:
description: A feature that provides Firefox Suggest search suggestions.
variables:
enabled:
description: >
Whether the feature is enabled. When Firefox Suggest is enabled,
Firefox will download and store new search suggestions in the
background, and show additional Search settings to control which
suggestions appear in the awesomebar. When Firefox Suggest is
disabled, Firefox will not download new suggestions, and hide the
additional Search settings.
type: Boolean
default: false
defaults:
- channel: developer
value:
enabled: true
types: types:
objects: {} objects: {}

@ -5,10 +5,6 @@ features:
description: A feature that shows juno onboarding flow. description: A feature that shows juno onboarding flow.
variables: variables:
enabled:
description: if true, juno onboarding is shown to the user.
type: Boolean
default: false
cards: cards:
description: Collection of user facing onboarding cards. description: Collection of user facing onboarding cards.
type: Map<String, OnboardingCardData> type: Map<String, OnboardingCardData>
@ -51,14 +47,6 @@ features:
primary-button-label: juno_onboarding_enable_notifications_positive_button primary-button-label: juno_onboarding_enable_notifications_positive_button
secondary-button-label: juno_onboarding_enable_notifications_negative_button secondary-button-label: juno_onboarding_enable_notifications_negative_button
defaults:
- channel: developer
value:
enabled: false
- channel: nightly
value:
enabled: true
objects: objects:
OnboardingCardData: OnboardingCardData:

@ -13,7 +13,7 @@ features:
defaults: defaults:
- channel: developer - channel: developer
value: value:
felt-privacy-enabled: true felt-privacy-enabled: false
- channel: nightly - channel: nightly
value: value:
felt-privacy-enabled: false felt-privacy-enabled: false

@ -8,19 +8,22 @@
<p>Misc Link Types</p> <p>Misc Link Types</p>
<section> <section>
<a href="https://duckduckgo.com/">External link</a> <a href="mailto://example@example.com">Email link</a>
</section> </section>
<section> <section>
<a href="mailto://example@example.com">Email link</a> <a href="tel://1234567890">Telephone link</a>
</section> </section>
<section> <section>
<a href="tel://1234567890">Telephone link</a> <a href="vnd.youtube://@Mozilla">Youtube schema link</a>
</section> </section>
<section> <section>
<a href="https://m.youtube.com/user/mozilla?cbrd=1">Youtube link</a> <a href="https://m.youtube.com/user/mozilla?cbrd=1">Youtube full link</a>
</section> </section>
<section>
<a href="http://play.google.com/store/apps/details?id=org.mozilla.firefox">Playstore link</a>
</section>
</html> </html>

@ -7,6 +7,8 @@ name = "pypi"
pytest = "*" pytest = "*"
pytest-html = "*" pytest-html = "*"
pytest-metadata = "*" pytest-metadata = "*"
pytest-variables = "*"
pyyaml = "*"
requests = "*" requests = "*"
[dev-packages] [dev-packages]

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "917d5c85bd6545dedfbce6aedbd76bd1516993e65943ecfbf7affbece9a2a0ab" "sha256": "53501c7e751ae79697bf8c7289b6095f49fed97242fe186fea42989e800c39d5"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -16,141 +16,94 @@
] ]
}, },
"default": { "default": {
"black": {
"hashes": [
"sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5",
"sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915",
"sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326",
"sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940",
"sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b",
"sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30",
"sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c",
"sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c",
"sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab",
"sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27",
"sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2",
"sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961",
"sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9",
"sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb",
"sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70",
"sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331",
"sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2",
"sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266",
"sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d",
"sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6",
"sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b",
"sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925",
"sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8",
"sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4",
"sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"
],
"index": "pypi",
"version": "==23.3.0"
},
"certifi": { "certifi": {
"hashes": [ "hashes": [
"sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7", "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082",
"sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716" "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==2023.5.7" "version": "==2023.7.22"
}, },
"charset-normalizer": { "charset-normalizer": {
"hashes": [ "hashes": [
"sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6", "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96",
"sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1", "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c",
"sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e", "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710",
"sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373", "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706",
"sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62", "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020",
"sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230", "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252",
"sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be", "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad",
"sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c", "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329",
"sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0", "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a",
"sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448", "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f",
"sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f", "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6",
"sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649", "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4",
"sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d", "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a",
"sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0", "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46",
"sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706", "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2",
"sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a", "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23",
"sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59", "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace",
"sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23", "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd",
"sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5", "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982",
"sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb", "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10",
"sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e", "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2",
"sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e", "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea",
"sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c", "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09",
"sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28", "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5",
"sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d", "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149",
"sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41", "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489",
"sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974", "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9",
"sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce", "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80",
"sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f", "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592",
"sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1", "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3",
"sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d", "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6",
"sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8", "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed",
"sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017", "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c",
"sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31", "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200",
"sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7", "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a",
"sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8", "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e",
"sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e", "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d",
"sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14", "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6",
"sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd", "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623",
"sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d", "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669",
"sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795", "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3",
"sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b", "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa",
"sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b", "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9",
"sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b", "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2",
"sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203", "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f",
"sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f", "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1",
"sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19", "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4",
"sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1", "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a",
"sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a", "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8",
"sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac", "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3",
"sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9", "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029",
"sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0", "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f",
"sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137", "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959",
"sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f", "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22",
"sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6", "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7",
"sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5", "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952",
"sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909", "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346",
"sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f", "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e",
"sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0", "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d",
"sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324", "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299",
"sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755", "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd",
"sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb", "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a",
"sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854", "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3",
"sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c", "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037",
"sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60", "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94",
"sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84", "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c",
"sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0", "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858",
"sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b", "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a",
"sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1", "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449",
"sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531", "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c",
"sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1", "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918",
"sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11", "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1",
"sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326", "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c",
"sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df", "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac",
"sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab" "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_full_version >= '3.7.0'",
"version": "==3.1.0" "version": "==3.2.0"
},
"click": {
"hashes": [
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
"sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
],
"markers": "python_version >= '3.7'",
"version": "==8.1.3"
},
"flake8": {
"hashes": [
"sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7",
"sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"
],
"index": "pypi",
"version": "==6.0.0"
}, },
"idna": { "idna": {
"hashes": [ "hashes": [
@ -168,21 +121,69 @@
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==2.0.0" "version": "==2.0.0"
}, },
"mccabe": { "jinja2": {
"hashes": [ "hashes": [
"sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852",
"sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.7'",
"version": "==0.7.0" "version": "==3.1.2"
}, },
"mypy-extensions": { "markupsafe": {
"hashes": [ "hashes": [
"sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e",
"sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e",
"sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431",
"sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686",
"sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559",
"sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc",
"sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c",
"sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0",
"sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4",
"sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9",
"sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575",
"sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba",
"sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d",
"sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3",
"sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00",
"sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155",
"sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac",
"sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52",
"sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f",
"sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8",
"sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b",
"sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24",
"sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea",
"sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198",
"sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0",
"sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee",
"sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be",
"sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2",
"sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707",
"sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6",
"sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58",
"sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779",
"sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636",
"sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c",
"sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad",
"sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee",
"sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc",
"sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2",
"sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48",
"sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7",
"sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e",
"sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b",
"sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa",
"sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5",
"sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e",
"sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb",
"sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9",
"sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57",
"sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc",
"sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"
], ],
"markers": "python_version >= '3.5'", "markers": "python_version >= '3.7'",
"version": "==1.0.0" "version": "==2.1.3"
}, },
"packaging": { "packaging": {
"hashes": [ "hashes": [
@ -192,94 +193,219 @@
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==23.1" "version": "==23.1"
}, },
"pathspec": { "pluggy": {
"hashes": [ "hashes": [
"sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687", "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12",
"sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293" "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.8'",
"version": "==0.11.1" "version": "==1.3.0"
}, },
"platformdirs": { "pytest": {
"hashes": [ "hashes": [
"sha256:b0cabcb11063d21a0b261d557acb0a9d2126350e63b70cdf7db6347baea456dc", "sha256:2f2301e797521b23e4d2585a0a3d7b5e50fdddaaf7e7d6773ea26ddb17c213ab",
"sha256:ca9ed98ce73076ba72e092b23d3c93ea6c4e186b3f1c3dad6edd98ff6ffcca2e" "sha256:460c9a59b14e27c602eb5ece2e47bec99dc5fc5f6513cf924a7d03a578991b1f"
], ],
"markers": "python_version >= '3.7'", "index": "pypi",
"version": "==3.8.0" "version": "==7.4.1"
}, },
"pluggy": { "pytest-html": {
"hashes": [ "hashes": [
"sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849", "sha256:3b473cc278272f8b5a34cd3bf10f88ac5fcb17cb5af22f9323514af00c310e64",
"sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3" "sha256:79c4677ed6196417bf290d8b81f706342ae49f726f623728efa3f7dfff09f8eb"
], ],
"markers": "python_version >= '3.7'", "index": "pypi",
"version": "==1.2.0" "version": "==4.0.0"
}, },
"py": { "pytest-metadata": {
"hashes": [ "hashes": [
"sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", "sha256:769a9c65d2884bd583bc626b0ace77ad15dbe02dd91a9106d47fd46d9c2569ca",
"sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" "sha256:a17b1e40080401dc23177599208c52228df463db191c1a573ccdffacd885e190"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "index": "pypi",
"version": "==1.11.0" "version": "==3.0.0"
}, },
"pycodestyle": { "pytest-variables": {
"hashes": [ "hashes": [
"sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053", "sha256:190d9d4da5a6013eb02df2049f6047d911cdbe44c5b1734a6acc1748433c93d0",
"sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610" "sha256:ab84235417afac5a0a7dd4c3918287d9c7329d2e16d570d6e943f8d8e02533b9"
], ],
"markers": "python_version >= '3.6'", "index": "pypi",
"version": "==2.10.0" "version": "==3.0.0"
}, },
"pyflakes": { "pyyaml": {
"hashes": [ "hashes": [
"sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf", "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5",
"sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd" "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc",
"sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df",
"sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741",
"sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206",
"sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27",
"sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595",
"sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62",
"sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98",
"sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696",
"sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290",
"sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9",
"sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d",
"sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6",
"sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867",
"sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47",
"sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486",
"sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6",
"sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3",
"sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007",
"sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938",
"sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0",
"sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c",
"sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735",
"sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d",
"sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28",
"sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4",
"sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba",
"sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8",
"sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5",
"sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd",
"sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3",
"sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0",
"sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515",
"sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c",
"sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c",
"sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924",
"sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34",
"sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43",
"sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859",
"sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673",
"sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54",
"sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a",
"sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b",
"sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab",
"sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa",
"sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c",
"sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585",
"sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d",
"sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"
], ],
"markers": "python_version >= '3.6'", "index": "pypi",
"version": "==3.0.1" "version": "==6.0.1"
}, },
"pytest": { "requests": {
"hashes": [ "hashes": [
"sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32", "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f",
"sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a" "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"
], ],
"index": "pypi", "index": "pypi",
"version": "==7.4.0" "version": "==2.31.0"
}, },
"pytest-html": { "urllib3": {
"hashes": [ "hashes": [
"sha256:868c08564a68d8b2c26866f1e33178419bb35b1e127c33784a28622eb827f3f3", "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11",
"sha256:c4e2f4bb0bffc437f51ad2174a8a3e71df81bbc2f6894604e604af18fbe687c3" "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"
],
"markers": "python_version >= '3.7'",
"version": "==2.0.4"
}
},
"develop": {
"black": {
"hashes": [
"sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3",
"sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb",
"sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087",
"sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320",
"sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6",
"sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3",
"sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc",
"sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f",
"sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587",
"sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91",
"sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a",
"sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad",
"sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926",
"sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9",
"sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be",
"sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd",
"sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96",
"sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491",
"sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2",
"sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a",
"sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f",
"sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.2.0" "version": "==23.7.0"
}, },
"pytest-metadata": { "click": {
"hashes": [ "hashes": [
"sha256:769a9c65d2884bd583bc626b0ace77ad15dbe02dd91a9106d47fd46d9c2569ca", "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28",
"sha256:a17b1e40080401dc23177599208c52228df463db191c1a573ccdffacd885e190" "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"
], ],
"index": "pypi", "markers": "python_version >= '3.7'",
"version": "==3.0.0" "version": "==8.1.7"
}, },
"requests": { "flake8": {
"hashes": [ "hashes": [
"sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23",
"sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.31.0" "version": "==6.1.0"
}, },
"urllib3": { "mccabe": {
"hashes": [ "hashes": [
"sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1", "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325",
"sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825" "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"
],
"markers": "python_version >= '3.6'",
"version": "==0.7.0"
},
"mypy-extensions": {
"hashes": [
"sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d",
"sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"
],
"markers": "python_version >= '3.5'",
"version": "==1.0.0"
},
"packaging": {
"hashes": [
"sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61",
"sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==2.0.3" "version": "==23.1"
},
"pathspec": {
"hashes": [
"sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20",
"sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"
],
"markers": "python_version >= '3.7'",
"version": "==0.11.2"
},
"platformdirs": {
"hashes": [
"sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d",
"sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"
],
"markers": "python_version >= '3.7'",
"version": "==3.10.0"
},
"pycodestyle": {
"hashes": [
"sha256:259bcc17857d8a8b3b4a2327324b79e5f020a13c16074670f9c8c8f872ea76d0",
"sha256:5d1013ba8dc7895b548be5afb05740ca82454fd899971563d2ef625d090326f8"
],
"markers": "python_version >= '3.8'",
"version": "==2.11.0"
},
"pyflakes": {
"hashes": [
"sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774",
"sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"
],
"markers": "python_version >= '3.8'",
"version": "==3.1.0"
} }
}, }
"develop": {}
} }

@ -22,7 +22,11 @@ class SurveyExperimentIntegrationTest {
private val experimentName = "Viewpoint" private val experimentName = "Viewpoint"
@get:Rule @get:Rule
val activityTestRule = HomeActivityTestRule() val activityTestRule = HomeActivityTestRule(
isJumpBackInCFREnabled = false,
isPWAsPromptEnabled = false,
isTCPCFREnabled = false,
)
@Before @Before
fun setUp() { fun setUp() {
@ -38,7 +42,25 @@ class SurveyExperimentIntegrationTest {
fun checkSurveyNavigatesCorrectly() { fun checkSurveyNavigatesCorrectly() {
browserScreen { browserScreen {
verifySurveyButton() verifySurveyButton()
}.clickSurveyButton {} }.clickSurveyButton {
verifyUrl(surveyURL)
}
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openExperimentsMenu {
verifyExperimentExists(experimentName)
}
}
@Test
fun checkSurveyNoThanksNavigatesCorrectly() {
browserScreen {
verifySurveyNoThanksButton()
}.clickNoThanksSurveyButton {
verifyTabCounter("0")
}
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {

@ -1,4 +1,5 @@
import json import json
import logging
import os import os
from pathlib import Path from pathlib import Path
import subprocess import subprocess
@ -15,15 +16,32 @@ KLAATU_LOCAL_SERVER_URL = "http://localhost:1378"
here = Path() here = Path()
def load_branches(): def pytest_addoption(parser):
parser.addoption(
"--experiment", action="store", help="The experiments experimenter URL"
)
parser.addoption(
"--stage", action="store_true", default=None, help="Use the stage server"
)
@pytest.fixture(name="load_branches")
def fixture_load_branches(experiment_url):
branches = [] branches = []
data = requests.get(f"{KLAATU_SERVER_URL}/experiment").json()
for item in reversed(data): if experiment_url:
if isinstance(item, dict): data = experiment_url
else:
try:
data = requests.get(f"{KLAATU_SERVER_URL}/experiment").json()
except ConnectionRefusedError:
logging.warn("No URL or experiment slug provided, exiting.")
exit() exit()
else: else:
data = item for item in reversed(data):
break data = item
break
experiment = requests.get(data).json() experiment = requests.get(data).json()
for item in experiment["branches"]: for item in experiment["branches"]:
branches.append(item["slug"]) branches.append(item["slug"])
@ -45,7 +63,6 @@ def gradlewbuild(gradlewbuild_log):
@pytest.fixture(name="experiment_data") @pytest.fixture(name="experiment_data")
def fixture_experiment_data(experiment_url): def fixture_experiment_data(experiment_url):
data = requests.get(experiment_url).json() data = requests.get(experiment_url).json()
del(data["branches"][0]["features"][0]["value"]["message-under-experiment"])
for item in data["branches"][0]["features"][0]["value"]["messages"].values(): for item in data["branches"][0]["features"][0]["value"]["messages"].values():
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:
@ -54,17 +71,33 @@ def fixture_experiment_data(experiment_url):
@pytest.fixture(name="experiment_url", scope="module") @pytest.fixture(name="experiment_url", scope="module")
def fixture_experiment_url(): def fixture_experiment_url(request, variables):
data = requests.get(f"{KLAATU_LOCAL_SERVER_URL}/experiment").json()
url = None url = None
for item in data:
if isinstance(item, dict): if slug := request.config.getoption("--experiment"):
continue # Build URL from slug
if request.config.getoption("--stage"):
url = f"{variables['urls']['stage_server']}/api/v6/experiments/{slug}"
else: else:
url = item url = f"{variables['urls']['prod_server']}/api/v6/experiments/{slug}"
else:
try:
data = requests.get(f"{KLAATU_SERVER_URL}/experiment").json()
except requests.exceptions.ConnectionError:
logging.error("No URL or experiment slug provided, exiting.")
exit()
else:
for item in data:
if isinstance(item, dict):
continue
else:
url = item
yield url yield url
return_data = {"url": url} return_data = {"url": url}
requests.put(f"{KLAATU_SERVER_URL}/experiment", json=return_data) try:
requests.put(f"{KLAATU_SERVER_URL}/experiment", json=return_data)
except requests.exceptions.ConnectionError:
pass
@pytest.fixture(name="json_data") @pytest.fixture(name="json_data")
@ -116,13 +149,17 @@ def fixture_send_test_results():
with open(f"{here.resolve()}/results/index.html", "rb") as f: with open(f"{here.resolve()}/results/index.html", "rb") as f:
files = {"file": f} files = {"file": f}
requests.post(f"{KLAATU_SERVER_URL}/test_results", files=files) try:
requests.post(f"{KLAATU_SERVER_URL}/test_results", files=files)
except requests.exceptions.ConnectionError:
pass
@pytest.fixture(name="setup_experiment", params=load_branches(), autouse=True) @pytest.fixture(name="setup_experiment")
def fixture_setup_experiment(experiment_slug, json_data, gradlewbuild_log, request): def fixture_setup_experiment(experiment_slug, json_data, gradlewbuild_log):
def _(): def _(branch):
command = f"nimbus-cli --app fenix --channel developer enroll {experiment_slug} --branch {request.param} --file {json_data} --reset-app" 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"
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:

@ -1,4 +1,4 @@
[pytest] [pytest]
addopts = --verbose --html=results/index.html --self-contained-html addopts = --verbose --html=results/index.html --self-contained-html --variables=variables.yaml
log_cli = true log_cli = true
log_cli_level = info log_cli_level = info

@ -1,3 +1,12 @@
def test_survey_navigates_correctly(setup_experiment, gradlewbuild): import pytest
setup_experiment()
@pytest.mark.parametrize("load_branches", [("branch")], indirect=True)
def test_survey_navigates_correctly(setup_experiment, gradlewbuild, load_branches):
setup_experiment(load_branches)
gradlewbuild.test("SurveyExperimentIntegrationTest#checkSurveyNavigatesCorrectly") gradlewbuild.test("SurveyExperimentIntegrationTest#checkSurveyNavigatesCorrectly")
@pytest.mark.parametrize("load_branches", [("branch")], indirect=True)
def test_survey_no_thanks_navigates_correctly(setup_experiment, gradlewbuild, load_branches):
setup_experiment(load_branches)
gradlewbuild.test("SurveyExperimentIntegrationTest#checkSurveyNoThanksNavigatesCorrectly")

@ -0,0 +1,3 @@
urls:
stage_server: "https://stage.experimenter.nonprod.dataops.mozgcp.net"
prod_server: "https://experimenter.services.mozilla.com"

@ -82,6 +82,11 @@ interface FeatureSettingsHelper {
*/ */
var tabsTrayRewriteEnabled: Boolean var tabsTrayRewriteEnabled: Boolean
/**
* Enable or disable the Top Sites to Compose rewrite.
*/
var composeTopSitesEnabled: Boolean
fun applyFlagUpdates() fun applyFlagUpdates()
fun resetAllFeatureFlags() fun resetAllFeatureFlags()

@ -37,6 +37,7 @@ class FeatureSettingsHelperDelegate() : FeatureSettingsHelper {
isOpenInAppBannerEnabled = settings.shouldShowOpenInAppBanner, isOpenInAppBannerEnabled = settings.shouldShowOpenInAppBanner,
etpPolicy = getETPPolicy(settings), etpPolicy = getETPPolicy(settings),
tabsTrayRewriteEnabled = settings.enableTabsTrayToCompose, tabsTrayRewriteEnabled = settings.enableTabsTrayToCompose,
composeTopSitesEnabled = settings.enableComposeTopSites,
) )
/** /**
@ -66,6 +67,7 @@ class FeatureSettingsHelperDelegate() : FeatureSettingsHelper {
override var isOpenInAppBannerEnabled: Boolean by updatedFeatureFlags::isOpenInAppBannerEnabled override var isOpenInAppBannerEnabled: Boolean by updatedFeatureFlags::isOpenInAppBannerEnabled
override var etpPolicy: ETPPolicy by updatedFeatureFlags::etpPolicy override var etpPolicy: ETPPolicy by updatedFeatureFlags::etpPolicy
override var tabsTrayRewriteEnabled: Boolean by updatedFeatureFlags::tabsTrayRewriteEnabled override var tabsTrayRewriteEnabled: Boolean by updatedFeatureFlags::tabsTrayRewriteEnabled
override var composeTopSitesEnabled: Boolean by updatedFeatureFlags::composeTopSitesEnabled
override fun applyFlagUpdates() { override fun applyFlagUpdates() {
applyFeatureFlags(updatedFeatureFlags) applyFeatureFlags(updatedFeatureFlags)
@ -91,6 +93,7 @@ class FeatureSettingsHelperDelegate() : FeatureSettingsHelper {
settings.userOptOutOfReEngageCookieBannerDialog = !featureFlags.isCookieBannerReductionDialogEnabled settings.userOptOutOfReEngageCookieBannerDialog = !featureFlags.isCookieBannerReductionDialogEnabled
settings.shouldShowOpenInAppBanner = featureFlags.isOpenInAppBannerEnabled settings.shouldShowOpenInAppBanner = featureFlags.isOpenInAppBannerEnabled
settings.enableTabsTrayToCompose = featureFlags.tabsTrayRewriteEnabled settings.enableTabsTrayToCompose = featureFlags.tabsTrayRewriteEnabled
settings.enableComposeTopSites = featureFlags.composeTopSitesEnabled
setETPPolicy(featureFlags.etpPolicy) setETPPolicy(featureFlags.etpPolicy)
} }
} }
@ -110,6 +113,7 @@ private data class FeatureFlags(
var isOpenInAppBannerEnabled: Boolean, var isOpenInAppBannerEnabled: Boolean,
var etpPolicy: ETPPolicy, var etpPolicy: ETPPolicy,
var tabsTrayRewriteEnabled: Boolean, var tabsTrayRewriteEnabled: Boolean,
var composeTopSitesEnabled: Boolean,
) )
internal fun getETPPolicy(settings: Settings): ETPPolicy { internal fun getETPPolicy(settings: Settings): ETPPolicy {

@ -56,6 +56,7 @@ class HomeActivityTestRule(
isOpenInAppBannerEnabled: Boolean = settings.shouldShowOpenInAppBanner, isOpenInAppBannerEnabled: Boolean = settings.shouldShowOpenInAppBanner,
etpPolicy: ETPPolicy = getETPPolicy(settings), etpPolicy: ETPPolicy = getETPPolicy(settings),
tabsTrayRewriteEnabled: Boolean = false, tabsTrayRewriteEnabled: Boolean = false,
composeTopSitesEnabled: Boolean = false,
) : this(initialTouchMode, launchActivity, skipOnboarding) { ) : this(initialTouchMode, launchActivity, skipOnboarding) {
this.isHomeOnboardingDialogEnabled = isHomeOnboardingDialogEnabled this.isHomeOnboardingDialogEnabled = isHomeOnboardingDialogEnabled
this.isPocketEnabled = isPocketEnabled this.isPocketEnabled = isPocketEnabled
@ -70,6 +71,7 @@ class HomeActivityTestRule(
this.isOpenInAppBannerEnabled = isOpenInAppBannerEnabled this.isOpenInAppBannerEnabled = isOpenInAppBannerEnabled
this.etpPolicy = etpPolicy this.etpPolicy = etpPolicy
this.tabsTrayRewriteEnabled = tabsTrayRewriteEnabled this.tabsTrayRewriteEnabled = tabsTrayRewriteEnabled
this.composeTopSitesEnabled = composeTopSitesEnabled
} }
/** /**
@ -114,6 +116,7 @@ class HomeActivityTestRule(
launchActivity: Boolean = true, launchActivity: Boolean = true,
skipOnboarding: Boolean = false, skipOnboarding: Boolean = false,
tabsTrayRewriteEnabled: Boolean = false, tabsTrayRewriteEnabled: Boolean = false,
composeTopSitesEnabled: Boolean = false,
) = HomeActivityTestRule( ) = HomeActivityTestRule(
initialTouchMode = initialTouchMode, initialTouchMode = initialTouchMode,
launchActivity = launchActivity, launchActivity = launchActivity,
@ -125,6 +128,7 @@ class HomeActivityTestRule(
isWallpaperOnboardingEnabled = false, isWallpaperOnboardingEnabled = false,
isCookieBannerReductionDialogEnabled = false, isCookieBannerReductionDialogEnabled = false,
isOpenInAppBannerEnabled = false, isOpenInAppBannerEnabled = false,
composeTopSitesEnabled = composeTopSitesEnabled,
) )
} }
} }
@ -164,6 +168,7 @@ class HomeActivityIntentTestRule internal constructor(
isOpenInAppBannerEnabled: Boolean = settings.shouldShowOpenInAppBanner, isOpenInAppBannerEnabled: Boolean = settings.shouldShowOpenInAppBanner,
etpPolicy: ETPPolicy = getETPPolicy(settings), etpPolicy: ETPPolicy = getETPPolicy(settings),
tabsTrayRewriteEnabled: Boolean = false, tabsTrayRewriteEnabled: Boolean = false,
composeTopSitesEnabled: Boolean = false,
) : this(initialTouchMode, launchActivity, skipOnboarding) { ) : this(initialTouchMode, launchActivity, skipOnboarding) {
this.isHomeOnboardingDialogEnabled = isHomeOnboardingDialogEnabled this.isHomeOnboardingDialogEnabled = isHomeOnboardingDialogEnabled
this.isPocketEnabled = isPocketEnabled this.isPocketEnabled = isPocketEnabled
@ -178,6 +183,7 @@ class HomeActivityIntentTestRule internal constructor(
this.isOpenInAppBannerEnabled = isOpenInAppBannerEnabled this.isOpenInAppBannerEnabled = isOpenInAppBannerEnabled
this.etpPolicy = etpPolicy this.etpPolicy = etpPolicy
this.tabsTrayRewriteEnabled = tabsTrayRewriteEnabled this.tabsTrayRewriteEnabled = tabsTrayRewriteEnabled
this.composeTopSitesEnabled = composeTopSitesEnabled
} }
private val longTapUserPreference = getLongPressTimeout() private val longTapUserPreference = getLongPressTimeout()
@ -259,6 +265,7 @@ class HomeActivityIntentTestRule internal constructor(
launchActivity: Boolean = true, launchActivity: Boolean = true,
skipOnboarding: Boolean = false, skipOnboarding: Boolean = false,
tabsTrayRewriteEnabled: Boolean = false, tabsTrayRewriteEnabled: Boolean = false,
composeTopSitesEnabled: Boolean = false,
) = HomeActivityIntentTestRule( ) = HomeActivityIntentTestRule(
initialTouchMode = initialTouchMode, initialTouchMode = initialTouchMode,
launchActivity = launchActivity, launchActivity = launchActivity,
@ -270,6 +277,7 @@ class HomeActivityIntentTestRule internal constructor(
isWallpaperOnboardingEnabled = false, isWallpaperOnboardingEnabled = false,
isCookieBannerReductionDialogEnabled = false, isCookieBannerReductionDialogEnabled = false,
isOpenInAppBannerEnabled = false, isOpenInAppBannerEnabled = false,
composeTopSitesEnabled = composeTopSitesEnabled,
) )
} }
} }

@ -56,7 +56,7 @@ object MockWebServerHelper {
* If the dispatcher is unable to read a requested asset, it will fail the test by throwing an * If the dispatcher is unable to read a requested asset, it will fail the test by throwing an
* Exception on the main thread. * Exception on the main thread.
* *
* @sample [org.mozilla.fenix.ui.NavigationToolbarTest.visitURLTest] * @sample [org.mozilla.fenix.ui.BookmarksTest.verifyBookmarkButtonTest]
*/ */
const val HTTP_OK = 200 const val HTTP_OK = 200
const val HTTP_NOT_FOUND = 404 const val HTTP_NOT_FOUND = 404

@ -187,9 +187,11 @@ object TestHelper {
val storageVolume: StorageVolume = storageVolumes[0] val storageVolume: StorageVolume = storageVolumes[0]
val file = File(storageVolume.directory!!.path + "/Download/" + fileName) val file = File(storageVolume.directory!!.path + "/Download/" + fileName)
try { try {
file.delete() if (file.exists()) {
Log.d("TestLog", "File delete try 1") file.delete()
assertFalse("The file was not deleted", file.exists()) Log.d("TestLog", "File delete try 1")
assertFalse("The file was not deleted", file.exists())
}
} catch (e: AssertionError) { } catch (e: AssertionError) {
file.delete() file.delete()
Log.d("TestLog", "File delete retried") Log.d("TestLog", "File delete retried")

@ -37,7 +37,7 @@
"sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082",
"sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"
], ],
"index": "pypi", "markers": "python_version >= '3.6'",
"version": "==2023.7.22" "version": "==2023.7.22"
}, },
"cffi": { "cffi": {
@ -192,32 +192,32 @@
}, },
"cryptography": { "cryptography": {
"hashes": [ "hashes": [
"sha256:01f1d9e537f9a15b037d5d9ee442b8c22e3ae11ce65ea1f3316a41c78756b711", "sha256:0d09fb5356f975974dbcb595ad2d178305e5050656affb7890a1583f5e02a306",
"sha256:079347de771f9282fbfe0e0236c716686950c19dee1b76240ab09ce1624d76d7", "sha256:23c2d778cf829f7d0ae180600b17e9fceea3c2ef8b31a99e3c694cbbf3a24b84",
"sha256:182be4171f9332b6741ee818ec27daff9fb00349f706629f5cbf417bd50e66fd", "sha256:3fb248989b6363906827284cd20cca63bb1a757e0a2864d4c1682a985e3dca47",
"sha256:192255f539d7a89f2102d07d7375b1e0a81f7478925b3bc2e0549ebf739dae0e", "sha256:41d7aa7cdfded09b3d73a47f429c298e80796c8e825ddfadc84c8a7f12df212d",
"sha256:2a034bf7d9ca894720f2ec1d8b7b5832d7e363571828037f9e0c4f18c1b58a58", "sha256:42cb413e01a5d36da9929baa9d70ca90d90b969269e5a12d39c1e0d475010116",
"sha256:342f3767e25876751e14f8459ad85e77e660537ca0a066e10e75df9c9e9099f0", "sha256:4c2f0d35703d61002a2bbdcf15548ebb701cfdd83cdc12471d2bae80878a4207",
"sha256:439c3cc4c0d42fa999b83ded80a9a1fb54d53c58d6e59234cfe97f241e6c781d", "sha256:4fd871184321100fb400d759ad0cddddf284c4b696568204d281c902fc7b0d81",
"sha256:49c3222bb8f8e800aead2e376cbef687bc9e3cb9b58b29a261210456a7783d83", "sha256:5259cb659aa43005eb55a0e4ff2c825ca111a0da1814202c64d28a985d33b087",
"sha256:674b669d5daa64206c38e507808aae49904c988fa0a71c935e7006a3e1e83831", "sha256:57a51b89f954f216a81c9d057bf1a24e2f36e764a1ca9a501a6964eb4a6800dd",
"sha256:7a9a3bced53b7f09da251685224d6a260c3cb291768f54954e28f03ef14e3766", "sha256:652627a055cb52a84f8c448185922241dd5217443ca194d5739b44612c5e6507",
"sha256:7af244b012711a26196450d34f483357e42aeddb04128885d95a69bd8b14b69b", "sha256:67e120e9a577c64fe1f611e53b30b3e69744e5910ff3b6e97e935aeb96005858",
"sha256:7d230bf856164de164ecb615ccc14c7fc6de6906ddd5b491f3af90d3514c925c", "sha256:6af1c6387c531cd364b72c28daa29232162010d952ceb7e5ca8e2827526aceae",
"sha256:84609ade00a6ec59a89729e87a503c6e36af98ddcd566d5f3be52e29ba993182", "sha256:6d192741113ef5e30d89dcb5b956ef4e1578f304708701b8b73d38e3e1461f34",
"sha256:9a6673c1828db6270b76b22cc696f40cde9043eb90373da5c2f8f2158957f42f", "sha256:7efe8041897fe7a50863e51b77789b657a133c75c3b094e51b5e4b5cec7bf906",
"sha256:9b6d717393dbae53d4e52684ef4f022444fc1cce3c48c38cb74fca29e1f08eaa", "sha256:84537453d57f55a50a5b6835622ee405816999a7113267739a1b4581f83535bd",
"sha256:9c3fe6534d59d071ee82081ca3d71eed3210f76ebd0361798c74abc2bcf347d4", "sha256:8f09daa483aedea50d249ef98ed500569841d6498aa9c9f4b0531b9964658922",
"sha256:a719399b99377b218dac6cf547b6ec54e6ef20207b6165126a280b0ce97e0d2a", "sha256:95dd7f261bb76948b52a5330ba5202b91a26fbac13ad0e9fc8a3ac04752058c7",
"sha256:b332cba64d99a70c1e0836902720887fb4529ea49ea7f5462cf6640e095e11d2", "sha256:a74fbcdb2a0d46fe00504f571a2a540532f4c188e6ccf26f1f178480117b33c4",
"sha256:d124682c7a23c9764e54ca9ab5b308b14b18eba02722b8659fb238546de83a76", "sha256:a983e441a00a9d57a4d7c91b3116a37ae602907a7618b882c8013b5762e80574",
"sha256:d73f419a56d74fef257955f51b18d046f3506270a5fd2ac5febbfa259d6c0fa5", "sha256:ab8de0d091acbf778f74286f4989cf3d1528336af1b59f3e5d2ebca8b5fe49e1",
"sha256:f0dc40e6f7aa37af01aba07277d3d64d5a03dc66d682097541ec4da03cc140ee", "sha256:aeb57c421b34af8f9fe830e1955bf493a86a7996cc1338fe41b30047d16e962c",
"sha256:f14ad275364c8b4e525d018f6716537ae7b6d369c094805cae45300847e0894f", "sha256:ce785cf81a7bdade534297ef9e490ddff800d956625020ab2ec2780a556c313e",
"sha256:f772610fe364372de33d76edcd313636a25684edb94cee53fd790195f5989d14" "sha256:d0d651aa754ef58d75cec6edfbd21259d93810b73f6ec246436a21b7841908de"
], ],
"markers": "python_version >= '3.7'", "index": "pypi",
"version": "==41.0.2" "version": "==41.0.3"
}, },
"distro": { "distro": {
"hashes": [ "hashes": [
@ -229,11 +229,11 @@
}, },
"exceptiongroup": { "exceptiongroup": {
"hashes": [ "hashes": [
"sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5", "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9",
"sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f" "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"
], ],
"markers": "python_version < '3.11'", "markers": "python_version < '3.11'",
"version": "==1.1.2" "version": "==1.1.3"
}, },
"fxapom": { "fxapom": {
"hashes": [ "hashes": [
@ -373,11 +373,11 @@
}, },
"pluggy": { "pluggy": {
"hashes": [ "hashes": [
"sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849", "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12",
"sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3" "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.8'",
"version": "==1.2.0" "version": "==1.3.0"
}, },
"progressbar2": { "progressbar2": {
"hashes": [ "hashes": [
@ -495,19 +495,19 @@
}, },
"selenium": { "selenium": {
"hashes": [ "hashes": [
"sha256:40241b9d872f58959e9b34e258488bf11844cd86142fd68182bd41db9991fc5c", "sha256:95be6aa449a0ab4ac1198bb9de71bbe9170405e04b9752f4b450dc7292a21828",
"sha256:871bf800c4934f745b909c8dfc7d15c65cf45bd2e943abd54451c810ada395e3" "sha256:b2c48b1440db54a0653300d9955f5421390723d53b36ec835e18de8e13bbd401"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.8'",
"version": "==4.10.0" "version": "==4.12.0"
}, },
"setuptools": { "setuptools": {
"hashes": [ "hashes": [
"sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f", "sha256:00478ca80aeebeecb2f288d3206b0de568df5cd2b8fada1209843cc9a8d88a48",
"sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235" "sha256:af3d5949030c3f493f550876b2fd1dd5ec66689c4ee5d5344f009746f71fd5a8"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.8'",
"version": "==68.0.0" "version": "==68.2.0"
}, },
"six": { "six": {
"hashes": [ "hashes": [
@ -557,11 +557,11 @@
}, },
"trio-websocket": { "trio-websocket": {
"hashes": [ "hashes": [
"sha256:1a748604ad906a7dcab9a43c6eb5681e37de4793ba0847ef0bc9486933ed027b", "sha256:c7a620c4013c34b7e4477d89fe76695da1e455e4510a8d7ae13f81c632bdce1d",
"sha256:a9937d48e8132ebf833019efde2a52ca82d223a30a7ea3e8d60a7d28f75a4e3a" "sha256:e66b3db3e2453017431dfbd352081006654e1241c2a6800dc2f43d7df54d55c5"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==0.10.3" "version": "==0.10.4"
}, },
"typing-extensions": { "typing-extensions": {
"hashes": [ "hashes": [

@ -4,34 +4,28 @@
package org.mozilla.fenix.ui package org.mozilla.fenix.ui
import androidx.core.net.toUri import androidx.compose.ui.test.junit4.AndroidComposeTestRule
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.customannotations.SmokeTest 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.HomeActivityTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
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.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.searchScreen import org.mozilla.fenix.ui.robots.searchScreen
class AddToHomeScreenTest { class AddToHomeScreenTest {
private lateinit var mockWebServer: MockWebServer private lateinit var mockWebServer: MockWebServer
private val downloadTestPage =
"https://storage.googleapis.com/mobile_test_assets/test_app/downloads.html"
private val pdfFileName = "washington.pdf"
private val pdfFileURL = "storage.googleapis.com/mobile_test_assets/public/washington.pdf"
private val pdfFileContent = "Washington Crossing the Delaware"
@get:Rule @get:Rule
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() val composeTestRule =
AndroidComposeTestRule(HomeActivityTestRule.withDefaultSettingsOverrides()) { it.activity }
@Before @Before
fun setUp() { fun setUp() {
@ -76,17 +70,15 @@ class AddToHomeScreenTest {
} }
} }
@Ignore("Failure, more details at: https://bugzilla.mozilla.org/show_bug.cgi?id=1830005")
@SmokeTest @SmokeTest
@Test @Test
fun addPrivateBrowsingShortcutTest() { fun addPrivateBrowsingShortcutTest() {
homeScreen {
}.dismissOnboarding()
homeScreen { homeScreen {
}.triggerPrivateBrowsingShortcutPrompt { }.triggerPrivateBrowsingShortcutPrompt {
verifyNoThanksPrivateBrowsingShortcutButton() verifyNoThanksPrivateBrowsingShortcutButton(composeTestRule)
verifyAddPrivateBrowsingShortcutButton() verifyAddPrivateBrowsingShortcutButton(composeTestRule)
clickAddPrivateBrowsingShortcutButton() clickAddPrivateBrowsingShortcutButton(composeTestRule)
clickAddAutomaticallyButton() clickAddAutomaticallyButton()
}.openHomeScreenShortcut("Private ${TestHelper.appName}") {} }.openHomeScreenShortcut("Private ${TestHelper.appName}") {}
searchScreen { searchScreen {
@ -95,23 +87,4 @@ class AddToHomeScreenTest {
verifyCommonMythsLink() verifyCommonMythsLink()
} }
} }
@SmokeTest
@Test
fun addPDFToHomeScreenTest() {
navigationToolbar {
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
clickPageObject(itemContainingText(pdfFileName))
verifyUrl(pdfFileURL)
verifyPageContent(pdfFileContent)
}.openThreeDotMenu {
expandMenu()
}.openAddToHomeScreen {
verifyShortcutTextFieldTitle(pdfFileName)
clickAddShortcutButton()
clickAddAutomaticallyButton()
}.openHomeScreenShortcut(pdfFileName) {
verifyUrl(pdfFileURL)
}
}
} }

@ -41,6 +41,7 @@ class AddressAutofillTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836845
@SmokeTest @SmokeTest
@Test @Test
fun verifyAddressAutofillTest() { fun verifyAddressAutofillTest() {
@ -81,6 +82,7 @@ class AddressAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836856
@SmokeTest @SmokeTest
@Test @Test
fun deleteSavedAddressTest() { fun deleteSavedAddressTest() {
@ -111,6 +113,7 @@ class AddressAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836840
@Test @Test
fun verifyAddAddressViewTest() { fun verifyAddAddressViewTest() {
homeScreen { homeScreen {
@ -124,6 +127,7 @@ class AddressAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836841
@Test @Test
fun verifyEditAddressViewTest() { fun verifyEditAddressViewTest() {
homeScreen { homeScreen {
@ -149,6 +153,7 @@ class AddressAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836839
@Test @Test
fun verifyAddressAutofillToggleTest() { fun verifyAddressAutofillToggleTest() {
val addressFormPage = val addressFormPage =
@ -196,6 +201,7 @@ class AddressAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836847
@Test @Test
fun verifyManageAddressesPromptOptionTest() { fun verifyManageAddressesPromptOptionTest() {
val addressFormPage = val addressFormPage =
@ -234,9 +240,10 @@ class AddressAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836849
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1814032") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1814032")
@Test @Test
fun verifyAddressAutofillSelectionTest() { fun verifyMultipleAddressesSelectionTest() {
val addressFormPage = val addressFormPage =
TestAssetHelper.getAddressFormAsset(mockWebServer) TestAssetHelper.getAddressFormAsset(mockWebServer)
@ -301,6 +308,7 @@ class AddressAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836850
@Test @Test
fun verifySavedAddressCanBeEditedTest() { fun verifySavedAddressCanBeEditedTest() {
homeScreen { homeScreen {
@ -339,6 +347,7 @@ class AddressAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836848
@Test @Test
fun verifyStateFieldUpdatesInAccordanceWithCountryFieldTest() { fun verifyStateFieldUpdatesInAccordanceWithCountryFieldTest() {
homeScreen { homeScreen {
@ -355,6 +364,7 @@ class AddressAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836858
@Test @Test
fun verifyFormFieldCanBeFilledManuallyTest() { fun verifyFormFieldCanBeFilledManuallyTest() {
val addressFormPage = val addressFormPage =
@ -397,6 +407,7 @@ class AddressAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836838
@Test @Test
fun verifyAutofillAddressSectionTest() { fun verifyAutofillAddressSectionTest() {
homeScreen { homeScreen {

@ -27,7 +27,6 @@ import org.mozilla.fenix.helpers.MockBrowserDataHelper.createBookmarkItem
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
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
import org.mozilla.fenix.helpers.TestHelper.appContext import org.mozilla.fenix.helpers.TestHelper.appContext
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem
@ -81,6 +80,7 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/522919
@Test @Test
fun verifyEmptyBookmarksMenuTest() { fun verifyEmptyBookmarksMenuTest() {
homeScreen { homeScreen {
@ -93,18 +93,6 @@ class BookmarksTest {
verifyAddFolderButton() verifyAddFolderButton()
verifyCloseButton() verifyCloseButton()
verifyBookmarkTitle("Desktop Bookmarks") verifyBookmarkTitle("Desktop Bookmarks")
}
}
}
@Test
fun defaultDesktopBookmarksFoldersTest() {
homeScreen {
}.openThreeDotMenu {
}.openBookmarks {
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1),
) {
selectFolder("Desktop Bookmarks") selectFolder("Desktop Bookmarks")
verifyFolderTitle("Bookmarks Menu") verifyFolderTitle("Bookmarks Menu")
verifyFolderTitle("Bookmarks Toolbar") verifyFolderTitle("Bookmarks Toolbar")
@ -116,54 +104,31 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2301370
@Test @Test
fun verifyBookmarkButtonTest() { fun verifyAddBookmarkButtonTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {
}.openThreeDotMenu { }.openThreeDotMenu {
}.bookmarkPage { }.bookmarkPage {
verifySnackBarText("Bookmark saved!")
}.openThreeDotMenu { }.openThreeDotMenu {
verifyEditBookmarkButton() verifyEditBookmarkButton()
}
}
@Test
fun addBookmarkTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen {
createBookmark(defaultWebPage.url)
}.openThreeDotMenu {
}.openBookmarks { }.openBookmarks {
registerAndCleanupIdlingResources( registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2), RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
) { ) {
verifyBookmarksMenuView()
verifyBookmarkTitle(defaultWebPage.title)
verifyBookmarkedURL(defaultWebPage.url.toString()) verifyBookmarkedURL(defaultWebPage.url.toString())
verifyBookmarkFavicon(defaultWebPage.url) verifyBookmarkFavicon(defaultWebPage.url)
} }
} }
} }
@Test // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/522920
fun createBookmarkFolderTest() {
homeScreen {
}.openThreeDotMenu {
}.openBookmarks {
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1),
) {
clickAddFolderButton()
verifyKeyboardVisible()
addNewFolderName(bookmarksFolderName)
saveNewFolder()
verifyFolderTitle(bookmarksFolderName)
verifyKeyboardHidden()
}
}
}
@Test @Test
fun cancelCreateBookmarkFolderTest() { fun cancelCreateBookmarkFolderTest() {
homeScreen { homeScreen {
@ -177,9 +142,9 @@ class BookmarksTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2299619
@Test @Test
fun cancelEditBookmarkTest() { fun cancelingChangesInEditModeAreNotSavedTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -202,9 +167,10 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325633
@SmokeTest @SmokeTest
@Test @Test
fun editBookmarkTest() { fun editBookmarksNameAndUrlTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen { browserScreen {
@ -229,6 +195,7 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/341696
@Test @Test
fun copyBookmarkURLTest() { fun copyBookmarkURLTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -255,8 +222,9 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325634
@Test @Test
fun threeDotMenuShareBookmarkTest() { fun shareBookmarkTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen { browserScreen {
@ -275,6 +243,7 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325636
@Test @Test
fun openBookmarkInNewTabTest() { fun openBookmarkInNewTabTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -293,9 +262,10 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1919261
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268")
@Test @Test
fun openAllInTabsTest() { fun verifyOpenAllInNewTabsOptionTest() {
val webPages = listOf( val webPages = listOf(
TestAssetHelper.getGenericAsset(mockWebServer, 1), TestAssetHelper.getGenericAsset(mockWebServer, 1),
TestAssetHelper.getGenericAsset(mockWebServer, 2), TestAssetHelper.getGenericAsset(mockWebServer, 2),
@ -336,9 +306,10 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1919262
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268")
@Test @Test
fun openAllInPrivateTabsTest() { fun verifyOpenAllInPrivateTabsTest() {
val webPages = listOf( val webPages = listOf(
TestAssetHelper.getGenericAsset(mockWebServer, 1), TestAssetHelper.getGenericAsset(mockWebServer, 1),
TestAssetHelper.getGenericAsset(mockWebServer, 2), TestAssetHelper.getGenericAsset(mockWebServer, 2),
@ -372,6 +343,7 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325637
@Test @Test
fun openBookmarkInPrivateTabTest() { fun openBookmarkInPrivateTabTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -390,30 +362,11 @@ class BookmarksTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325635
@Test @Test
fun deleteBookmarkTest() { fun deleteBookmarkTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen {
createBookmark(defaultWebPage.url)
}.openThreeDotMenu {
}.openBookmarks {
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
) {}
}.openThreeDotMenu(defaultWebPage.title) {
}.clickDelete {
verifyDeleteSnackBarText()
verifyUndoDeleteSnackBarButton()
}
}
@SmokeTest
@Test
fun undoDeleteBookmarkTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen { browserScreen {
createBookmark(defaultWebPage.url) createBookmark(defaultWebPage.url)
}.openThreeDotMenu { }.openThreeDotMenu {
@ -431,10 +384,13 @@ class BookmarksTest {
) { ) {
verifyBookmarkedURL(defaultWebPage.url.toString()) verifyBookmarkedURL(defaultWebPage.url.toString())
} }
}.openThreeDotMenu(defaultWebPage.title) {
}.clickDelete {
verifyBookmarkIsDeleted(defaultWebPage.title)
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2300275
@Test @Test
fun bookmarksMultiSelectionToolbarItemsTest() { fun bookmarksMultiSelectionToolbarItemsTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -460,9 +416,10 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2300276
@SmokeTest @SmokeTest
@Test @Test
fun openSelectionInNewTabTest() { fun openMultipleSelectedBookmarksInANewTabTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen { browserScreen {
@ -489,9 +446,9 @@ class BookmarksTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2300277
@Test @Test
fun openSelectionInPrivateTabTest() { fun openMultipleSelectedBookmarksInPrivateTabTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen { browserScreen {
@ -513,9 +470,10 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325644
@SmokeTest @SmokeTest
@Test @Test
fun deleteMultipleSelectionTest() { fun deleteMultipleSelectedBookmarksTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
@ -539,20 +497,9 @@ class BookmarksTest {
bookmarksMenu { bookmarksMenu {
verifyDeleteMultipleBookmarksSnackBar() verifyDeleteMultipleBookmarksSnackBar()
} clickUndoDeleteButton()
} verifyBookmarkedURL(firstWebPage.url.toString())
verifyBookmarkedURL(secondWebPage.url.toString())
@SmokeTest
@Test
fun undoDeleteMultipleSelectionTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
browserScreen {
createBookmark(firstWebPage.url)
createBookmark(secondWebPage.url)
}.openThreeDotMenu {
}.openBookmarks {
registerAndCleanupIdlingResources( registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 3), RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 3),
) { ) {
@ -568,14 +515,12 @@ class BookmarksTest {
bookmarksMenu { bookmarksMenu {
verifyDeleteMultipleBookmarksSnackBar() verifyDeleteMultipleBookmarksSnackBar()
clickUndoDeleteButton()
verifyBookmarkedURL(firstWebPage.url.toString())
verifyBookmarkedURL(secondWebPage.url.toString())
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2301355
@Test @Test
fun multipleSelectionShareButtonTest() { fun shareMultipleSelectedBookmarksTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen { browserScreen {
@ -598,43 +543,9 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325639
@Test @Test
fun multipleBookmarkDeletionsTest() { fun createBookmarkFolderTest() {
homeScreen {
}.openThreeDotMenu {
}.openBookmarks {
createFolder("1")
getInstrumentation().waitForIdleSync()
createFolder("2")
getInstrumentation().waitForIdleSync()
createFolder("3")
getInstrumentation().waitForIdleSync()
}.openThreeDotMenu("1") {
}.clickDelete {
verifyDeleteFolderConfirmationMessage()
confirmDeletion()
verifyDeleteSnackBarText()
}.openThreeDotMenu("2") {
}.clickDelete {
verifyDeleteFolderConfirmationMessage()
confirmDeletion()
verifyDeleteSnackBarText()
verifyFolderTitle("3")
// On some devices we need to wait for the Snackbar to be gone before continuing
TestHelper.waitUntilSnackbarGone()
}.closeMenu {
}
homeScreen {
}.openThreeDotMenu {
}.openBookmarks {
verifyFolderTitle("3")
}
}
@SmokeTest
@Test
fun changeBookmarkParentFolderTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen { browserScreen {
@ -643,13 +554,13 @@ class BookmarksTest {
}.openBookmarks { }.openBookmarks {
registerAndCleanupIdlingResources( registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2), RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
) { ) {}
createFolder(bookmarksFolderName)
}
}.openThreeDotMenu(defaultWebPage.title) { }.openThreeDotMenu(defaultWebPage.title) {
}.clickEdit { }.clickEdit {
clickParentFolderSelector() clickParentFolderSelector()
selectFolder(bookmarksFolderName) clickAddNewFolderButtonFromSelectFolderView()
addNewFolderName(bookmarksFolderName)
saveNewFolder()
navigateUp() navigateUp()
saveEditBookmark() saveEditBookmark()
selectFolder(bookmarksFolderName) selectFolder(bookmarksFolderName)
@ -657,6 +568,7 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325645
@Test @Test
fun navigateBookmarksFoldersTest() { fun navigateBookmarksFoldersTest() {
homeScreen { homeScreen {
@ -680,8 +592,9 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/374855
@Test @Test
fun cantSelectDesktopFoldersTest() { fun cantSelectDefaultFoldersTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openBookmarks { }.openBookmarks {
@ -694,16 +607,7 @@ class BookmarksTest {
} }
} }
@Test // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2299703
fun verifyCloseMenuTest() {
homeScreen {
}.openThreeDotMenu {
}.openBookmarks {
}.closeMenu {
verifyHomeScreen()
}
}
@Test @Test
fun deleteBookmarkInEditModeTest() { fun deleteBookmarkInEditModeTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -726,31 +630,7 @@ class BookmarksTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715710
@Test
fun undoDeleteBookmarkFolderTest() {
browserScreen {
}.openThreeDotMenu {
}.openBookmarks {
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1),
) {
createFolder("My Folder")
verifyFolderTitle("My Folder")
}
}.openThreeDotMenu("My Folder") {
}.clickDelete {
cancelFolderDeletion()
verifyFolderTitle("My Folder")
}.openThreeDotMenu("My Folder") {
}.clickDelete {
confirmDeletion()
verifyDeleteSnackBarText()
clickUndoDeleteButton()
verifyFolderTitle("My Folder")
}
}
@Test @Test
fun verifySearchBookmarksViewTest() { fun verifySearchBookmarksViewTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -788,6 +668,7 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715712
@Test @Test
fun verifySearchForBookmarkedItemsTest() { fun verifySearchForBookmarkedItemsTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -803,13 +684,13 @@ class BookmarksTest {
// Search for a valid term // Search for a valid term
typeSearch(firstWebPage.title) typeSearch(firstWebPage.title)
verifySearchEngineSuggestionResults(activityTestRule, firstWebPage.url.toString(), searchTerm = firstWebPage.title) verifySearchEngineSuggestionResults(activityTestRule, firstWebPage.url.toString(), searchTerm = firstWebPage.title)
verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString())
}.dismissSearchBar {} }.dismissSearchBar {}
bookmarksMenu { bookmarksMenu {
}.clickSearchButton { }.clickSearchButton {
// Search for invalid term // Search for invalid term
typeSearch("Android") typeSearch("Android")
verifyNoSuggestionsAreDisplayed( verifySuggestionsAreNotDisplayed(
activityTestRule, activityTestRule,
firstWebPage.url.toString(), firstWebPage.url.toString(),
secondWebPage.url.toString(), secondWebPage.url.toString(),
@ -817,6 +698,7 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715711
@Test @Test
fun verifyVoiceSearchInBookmarksTest() { fun verifyVoiceSearchInBookmarksTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -832,8 +714,9 @@ class BookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715714
@Test @Test
fun verifyDeletedBookmarksCanNotBeSearchedTest() { fun verifyDeletedBookmarksAreNotDisplayedAsSearchResultsTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
val thirdWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3) val thirdWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3)
@ -853,8 +736,8 @@ class BookmarksTest {
}.clickSearchButton { }.clickSearchButton {
// Search for a valid term // Search for a valid term
typeSearch("generic") typeSearch("generic")
verifyNoSuggestionsAreDisplayed(activityTestRule, firstWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString())
verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString())
verifySearchEngineSuggestionResults(activityTestRule, thirdWebPage.url.toString(), searchTerm = "generic") verifySearchEngineSuggestionResults(activityTestRule, thirdWebPage.url.toString(), searchTerm = "generic")
pressBack() pressBack()
} }
@ -865,7 +748,54 @@ class BookmarksTest {
}.clickSearchButton { }.clickSearchButton {
// Search for a valid term // Search for a valid term
typeSearch("generic") typeSearch("generic")
verifyNoSuggestionsAreDisplayed(activityTestRule, thirdWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, thirdWebPage.url.toString())
}
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325642
@SmokeTest
@Test
fun deleteBookmarkFoldersTest() {
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen {
createBookmark(website.url)
}.openThreeDotMenu {
}.openBookmarks {
verifyBookmarkTitle("Test_Page_1")
createFolder("My Folder")
verifyFolderTitle("My Folder")
}.openThreeDotMenu("Test_Page_1") {
}.clickEdit {
clickParentFolderSelector()
selectFolder("My Folder")
navigateUp()
saveEditBookmark()
createFolder("My Folder 2")
verifyFolderTitle("My Folder 2")
}.openThreeDotMenu("My Folder 2") {
}.clickEdit {
clickParentFolderSelector()
selectFolder("My Folder")
navigateUp()
saveEditBookmark()
}.openThreeDotMenu("My Folder") {
}.clickDelete {
cancelFolderDeletion()
verifyFolderTitle("My Folder")
}.openThreeDotMenu("My Folder") {
}.clickDelete {
confirmDeletion()
verifyDeleteSnackBarText()
clickUndoDeleteButton()
verifyFolderTitle("My Folder")
}.openThreeDotMenu("My Folder") {
}.clickDelete {
confirmDeletion()
verifyDeleteSnackBarText()
verifyBookmarkIsDeleted("My Folder")
verifyBookmarkIsDeleted("My Folder 2")
verifyBookmarkIsDeleted("Test_Page_1")
} }
} }
} }

@ -15,6 +15,7 @@ import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest 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.TestAssetHelper
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.browserScreen
@ -94,6 +95,19 @@ class CollectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2283299
@Test
fun createFirstCollectionFromMainMenuTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
}.openThreeDotMenu {
}.openSaveToCollection {
verifyCollectionNameTextField()
}
}
@SmokeTest @SmokeTest
@Test @Test
fun verifyExpandedCollectionItemsTest() { fun verifyExpandedCollectionItemsTest() {

@ -24,7 +24,6 @@ import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
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
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.exitMenu
import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem
@ -91,18 +90,6 @@ class ComposeBookmarksTest {
verifyAddFolderButton() verifyAddFolderButton()
verifyCloseButton() verifyCloseButton()
verifyBookmarkTitle("Desktop Bookmarks") verifyBookmarkTitle("Desktop Bookmarks")
}
}
}
@Test
fun defaultDesktopBookmarksFoldersTest() {
homeScreen {
}.openThreeDotMenu {
}.openBookmarks {
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1),
) {
selectFolder("Desktop Bookmarks") selectFolder("Desktop Bookmarks")
verifyFolderTitle("Bookmarks Menu") verifyFolderTitle("Bookmarks Menu")
verifyFolderTitle("Bookmarks Toolbar") verifyFolderTitle("Bookmarks Toolbar")
@ -114,54 +101,6 @@ class ComposeBookmarksTest {
} }
} }
@Test
fun verifyBookmarkButtonTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
}.openThreeDotMenu {
}.bookmarkPage {
}.openThreeDotMenu {
verifyEditBookmarkButton()
}
}
@Test
fun addBookmarkTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen {
createBookmark(defaultWebPage.url)
}.openThreeDotMenu {
}.openBookmarks {
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
) {
verifyBookmarkedURL(defaultWebPage.url.toString())
verifyBookmarkFavicon(defaultWebPage.url)
}
}
}
@Test
fun createBookmarkFolderTest() {
homeScreen {
}.openThreeDotMenu {
}.openBookmarks {
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1),
) {
clickAddFolderButton()
verifyKeyboardVisible()
addNewFolderName(bookmarksFolderName)
saveNewFolder()
verifyFolderTitle(bookmarksFolderName)
verifyKeyboardHidden()
}
}
}
@Test @Test
fun cancelCreateBookmarkFolderTest() { fun cancelCreateBookmarkFolderTest() {
homeScreen { homeScreen {
@ -175,9 +114,8 @@ class ComposeBookmarksTest {
} }
} }
@SmokeTest
@Test @Test
fun cancelEditBookmarkTest() { fun cancelingChangesInEditModeAreNotSavedTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -202,7 +140,7 @@ class ComposeBookmarksTest {
@SmokeTest @SmokeTest
@Test @Test
fun editBookmarkTest() { fun editBookmarksNameAndUrlTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen { browserScreen {
@ -292,7 +230,7 @@ class ComposeBookmarksTest {
} }
@Test @Test
fun openAllInTabsTest() { fun verifyOpenAllInNewTabsOptionTest() {
val webPages = listOf( val webPages = listOf(
TestAssetHelper.getGenericAsset(mockWebServer, 1), TestAssetHelper.getGenericAsset(mockWebServer, 1),
TestAssetHelper.getGenericAsset(mockWebServer, 2), TestAssetHelper.getGenericAsset(mockWebServer, 2),
@ -334,7 +272,7 @@ class ComposeBookmarksTest {
} }
@Test @Test
fun openAllInPrivateTabsTest() { fun verifyOpenAllInPrivateTabsTest() {
val webPages = listOf( val webPages = listOf(
TestAssetHelper.getGenericAsset(mockWebServer, 1), TestAssetHelper.getGenericAsset(mockWebServer, 1),
TestAssetHelper.getGenericAsset(mockWebServer, 2), TestAssetHelper.getGenericAsset(mockWebServer, 2),
@ -386,30 +324,10 @@ class ComposeBookmarksTest {
} }
} }
@SmokeTest
@Test @Test
fun deleteBookmarkTest() { fun deleteBookmarkTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen {
createBookmark(defaultWebPage.url)
}.openThreeDotMenu {
}.openBookmarks {
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
) {}
}.openThreeDotMenu(defaultWebPage.title) {
}.clickDelete {
verifyDeleteSnackBarText()
verifyUndoDeleteSnackBarButton()
}
}
@SmokeTest
@Test
fun undoDeleteBookmarkTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen { browserScreen {
createBookmark(defaultWebPage.url) createBookmark(defaultWebPage.url)
}.openThreeDotMenu { }.openThreeDotMenu {
@ -427,10 +345,12 @@ class ComposeBookmarksTest {
) { ) {
verifyBookmarkedURL(defaultWebPage.url.toString()) verifyBookmarkedURL(defaultWebPage.url.toString())
} }
}.openThreeDotMenu(defaultWebPage.title) {
}.clickDelete {
verifyBookmarkIsDeleted(defaultWebPage.title)
} }
} }
@SmokeTest
@Test @Test
fun bookmarksMultiSelectionToolbarItemsTest() { fun bookmarksMultiSelectionToolbarItemsTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -458,7 +378,7 @@ class ComposeBookmarksTest {
@SmokeTest @SmokeTest
@Test @Test
fun openSelectionInNewTabTest() { fun openMultipleSelectedBookmarksInANewTabTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen { browserScreen {
@ -486,9 +406,8 @@ class ComposeBookmarksTest {
} }
} }
@SmokeTest
@Test @Test
fun openSelectionInPrivateTabTest() { fun openMultipleSelectedBookmarksInPrivateTabTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen { browserScreen {
@ -512,7 +431,7 @@ class ComposeBookmarksTest {
@SmokeTest @SmokeTest
@Test @Test
fun deleteMultipleSelectionTest() { fun deleteMultipleSelectedBookmarksTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
@ -536,20 +455,9 @@ class ComposeBookmarksTest {
bookmarksMenu { bookmarksMenu {
verifyDeleteMultipleBookmarksSnackBar() verifyDeleteMultipleBookmarksSnackBar()
} clickUndoDeleteButton()
} verifyBookmarkedURL(firstWebPage.url.toString())
verifyBookmarkedURL(secondWebPage.url.toString())
@SmokeTest
@Test
fun undoDeleteMultipleSelectionTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
browserScreen {
createBookmark(firstWebPage.url)
createBookmark(secondWebPage.url)
}.openThreeDotMenu {
}.openBookmarks {
registerAndCleanupIdlingResources( registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 3), RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 3),
) { ) {
@ -565,9 +473,6 @@ class ComposeBookmarksTest {
bookmarksMenu { bookmarksMenu {
verifyDeleteMultipleBookmarksSnackBar() verifyDeleteMultipleBookmarksSnackBar()
clickUndoDeleteButton()
verifyBookmarkedURL(firstWebPage.url.toString())
verifyBookmarkedURL(secondWebPage.url.toString())
} }
} }
@ -596,42 +501,7 @@ class ComposeBookmarksTest {
} }
@Test @Test
fun multipleBookmarkDeletionsTest() { fun createBookmarkFolderTest() {
homeScreen {
}.openThreeDotMenu {
}.openBookmarks {
createFolder("1")
getInstrumentation().waitForIdleSync()
createFolder("2")
getInstrumentation().waitForIdleSync()
createFolder("3")
getInstrumentation().waitForIdleSync()
}.openThreeDotMenu("1") {
}.clickDelete {
verifyDeleteFolderConfirmationMessage()
confirmDeletion()
verifyDeleteSnackBarText()
}.openThreeDotMenu("2") {
}.clickDelete {
verifyDeleteFolderConfirmationMessage()
confirmDeletion()
verifyDeleteSnackBarText()
verifyFolderTitle("3")
// On some devices we need to wait for the Snackbar to be gone before continuing
TestHelper.waitUntilSnackbarGone()
}.closeMenu {
}
homeScreen {
}.openThreeDotMenu {
}.openBookmarks {
verifyFolderTitle("3")
}
}
@SmokeTest
@Test
fun changeBookmarkParentFolderTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen { browserScreen {
@ -640,13 +510,13 @@ class ComposeBookmarksTest {
}.openBookmarks { }.openBookmarks {
registerAndCleanupIdlingResources( registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2), RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2),
) { ) {}
createFolder(bookmarksFolderName)
}
}.openThreeDotMenu(defaultWebPage.title) { }.openThreeDotMenu(defaultWebPage.title) {
}.clickEdit { }.clickEdit {
clickParentFolderSelector() clickParentFolderSelector()
selectFolder(bookmarksFolderName) clickAddNewFolderButtonFromSelectFolderView()
addNewFolderName(bookmarksFolderName)
saveNewFolder()
navigateUp() navigateUp()
saveEditBookmark() saveEditBookmark()
selectFolder(bookmarksFolderName) selectFolder(bookmarksFolderName)
@ -691,16 +561,6 @@ class ComposeBookmarksTest {
} }
} }
@Test
fun verifyCloseMenuTest() {
homeScreen {
}.openThreeDotMenu {
}.openBookmarks {
}.closeMenu {
verifyHomeScreen()
}
}
@Test @Test
fun deleteBookmarkInEditModeTest() { fun deleteBookmarkInEditModeTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -723,31 +583,6 @@ class ComposeBookmarksTest {
} }
} }
@SmokeTest
@Test
fun undoDeleteBookmarkFolderTest() {
browserScreen {
}.openThreeDotMenu {
}.openBookmarks {
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1),
) {
createFolder("My Folder")
verifyFolderTitle("My Folder")
}
}.openThreeDotMenu("My Folder") {
}.clickDelete {
cancelFolderDeletion()
verifyFolderTitle("My Folder")
}.openThreeDotMenu("My Folder") {
}.clickDelete {
confirmDeletion()
verifyDeleteSnackBarText()
clickUndoDeleteButton()
verifyFolderTitle("My Folder")
}
}
@Test @Test
fun verifySearchBookmarksViewTest() { fun verifySearchBookmarksViewTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -788,6 +623,7 @@ class ComposeBookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715712
@Test @Test
fun verifySearchForBookmarkedItemsTest() { fun verifySearchForBookmarkedItemsTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -810,11 +646,11 @@ class ComposeBookmarksTest {
// Search for a valid term // Search for a valid term
typeSearch(firstWebPage.title) typeSearch(firstWebPage.title)
verifySearchEngineSuggestionResults(activityTestRule, firstWebPage.url.toString(), searchTerm = firstWebPage.title) verifySearchEngineSuggestionResults(activityTestRule, firstWebPage.url.toString(), searchTerm = firstWebPage.title)
verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString())
// Search for invalid term // Search for invalid term
typeSearch("Android") typeSearch("Android")
verifyNoSuggestionsAreDisplayed(activityTestRule, firstWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString())
verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString())
} }
} }
@ -833,8 +669,9 @@ class ComposeBookmarksTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715714
@Test @Test
fun verifyDeletedBookmarksCanNotBeSearchedTest() { fun verifyDeletedBookmarksAreNotDisplayedAsSearchResultsTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
val thirdWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3) val thirdWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3)
@ -854,8 +691,8 @@ class ComposeBookmarksTest {
}.clickSearchButton { }.clickSearchButton {
// Search for a valid term // Search for a valid term
typeSearch("generic") typeSearch("generic")
verifyNoSuggestionsAreDisplayed(activityTestRule, firstWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString())
verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString())
verifySearchEngineSuggestionResults(activityTestRule, thirdWebPage.url.toString(), searchTerm = "generic") verifySearchEngineSuggestionResults(activityTestRule, thirdWebPage.url.toString(), searchTerm = "generic")
pressBack() pressBack()
} }
@ -866,7 +703,55 @@ class ComposeBookmarksTest {
}.clickSearchButton { }.clickSearchButton {
// Search for a valid term // Search for a valid term
typeSearch("generic") typeSearch("generic")
verifyNoSuggestionsAreDisplayed(activityTestRule, thirdWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, thirdWebPage.url.toString())
}
}
// Verifies that deleting a Bookmarks folder also removes the item from inside it.
@SmokeTest
@Test
fun deleteBookmarkFoldersTest() {
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen {
createBookmark(website.url)
}.openThreeDotMenu {
}.openBookmarks {
verifyBookmarkTitle("Test_Page_1")
createFolder("My Folder")
verifyFolderTitle("My Folder")
}.openThreeDotMenu("Test_Page_1") {
}.clickEdit {
clickParentFolderSelector()
selectFolder("My Folder")
navigateUp()
saveEditBookmark()
createFolder("My Folder 2")
verifyFolderTitle("My Folder 2")
}.openThreeDotMenu("My Folder 2") {
}.clickEdit {
clickParentFolderSelector()
selectFolder("My Folder")
navigateUp()
saveEditBookmark()
}.openThreeDotMenu("My Folder") {
}.clickDelete {
cancelFolderDeletion()
verifyFolderTitle("My Folder")
}.openThreeDotMenu("My Folder") {
}.clickDelete {
confirmDeletion()
verifyDeleteSnackBarText()
clickUndoDeleteButton()
verifyFolderTitle("My Folder")
}.openThreeDotMenu("My Folder") {
}.clickDelete {
confirmDeletion()
verifyDeleteSnackBarText()
verifyBookmarkIsDeleted("My Folder")
verifyBookmarkIsDeleted("My Folder 2")
verifyBookmarkIsDeleted("Test_Page_1")
navigateUp()
} }
} }
} }

@ -15,12 +15,13 @@ import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.Constants
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.itemWithText import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
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.assertYoutubeAppOpens import org.mozilla.fenix.helpers.TestHelper.assertExternalAppOpens
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
import org.mozilla.fenix.ui.robots.clickContextMenuItem import org.mozilla.fenix.ui.robots.clickContextMenuItem
import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.clickPageObject
@ -235,7 +236,7 @@ class ComposeContextMenusTest {
} }
downloadRobot { downloadRobot {
verifyDownloadNotificationPopup() verifyDownloadCompleteNotificationPopup()
}.clickOpen("image/jpeg") {} // verify open intent is matched with associated data type }.clickOpen("image/jpeg") {} // verify open intent is matched with associated data type
downloadRobot { downloadRobot {
verifyPhotosAppOpens() verifyPhotosAppOpens()
@ -291,9 +292,10 @@ class ComposeContextMenusTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {
longClickPageObject(itemContainingText("Youtube link")) longClickPageObject(itemContainingText("Youtube full link"))
verifyContextMenuForLinksToOtherApps("youtube.com")
clickContextMenuItem("Open link in external app") clickContextMenuItem("Open link in external app")
assertYoutubeAppOpens() assertExternalAppOpens(Constants.PackageName.YOUTUBE_APP)
} }
} }
} }

@ -75,7 +75,7 @@ class ComposeHistoryTest {
} }
@Test @Test
fun noHistoryItemsInCacheTest() { fun verifyEmptyHistoryMenuTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
verifyHistoryButton() verifyHistoryButton()
@ -87,8 +87,9 @@ class ComposeHistoryTest {
// 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
@Test @Test
fun visitedUrlHistoryTest() { fun verifyHistoryMenuWithHistoryItemsTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -104,6 +105,7 @@ class ComposeHistoryTest {
verifyVisitedTimeTitle() verifyVisitedTimeTitle()
verifyFirstTestPageTitle("Test_Page_1") verifyFirstTestPageTitle("Test_Page_1")
verifyTestPageUrl(firstWebPage.url) verifyTestPageUrl(firstWebPage.url)
verifyDeleteHistoryItemButton("Test_Page_1")
} }
} }
} }
@ -128,50 +130,6 @@ class ComposeHistoryTest {
} }
} }
@Test
fun undoDeleteHistoryItemTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(firstWebPage.url) {
mDevice.waitForIdle()
}.openThreeDotMenu {
}.openHistory {
verifyHistoryListExists()
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1),
) {
clickDeleteHistoryButton(firstWebPage.url.toString())
}
verifyUndoDeleteSnackBarButton()
clickUndoDeleteButton()
verifyHistoryItemExists(true, firstWebPage.url.toString())
}
}
@SmokeTest
@Test
fun cancelDeleteAllHistoryTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(firstWebPage.url) {
mDevice.waitForIdle()
}.openThreeDotMenu {
}.openHistory {
verifyHistoryListExists()
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1),
) {
clickDeleteAllHistoryButton()
}
verifyDeleteConfirmationMessage()
selectEverythingOption()
cancelDeleteHistory()
verifyHistoryItemExists(true, firstWebPage.url.toString())
}
}
@SmokeTest @SmokeTest
@Test @Test
fun deleteAllHistoryTest() { fun deleteAllHistoryTest() {
@ -226,7 +184,7 @@ class ComposeHistoryTest {
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268")
@Test @Test
fun openHistoryInNewTabTest() { fun openMultipleSelectedHistoryItemsInANewTabTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -255,7 +213,7 @@ class ComposeHistoryTest {
} }
@Test @Test
fun openHistoryInPrivateTabTest() { fun openMultipleSelectedHistoryItemsInPrivateTabTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -280,7 +238,7 @@ class ComposeHistoryTest {
} }
@Test @Test
fun deleteMultipleSelectionTest() { fun deleteMultipleSelectedHistoryItemsTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
@ -314,7 +272,7 @@ class ComposeHistoryTest {
} }
@Test @Test
fun shareButtonTest() { fun shareMultipleSelectedHistoryItemsTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -409,12 +367,12 @@ class ComposeHistoryTest {
// Search for a valid term // Search for a valid term
typeSearch(firstWebPage.title) typeSearch(firstWebPage.title)
verifySearchEngineSuggestionResults(activityTestRule, firstWebPage.url.toString(), searchTerm = firstWebPage.title) verifySearchEngineSuggestionResults(activityTestRule, firstWebPage.url.toString(), searchTerm = firstWebPage.title)
verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString())
clickClearButton() clickClearButton()
// Search for invalid term // Search for invalid term
typeSearch("Android") typeSearch("Android")
verifyNoSuggestionsAreDisplayed(activityTestRule, firstWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString())
verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString())
} }
} }
@ -445,8 +403,8 @@ class ComposeHistoryTest {
}.clickSearchButton { }.clickSearchButton {
// Search for a valid term // Search for a valid term
typeSearch("generic") typeSearch("generic")
verifyNoSuggestionsAreDisplayed(activityTestRule, firstWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString())
verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString())
verifySearchEngineSuggestionResults(activityTestRule, thirdWebPage.url.toString(), searchTerm = "generic") verifySearchEngineSuggestionResults(activityTestRule, thirdWebPage.url.toString(), searchTerm = "generic")
pressBack() pressBack()
} }
@ -456,7 +414,7 @@ class ComposeHistoryTest {
}.clickSearchButton { }.clickSearchButton {
// Search for a valid term // Search for a valid term
typeSearch("generic") typeSearch("generic")
verifyNoSuggestionsAreDisplayed(activityTestRule, thirdWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, thirdWebPage.url.toString())
} }
} }
} }

@ -63,7 +63,6 @@ class ComposeHomeScreenTest {
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1844580") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1844580")
@Test @Test
fun homeScreenItemsTest() { fun homeScreenItemsTest() {
homeScreen {}.dismissOnboarding()
homeScreen { homeScreen {
verifyHomeWordmark() verifyHomeWordmark()
verifyHomePrivateBrowsingButton() verifyHomePrivateBrowsingButton()
@ -86,7 +85,6 @@ class ComposeHomeScreenTest {
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/244199 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/244199
@Test @Test
fun privateBrowsingHomeScreenItemsTest() { fun privateBrowsingHomeScreenItemsTest() {
homeScreen { }.dismissOnboarding()
homeScreen { }.togglePrivateBrowsingMode() homeScreen { }.togglePrivateBrowsingMode()
homeScreen { homeScreen {

@ -5,7 +5,6 @@
package org.mozilla.fenix.ui package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.core.net.toUri
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import okhttp3.mockwebserver.MockWebServer import okhttp3.mockwebserver.MockWebServer
@ -16,11 +15,8 @@ import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestHelper.runWithSystemLocaleChanged import org.mozilla.fenix.helpers.TestHelper.runWithSystemLocaleChanged
import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.navigationToolbar
import java.util.Locale import java.util.Locale
@ -60,51 +56,6 @@ class ComposeNavigationToolbarTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
@Test
fun goBackTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val nextWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.waitForIdle()
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(nextWebPage.url) {
verifyUrl(nextWebPage.url.toString())
}.openThreeDotMenu {
}.goToPreviousPage {
mDevice.waitForIdle()
verifyUrl(defaultWebPage.url.toString())
}
}
@Test
fun goForwardTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val nextWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.waitForIdle()
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(nextWebPage.url) {
mDevice.waitForIdle()
verifyUrl(nextWebPage.url.toString())
}.openThreeDotMenu {
}.goToPreviousPage {
mDevice.waitForIdle()
verifyUrl(defaultWebPage.url.toString())
}
// Re-open the three-dot menu for verification
navigationToolbar {
}.openThreeDotMenu {
verifyThreeDotMenuExists()
}.goForward {
verifyUrl(nextWebPage.url.toString())
}
}
// Swipes the nav bar left/right to switch between tabs // Swipes the nav bar left/right to switch between tabs
@SmokeTest @SmokeTest
@Test @Test
@ -144,126 +95,4 @@ class ComposeNavigationToolbarTest {
} }
} }
} }
// Test running on beta/release builds in CI:
// caution when making changes to it, so they don't block the builds
@Test
fun visitURLTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
verifyUrl(defaultWebPage.url.toString())
}
}
@Test
fun findInPageTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.waitForIdle()
}.openThreeDotMenu {
verifyThreeDotMenuExists()
verifyFindInPageButton()
}.openFindInPage {
verifyFindInPageNextButton()
verifyFindInPagePrevButton()
verifyFindInPageCloseButton()
enterFindInPageQuery("a")
verifyFindNextInPageResult("1/3")
clickFindInPageNextButton()
verifyFindNextInPageResult("2/3")
clickFindInPageNextButton()
verifyFindNextInPageResult("3/3")
clickFindInPagePrevButton()
verifyFindPrevInPageResult("2/3")
clickFindInPagePrevButton()
verifyFindPrevInPageResult("1/3")
}.closeFindInPageWithCloseButton {
verifyFindInPageBar(false)
}.openThreeDotMenu {
}.openFindInPage {
enterFindInPageQuery("3")
verifyFindNextInPageResult("1/1")
}.closeFindInPageWithBackButton {
verifyFindInPageBar(false)
}
}
@Test
fun pdfFindInPageTest() {
val genericURL =
TestAssetHelper.getGenericAsset(mockWebServer, 3)
navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
clickPageObject(itemWithText("PDF form file"))
}.openThreeDotMenu {
verifyThreeDotMenuExists()
verifyFindInPageButton()
}.openFindInPage {
verifyFindInPageNextButton()
verifyFindInPagePrevButton()
verifyFindInPageCloseButton()
enterFindInPageQuery("l")
verifyFindNextInPageResult("1/2")
clickFindInPageNextButton()
verifyFindNextInPageResult("2/2")
clickFindInPagePrevButton()
verifyFindPrevInPageResult("1/2")
}.closeFindInPageWithCloseButton {
verifyFindInPageBar(false)
}.openThreeDotMenu {
}.openFindInPage {
enterFindInPageQuery("p")
verifyFindNextInPageResult("1/1")
}.closeFindInPageWithBackButton {
verifyFindInPageBar(false)
}
}
@SmokeTest
@Test
fun verifySecurePageSecuritySubMenuTest() {
val defaultWebPage = "https://mozilla-mobile.github.io/testapp/loginForm"
val defaultWebPageTitle = "Login_form"
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.toUri()) {
}.openSiteSecuritySheet {
verifyQuickActionSheet(defaultWebPage, true)
openSecureConnectionSubMenu(true)
verifySecureConnectionSubMenu(defaultWebPageTitle, defaultWebPage, true)
}
}
@SmokeTest
@Test
fun verifyInsecurePageSecuritySubMenuTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
waitForPageToLoad()
}.openSiteSecuritySheet {
verifyQuickActionSheet(defaultWebPage.url.toString(), false)
openSecureConnectionSubMenu(false)
verifySecureConnectionSubMenu(defaultWebPage.title, defaultWebPage.url.toString(), false)
}
}
@Test
fun verifyClearCookiesFromQuickSettingsTest() {
val helpPageUrl = "mozilla.org"
homeScreen {
}.openThreeDotMenu {
}.openHelp {
}.openSiteSecuritySheet {
clickQuickActionSheetClearSiteData()
verifyClearSiteDataPrompt(helpPageUrl)
}
}
} }

@ -666,7 +666,7 @@ class ComposeSearchTest {
clickSearchSelectorButton() clickSearchSelectorButton()
selectTemporarySearchMethod(searchEngineName = "Tabs") selectTemporarySearchMethod(searchEngineName = "Tabs")
typeSearch(searchTerm = "Mozilla") typeSearch(searchTerm = "Mozilla")
verifyNoSuggestionsAreDisplayed(rule = activityTestRule, "Mozilla") verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla")
clickClearButton() clickClearButton()
verifySearchBarPlaceholder("Search tabs") verifySearchBarPlaceholder("Search tabs")
} }
@ -686,7 +686,7 @@ class ComposeSearchTest {
clickSearchSelectorButton() clickSearchSelectorButton()
selectTemporarySearchMethod(searchEngineName = "Tabs") selectTemporarySearchMethod(searchEngineName = "Tabs")
typeSearch(searchTerm = "Mozilla") typeSearch(searchTerm = "Mozilla")
verifyNoSuggestionsAreDisplayed(rule = activityTestRule, "Mozilla") verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla")
clickClearButton() clickClearButton()
typeSearch(searchTerm = "generic") typeSearch(searchTerm = "generic")
verifyTypedToolbarText("generic") verifyTypedToolbarText("generic")
@ -725,7 +725,7 @@ class ComposeSearchTest {
}.clickSearchSelectorButton { }.clickSearchSelectorButton {
selectTemporarySearchMethod("Bookmarks") selectTemporarySearchMethod("Bookmarks")
typeSearch("test") typeSearch("test")
verifyNoSuggestionsAreDisplayed(activityTestRule, "test") verifySuggestionsAreNotDisplayed(activityTestRule, "test")
} }
} }
@ -752,7 +752,7 @@ class ComposeSearchTest {
}.dismissSearchBar { }.dismissSearchBar {
}.openSearch { }.openSearch {
typeSearch("mozilla ") typeSearch("mozilla ")
verifyNoSuggestionsAreDisplayed(activityTestRule, "Test1", "Test2") verifySuggestionsAreNotDisplayed(activityTestRule, "Test1", "Test2")
} }
} }
@ -776,7 +776,7 @@ class ComposeSearchTest {
clickSearchSelectorButton() clickSearchSelectorButton()
selectTemporarySearchMethod(searchEngineName = "History") selectTemporarySearchMethod(searchEngineName = "History")
typeSearch(searchTerm = "Mozilla") typeSearch(searchTerm = "Mozilla")
verifyNoSuggestionsAreDisplayed(rule = activityTestRule, "Mozilla") verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla")
clickClearButton() clickClearButton()
verifySearchBarPlaceholder("Search history") verifySearchBarPlaceholder("Search history")
} }

@ -68,7 +68,7 @@ class ComposeSettingsDeleteBrowsingDataOnQuitTest {
} }
@Test @Test
fun deleteBrowsingDataOnQuitSettingsItemsTest() { fun deleteBrowsingDataOnQuitSettingTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -120,7 +120,7 @@ class ComposeSettingsDeleteBrowsingDataOnQuitTest {
} }
@Test @Test
fun deleteHistoryOnQuitTest() { fun deleteBrowsingHistoryOnQuitTest() {
val genericPage = val genericPage =
getStorageTestAsset(mockWebServer, "generic1.html") getStorageTestAsset(mockWebServer, "generic1.html")
@ -147,6 +147,7 @@ class ComposeSettingsDeleteBrowsingDataOnQuitTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416051
@Test @Test
fun deleteCookiesAndSiteDataOnQuitTest() { fun deleteCookiesAndSiteDataOnQuitTest() {
val storageWritePage = val storageWritePage =
@ -198,7 +199,7 @@ class ComposeSettingsDeleteBrowsingDataOnQuitTest {
}.clickDownloadLink("smallZip.zip") { }.clickDownloadLink("smallZip.zip") {
verifyDownloadPrompt("smallZip.zip") verifyDownloadPrompt("smallZip.zip")
}.clickDownload { }.clickDownload {
verifyDownloadNotificationPopup() verifyDownloadCompleteNotificationPopup()
}.closeCompletedDownloadPrompt { }.closeCompletedDownloadPrompt {
}.goToHomescreen { }.goToHomescreen {
}.openThreeDotMenu { }.openThreeDotMenu {

@ -117,7 +117,7 @@ class ComposeSettingsDeleteBrowsingDataTest {
} }
@Test @Test
fun deleteTabsDataWithNoOpenTabsTest() { fun deleteOpenTabsBrowsingDataWithNoOpenTabsTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -135,7 +135,7 @@ class ComposeSettingsDeleteBrowsingDataTest {
@SmokeTest @SmokeTest
@Test @Test
fun deleteTabsDataTest() { fun deleteOpenTabsBrowsingDataTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {

@ -1,384 +1,238 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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, You can obtain one at http://mozilla.org/MPL/2.0/. */
@file:Suppress("DEPRECATION") @file:Suppress("DEPRECATION")
package org.mozilla.fenix.ui package org.mozilla.fenix.ui
import android.view.View import android.view.View
import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.ActivityTestRule import androidx.test.rule.ActivityTestRule
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.mediasession.MediaSession 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.Ignore import org.junit.Rule
import org.junit.Rule import org.junit.Test
import org.junit.Test import org.mozilla.fenix.IntentReceiverActivity
import org.mozilla.fenix.IntentReceiverActivity import org.mozilla.fenix.R
import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.ext.components
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.itemWithText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText 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.registerAndCleanupIdlingResources
import org.mozilla.fenix.helpers.TestHelper.assertYoutubeAppOpens import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource
import org.mozilla.fenix.helpers.TestHelper.registerAndCleanupIdlingResources import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.navigationToolbar
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
* Test Suite that contains a part of the Smoke and Sanity tests defined in TestRail: * Other smoke tests have been marked with the @SmokeTest annotation throughout the ui package in order to limit this class expansion.
* https://testrail.stage.mozaws.net/index.php?/suites/view/3192 * These tests will verify different functionalities of the app as a way to quickly detect regressions in main areas
* 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
@Suppress("ForbiddenComment") class ComposeSmokeTest {
@SmokeTest private lateinit var mDevice: UiDevice
class ComposeSmokeTest { private lateinit var mockWebServer: MockWebServer
private lateinit var mDevice: UiDevice private val customMenuItem = "TestMenuItem"
private lateinit var mockWebServer: MockWebServer private lateinit var browserStore: BrowserStore
private val customMenuItem = "TestMenuItem"
private lateinit var browserStore: BrowserStore @get:Rule(order = 0)
val activityTestRule = AndroidComposeTestRule(
@get:Rule(order = 0) HomeActivityIntentTestRule.withDefaultSettingsOverrides(
val activityTestRule = AndroidComposeTestRule( tabsTrayRewriteEnabled = true,
HomeActivityIntentTestRule.withDefaultSettingsOverrides( ),
tabsTrayRewriteEnabled = true, ) { it.activity }
),
) { it.activity } @get: Rule(order = 1)
val intentReceiverActivityTestRule = ActivityTestRule(
@get: Rule(order = 1) IntentReceiverActivity::class.java,
val intentReceiverActivityTestRule = ActivityTestRule( true,
IntentReceiverActivity::class.java, false,
true, )
false,
) @Rule(order = 2)
@JvmField
@Rule(order = 2) val retryTestRule = RetryTestRule(3)
@JvmField
val retryTestRule = RetryTestRule(3) @Before
fun setUp() {
@Before // Initializing this as part of class construction, below the rule would throw a NPE
fun setUp() { // So we are initializing this here instead of in all related tests.
// Initializing this as part of class construction, below the rule would throw a NPE browserStore = activityTestRule.activity.components.core.store
// 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 {
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) dispatcher = AndroidAssetDispatcher()
mockWebServer = MockWebServer().apply { start()
dispatcher = AndroidAssetDispatcher() }
start() }
}
} @After
fun tearDown() {
@After mockWebServer.shutdown()
fun tearDown() { }
mockWebServer.shutdown()
} @Test
fun shareTabsFromTabsTrayTest() {
// Device or AVD requires a Google Services Android OS installation with Play Store installed val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1)
// Verifies the Open in app button when an app is installed val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2)
@Test val firstWebsiteTitle = firstWebsite.title
fun mainMenuOpenInAppTest() { val secondWebsiteTitle = secondWebsite.title
val youtubeURL = "vnd.youtube://".toUri() val sharingApp = "Gmail"
val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}"
navigationToolbar {
}.enterURLAndEnterToBrowser(youtubeURL) { homeScreen {
verifyNotificationDotOnMainMenu() }.openNavigationToolbar {
}.openThreeDotMenu { }.enterURLAndEnterToBrowser(firstWebsite.url) {
}.clickOpenInApp { verifyPageContent(firstWebsite.content)
assertYoutubeAppOpens() }.openComposeTabDrawer(activityTestRule) {
} }.openNewTab {
} }.submitQuery(secondWebsite.url.toString()) {
verifyPageContent(secondWebsite.content)
// Verifies that deleting a Bookmarks folder also removes the item from inside it. }.openComposeTabDrawer(activityTestRule) {
@Test verifyExistingOpenTabs("Test_Page_1")
fun deleteNonEmptyBookmarkFolderTest() { verifyExistingOpenTabs("Test_Page_2")
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) }.openThreeDotMenu {
verifyShareAllTabsButton()
browserScreen { }.clickShareAllTabsButton {
createBookmark(website.url) verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle)
}.openThreeDotMenu { verifySharingWithSelectedApp(
}.openBookmarks { sharingApp,
verifyBookmarkTitle("Test_Page_1") sharedUrlsString,
createFolder("My Folder") "$firstWebsiteTitle, $secondWebsiteTitle",
verifyFolderTitle("My Folder") )
}.openThreeDotMenu("Test_Page_1") { }
}.clickEdit { }
clickParentFolderSelector()
selectFolder("My Folder") @Test
navigateUp() fun privateTabsTrayWithOpenedTabTest() {
saveEditBookmark() val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
createFolder("My Folder 2")
verifyFolderTitle("My Folder 2") homeScreen {
}.openThreeDotMenu("My Folder 2") { }.togglePrivateBrowsingMode()
}.clickEdit {
clickParentFolderSelector() homeScreen {
selectFolder("My Folder") }.openNavigationToolbar {
navigateUp() }.enterURLAndEnterToBrowser(website.url) {
saveEditBookmark() }.openComposeTabDrawer(activityTestRule) {
}.openThreeDotMenu("My Folder") { verifyNormalBrowsingButtonIsSelected(false)
}.clickDelete { verifyPrivateBrowsingButtonIsSelected(true)
cancelFolderDeletion() verifySyncedTabsButtonIsSelected(false)
verifyFolderTitle("My Folder") verifyThreeDotButton()
}.openThreeDotMenu("My Folder") { verifyNormalTabCounter()
}.clickDelete { verifyPrivateTabsList()
confirmDeletion() verifyExistingOpenTabs(website.title)
verifyDeleteSnackBarText() verifyTabCloseButton()
verifyBookmarkIsDeleted("My Folder") verifyTabThumbnail()
verifyBookmarkIsDeleted("My Folder 2") verifyFab()
verifyBookmarkIsDeleted("Test_Page_1") }
navigateUp() }
}
// Test running on beta/release builds in CI:
browserScreen { // caution when making changes to it, so they don't block the builds
}.openThreeDotMenu { @Test
verifyAddBookmarkButton() fun noHistoryInPrivateBrowsingTest() {
} val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
}
homeScreen {
@Test }.togglePrivateBrowsingMode()
fun shareTabsFromTabsTrayTest() {
val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1) homeScreen {
val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2) }.openNavigationToolbar {
val firstWebsiteTitle = firstWebsite.title }.enterURLAndEnterToBrowser(website.url) {
val secondWebsiteTitle = secondWebsite.title mDevice.waitForIdle()
val sharingApp = "Gmail" }.openThreeDotMenu {
val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}" }.openHistory {
verifyEmptyHistoryView()
homeScreen { }
}.openNavigationToolbar { }
}.enterURLAndEnterToBrowser(firstWebsite.url) {
verifyPageContent(firstWebsite.content) @Test
}.openComposeTabDrawer(activityTestRule) { fun mainMenuInstallPWATest() {
}.openNewTab { val pwaPage = "https://mozilla-mobile.github.io/testapp/"
}.submitQuery(secondWebsite.url.toString()) {
verifyPageContent(secondWebsite.content) navigationToolbar {
}.openComposeTabDrawer(activityTestRule) { }.enterURLAndEnterToBrowser(pwaPage.toUri()) {
verifyExistingOpenTabs("Test_Page_1") verifyNotificationDotOnMainMenu()
verifyExistingOpenTabs("Test_Page_2") }.openThreeDotMenu {
}.openThreeDotMenu { }.clickInstall {
verifyShareAllTabsButton() clickAddAutomaticallyButton()
}.clickShareAllTabsButton { }.openHomeScreenShortcut("TEST_APP") {
verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle) mDevice.waitForIdle()
verifySharingWithSelectedApp( verifyNavURLBarHidden()
sharingApp, }
sharedUrlsString, }
"$firstWebsiteTitle, $secondWebsiteTitle",
) // Verifies that reader mode is detected and the custom appearance controls are displayed
} @Test
} fun verifyReaderViewAppearanceUI() {
val readerViewPage =
@Test TestAssetHelper.getLoremIpsumAsset(mockWebServer)
fun privateTabsTrayWithOpenedTabTest() { val estimatedReadingTime = "1 - 2 minutes"
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
homeScreen { }.enterURLAndEnterToBrowser(readerViewPage.url) {
}.togglePrivateBrowsingMode() mDevice.waitForIdle()
}
homeScreen {
}.openNavigationToolbar { registerAndCleanupIdlingResources(
}.enterURLAndEnterToBrowser(website.url) { ViewVisibilityIdlingResource(
}.openComposeTabDrawer(activityTestRule) { activityTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
verifyNormalBrowsingButtonIsSelected(false) View.VISIBLE,
verifyPrivateBrowsingButtonIsSelected(true) ),
verifySyncedTabsButtonIsSelected(false) ) {}
verifyThreeDotButton()
verifyNormalTabCounter() navigationToolbar {
verifyPrivateTabsList() verifyReaderViewDetected(true)
verifyExistingOpenTabs(website.title) toggleReaderView()
verifyTabCloseButton() }
verifyTabThumbnail()
verifyFab() browserScreen {
} waitForPageToLoad()
} verifyPageContent(estimatedReadingTime)
}.openThreeDotMenu {
// Test running on beta/release builds in CI: verifyReaderViewAppearance(true)
// caution when making changes to it, so they don't block the builds }.openReaderViewAppearance {
@Test verifyAppearanceFontGroup(true)
fun noHistoryInPrivateBrowsingTest() { verifyAppearanceFontSansSerif(true)
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) verifyAppearanceFontSerif(true)
verifyAppearanceFontIncrease(true)
homeScreen { verifyAppearanceFontDecrease(true)
}.togglePrivateBrowsingMode() verifyAppearanceColorGroup(true)
verifyAppearanceColorDark(true)
homeScreen { verifyAppearanceColorLight(true)
}.openNavigationToolbar { verifyAppearanceColorSepia(true)
}.enterURLAndEnterToBrowser(website.url) { }
mDevice.waitForIdle() }
}.openThreeDotMenu {
}.openHistory { @Test
verifyEmptyHistoryView() fun tabMediaControlButtonTest() {
} val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
}
navigationToolbar {
@Test }.enterURLAndEnterToBrowser(audioTestPage.url) {
fun mainMenuInstallPWATest() { mDevice.waitForIdle()
val pwaPage = "https://mozilla-mobile.github.io/testapp/" clickPageObject(itemWithText("Play"))
assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING)
navigationToolbar { }.openComposeTabDrawer(activityTestRule) {
}.enterURLAndEnterToBrowser(pwaPage.toUri()) { verifyTabMediaControlButtonState("Pause")
verifyNotificationDotOnMainMenu() clickTabMediaControlButton("Pause")
}.openThreeDotMenu { verifyTabMediaControlButtonState("Play")
}.clickInstall { }.openTab(audioTestPage.title) {
clickAddAutomaticallyButton() assertPlaybackState(browserStore, MediaSession.PlaybackState.PAUSED)
}.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)
}
}
@Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1846941")
@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)
}
}
// For API>23
// Verifies the default browser switch opens the system default apps menu.
@Test
fun changeDefaultBrowserSetting() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
verifyDefaultBrowserToggle(false)
clickDefaultBrowserSwitch()
verifyAndroidDefaultAppsMenuAppears()
}
// Dismiss the request
mDevice.pressBack()
}
@Test
fun goToHomeScreenBottomToolbarTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
mDevice.waitForIdle()
}.goToHomescreen {
verifyHomeScreen()
}
}
@Test
fun goToHomeScreenTopToolbarTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openCustomizeSubMenu {
clickTopToolbarToggle()
}.goBack {
}.goBack {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
mDevice.waitForIdle()
}.goToHomescreen {
verifyHomeScreen()
}
}
@Test
fun goToHomeScreenBottomToolbarPrivateModeTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
togglePrivateBrowsingModeOnOff()
}
navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
mDevice.waitForIdle()
}.goToHomescreen {
verifyHomeScreen()
}
}
@Test
fun goToHomeScreenTopToolbarPrivateModeTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
togglePrivateBrowsingModeOnOff()
}.openThreeDotMenu {
}.openSettings {
}.openCustomizeSubMenu {
clickTopToolbarToggle()
}.goBack {
}.goBack {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
mDevice.waitForIdle()
}.goToHomescreen {
verifyHomeScreen()
}
}
}

@ -0,0 +1,256 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
import org.mozilla.fenix.helpers.TestHelper.generateRandomString
import org.mozilla.fenix.helpers.TestHelper.getStringResource
import org.mozilla.fenix.helpers.TestHelper.waitUntilSnackbarGone
import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.homeScreenWithComposeTopSites
import org.mozilla.fenix.ui.robots.navigationToolbar
/**
* Tests Top Sites functionality
*
* - Verifies 'Add to Firefox Home' UI functionality
* - Verifies 'Top Sites' context menu UI functionality
* - Verifies 'Top Site' usage UI functionality
* - Verifies existence of default top sites available on the home-screen
*/
class ComposeTopSitesTest {
private lateinit var mDevice: UiDevice
private lateinit var mockWebServer: MockWebServer
@get:Rule
val composeTestRule =
AndroidComposeTestRule(
HomeActivityTestRule.withDefaultSettingsOverrides(
composeTopSitesEnabled = true,
),
) { it.activity }
@Before
fun setUp() {
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher()
start()
}
}
@After
fun tearDown() {
mockWebServer.shutdown()
}
@SmokeTest
@Test
fun verifyAddToFirefoxHome() {
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)
}
}
@Test
fun verifyOpenTopSiteNormalTab() {
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)
}.openTopSiteTabWithTitle(title = defaultWebPage.title) {
verifyUrl(defaultWebPage.url.toString().replace("http://", ""))
}.goToHomescreenWithComposeTopSites(composeTestRule) {
verifyExistingTopSitesList()
verifyExistingTopSiteItem(defaultWebPage.title)
}.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) {
verifyTopSiteContextMenuItems()
}
// Dismiss context menu popup
mDevice.pressBack()
}
@Test
fun verifyOpenTopSitePrivateTab() {
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)
}.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) {
verifyTopSiteContextMenuItems()
}.openTopSiteInPrivate() {
verifyCurrentPrivateSession(composeTestRule.activity.applicationContext)
}
}
@Test
fun verifyRenameTopSite() {
val defaultWebPage = getGenericAsset(mockWebServer, 1)
val newPageTitle = generateRandomString(5)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
waitForPageToLoad()
}.openThreeDotMenu {
expandMenu()
verifyAddToShortcutsButton(true)
}.addToFirefoxHome {
verifySnackBarText(getStringResource(R.string.snackbar_added_to_shortcuts))
}.goToHomescreenWithComposeTopSites(composeTestRule) {
verifyExistingTopSitesList()
verifyExistingTopSiteItem(defaultWebPage.title)
}.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) {
verifyTopSiteContextMenuItems()
}.renameTopSite(newPageTitle) {
verifyExistingTopSitesList()
verifyExistingTopSiteItem(newPageTitle)
}
}
@Test
fun verifyRemoveTopSite() {
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)
}.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) {
verifyTopSiteContextMenuItems()
}.removeTopSite {
verifyNotExistingTopSiteItem(defaultWebPage.title)
}
}
@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)
}.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) {
verifyTopSiteContextMenuItems()
}.removeTopSite {
clickSnackbarButton("UNDO")
verifyExistingTopSiteItem(defaultWebPage.title)
}
}
@Test
fun verifyRemoveTopSiteFromMainMenu() {
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)
}.openTopSiteTabWithTitle(defaultWebPage.title) {
}.openThreeDotMenu {
verifyRemoveFromShortcutsButton()
}.clickRemoveFromShortcuts {
}.goToHomescreenWithComposeTopSites(composeTestRule) {
verifyNotExistingTopSiteItem(defaultWebPage.title)
}
}
// Expected for en-us defaults
@Test
fun verifyDefaultTopSitesList() {
homeScreenWithComposeTopSites(composeTestRule) {
verifyExistingTopSitesList()
val topSitesTitles = arrayListOf("Google", "Top Articles", "Wikipedia")
topSitesTitles.forEach { value ->
verifyExistingTopSiteItem(value)
}
}
}
@SmokeTest
@Test
fun addAndRemoveMostViewedTopSiteTest() {
val defaultWebPage = getGenericAsset(mockWebServer, 1)
for (i in 0..1) {
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
waitForPageToLoad()
}
}
browserScreen {
}.goToHomescreenWithComposeTopSites(composeTestRule) {
verifyExistingTopSitesList()
verifyExistingTopSiteItem(defaultWebPage.title)
}.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) {
}.deleteTopSiteFromHistory {
verifySnackBarText(getStringResource(R.string.snackbar_top_site_removed))
waitUntilSnackbarGone()
}.openThreeDotMenu {
}.openHistory {
verifyEmptyHistoryView()
}
}
}

@ -15,12 +15,13 @@ import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.Constants.PackageName.YOUTUBE_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.itemWithText import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
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.assertYoutubeAppOpens import org.mozilla.fenix.helpers.TestHelper.assertExternalAppOpens
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
import org.mozilla.fenix.ui.robots.clickContextMenuItem import org.mozilla.fenix.ui.robots.clickContextMenuItem
import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.clickPageObject
@ -231,7 +232,7 @@ class ContextMenusTest {
} }
downloadRobot { downloadRobot {
verifyDownloadNotificationPopup() verifyDownloadCompleteNotificationPopup()
}.clickOpen("image/jpeg") {} // verify open intent is matched with associated data type }.clickOpen("image/jpeg") {} // verify open intent is matched with associated data type
downloadRobot { downloadRobot {
verifyPhotosAppOpens() verifyPhotosAppOpens()
@ -287,10 +288,10 @@ class ContextMenusTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {
longClickPageObject(itemContainingText("Youtube link")) longClickPageObject(itemContainingText("Youtube full link"))
verifyContextMenuForLinksToOtherApps("youtube.com".toUri()) verifyContextMenuForLinksToOtherApps("youtube.com")
clickContextMenuItem("Open link in external app") clickContextMenuItem("Open link in external app")
assertYoutubeAppOpens() assertExternalAppOpens(YOUTUBE_APP)
} }
} }
} }

@ -14,17 +14,17 @@ import org.mozilla.fenix.helpers.TestHelper.exitMenu
import org.mozilla.fenix.helpers.TestHelper.restartApp import org.mozilla.fenix.helpers.TestHelper.restartApp
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
import org.mozilla.fenix.ui.robots.navigationToolbar
class CookieBannerReductionTest { class CookieBannerReductionTest {
@get:Rule @get:Rule
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true) val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1980504
// Bug causing flakiness https://bugzilla.mozilla.org/show_bug.cgi?id=1807440 // Bug causing flakiness https://bugzilla.mozilla.org/show_bug.cgi?id=1807440
@Ignore("Disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1852803") @Ignore("Disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1852803")
@SmokeTest @SmokeTest
@Test @Test
fun verifyCookieBannerReductionTest() { fun verifyCookieBannerReductionFunctionalityTest() {
val webSite = "startsiden.no" val webSite = "startsiden.no"
homeScreen { homeScreen {
@ -69,55 +69,4 @@ class CookieBannerReductionTest {
verifyCookieBannerExists(exists = false) verifyCookieBannerExists(exists = false)
} }
} }
// Bug causing flakiness https://bugzilla.mozilla.org/show_bug.cgi?id=1807440
@SmokeTest
@Test
fun verifyCookieBannerReductionInPrivateBrowsingTest() {
val webSite = "startsiden.no"
homeScreen {
}.togglePrivateBrowsingMode()
navigationToolbar {
}.enterURLAndEnterToBrowser(webSite.toUri()) {
waitForPageToLoad()
verifyCookieBannerExists(exists = true)
}.openThreeDotMenu {
}.openSettings {
verifySettingsOptionSummary("Cookie banner reduction", "Off")
}.openCookieBannerReductionSubMenu {
verifyCookieBannerView(isCookieBannerReductionChecked = false)
clickCookieBannerReductionToggle()
verifyCheckedCookieBannerReductionToggle(isCookieBannerReductionChecked = true)
}.goBack {
verifySettingsOptionSummary("Cookie banner reduction", "On")
}
exitMenu()
browserScreen {
verifyCookieBannerExists(exists = false)
}
restartApp(activityTestRule)
homeScreen {
}.openTabDrawer {
}.openTab("Startsiden.no") {
verifyCookieBannerExists(exists = false)
}.openThreeDotMenu {
}.openSettings {
}.openCookieBannerReductionSubMenu {
clickCookieBannerReductionToggle()
verifyCheckedCookieBannerReductionToggle(false)
exitMenu()
}
browserScreen {
waitForPageToLoad()
}.openThreeDotMenu {
}.refreshPage {
verifyCookieBannerExists(exists = false)
}
}
} }

@ -62,6 +62,7 @@ class CreditCardAutofillTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512792
@SmokeTest @SmokeTest
@Test @Test
fun verifyCreditCardAutofillTest() { fun verifyCreditCardAutofillTest() {
@ -99,32 +100,10 @@ class CreditCardAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512798
@SmokeTest @SmokeTest
@Test @Test
fun deleteSavedCreditCardUsingToolbarButtonTest() { fun deleteSavedCreditCardUsingToolbarButtonTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openAutofillSubMenu {
clickAddCreditCardButton()
fillAndSaveCreditCard(
MockCreditCard1.MOCK_CREDIT_CARD_NUMBER,
MockCreditCard1.MOCK_NAME_ON_CARD,
MockCreditCard1.MOCK_EXPIRATION_MONTH,
MockCreditCard1.MOCK_EXPIRATION_YEAR,
)
clickManageSavedCreditCardsButton()
clickSecuredCreditCardsLaterButton()
clickSavedCreditCard()
clickDeleteCreditCardToolbarButton()
clickConfirmDeleteCreditCardButton()
verifyAddCreditCardsButton()
}
}
@SmokeTest
@Test
fun cancelDeleteSavedCreditCardUsingToolbarButtonTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -142,35 +121,16 @@ class CreditCardAutofillTest {
clickDeleteCreditCardToolbarButton() clickDeleteCreditCardToolbarButton()
clickCancelDeleteCreditCardButton() clickCancelDeleteCreditCardButton()
verifyEditCreditCardToolbarTitle() verifyEditCreditCardToolbarTitle()
} clickDeleteCreditCardToolbarButton()
}
@SmokeTest
@Test
fun deleteSavedCreditCardUsingMenuButtonTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openAutofillSubMenu {
clickAddCreditCardButton()
fillAndSaveCreditCard(
MockCreditCard1.MOCK_CREDIT_CARD_NUMBER,
MockCreditCard1.MOCK_NAME_ON_CARD,
MockCreditCard1.MOCK_EXPIRATION_MONTH,
MockCreditCard1.MOCK_EXPIRATION_YEAR,
)
clickManageSavedCreditCardsButton()
clickSecuredCreditCardsLaterButton()
clickSavedCreditCard()
clickDeleteCreditCardMenuButton()
clickConfirmDeleteCreditCardButton() clickConfirmDeleteCreditCardButton()
verifyAddCreditCardsButton() verifyAddCreditCardsButton()
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2271192
@SmokeTest @SmokeTest
@Test @Test
fun cancelDeleteSavedCreditCardUsingMenuButtonTest() { fun deleteSavedCreditCardUsingMenuButtonTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -188,9 +148,13 @@ class CreditCardAutofillTest {
clickDeleteCreditCardMenuButton() clickDeleteCreditCardMenuButton()
clickCancelDeleteCreditCardButton() clickCancelDeleteCreditCardButton()
verifyEditCreditCardToolbarTitle() verifyEditCreditCardToolbarTitle()
clickDeleteCreditCardMenuButton()
clickConfirmDeleteCreditCardButton()
verifyAddCreditCardsButton()
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512788
@Test @Test
fun verifyCreditCardsSectionTest() { fun verifyCreditCardsSectionTest() {
homeScreen { homeScreen {
@ -214,6 +178,7 @@ class CreditCardAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1859917
@Test @Test
fun verifyManageCreditCardsPromptOptionTest() { fun verifyManageCreditCardsPromptOptionTest() {
val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer)
@ -243,6 +208,7 @@ class CreditCardAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512790
@Test @Test
fun verifyCreditCardsAutofillToggleTest() { fun verifyCreditCardsAutofillToggleTest() {
val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer)
@ -283,6 +249,7 @@ class CreditCardAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512795
@Test @Test
fun verifyEditCardsViewTest() { fun verifyEditCardsViewTest() {
homeScreen { homeScreen {
@ -318,6 +285,7 @@ class CreditCardAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512796
@Test @Test
fun verifyEditedCardIsSavedTest() { fun verifyEditedCardIsSavedTest() {
val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer)
@ -365,8 +333,9 @@ class CreditCardAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512797
@Test @Test
fun verifyCreditCardCannotBeSavedWithoutCardNumberTest() { fun verifyCreditCardCannotBeSavedWithoutCardNumberOrNameTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -390,29 +359,7 @@ class CreditCardAutofillTest {
clickSaveCreditCardToolbarButton() clickSaveCreditCardToolbarButton()
verifyEditCreditCardToolbarTitle() verifyEditCreditCardToolbarTitle()
verifyCreditCardNumberErrorMessage() verifyCreditCardNumberErrorMessage()
} }.goBackToSavedCreditCards {
}
@Test
fun verifyCreditCardCannotBeSavedWithoutNameOnCardTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openAutofillSubMenu {
verifyCreditCardsAutofillSection(true, false)
clickAddCreditCardButton()
fillAndSaveCreditCard(
MockCreditCard1.MOCK_CREDIT_CARD_NUMBER,
MockCreditCard1.MOCK_NAME_ON_CARD,
MockCreditCard1.MOCK_EXPIRATION_MONTH,
MockCreditCard1.MOCK_EXPIRATION_YEAR,
)
clickManageSavedCreditCardsButton()
clickSecuredCreditCardsLaterButton()
verifySavedCreditCardsSection(
MockCreditCard1.MOCK_LAST_CARD_DIGITS,
MockCreditCard1.MOCK_EXPIRATION_MONTH_AND_YEAR,
)
clickSavedCreditCard() clickSavedCreditCard()
clearNameOnCreditCard() clearNameOnCreditCard()
clickSaveCreditCardToolbarButton() clickSaveCreditCardToolbarButton()
@ -421,8 +368,9 @@ class CreditCardAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512794
@Test @Test
fun verifyMultipleCreditCardsCanBeSavedTest() { fun verifyMultipleCreditCardsCanBeAddedTest() {
val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer)
homeScreen { homeScreen {
@ -476,8 +424,9 @@ class CreditCardAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2271304
@Test @Test
fun verifyDoNotSaveCreditCardFromFormTest() { fun verifyDoNotSaveCreditCardFromPromptTest() {
val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer)
navigationToolbar { navigationToolbar {
@ -496,8 +445,9 @@ class CreditCardAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1779194
@Test @Test
fun verifySaveCreditCardFromFormTest() { fun verifySaveCreditCardFromPromptTest() {
val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer)
navigationToolbar { navigationToolbar {
@ -522,6 +472,7 @@ class CreditCardAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2271305
@Test @Test
fun verifyCancelCreditCardUpdatePromptTest() { fun verifyCancelCreditCardUpdatePromptTest() {
val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer)
@ -572,6 +523,7 @@ class CreditCardAutofillTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1779195
@Test @Test
fun verifyConfirmCreditCardUpdatePromptTest() { fun verifyConfirmCreditCardUpdatePromptTest() {
val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer)
@ -622,9 +574,10 @@ class CreditCardAutofillTest {
} }
} }
@Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1847774") // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512791
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1854566")
@Test @Test
fun verifySavedCreditCardsRedirectionToAutofillAfterInterruptionTest() { fun verifyCreditCardRedirectionsToAutofillSectionAfterInterruptionTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -639,33 +592,15 @@ class CreditCardAutofillTest {
) )
clickManageSavedCreditCardsButton() clickManageSavedCreditCardsButton()
clickSecuredCreditCardsLaterButton() clickSecuredCreditCardsLaterButton()
verifySavedCreditCardsSection( clickSavedCreditCard()
MockCreditCard1.MOCK_LAST_CARD_DIGITS,
MockCreditCard1.MOCK_EXPIRATION_MONTH_AND_YEAR,
)
putAppToBackground() putAppToBackground()
bringAppToForeground() bringAppToForeground()
verifyAutofillToolbarTitle() verifyAutofillToolbarTitle()
}
}
@Test
fun verifyEditCreditCardRedirectionToAutofillAfterInterruptionTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openAutofillSubMenu {
verifyCreditCardsAutofillSection(true, false)
clickAddCreditCardButton()
fillAndSaveCreditCard(
MockCreditCard1.MOCK_CREDIT_CARD_NUMBER,
MockCreditCard1.MOCK_NAME_ON_CARD,
MockCreditCard1.MOCK_EXPIRATION_MONTH,
MockCreditCard1.MOCK_EXPIRATION_YEAR,
)
clickManageSavedCreditCardsButton() clickManageSavedCreditCardsButton()
clickSecuredCreditCardsLaterButton() verifySavedCreditCardsSection(
clickSavedCreditCard() MockCreditCard1.MOCK_LAST_CARD_DIGITS,
MockCreditCard1.MOCK_EXPIRATION_MONTH_AND_YEAR,
)
putAppToBackground() putAppToBackground()
bringAppToForeground() bringAppToForeground()
verifyAutofillToolbarTitle() verifyAutofillToolbarTitle()

@ -206,7 +206,7 @@ class CustomTabsTest {
}.clickDownloadLink(downloadFile) { }.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(downloadFile) verifyDownloadPrompt(downloadFile)
}.clickDownload { }.clickDownload {
verifyDownloadNotificationPopup() verifyDownloadCompleteNotificationPopup()
} }
mDevice.openNotification() mDevice.openNotification()
notificationShade { notificationShade {

@ -91,7 +91,6 @@ class DeepLinkTest {
@Test @Test
fun openCollections() { fun openCollections() {
robot.openHomeScreen { /* do nothing */ }.dismissOnboarding()
robot.openCollections { robot.openCollections {
verifyCollectionsHeader() verifyCollectionsHeader()
} }

@ -41,18 +41,20 @@ class DownloadFileTypesTest(fileName: String) {
"videoSample.webm", "videoSample.webm",
"CSVfile.csv", "CSVfile.csv",
"XMLfile.xml", "XMLfile.xml",
"tAJwqaWjJsXS8AhzSninBMCfIZbHBGgcc001lx5DIdDwIcfEgQ6vE5Gb5VgAled17DFZ2A7ZDOHA0NpQPHXXFt.svg",
) )
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/251028&group_by=cases:section_id&group_id=31659&group_order=asc
@SmokeTest @SmokeTest
@Test @Test
fun downloadMultipleFileTypesTest() { fun allFilesAppearInDownloadsMenuTest() {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
}.clickDownloadLink(downloadFile) { }.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(downloadFile) verifyDownloadPrompt(downloadFile)
}.clickDownload { }.clickDownload {
verifyDownloadNotificationPopup() verifyDownloadCompleteNotificationPopup()
}.closeCompletedDownloadPrompt { }.closeCompletedDownloadPrompt {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openDownloadsManager { }.openDownloadsManager {

@ -13,6 +13,7 @@ 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.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_APPS_PHOTOS
import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_DOCS import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_DOCS
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
@ -20,6 +21,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestHelper.assertExternalAppOpens import org.mozilla.fenix.helpers.TestHelper.assertExternalAppOpens
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
import org.mozilla.fenix.helpers.TestHelper.deleteDownloadedFileOnStorage import org.mozilla.fenix.helpers.TestHelper.deleteDownloadedFileOnStorage
import org.mozilla.fenix.helpers.TestHelper.exitMenu
import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.setNetworkEnabled import org.mozilla.fenix.helpers.TestHelper.setNetworkEnabled
import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.browserScreen
@ -72,8 +74,9 @@ class DownloadTest {
setNetworkEnabled(enabled = true) setNetworkEnabled(enabled = true)
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243844
@Test @Test
fun testDownloadPrompt() { fun verifyTheDownloadPromptsTest() {
downloadFile = "web_icon.png" downloadFile = "web_icon.png"
navigationToolbar { navigationToolbar {
@ -82,7 +85,7 @@ class DownloadTest {
}.clickDownloadLink(downloadFile) { }.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(downloadFile) verifyDownloadPrompt(downloadFile)
}.clickDownload { }.clickDownload {
verifyDownloadNotificationPopup() verifyDownloadCompleteNotificationPopup()
}.clickOpen("image/png") {} }.clickOpen("image/png") {}
downloadRobot { downloadRobot {
verifyPhotosAppOpens() verifyPhotosAppOpens()
@ -91,25 +94,34 @@ class DownloadTest {
deleteDownloadedFileOnStorage(downloadFile) deleteDownloadedFileOnStorage(downloadFile)
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2299405
@Test @Test
fun testCloseDownloadPrompt() { fun verifyTheDownloadFailedNotificationsTest() {
downloadFile = "smallZip.zip" downloadFile = "1GB.zip"
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
waitForPageToLoad() waitForPageToLoad()
}.clickDownloadLink(downloadFile) { }.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(downloadFile) verifyDownloadPrompt(downloadFile)
}.closePrompt { }.clickDownload {
}.openThreeDotMenu { setNetworkEnabled(enabled = false)
}.openDownloadsManager { verifyDownloadFailedPrompt(downloadFile)
verifyEmptyDownloadsList() setNetworkEnabled(enabled = true)
clickTryAgainButton()
} }
mDevice.openNotification()
notificationShade {
verifySystemNotificationDoesNotExist("Download failed")
verifySystemNotificationExists(downloadFile)
}.closeNotificationTray {}
deleteDownloadedFileOnStorage(downloadFile)
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2298616
@Test @Test
fun testDownloadCompleteNotification() { fun verifyDownloadCompleteNotificationTest() {
downloadFile = "smallZip.zip" downloadFile = "web_icon.png"
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
@ -117,15 +129,26 @@ class DownloadTest {
}.clickDownloadLink(downloadFile) { }.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(downloadFile) verifyDownloadPrompt(downloadFile)
}.clickDownload { }.clickDownload {
verifyDownloadNotificationPopup() verifyDownloadCompleteNotificationPopup()
} }
mDevice.openNotification() mDevice.openNotification()
notificationShade { notificationShade {
verifySystemNotificationExists("Download completed") verifySystemNotificationExists("Download completed")
} clickNotification("Download completed")
assertExternalAppOpens(GOOGLE_APPS_PHOTOS)
mDevice.pressBack()
mDevice.openNotification()
swipeDownloadNotification(
direction = "Left",
shouldDismissNotification = true,
canExpandNotification = false,
)
verifySystemNotificationDoesNotExist("Firefox Fenix")
}.closeNotificationTray {}
deleteDownloadedFileOnStorage(downloadFile) deleteDownloadedFileOnStorage(downloadFile)
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/451563
@Ignore("Failing: Bug https://bugzilla.mozilla.org/show_bug.cgi?id=1813521") @Ignore("Failing: Bug https://bugzilla.mozilla.org/show_bug.cgi?id=1813521")
@SmokeTest @SmokeTest
@Test @Test
@ -148,8 +171,10 @@ class DownloadTest {
verifySystemNotificationExists("Firefox Fenix") verifySystemNotificationExists("Firefox Fenix")
expandNotificationMessage() expandNotificationMessage()
clickDownloadNotificationControlButton("PAUSE") clickDownloadNotificationControlButton("PAUSE")
verifySystemNotificationExists("Download paused")
clickDownloadNotificationControlButton("RESUME") clickDownloadNotificationControlButton("RESUME")
clickDownloadNotificationControlButton("CANCEL") clickDownloadNotificationControlButton("CANCEL")
verifySystemNotificationDoesNotExist(downloadFile)
mDevice.pressBack() mDevice.pressBack()
} }
browserScreen { browserScreen {
@ -160,42 +185,9 @@ class DownloadTest {
deleteDownloadedFileOnStorage(downloadFile) deleteDownloadedFileOnStorage(downloadFile)
} }
/* Verifies downloads in the Downloads Menu: // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2301474
- downloads appear in the list
- deleting a download from device storage, removes it from the Downloads Menu too
*/
@SmokeTest
@Test @Test
fun manageDownloadsInDownloadsMenuTest() { fun openDownloadedFileFromDownloadsMenuTest() {
// a long filename to verify it's correctly displayed on the prompt and in the Downloads menu
downloadFile =
"tAJwqaWjJsXS8AhzSninBMCfIZbHBGgcc001lx5DIdDwIcfEgQ6vE5Gb5VgAled17DFZ2A7ZDOHA0NpQPHXXFt.svg"
navigationToolbar {
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
waitForPageToLoad()
}.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(downloadFile)
}.clickDownload {
verifyDownloadNotificationPopup()
}
browserScreen {
}.openThreeDotMenu {
}.openDownloadsManager {
waitForDownloadsListToExist()
verifyDownloadedFileName(downloadFile)
verifyDownloadedFileIcon()
deleteDownloadedFileOnStorage(downloadFile)
}.exitDownloadsManagerToBrowser {
}.openThreeDotMenu {
}.openDownloadsManager {
verifyEmptyDownloadsList()
}
}
@SmokeTest
@Test
fun openDownloadedFileTest() {
downloadFile = "web_icon.png" downloadFile = "web_icon.png"
navigationToolbar { navigationToolbar {
@ -204,7 +196,7 @@ class DownloadTest {
}.clickDownloadLink(downloadFile) { }.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(downloadFile) verifyDownloadPrompt(downloadFile)
}.clickDownload { }.clickDownload {
verifyDownloadNotificationPopup() verifyDownloadCompleteNotificationPopup()
} }
browserScreen { browserScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
@ -239,32 +231,11 @@ class DownloadTest {
deleteDownloadedFileOnStorage(downloadFile) deleteDownloadedFileOnStorage(downloadFile)
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1114970
@Test @Test
fun deleteDownloadedFileTest() { fun deleteDownloadedFileTest() {
downloadFile = "smallZip.zip" downloadFile = "smallZip.zip"
navigationToolbar {
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
waitForPageToLoad()
}.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(downloadFile)
}.clickDownload {
verifyDownloadedFileName(downloadFile)
}
browserScreen {
}.openThreeDotMenu {
}.openDownloadsManager {
verifyDownloadedFileName(downloadFile)
deleteDownloadedItem(downloadFile)
verifyEmptyDownloadsList()
}
deleteDownloadedFileOnStorage(downloadFile)
}
@Test
fun undoDeleteDownloadedFileTest() {
downloadFile = "smallZip.zip"
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
waitForPageToLoad() waitForPageToLoad()
@ -280,10 +251,13 @@ class DownloadTest {
deleteDownloadedItem(downloadFile) deleteDownloadedItem(downloadFile)
clickSnackbarButton("UNDO") clickSnackbarButton("UNDO")
verifyDownloadedFileName(downloadFile) verifyDownloadedFileName(downloadFile)
deleteDownloadedItem(downloadFile)
verifyEmptyDownloadsList()
} }
deleteDownloadedFileOnStorage(downloadFile) deleteDownloadedFileOnStorage(downloadFile)
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2302662
@Test @Test
fun deleteMultipleDownloadedFilesTest() { fun deleteMultipleDownloadedFilesTest() {
val firstDownloadedFile = "smallZip.zip" val firstDownloadedFile = "smallZip.zip"
@ -305,6 +279,13 @@ class DownloadTest {
browserScreen { browserScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openDownloadsManager { }.openDownloadsManager {
verifyDownloadedFileName(firstDownloadedFile)
verifyDownloadedFileName(secondDownloadedFile)
longClickDownloadedItem(firstDownloadedFile)
selectDownloadedItem(secondDownloadedFile)
openMultiSelectMoreOptionsMenu()
clickMultiSelectRemoveButton()
clickSnackbarButton("UNDO")
verifyDownloadedFileName(firstDownloadedFile) verifyDownloadedFileName(firstDownloadedFile)
verifyDownloadedFileName(secondDownloadedFile) verifyDownloadedFileName(secondDownloadedFile)
longClickDownloadedItem(firstDownloadedFile) longClickDownloadedItem(firstDownloadedFile)
@ -317,70 +298,52 @@ class DownloadTest {
deleteDownloadedFileOnStorage(secondDownloadedFile) deleteDownloadedFileOnStorage(secondDownloadedFile)
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2301537
@Test @Test
fun undoDeleteMultipleDownloadedFilesTest() { fun fileDeletedFromStorageIsDeletedEverywhereTest() {
val firstDownloadedFile = "smallZip.zip" val downloadFile = "smallZip.zip"
val secondDownloadedFile = "textfile.txt"
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
waitForPageToLoad() waitForPageToLoad()
}.clickDownloadLink(firstDownloadedFile) { }.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(firstDownloadedFile) verifyDownloadPrompt(downloadFile)
}.clickDownload {
verifyDownloadedFileName(firstDownloadedFile)
}.closeCompletedDownloadPrompt {
}.clickDownloadLink(secondDownloadedFile) {
verifyDownloadPrompt(secondDownloadedFile)
}.clickDownload { }.clickDownload {
verifyDownloadedFileName(secondDownloadedFile) verifyDownloadCompleteNotificationPopup()
} }
browserScreen { browserScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openDownloadsManager { }.openDownloadsManager {
verifyDownloadedFileName(firstDownloadedFile) waitForDownloadsListToExist()
verifyDownloadedFileName(secondDownloadedFile) verifyDownloadedFileName(downloadFile)
longClickDownloadedItem(firstDownloadedFile) deleteDownloadedFileOnStorage(downloadFile)
selectDownloadedItem(secondDownloadedFile) }.exitDownloadsManagerToBrowser {
openMultiSelectMoreOptionsMenu() }.openThreeDotMenu {
clickMultiSelectRemoveButton() }.openDownloadsManager {
clickSnackbarButton("UNDO") verifyEmptyDownloadsList()
verifyDownloadedFileName(firstDownloadedFile) exitMenu()
verifyDownloadedFileName(secondDownloadedFile)
}
deleteDownloadedFileOnStorage(firstDownloadedFile)
deleteDownloadedFileOnStorage(secondDownloadedFile)
}
@Ignore("Failing: https://bugzilla.mozilla.org/show_bug.cgi?id=1840994")
@Test
fun systemNotificationCantBeDismissedWhileDownloadingTest() {
// Clear the "Firefox Fenix default browser notification"
notificationShade {
cancelAllShownNotifications()
} }
downloadFile = "1GB.zip"
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
waitForPageToLoad() waitForPageToLoad()
}.clickDownloadLink(downloadFile) { }.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(downloadFile) verifyDownloadPrompt(downloadFile)
}.clickDownload { }.clickDownload {
verifyDownloadCompleteNotificationPopup()
} }
browserScreen { browserScreen {
}.openNotificationShade { }.openThreeDotMenu {
verifySystemNotificationExists("Firefox Fenix") }.openDownloadsManager {
expandNotificationMessage() waitForDownloadsListToExist()
swipeDownloadNotification("Left", false) verifyDownloadedFileName(downloadFile)
clickDownloadNotificationControlButton("CANCEL")
} }
deleteDownloadedFileOnStorage(downloadFile) deleteDownloadedFileOnStorage(downloadFile)
} }
@Ignore("Failing: https://bugzilla.mozilla.org/show_bug.cgi?id=1840994")
@Test @Test
fun systemNotificationCantBeDismissedWhileDownloadIsPausedTest() { fun systemNotificationCantBeDismissedWhileInProgressTest() {
// Clear the "Firefox Fenix default browser notification" // Clear the "Firefox Fenix default browser notification"
notificationShade { notificationShade {
cancelAllShownNotifications() cancelAllShownNotifications()
@ -399,15 +362,9 @@ class DownloadTest {
}.openNotificationShade { }.openNotificationShade {
verifySystemNotificationExists("Firefox Fenix") verifySystemNotificationExists("Firefox Fenix")
expandNotificationMessage() expandNotificationMessage()
swipeDownloadNotification(direction = "Left", shouldDismissNotification = false)
clickDownloadNotificationControlButton("PAUSE") clickDownloadNotificationControlButton("PAUSE")
swipeDownloadNotification("Left", false) swipeDownloadNotification(direction = "Right", shouldDismissNotification = false)
verifySystemNotificationExists("Firefox Fenix")
}.closeNotificationTray {
}.openNotificationShade {
verifySystemNotificationExists("Firefox Fenix")
expandNotificationMessage()
swipeDownloadNotification("Right", false)
verifySystemNotificationExists("Firefox Fenix")
clickDownloadNotificationControlButton("CANCEL") clickDownloadNotificationControlButton("CANCEL")
} }
deleteDownloadedFileOnStorage(downloadFile) deleteDownloadedFileOnStorage(downloadFile)
@ -427,8 +384,7 @@ class DownloadTest {
waitForPageToLoad() waitForPageToLoad()
}.clickDownloadLink(downloadFile) { }.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(downloadFile) verifyDownloadPrompt(downloadFile)
}.clickDownload { }.clickDownload {}
}
setNetworkEnabled(enabled = false) setNetworkEnabled(enabled = false)
@ -438,8 +394,7 @@ class DownloadTest {
expandNotificationMessage() expandNotificationMessage()
swipeDownloadNotification("Left", true) swipeDownloadNotification("Left", true)
verifySystemNotificationDoesNotExist("Firefox Fenix") verifySystemNotificationDoesNotExist("Firefox Fenix")
}.closeNotificationTray { }.closeNotificationTray {}
}
downloadRobot { downloadRobot {
}.closeDownloadPrompt { }.closeDownloadPrompt {
@ -449,56 +404,22 @@ class DownloadTest {
} }
@Test @Test
fun notificationCanBeDismissedIfDownloadIsCompletedTest() { fun warningWhenClosingPrivateTabsWhileDownloadingTest() {
// Clear the "Firefox Fenix default browser notification" downloadFile = "1GB.zip"
notificationShade {
cancelAllShownNotifications()
}
downloadFile = "smallZip.zip"
navigationToolbar {
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
waitForPageToLoad()
}.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(downloadFile)
}.clickDownload {
}
browserScreen {
}.openNotificationShade {
verifySystemNotificationExists("Download completed")
swipeDownloadNotification("Left", true, false)
verifySystemNotificationDoesNotExist("Firefox Fenix")
}.closeNotificationTray {
}
downloadRobot {
}.closeDownloadPrompt {
verifyDownloadPromptIsDismissed()
}
deleteDownloadedFileOnStorage(downloadFile)
}
@Test
fun stayInPrivateBrowsingPromptTest() {
// Clear the "Firefox Fenix default browser notification" // Clear the "Firefox Fenix default browser notification"
notificationShade { notificationShade {
cancelAllShownNotifications() cancelAllShownNotifications()
} }
downloadFile = "1GB.zip"
homeScreen { homeScreen {
}.togglePrivateBrowsingMode() }.togglePrivateBrowsingMode()
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
waitForPageToLoad() waitForPageToLoad()
}.clickDownloadLink(downloadFile) { }.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(downloadFile) verifyDownloadPrompt(downloadFile)
}.clickDownload { }.clickDownload {}
}
browserScreen { browserScreen {
}.openTabDrawer { }.openTabDrawer {
closeTab() closeTab()
@ -512,15 +433,16 @@ class DownloadTest {
deleteDownloadedFileOnStorage(downloadFile) deleteDownloadedFileOnStorage(downloadFile)
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2302663
@Test @Test
fun cancelActiveDownloadsFromPrivateBrowsingPromptTest() { fun cancelActivePrivateBrowsingDownloadsTest() {
downloadFile = "1GB.zip"
// Clear the "Firefox Fenix default browser notification" // Clear the "Firefox Fenix default browser notification"
notificationShade { notificationShade {
cancelAllShownNotifications() cancelAllShownNotifications()
} }
downloadFile = "1GB.zip"
homeScreen { homeScreen {
}.togglePrivateBrowsingMode() }.togglePrivateBrowsingMode()
@ -529,8 +451,7 @@ class DownloadTest {
waitForPageToLoad() waitForPageToLoad()
}.clickDownloadLink(downloadFile) { }.clickDownloadLink(downloadFile) {
verifyDownloadPrompt(downloadFile) verifyDownloadPrompt(downloadFile)
}.clickDownload { }.clickDownload {}
}
browserScreen { browserScreen {
}.openTabDrawer { }.openTabDrawer {
closeTab() closeTab()

@ -63,6 +63,7 @@ class EnhancedTrackingProtectionTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416046
@Test @Test
fun testETPSettingsItemsAndSubMenus() { fun testETPSettingsItemsAndSubMenus() {
homeScreen { homeScreen {
@ -97,30 +98,9 @@ class EnhancedTrackingProtectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1514599
@Test @Test
fun testETPSettingsSummaryChange() { fun verifyETPStateIsReflectedInTPSheetTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
verifyEnhancedTrackingProtectionButton()
verifySettingsOptionSummary("Enhanced Tracking Protection", "Standard")
}.openEnhancedTrackingProtectionSubMenu {
selectTrackingProtectionOption("Strict")
}.goBack {
verifySettingsOptionSummary("Enhanced Tracking Protection", "Strict")
}.openEnhancedTrackingProtectionSubMenu {
selectTrackingProtectionOption("Custom")
}.goBack {
verifySettingsOptionSummary("Enhanced Tracking Protection", "Custom")
}.openEnhancedTrackingProtectionSubMenu {
switchEnhancedTrackingProtectionToggle()
}.goBack {
verifySettingsOptionSummary("Enhanced Tracking Protection", "Off")
}
}
@Test
fun testETPOffGlobally() {
val genericPage = getGenericAsset(mockWebServer, 1) val genericPage = getGenericAsset(mockWebServer, 1)
homeScreen { homeScreen {
@ -129,6 +109,8 @@ class EnhancedTrackingProtectionTest {
}.openEnhancedTrackingProtectionSubMenu { }.openEnhancedTrackingProtectionSubMenu {
switchEnhancedTrackingProtectionToggle() switchEnhancedTrackingProtectionToggle()
verifyEnhancedTrackingProtectionOptionsEnabled(false) verifyEnhancedTrackingProtectionOptionsEnabled(false)
}.goBack {
verifySettingsOptionSummary("Enhanced Tracking Protection", "Off")
exitMenu() exitMenu()
} }
@ -151,10 +133,11 @@ class EnhancedTrackingProtectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/339712
// Tests adding ETP exceptions to websites and keeping that preference after restart // Tests adding ETP exceptions to websites and keeping that preference after restart
@SmokeTest @SmokeTest
@Test @Test
fun testDisableETPExceptionToggle() { fun disablingETPOnAWebsiteAddsItToExceptionListTest() {
val firstPage = getGenericAsset(mockWebServer, 1) val firstPage = getGenericAsset(mockWebServer, 1)
val secondPage = "example.com" val secondPage = "example.com"
@ -182,8 +165,9 @@ class EnhancedTrackingProtectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/339714
@Test @Test
fun trackingProtectionSwitchEnabledRemovesExceptionTest() { fun enablingETPOnAWebsiteRemovesItFromTheExceptionListTest() {
val trackingPage = getEnhancedTrackingProtectionAsset(mockWebServer) val trackingPage = getEnhancedTrackingProtectionAsset(mockWebServer)
navigationToolbar { navigationToolbar {
@ -212,9 +196,10 @@ class EnhancedTrackingProtectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/339713
// Tests removing TP exceptions individually or all at once // Tests removing TP exceptions individually or all at once
@Test @Test
fun clearTrackingProtectionExceptionsTest() { fun clearWebsitesFromTPExceptionListTest() {
val firstPage = getGenericAsset(mockWebServer, 1) val firstPage = getGenericAsset(mockWebServer, 1)
val secondPage = "example.com" val secondPage = "example.com"
@ -249,11 +234,20 @@ class EnhancedTrackingProtectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/417444
@Test @Test
fun testStandardETPVisitSheetDetails() { fun verifyTrackersBlockedWithStandardTPTest() {
val genericPage = getGenericAsset(mockWebServer, 1) val genericPage = getGenericAsset(mockWebServer, 1)
val trackingProtectionTest = getEnhancedTrackingProtectionAsset(mockWebServer).url val trackingProtectionTest = getEnhancedTrackingProtectionAsset(mockWebServer).url
homeScreen {
}.openThreeDotMenu {
}.openSettings {
verifyEnhancedTrackingProtectionButton()
verifySettingsOptionSummary("Enhanced Tracking Protection", "Standard")
exitMenu()
}
// browsing a generic page to allow GV to load on a fresh run // browsing a generic page to allow GV to load on a fresh run
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(genericPage.url) { }.enterURLAndEnterToBrowser(genericPage.url) {
@ -280,12 +274,21 @@ class EnhancedTrackingProtectionTest {
}.closeEnhancedTrackingProtectionSheet {} }.closeEnhancedTrackingProtectionSheet {}
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/417441
@Test @Test
fun testStrictVisitSheetDetails() { fun verifyTrackersBlockedWithStrictTPTest() {
appContext.settings().setStrictETP() appContext.settings().setStrictETP()
val genericPage = getGenericAsset(mockWebServer, 1) val genericPage = getGenericAsset(mockWebServer, 1)
val trackingProtectionTest = getEnhancedTrackingProtectionAsset(mockWebServer).url val trackingProtectionTest = getEnhancedTrackingProtectionAsset(mockWebServer).url
homeScreen {
}.openThreeDotMenu {
}.openSettings {
verifyEnhancedTrackingProtectionButton()
verifySettingsOptionSummary("Enhanced Tracking Protection", "Strict")
exitMenu()
}
// browsing a generic page to allow GV to load on a fresh run // browsing a generic page to allow GV to load on a fresh run
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(genericPage.url) { }.enterURLAndEnterToBrowser(genericPage.url) {
@ -316,9 +319,10 @@ class EnhancedTrackingProtectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/561637
@SmokeTest @SmokeTest
@Test @Test
fun defaultCustomTrackingProtectionSettingsTest() { fun verifyTrackersBlockedWithCustomTPTest() {
val genericWebPage = getGenericAsset(mockWebServer, 1) val genericWebPage = getGenericAsset(mockWebServer, 1)
val trackingPage = getEnhancedTrackingProtectionAsset(mockWebServer) val trackingPage = getEnhancedTrackingProtectionAsset(mockWebServer)
@ -328,9 +332,12 @@ class EnhancedTrackingProtectionTest {
}.openEnhancedTrackingProtectionSubMenu { }.openEnhancedTrackingProtectionSubMenu {
selectTrackingProtectionOption("Custom") selectTrackingProtectionOption("Custom")
verifyCustomTrackingProtectionSettings() verifyCustomTrackingProtectionSettings()
}.goBackToHomeScreen { }.goBack {
}.openNavigationToolbar { verifySettingsOptionSummary("Enhanced Tracking Protection", "Custom")
// browsing a basic page to allow GV to load on a fresh run exitMenu()
}
navigationToolbar {
}.enterURLAndEnterToBrowser(genericWebPage.url) { }.enterURLAndEnterToBrowser(genericWebPage.url) {
}.openNavigationToolbar { }.openNavigationToolbar {
}.enterURLAndEnterToBrowser(trackingPage.url) { }.enterURLAndEnterToBrowser(trackingPage.url) {
@ -355,6 +362,7 @@ class EnhancedTrackingProtectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/562710
// Tests the trackers blocked with the following Custom TP set up: // Tests the trackers blocked with the following Custom TP set up:
// - Cookies set to "All cookies" // - Cookies set to "All cookies"
// - Tracking content option OFF // - Tracking content option OFF
@ -398,8 +406,9 @@ class EnhancedTrackingProtectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/562709
@Test @Test
fun disableCustomTrackingProtectionOptionsTest() { fun verifyTrackersBlockedWithCustomTPOptionsDisabledTest() {
val genericWebPage = getGenericAsset(mockWebServer, 1) val genericWebPage = getGenericAsset(mockWebServer, 1)
val trackingPage = getEnhancedTrackingProtectionAsset(mockWebServer) val trackingPage = getEnhancedTrackingProtectionAsset(mockWebServer)
@ -430,8 +439,9 @@ class EnhancedTrackingProtectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2106997
@Test @Test
fun testTrackingContentBlockedOnlyInPrivateTabs() { fun verifyTrackingContentBlockedOnlyInPrivateTabsTest() {
val genericWebPage = getGenericAsset(mockWebServer, 1) val genericWebPage = getGenericAsset(mockWebServer, 1)
val trackingPage = getEnhancedTrackingProtectionAsset(mockWebServer) val trackingPage = getEnhancedTrackingProtectionAsset(mockWebServer)
@ -480,6 +490,7 @@ class EnhancedTrackingProtectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2285368
@SmokeTest @SmokeTest
@Test @Test
fun blockCookiesStorageAccessTest() { fun blockCookiesStorageAccessTest() {
@ -502,6 +513,7 @@ class EnhancedTrackingProtectionTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2285369
@SmokeTest @SmokeTest
@Test @Test
fun allowCookiesStorageAccessTest() { fun allowCookiesStorageAccessTest() {

@ -73,8 +73,9 @@ class HistoryTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243285
@Test @Test
fun noHistoryItemsInCacheTest() { fun verifyEmptyHistoryMenuTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
verifyHistoryButton() verifyHistoryButton()
@ -84,10 +85,12 @@ class HistoryTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2302742
// 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
@Test @Test
fun visitedUrlHistoryTest() { fun verifyHistoryMenuWithHistoryItemsTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -103,34 +106,16 @@ class HistoryTest {
verifyVisitedTimeTitle() verifyVisitedTimeTitle()
verifyFirstTestPageTitle("Test_Page_1") verifyFirstTestPageTitle("Test_Page_1")
verifyTestPageUrl(firstWebPage.url) verifyTestPageUrl(firstWebPage.url)
verifyDeleteHistoryItemButton("Test_Page_1")
} }
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243288
@Test @Test
fun deleteHistoryItemTest() { fun deleteHistoryItemTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(firstWebPage.url) {
mDevice.waitForIdle()
}.openThreeDotMenu {
}.openHistory {
verifyHistoryListExists()
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1),
) {
clickDeleteHistoryButton(firstWebPage.url.toString())
}
verifyDeleteSnackbarText("Deleted")
verifyEmptyHistoryView()
}
}
@Test
fun undoDeleteHistoryItemTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(firstWebPage.url) { }.enterURLAndEnterToBrowser(firstWebPage.url) {
mDevice.waitForIdle() mDevice.waitForIdle()
@ -145,12 +130,16 @@ class HistoryTest {
verifyUndoDeleteSnackBarButton() verifyUndoDeleteSnackBarButton()
clickUndoDeleteButton() clickUndoDeleteButton()
verifyHistoryItemExists(true, firstWebPage.url.toString()) verifyHistoryItemExists(true, firstWebPage.url.toString())
clickDeleteHistoryButton(firstWebPage.url.toString())
verifyDeleteSnackbarText("Deleted")
verifyEmptyHistoryView()
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1848881
@SmokeTest @SmokeTest
@Test @Test
fun cancelDeleteAllHistoryTest() { fun deleteAllHistoryTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -168,25 +157,7 @@ class HistoryTest {
selectEverythingOption() selectEverythingOption()
cancelDeleteHistory() cancelDeleteHistory()
verifyHistoryItemExists(true, firstWebPage.url.toString()) verifyHistoryItemExists(true, firstWebPage.url.toString())
} clickDeleteAllHistoryButton()
}
@SmokeTest
@Test
fun deleteAllHistoryTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(firstWebPage.url) {
mDevice.waitForIdle()
}.openThreeDotMenu {
}.openHistory {
verifyHistoryListExists()
registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1),
) {
clickDeleteAllHistoryButton()
}
verifyDeleteConfirmationMessage() verifyDeleteConfirmationMessage()
selectEverythingOption() selectEverythingOption()
confirmDeleteAllHistory() confirmDeleteAllHistory()
@ -195,7 +166,7 @@ class HistoryTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/339690
@Test @Test
fun historyMultiSelectionToolbarItemsTest() { fun historyMultiSelectionToolbarItemsTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -223,9 +194,10 @@ class HistoryTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/339696
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268")
@Test @Test
fun openHistoryInNewTabTest() { fun openMultipleSelectedHistoryItemsInANewTabTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -253,8 +225,9 @@ class HistoryTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/346098
@Test @Test
fun openHistoryInPrivateTabTest() { fun openMultipleSelectedHistoryItemsInPrivateTabTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -278,8 +251,9 @@ class HistoryTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/346099
@Test @Test
fun deleteMultipleSelectionTest() { fun deleteMultipleSelectedHistoryItemsTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
@ -312,8 +286,9 @@ class HistoryTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/339701
@Test @Test
fun shareButtonTest() { fun shareMultipleSelectedHistoryItemsTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -338,6 +313,7 @@ class HistoryTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715627
@Test @Test
fun verifySearchHistoryViewTest() { fun verifySearchHistoryViewTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -380,6 +356,7 @@ class HistoryTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715631
@Test @Test
fun verifyVoiceSearchInHistoryTest() { fun verifyVoiceSearchInHistoryTest() {
homeScreen { homeScreen {
@ -392,6 +369,7 @@ class HistoryTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715632
@Test @Test
fun verifySearchForHistoryItemsTest() { fun verifySearchForHistoryItemsTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -407,13 +385,13 @@ class HistoryTest {
// Search for a valid term // Search for a valid term
typeSearch("generic") typeSearch("generic")
verifySearchEngineSuggestionResults(activityTestRule, firstWebPage.url.toString(), searchTerm = "generic") verifySearchEngineSuggestionResults(activityTestRule, firstWebPage.url.toString(), searchTerm = "generic")
verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString())
}.dismissSearchBar {} }.dismissSearchBar {}
historyMenu { historyMenu {
}.clickSearchButton { }.clickSearchButton {
// Search for invalid term // Search for invalid term
typeSearch("Android") typeSearch("Android")
verifyNoSuggestionsAreDisplayed( verifySuggestionsAreNotDisplayed(
activityTestRule, activityTestRule,
firstWebPage.url.toString(), firstWebPage.url.toString(),
secondWebPage.url.toString(), secondWebPage.url.toString(),
@ -421,6 +399,7 @@ class HistoryTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715634
@Test @Test
fun verifyDeletedHistoryItemsCanNotBeSearchedTest() { fun verifyDeletedHistoryItemsCanNotBeSearchedTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -448,8 +427,8 @@ class HistoryTest {
}.clickSearchButton { }.clickSearchButton {
// Search for a valid term // Search for a valid term
typeSearch("generic") typeSearch("generic")
verifyNoSuggestionsAreDisplayed(activityTestRule, firstWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString())
verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString())
verifySearchEngineSuggestionResults( verifySearchEngineSuggestionResults(
activityTestRule, activityTestRule,
thirdWebPage.url.toString(), thirdWebPage.url.toString(),
@ -463,7 +442,7 @@ class HistoryTest {
}.clickSearchButton { }.clickSearchButton {
// Search for a valid term // Search for a valid term
typeSearch("generic") typeSearch("generic")
verifyNoSuggestionsAreDisplayed(activityTestRule, thirdWebPage.url.toString()) verifySuggestionsAreNotDisplayed(activityTestRule, thirdWebPage.url.toString())
} }
} }
} }

@ -57,8 +57,11 @@ class HomeScreenTest {
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/235396 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/235396
@Test @Test
fun homeScreenItemsTest() { fun homeScreenItemsTest() {
homeScreen {}.dismissOnboarding() // Workaround to make sure the Pocket articles are populated before starting the test.
homeScreen { homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.goBack {
verifyHomeWordmark() verifyHomeWordmark()
verifyHomePrivateBrowsingButton() verifyHomePrivateBrowsingButton()
verifyExistingTopSitesTabs("Wikipedia") verifyExistingTopSitesTabs("Wikipedia")
@ -80,7 +83,6 @@ class HomeScreenTest {
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/244199 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/244199
@Test @Test
fun privateBrowsingHomeScreenItemsTest() { fun privateBrowsingHomeScreenItemsTest() {
homeScreen { }.dismissOnboarding()
homeScreen { }.togglePrivateBrowsingMode() homeScreen { }.togglePrivateBrowsingMode()
homeScreen { homeScreen {

@ -67,6 +67,7 @@ class LoginsTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2092713
// Tests the Logins and passwords menu items and default values // Tests the Logins and passwords menu items and default values
@Test @Test
fun loginsAndPasswordsSettingsItemsTest() { fun loginsAndPasswordsSettingsItemsTest() {
@ -82,10 +83,11 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/517816
// Tests only for initial state without signing in. // Tests only for initial state without signing in.
// For tests after signing in, see SyncIntegration test suite // For tests after signing in, see SyncIntegration test suite
@Test @Test
fun savedLoginsMenuItemsTest() { fun verifySavedLoginsListTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -101,8 +103,9 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2092925
@Test @Test
fun syncLoginsMenuItemsTest() { fun verifySyncLoginsOptionsTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -115,8 +118,12 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/523839
@Test @Test
fun saveLoginsAndPasswordsOptionsItemsTest() { fun saveLoginFromPromptTest() {
val saveLoginTest =
TestAssetHelper.getSaveLoginAsset(mockWebServer)
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -124,12 +131,8 @@ class LoginsTest {
}.openSaveLoginsAndPasswordsOptions { }.openSaveLoginsAndPasswordsOptions {
verifySaveLoginsOptionsView() verifySaveLoginsOptionsView()
} }
}
@Test exitMenu()
fun saveLoginFromPromptTest() {
val saveLoginTest =
TestAssetHelper.getSaveLoginAsset(mockWebServer)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(saveLoginTest.url) { }.enterURLAndEnterToBrowser(saveLoginTest.url) {
@ -152,8 +155,9 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/960412
@Test @Test
fun openWebsiteForSavedLoginTest() { fun openLoginWebsiteInBrowserTest() {
val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm"
val originWebsite = "mozilla-mobile.github.io" val originWebsite = "mozilla-mobile.github.io"
val userName = "test" val userName = "test"
@ -179,6 +183,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/517817
@Test @Test
fun neverSaveLoginFromPromptTest() { fun neverSaveLoginFromPromptTest() {
val saveLoginTest = TestAssetHelper.getSaveLoginAsset(mockWebServer) val saveLoginTest = TestAssetHelper.getSaveLoginAsset(mockWebServer)
@ -206,9 +211,10 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1508171
@SmokeTest @SmokeTest
@Test @Test
fun updateSavedLoginTest() { fun verifyUpdatedLoginIsSavedTest() {
val saveLoginTest = val saveLoginTest =
TestAssetHelper.getSaveLoginAsset(mockWebServer) TestAssetHelper.getSaveLoginAsset(mockWebServer)
@ -241,6 +247,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1049971
@SmokeTest @SmokeTest
@Test @Test
fun verifyMultipleLoginsSelectionsTest() { fun verifyMultipleLoginsSelectionsTest() {
@ -277,6 +284,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/875849
@Test @Test
fun verifyEditLoginsViewTest() { fun verifyEditLoginsViewTest() {
val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm"
@ -305,6 +313,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/875851
@Test @Test
fun verifyEditedLoginsAreSavedTest() { fun verifyEditedLoginsAreSavedTest() {
val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html" val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html"
@ -342,6 +351,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2266452
@Test @Test
fun verifyLoginWithNoUserNameCanNotBeSavedTest() { fun verifyLoginWithNoUserNameCanNotBeSavedTest() {
val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm"
@ -371,6 +381,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2266453
@Test @Test
fun verifyLoginWithoutPasswordCanNotBeSavedTest() { fun verifyLoginWithoutPasswordCanNotBeSavedTest() {
val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm"
@ -401,6 +412,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/876531
@Test @Test
fun verifyEditModeDismissalDoesNotSaveLoginCredentialsTest() { fun verifyEditModeDismissalDoesNotSaveLoginCredentialsTest() {
val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm"
@ -431,6 +443,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/876532
@Test @Test
fun verifyDeleteLoginButtonTest() { fun verifyDeleteLoginButtonTest() {
val loginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer) val loginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer)
@ -461,6 +474,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/517818
@SmokeTest @SmokeTest
@Test @Test
fun verifyNeverSaveLoginOptionTest() { fun verifyNeverSaveLoginOptionTest() {
@ -484,6 +498,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/517819
@Test @Test
fun verifyAutofillToggleTest() { fun verifyAutofillToggleTest() {
val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html" val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html"
@ -524,9 +539,10 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/593768
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1812995") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1812995")
@Test @Test
fun verifyLoginIsNotUpdatedTest() { fun doNotSaveOptionWillNotUpdateALoginTest() {
val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html" val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html"
val originWebsite = "mozilla-mobile.github.io" val originWebsite = "mozilla-mobile.github.io"
@ -572,6 +588,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2090455
@Test @Test
fun searchLoginsByUsernameTest() { fun searchLoginsByUsernameTest() {
val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer) val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer)
@ -618,6 +635,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/608834
@Test @Test
fun searchLoginsByUrlTest() { fun searchLoginsByUrlTest() {
val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer) val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer)
@ -664,6 +682,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2266441
@Test @Test
fun verifyLastUsedLoginSortingOptionTest() { fun verifyLastUsedLoginSortingOptionTest() {
val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer) val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer)
@ -710,6 +729,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2266442
@Test @Test
fun verifyAlphabeticalLoginSortingOptionTest() { fun verifyAlphabeticalLoginSortingOptionTest() {
val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer) val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer)
@ -754,6 +774,7 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1518435
@Test @Test
fun verifyAddLoginManuallyTest() { fun verifyAddLoginManuallyTest() {
val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html" val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html"
@ -792,8 +813,9 @@ class LoginsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2068215
@Test @Test
fun verifyCopyUsernameTest() { fun verifyCopyLoginCredentialsToClipboardTest() {
val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer) val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer)
navigationToolbar { navigationToolbar {
@ -809,24 +831,6 @@ class LoginsTest {
viewSavedLoginDetails("test@example.com") viewSavedLoginDetails("test@example.com")
clickCopyUserNameButton() clickCopyUserNameButton()
verifySnackBarText("Username copied to clipboard") verifySnackBarText("Username copied to clipboard")
}
}
@Test
fun verifyCopyPasswordTest() {
val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer)
navigationToolbar {
}.enterURLAndEnterToBrowser(firstLoginPage.url) {
clickSubmitLoginButton()
verifySaveLoginPromptIsDisplayed()
clickPageObject(itemWithText("Save"))
}.openThreeDotMenu {
}.openSettings {
}.openLoginsAndPasswordSubMenu {
}.openSavedLogins {
tapSetupLater()
viewSavedLoginDetails("test@example.com")
clickCopyPasswordButton() clickCopyPasswordButton()
verifySnackBarText("Password copied to clipboard") verifySnackBarText("Password copied to clipboard")
} }

@ -4,6 +4,7 @@
package org.mozilla.fenix.ui package org.mozilla.fenix.ui
import androidx.core.net.toUri
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import mozilla.components.concept.engine.utils.EngineReleaseChannel import mozilla.components.concept.engine.utils.EngineReleaseChannel
@ -12,15 +13,20 @@ 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.R
import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource import org.mozilla.fenix.helpers.MatcherHelper
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.assertYoutubeAppOpens
import org.mozilla.fenix.helpers.TestHelper.runWithCondition import org.mozilla.fenix.helpers.TestHelper.runWithCondition
import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.clickContextMenuItem
import org.mozilla.fenix.ui.robots.clickPageObject
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
class MainMenuTest { class MainMenuTest {
@ -28,7 +34,7 @@ class MainMenuTest {
private lateinit var mockWebServer: MockWebServer private lateinit var mockWebServer: MockWebServer
@get:Rule @get:Rule
val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides() val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
@Before @Before
fun setUp() { fun setUp() {
@ -44,9 +50,9 @@ class MainMenuTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/233849
@Test @Test
fun verifyPageMainMenuItemsTest() { fun verifyTabMainMenuItemsTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -57,109 +63,182 @@ class MainMenuTest {
} }
} }
// Verifies the list of items in the homescreen's 3 dot main menu
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/233848
@SmokeTest @SmokeTest
@Test @Test
fun openMainMenuNewTabItemTest() { fun homeMainMenuItemsTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) homeScreen {
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
}.openThreeDotMenu { }.openThreeDotMenu {
}.clickNewTabButton { verifyHomeThreeDotMainMenuItems(isRequestDesktopSiteEnabled = false)
verifySearchView() }.openBookmarks {
verifyBookmarksMenuView()
}.goBack {
}.openThreeDotMenu {
}.openHistory {
verifyHistoryMenuView()
}.goBack {
}.openThreeDotMenu {
}.openDownloadsManager {
verifyEmptyDownloadsList()
}.goBack {
}.openThreeDotMenu {
}.openAddonsManagerMenu {
verifyAddonsListIsDisplayed(true)
}.goBack {
}.openThreeDotMenu {
}.openSyncSignIn {
verifyTurnOnSyncMenu()
}.goBack {}
homeScreen {
}.openThreeDotMenu {
}.openWhatsNew {
verifyWhatsNewURL()
}.goToHomescreen {
}.openThreeDotMenu {
}.openHelp {
verifyHelpUrl()
}.goToHomescreen {
}.openThreeDotMenu {
}.openCustomizeHome {
verifyHomePageView()
}.goBackToHomeScreen {
}.openThreeDotMenu {
}.openSettings {
verifySettingsView()
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2284134
@Test @Test
fun openMainMenuBookmarksItemTest() { fun openNewTabTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openBookmarks { }.clickNewTabButton {
verifyBookmarksMenuView() verifySearchView()
}.submitQuery("test") {
verifyTabCounter("2")
} }
} }
// Device or AVD requires a Google Services Android OS installation with Play Store installed
// Verifies the Open in app button when an app is installed
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/387756
@SmokeTest @SmokeTest
@Test @Test
fun openMainMenuHistoryItemTest() { fun openInAppFunctionalityTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val youtubeURL = "vnd.youtube://".toUri()
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(youtubeURL) {
verifyNotificationDotOnMainMenu()
}.openThreeDotMenu { }.openThreeDotMenu {
}.openHistory { }.clickOpenInApp {
verifyHistoryListExists() assertYoutubeAppOpens()
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2284323
@Test @Test
fun openMainMenuAddonsTest() { fun openSyncAndSaveDataTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.waitForIdle()
}.openThreeDotMenu { }.openThreeDotMenu {
}.openAddonsManagerMenu { }.openSyncSignIn {
TestHelper.registerAndCleanupIdlingResources( verifyTurnOnSyncMenu()
RecyclerViewIdlingResource(
activityTestRule.activity.findViewById(R.id.add_ons_list),
1,
),
) {
verifyAddonsItems()
}
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243840
@Test @Test
fun openMainMenuSyncItemTest() { fun findInPageTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.waitForIdle() mDevice.waitForIdle()
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSyncSignIn { verifyThreeDotMenuExists()
verifyTurnOnSyncMenu() verifyFindInPageButton()
}.openFindInPage {
verifyFindInPageNextButton()
verifyFindInPagePrevButton()
verifyFindInPageCloseButton()
enterFindInPageQuery("a")
verifyFindNextInPageResult("1/3")
clickFindInPageNextButton()
verifyFindNextInPageResult("2/3")
clickFindInPageNextButton()
verifyFindNextInPageResult("3/3")
clickFindInPagePrevButton()
verifyFindPrevInPageResult("2/3")
clickFindInPagePrevButton()
verifyFindPrevInPageResult("1/3")
}.closeFindInPageWithCloseButton {
verifyFindInPageBar(false)
}.openThreeDotMenu {
}.openFindInPage {
enterFindInPageQuery("3")
verifyFindNextInPageResult("1/1")
}.closeFindInPageWithBackButton {
verifyFindInPageBar(false)
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2283303
@Test @Test
fun openMainMenuFindInPageTest() { fun switchDesktopSiteModeOnOffTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openFindInPage { }.switchDesktopSiteMode {
verifyFindInPageSearchBarItems() }.openThreeDotMenu {
verifyDesktopSiteModeEnabled(true)
}.switchDesktopSiteMode {
}.openThreeDotMenu {
verifyDesktopSiteModeEnabled(false)
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1314137
@Test @Test
fun mainMenuDesktopSiteTest() { fun setDesktopSiteBeforePageLoadTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 4)
navigationToolbar { homeScreen {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
}.openThreeDotMenu { }.openThreeDotMenu {
verifyDesktopSiteModeEnabled(false)
}.switchDesktopSiteMode { }.switchDesktopSiteMode {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(webPage.url) {
}.openThreeDotMenu {
verifyDesktopSiteModeEnabled(true)
}.closeBrowserMenuToBrowser {
clickPageObject(MatcherHelper.itemContainingText("Link 1"))
}.openThreeDotMenu { }.openThreeDotMenu {
verifyDesktopSiteModeEnabled(true) verifyDesktopSiteModeEnabled(true)
}.closeBrowserMenuToBrowser {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(webPage.url) {
longClickPageObject(MatcherHelper.itemWithText("Link 2"))
clickContextMenuItem("Open link in new tab")
TestHelper.clickSnackbarButton("SWITCH")
}.openThreeDotMenu {
verifyDesktopSiteModeEnabled(false)
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2283302
@Test @Test
fun mainMenuReportSiteIssueTest() { fun reportSiteIssueTest() {
runWithCondition( runWithCondition(
// This test will not run on RC builds because the "Report site issue button" is not available. // This test will not run on RC builds because the "Report site issue button" is not available.
activityTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, activityTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE,
@ -175,50 +254,77 @@ class MainMenuTest {
} }
} }
// Verifies the Add to home screen option in a tab's 3 dot menu
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/410724
@SmokeTest @SmokeTest
@Test @Test
fun openMainMenuAddToCollectionTest() { fun addPageShortcutToHomeScreenTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val shortcutTitle = TestHelper.generateRandomString(5)
navigationToolbar { homeScreen {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openNavigationToolbar {
}.enterURLAndEnterToBrowser(website.url) {
}.openThreeDotMenu {
expandMenu()
}.openAddToHomeScreen {
clickCancelShortcutButton()
}
browserScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSaveToCollection { expandMenu()
verifyCollectionNameTextField() }.openAddToHomeScreen {
verifyShortcutTextFieldTitle("Test_Page_1")
addShortcutName(shortcutTitle)
clickAddShortcutButton()
clickAddAutomaticallyButton()
}.openHomeScreenShortcut(shortcutTitle) {
verifyUrl(website.url.toString())
verifyTabCounter("1")
} }
} }
// Test running on beta/release builds in CI: // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/329893
// caution when making changes to it, so they don't block the builds
@SmokeTest @SmokeTest
@Test @Test
fun openMainMenuSettingsItemTest() { fun mainMenuShareButtonTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.clickShareButton {
verifySettingsView() verifyShareTabLayout()
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/233604
@Test @Test
fun mainMenuShareButtonTest() { fun navigateBackAndForwardTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val nextWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.waitForIdle()
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(nextWebPage.url) {
verifyUrl(nextWebPage.url.toString())
}.openThreeDotMenu { }.openThreeDotMenu {
}.clickShareButton { }.goToPreviousPage {
verifyShareTabLayout() mDevice.waitForIdle()
verifyUrl(defaultWebPage.url.toString())
}.openThreeDotMenu {
}.goForward {
verifyUrl(nextWebPage.url.toString())
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2195819
@SmokeTest @SmokeTest
@Test @Test
fun mainMenuRefreshButtonTest() { fun refreshPageButtonTest() {
val refreshWebPage = TestAssetHelper.getRefreshAsset(mockWebServer) val refreshWebPage = TestAssetHelper.getRefreshAsset(mockWebServer)
navigationToolbar { navigationToolbar {
@ -231,9 +337,9 @@ class MainMenuTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2265657
@Test @Test
fun mainMenuForceRefreshTest() { fun forceRefreshPageTest() {
val refreshWebPage = TestAssetHelper.getRefreshAsset(mockWebServer) val refreshWebPage = TestAssetHelper.getRefreshAsset(mockWebServer)
navigationToolbar { navigationToolbar {

@ -15,10 +15,8 @@ import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestHelper.runWithSystemLocaleChanged import org.mozilla.fenix.helpers.TestHelper.runWithSystemLocaleChanged
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 java.util.Locale import java.util.Locale
@ -54,51 +52,7 @@ class NavigationToolbarTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
@Test // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/987326
fun goBackTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val nextWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.waitForIdle()
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(nextWebPage.url) {
verifyUrl(nextWebPage.url.toString())
}.openThreeDotMenu {
}.goToPreviousPage {
mDevice.waitForIdle()
verifyUrl(defaultWebPage.url.toString())
}
}
@Test
fun goForwardTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val nextWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.waitForIdle()
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(nextWebPage.url) {
mDevice.waitForIdle()
verifyUrl(nextWebPage.url.toString())
}.openThreeDotMenu {
}.goToPreviousPage {
mDevice.waitForIdle()
verifyUrl(defaultWebPage.url.toString())
}
// Re-open the three-dot menu for verification
navigationToolbar {
}.openThreeDotMenu {
verifyThreeDotMenuExists()
}.goForward {
verifyUrl(nextWebPage.url.toString())
}
}
// Swipes the nav bar left/right to switch between tabs // Swipes the nav bar left/right to switch between tabs
@SmokeTest @SmokeTest
@Test @Test
@ -118,6 +72,7 @@ class NavigationToolbarTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/987327
// Because it requires changing system prefs, this test will run only on Debug builds // Because it requires changing system prefs, this test will run only on Debug builds
@Test @Test
fun swipeToSwitchTabInRTLTest() { fun swipeToSwitchTabInRTLTest() {
@ -139,85 +94,7 @@ class NavigationToolbarTest {
} }
} }
// Test running on beta/release builds in CI: // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2265279
// caution when making changes to it, so they don't block the builds
@Test
fun visitURLTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
verifyUrl(defaultWebPage.url.toString())
}
}
@Test
fun findInPageTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.waitForIdle()
}.openThreeDotMenu {
verifyThreeDotMenuExists()
verifyFindInPageButton()
}.openFindInPage {
verifyFindInPageNextButton()
verifyFindInPagePrevButton()
verifyFindInPageCloseButton()
enterFindInPageQuery("a")
verifyFindNextInPageResult("1/3")
clickFindInPageNextButton()
verifyFindNextInPageResult("2/3")
clickFindInPageNextButton()
verifyFindNextInPageResult("3/3")
clickFindInPagePrevButton()
verifyFindPrevInPageResult("2/3")
clickFindInPagePrevButton()
verifyFindPrevInPageResult("1/3")
}.closeFindInPageWithCloseButton {
verifyFindInPageBar(false)
}.openThreeDotMenu {
}.openFindInPage {
enterFindInPageQuery("3")
verifyFindNextInPageResult("1/1")
}.closeFindInPageWithBackButton {
verifyFindInPageBar(false)
}
}
@Test
fun pdfFindInPageTest() {
val genericURL =
TestAssetHelper.getGenericAsset(mockWebServer, 3)
navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
clickPageObject(itemWithText("PDF form file"))
}.openThreeDotMenu {
verifyThreeDotMenuExists()
verifyFindInPageButton()
}.openFindInPage {
verifyFindInPageNextButton()
verifyFindInPagePrevButton()
verifyFindInPageCloseButton()
enterFindInPageQuery("l")
verifyFindNextInPageResult("1/2")
clickFindInPageNextButton()
verifyFindNextInPageResult("2/2")
clickFindInPagePrevButton()
verifyFindPrevInPageResult("1/2")
}.closeFindInPageWithCloseButton {
verifyFindInPageBar(false)
}.openThreeDotMenu {
}.openFindInPage {
enterFindInPageQuery("p")
verifyFindNextInPageResult("1/1")
}.closeFindInPageWithBackButton {
verifyFindInPageBar(false)
}
}
@SmokeTest @SmokeTest
@Test @Test
fun verifySecurePageSecuritySubMenuTest() { fun verifySecurePageSecuritySubMenuTest() {
@ -233,6 +110,7 @@ class NavigationToolbarTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2265280
@SmokeTest @SmokeTest
@Test @Test
fun verifyInsecurePageSecuritySubMenuTest() { fun verifyInsecurePageSecuritySubMenuTest() {
@ -248,6 +126,8 @@ class NavigationToolbarTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1661318
@SmokeTest
@Test @Test
fun verifyClearCookiesFromQuickSettingsTest() { fun verifyClearCookiesFromQuickSettingsTest() {
val helpPageUrl = "mozilla.org" val helpPageUrl = "mozilla.org"
@ -260,4 +140,36 @@ class NavigationToolbarTest {
verifyClearSiteDataPrompt(helpPageUrl) verifyClearSiteDataPrompt(helpPageUrl)
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1360555
@SmokeTest
@Test
fun goToHomeScreenTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
mDevice.waitForIdle()
}.goToHomescreen {
verifyHomeScreen()
}
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2256552
@SmokeTest
@Test
fun goToHomeScreenInPrivateModeTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
togglePrivateBrowsingModeOnOff()
}
navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
mDevice.waitForIdle()
}.goToHomescreen {
verifyHomeScreen()
}
}
} }

@ -22,7 +22,6 @@ import org.mozilla.fenix.helpers.Experimentation
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.RetryTestRule
import org.mozilla.fenix.helpers.TestHelper.appContext import org.mozilla.fenix.helpers.TestHelper.appContext
import org.mozilla.fenix.ui.robots.homeScreen
class NimbusEventTest { class NimbusEventTest {
private lateinit var mDevice: UiDevice private lateinit var mDevice: UiDevice
@ -56,8 +55,6 @@ class NimbusEventTest {
@Test @Test
fun homeScreenNimbusEventsTest() { fun homeScreenNimbusEventsTest() {
homeScreen { }.dismissOnboarding()
Experimentation.withHelper { Experimentation.withHelper {
assertTrue(evalJexl("'app_opened'|eventSum('Days', 28, 0) > 0")) assertTrue(evalJexl("'app_opened'|eventSum('Days', 28, 0) > 0"))
} }

@ -43,8 +43,6 @@ class NoNetworkAccessStartupTests {
activityTestRule.launchActivity(null) activityTestRule.launchActivity(null)
homeScreen {
}.dismissOnboarding()
homeScreen { homeScreen {
verifyHomeScreen() verifyHomeScreen()
} }

@ -4,6 +4,7 @@
package org.mozilla.fenix.ui package org.mozilla.fenix.ui
import androidx.core.net.toUri
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import okhttp3.mockwebserver.MockWebServer import okhttp3.mockwebserver.MockWebServer
@ -15,10 +16,10 @@ import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_DOCS import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_DOCS
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText 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.getGenericAsset import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
import org.mozilla.fenix.helpers.TestHelper.assertExternalAppOpens import org.mozilla.fenix.helpers.TestHelper.assertExternalAppOpens
import org.mozilla.fenix.helpers.TestHelper.deleteDownloadedFileOnStorage import org.mozilla.fenix.helpers.TestHelper.deleteDownloadedFileOnStorage
@ -28,6 +29,11 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
class PDFViewerTest { class PDFViewerTest {
private lateinit var mockWebServer: MockWebServer private lateinit var mockWebServer: MockWebServer
private val downloadTestPage =
"https://storage.googleapis.com/mobile_test_assets/test_app/downloads.html"
private val pdfFileName = "washington.pdf"
private val pdfFileURL = "storage.googleapis.com/mobile_test_assets/public/washington.pdf"
private val pdfFileContent = "Washington Crossing the Delaware"
@get:Rule @get:Rule
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
@ -50,7 +56,7 @@ class PDFViewerTest {
@Test @Test
fun openPDFInBrowserTest() { fun openPDFInBrowserTest() {
val genericURL = val genericURL =
TestAssetHelper.getGenericAsset(mockWebServer, 3) getGenericAsset(mockWebServer, 3)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) { }.enterURLAndEnterToBrowser(genericURL.url) {
@ -88,4 +94,55 @@ class PDFViewerTest {
} }
deleteDownloadedFileOnStorage(downloadFile) deleteDownloadedFileOnStorage(downloadFile)
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2283305
@Test
fun pdfFindInPageTest() {
val genericURL = getGenericAsset(mockWebServer, 3)
navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
clickPageObject(MatcherHelper.itemWithText("PDF form file"))
}.openThreeDotMenu {
verifyThreeDotMenuExists()
verifyFindInPageButton()
}.openFindInPage {
verifyFindInPageNextButton()
verifyFindInPagePrevButton()
verifyFindInPageCloseButton()
enterFindInPageQuery("l")
verifyFindNextInPageResult("1/2")
clickFindInPageNextButton()
verifyFindNextInPageResult("2/2")
clickFindInPagePrevButton()
verifyFindPrevInPageResult("1/2")
}.closeFindInPageWithCloseButton {
verifyFindInPageBar(false)
}.openThreeDotMenu {
}.openFindInPage {
enterFindInPageQuery("p")
verifyFindNextInPageResult("1/1")
}.closeFindInPageWithBackButton {
verifyFindInPageBar(false)
}
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2284297
@Test
fun addPDFToHomeScreenTest() {
navigationToolbar {
}.enterURLAndEnterToBrowser(downloadTestPage.toUri()) {
clickPageObject(MatcherHelper.itemContainingText(pdfFileName))
verifyUrl(pdfFileURL)
verifyPageContent(pdfFileContent)
}.openThreeDotMenu {
expandMenu()
}.openAddToHomeScreen {
verifyShortcutTextFieldTitle(pdfFileName)
clickAddShortcutButton()
clickAddAutomaticallyButton()
}.openHomeScreenShortcut(pdfFileName) {
verifyUrl(pdfFileURL)
}
}
} }

@ -30,6 +30,12 @@ class PocketTest {
@Before @Before
fun setUp() { fun setUp() {
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
// Workaround to make sure the Pocket articles are populated before starting the tests.
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.goBack {}
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2252509 // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2252509
@ -40,9 +46,6 @@ class PocketTest {
it.isRecentlyVisitedFeatureEnabled = false it.isRecentlyVisitedFeatureEnabled = false
} }
homeScreen {
}.dismissOnboarding()
homeScreen { homeScreen {
verifyThoughtProvokingStories(true) verifyThoughtProvokingStories(true)
scrollToPocketProvokingStories() scrollToPocketProvokingStories()
@ -70,9 +73,6 @@ class PocketTest {
it.isRecentlyVisitedFeatureEnabled = false it.isRecentlyVisitedFeatureEnabled = false
} }
homeScreen {
}.dismissOnboarding()
homeScreen { homeScreen {
verifyThoughtProvokingStories(true) verifyThoughtProvokingStories(true)
scrollToPocketProvokingStories() scrollToPocketProvokingStories()
@ -90,9 +90,6 @@ class PocketTest {
it.isRecentlyVisitedFeatureEnabled = false it.isRecentlyVisitedFeatureEnabled = false
} }
homeScreen {
}.dismissOnboarding()
homeScreen { homeScreen {
scrollToPocketProvokingStories() scrollToPocketProvokingStories()
verifyDiscoverMoreStoriesButton() verifyDiscoverMoreStoriesButton()
@ -109,9 +106,6 @@ class PocketTest {
it.isRecentlyVisitedFeatureEnabled = false it.isRecentlyVisitedFeatureEnabled = false
} }
homeScreen {
}.dismissOnboarding()
homeScreen { homeScreen {
verifyStoriesByTopicItemState(activityTestRule, false, 1) verifyStoriesByTopicItemState(activityTestRule, false, 1)
clickStoriesByTopicItem(activityTestRule, 1) clickStoriesByTopicItem(activityTestRule, 1)
@ -127,9 +121,6 @@ class PocketTest {
it.isRecentlyVisitedFeatureEnabled = false it.isRecentlyVisitedFeatureEnabled = false
} }
homeScreen {
}.dismissOnboarding()
homeScreen { homeScreen {
verifyPoweredByPocket() verifyPoweredByPocket()
}.clickPocketLearnMoreLink(activityTestRule) { }.clickPocketLearnMoreLink(activityTestRule) {

@ -16,6 +16,7 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
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.TestHelper 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.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.addToHomeScreen
@ -58,7 +59,6 @@ class PwaTest {
} }
} }
@Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1807275")
@Test @Test
fun emailLinkPWATest() { fun emailLinkPWATest() {
navigationToolbar { navigationToolbar {
@ -71,7 +71,7 @@ class PwaTest {
}.openHomeScreenShortcut(shortcutTitle) { }.openHomeScreenShortcut(shortcutTitle) {
clickPageObject(itemContainingText("Email link")) clickPageObject(itemContainingText("Email link"))
clickPageObject(itemWithResIdAndText("android:id/button1", "OPEN")) clickPageObject(itemWithResIdAndText("android:id/button1", "OPEN"))
assertNativeAppOpens(GMAIL_APP, emailLink) assertExternalAppOpens(GMAIL_APP)
} }
} }

@ -20,11 +20,13 @@ 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.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.Constants.PackageName.ANDROID_SETTINGS import org.mozilla.fenix.helpers.Constants.PackageName.ANDROID_SETTINGS
import org.mozilla.fenix.helpers.Constants.searchEngineCodes import org.mozilla.fenix.helpers.Constants.searchEngineCodes
import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.MockBrowserDataHelper.createBookmarkItem
import org.mozilla.fenix.helpers.MockBrowserDataHelper.createHistoryItem import org.mozilla.fenix.helpers.MockBrowserDataHelper.createHistoryItem
import org.mozilla.fenix.helpers.MockBrowserDataHelper.createTabItem import org.mozilla.fenix.helpers.MockBrowserDataHelper.createTabItem
import org.mozilla.fenix.helpers.MockBrowserDataHelper.setCustomSearchEngine import org.mozilla.fenix.helpers.MockBrowserDataHelper.setCustomSearchEngine
@ -647,7 +649,7 @@ class SearchTest {
clickSearchSelectorButton() clickSearchSelectorButton()
selectTemporarySearchMethod(searchEngineName = "History") selectTemporarySearchMethod(searchEngineName = "History")
typeSearch(searchTerm = "Mozilla") typeSearch(searchTerm = "Mozilla")
verifyNoSuggestionsAreDisplayed(rule = activityTestRule, "Mozilla") verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla")
clickClearButton() clickClearButton()
typeSearch(searchTerm = "generic") typeSearch(searchTerm = "generic")
verifyTypedToolbarText("generic") verifyTypedToolbarText("generic")
@ -684,7 +686,7 @@ class SearchTest {
clickSearchSelectorButton() clickSearchSelectorButton()
selectTemporarySearchMethod(searchEngineName = "Tabs") selectTemporarySearchMethod(searchEngineName = "Tabs")
typeSearch(searchTerm = "Mozilla") typeSearch(searchTerm = "Mozilla")
verifyNoSuggestionsAreDisplayed(rule = activityTestRule, "Mozilla") verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla")
clickClearButton() clickClearButton()
typeSearch(searchTerm = "generic") typeSearch(searchTerm = "generic")
verifyTypedToolbarText("generic") verifyTypedToolbarText("generic")
@ -705,4 +707,50 @@ class SearchTest {
} }
} }
} }
@SmokeTest
@Test
fun searchHistoryNotRememberedInPrivateBrowsingTest() {
appContext.settings().shouldShowSearchSuggestionsInPrivate = true
val firstPageUrl = getGenericAsset(searchMockServer, 1)
val searchEngineName = "TestSearchEngine"
setCustomSearchEngine(searchMockServer, searchEngineName)
createBookmarkItem(firstPageUrl.url.toString(), firstPageUrl.title, 1u)
homeScreen {
}.openNavigationToolbar {
}.clickUrlbar {
}.submitQuery("test page 1") {
}.goToHomescreen {
}.togglePrivateBrowsingMode()
homeScreen {
}.openNavigationToolbar {
}.clickUrlbar {
}.submitQuery("test page 2") {
}.openNavigationToolbar {
}.clickUrlbar {
typeSearch(searchTerm = "test page")
verifySearchEngineSuggestionResults(
rule = activityTestRule,
searchSuggestions = arrayOf(
"TestSearchEngine search",
"test page 1",
"Firefox Suggest",
firstPageUrl.url.toString(),
),
searchTerm = "test page 1",
)
// 2 search engine suggestions and 2 browser suggestions (1 history, 1 bookmark)
verifySearchSuggestionsCount(activityTestRule, numberOfSuggestions = 4, searchTerm = "test page")
verifySuggestionsAreNotDisplayed(
activityTestRule,
searchSuggestions = arrayOf(
"test page 2",
),
)
}
}
} }

@ -49,23 +49,22 @@ class SettingsAboutTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// Walks through settings menu and sub-menus to ensure all items are present // Walks through the About settings menu to ensure all items are present
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2092700
@Test @Test
fun settingsAboutItemsTest() { fun verifyAboutSettingsItemsTest() {
// ABOUT
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
// ABOUT
verifyAboutHeading() verifyAboutHeading()
verifyRateOnGooglePlay() verifyRateOnGooglePlay()
verifyAboutFirefoxPreview() verifyAboutFirefoxPreview()
} }
} }
// ABOUT // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/246966
@Test @Test
fun verifyRateOnGooglePlayRedirect() { fun verifyRateOnGooglePlayButton() {
activityIntentTestRule.applySettingsExceptions { activityIntentTestRule.applySettingsExceptions {
it.isTCPCFREnabled = false it.isTCPCFREnabled = false
} }
@ -81,8 +80,9 @@ class SettingsAboutTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/246961
@Test @Test
fun verifyAboutFirefoxPreview() { fun verifyAboutFirefoxMenuItems() {
activityIntentTestRule.applySettingsExceptions { activityIntentTestRule.applySettingsExceptions {
it.isJumpBackInCFREnabled = false it.isJumpBackInCFREnabled = false
it.isTCPCFREnabled = false it.isTCPCFREnabled = false
@ -91,7 +91,7 @@ class SettingsAboutTest {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
}.openAboutFirefoxPreview { }.openAboutFirefoxPreview {
verifyAboutFirefoxPreview() verifyAboutFirefoxPreviewInfo()
} }
} }
} }

@ -47,9 +47,10 @@ class SettingsAddonsTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/875780
// Walks through settings add-ons menu to ensure all items are present // Walks through settings add-ons menu to ensure all items are present
@Test @Test
fun settingsAddonsItemsTest() { fun verifyAddonsListItemsTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -64,9 +65,10 @@ class SettingsAddonsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/875781
// Installs an add-on from the Add-ons menu and verifies the prompts // Installs an add-on from the Add-ons menu and verifies the prompts
@Test @Test
fun installAddonTest() { fun installAddonFromMainMenuTest() {
val addonName = "uBlock Origin" val addonName = "uBlock Origin"
homeScreen {} homeScreen {}
@ -92,9 +94,10 @@ class SettingsAddonsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/561597
// Installs an addon, then uninstalls it // Installs an addon, then uninstalls it
@Test @Test
fun verifyAddonsCanBeUninstalled() { fun verifyAddonsCanBeUninstalledTest() {
val addonName = "uBlock Origin" val addonName = "uBlock Origin"
addonsMenu { addonsMenu {
@ -112,6 +115,7 @@ class SettingsAddonsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/561600
// Installs uBlock add-on and checks that the app doesn't crash while loading pages with trackers // Installs uBlock add-on and checks that the app doesn't crash while loading pages with trackers
@SmokeTest @SmokeTest
@Test @Test
@ -133,9 +137,10 @@ class SettingsAddonsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/561594
@SmokeTest @SmokeTest
@Test @Test
fun useAddonsInPrivateModeTest() { fun verifyUBlockWorksInPrivateModeTest() {
val addonName = "uBlock Origin" val addonName = "uBlock Origin"
val genericPage = getGenericAsset(mockWebServer, 1) val genericPage = getGenericAsset(mockWebServer, 1)

@ -32,6 +32,11 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
class SettingsAdvancedTest { class SettingsAdvancedTest {
private lateinit var mDevice: UiDevice private lateinit var mDevice: UiDevice
private lateinit var mockWebServer: MockWebServer private lateinit var mockWebServer: MockWebServer
private val youTubeSchemaLink = itemContainingText("Youtube schema link")
private val youTubeFullLink = itemContainingText("Youtube full link")
private val playStoreLink = itemContainingText("Playstore link")
private val playStoreUrl = "play.google.com"
private val youTubePage = "vnd.youtube://".toUri()
@get:Rule @get:Rule
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
@ -50,9 +55,10 @@ class SettingsAdvancedTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2092699
// Walks through settings menu and sub-menus to ensure all items are present // Walks through settings menu and sub-menus to ensure all items are present
@Test @Test
fun settingsAdvancedItemsTest() { fun verifyAdvancedSettingsSectionItemsTest() {
// ADVANCED // ADVANCED
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
@ -71,24 +77,12 @@ class SettingsAdvancedTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2121046
@Test
fun verifyOpenLinkInAppViewTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
verifyOpenLinksInAppsButton()
verifySettingsOptionSummary("Open links in apps", "Never")
}.openOpenLinksInAppsMenu {
verifyOpenLinksInAppsView("Never")
}
}
// Assumes Youtube is installed and enabled // Assumes Youtube is installed and enabled
@SmokeTest @SmokeTest
@Test @Test
fun neverOpenLinkInAppTest() { fun neverOpenLinkInAppTest() {
val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer)
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
@ -102,17 +96,18 @@ class SettingsAdvancedTest {
exitMenu() exitMenu()
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(externalLinksPage.url) {
clickPageObject(itemContainingText("Youtube link")) clickPageObject(playStoreLink)
waitForPageToLoad() waitForPageToLoad()
verifyUrl("youtube.com") verifyUrl(playStoreUrl)
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2121052
// Assumes Youtube is installed and enabled // Assumes Youtube is installed and enabled
@Test @Test
fun privateBrowsingNeverOpenLinkInAppTest() { fun privateBrowsingNeverOpenLinkInAppTest() {
val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer)
homeScreen { homeScreen {
}.togglePrivateBrowsingMode() }.togglePrivateBrowsingMode()
@ -129,18 +124,19 @@ class SettingsAdvancedTest {
exitMenu() exitMenu()
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(externalLinksPage.url) {
clickPageObject(itemContainingText("Youtube link")) clickPageObject(playStoreLink)
waitForPageToLoad() waitForPageToLoad()
verifyUrl("youtube.com") verifyUrl(playStoreUrl)
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2121045
// Assumes Youtube is installed and enabled // Assumes Youtube is installed and enabled
@SmokeTest @SmokeTest
@Test @Test
fun askBeforeOpeningLinkInAppCancelTest() { fun askBeforeOpeningLinkInAppCancelTest() {
val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer)
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
@ -158,20 +154,21 @@ class SettingsAdvancedTest {
exitMenu() exitMenu()
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(externalLinksPage.url) {
clickPageObject(itemContainingText("Youtube link")) clickPageObject(youTubeFullLink)
verifyOpenLinkInAnotherAppPrompt() verifyOpenLinkInAnotherAppPrompt()
clickPageObject(itemWithResIdAndText("android:id/button2", "CANCEL")) clickPageObject(itemWithResIdAndText("android:id/button2", "CANCEL"))
waitForPageToLoad() waitForPageToLoad()
verifyUrl("youtube.com") verifyUrl("youtube")
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2288347
// Assumes Youtube is installed and enabled // Assumes Youtube is installed and enabled
@SmokeTest @SmokeTest
@Test @Test
fun askBeforeOpeningLinkInAppOpenTest() { fun askBeforeOpeningLinkInAppOpenTest() {
val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer)
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
@ -189,8 +186,8 @@ class SettingsAdvancedTest {
exitMenu() exitMenu()
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(externalLinksPage.url) {
clickPageObject(itemContainingText("Youtube link")) clickPageObject(youTubeSchemaLink)
verifyOpenLinkInAnotherAppPrompt() verifyOpenLinkInAnotherAppPrompt()
clickPageObject(itemWithResIdAndText("android:id/button1", "OPEN")) clickPageObject(itemWithResIdAndText("android:id/button1", "OPEN"))
mDevice.waitForIdle() mDevice.waitForIdle()
@ -198,10 +195,11 @@ class SettingsAdvancedTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2121051
// Assumes Youtube is installed and enabled // Assumes Youtube is installed and enabled
@Test @Test
fun privateBrowsingAskBeforeOpeningLinkInAppCancelTest() { fun privateBrowsingAskBeforeOpeningLinkInAppCancelTest() {
val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer)
homeScreen { homeScreen {
}.togglePrivateBrowsingMode() }.togglePrivateBrowsingMode()
@ -222,19 +220,20 @@ class SettingsAdvancedTest {
exitMenu() exitMenu()
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(externalLinksPage.url) {
clickPageObject(itemContainingText("Youtube link")) clickPageObject(youTubeFullLink)
verifyPrivateBrowsingOpenLinkInAnotherAppPrompt("youtube.com") verifyPrivateBrowsingOpenLinkInAnotherAppPrompt("youtube")
clickPageObject(itemWithResIdAndText("android:id/button2", "CANCEL")) clickPageObject(itemWithResIdAndText("android:id/button2", "CANCEL"))
waitForPageToLoad() waitForPageToLoad()
verifyUrl("youtube.com") verifyUrl("youtube")
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2288350
// Assumes Youtube is installed and enabled // Assumes Youtube is installed and enabled
@Test @Test
fun privateBrowsingAskBeforeOpeningLinkInAppOpenTest() { fun privateBrowsingAskBeforeOpeningLinkInAppOpenTest() {
val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer)
homeScreen { homeScreen {
}.togglePrivateBrowsingMode() }.togglePrivateBrowsingMode()
@ -255,19 +254,20 @@ class SettingsAdvancedTest {
exitMenu() exitMenu()
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(externalLinksPage.url) {
clickPageObject(itemContainingText("Youtube link")) clickPageObject(youTubeSchemaLink)
verifyPrivateBrowsingOpenLinkInAnotherAppPrompt("youtube.com") verifyPrivateBrowsingOpenLinkInAnotherAppPrompt("youtube")
clickPageObject(itemWithResIdAndText("android:id/button1", "OPEN")) clickPageObject(itemWithResIdAndText("android:id/button1", "OPEN"))
mDevice.waitForIdle() mDevice.waitForIdle()
assertYoutubeAppOpens() assertYoutubeAppOpens()
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1058618
// Assumes Youtube is installed and enabled // Assumes Youtube is installed and enabled
@Test @Test
fun alwaysOpenLinkInAppTest() { fun alwaysOpenLinkInAppTest() {
val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer)
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
@ -285,22 +285,22 @@ class SettingsAdvancedTest {
exitMenu() exitMenu()
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(externalLinksPage.url) {
clickPageObject(itemContainingText("Youtube link")) clickPageObject(youTubeSchemaLink)
mDevice.waitForIdle() mDevice.waitForIdle()
assertYoutubeAppOpens() assertYoutubeAppOpens()
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1058617
@Test @Test
fun dismissOpenLinksInAppCFRTest() { fun dismissOpenLinksInAppCFRTest() {
activityIntentTestRule.applySettingsExceptions { activityIntentTestRule.applySettingsExceptions {
it.isOpenInAppBannerEnabled = true it.isOpenInAppBannerEnabled = true
} }
val defaultWebPage = "https://m.youtube.com/"
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.toUri()) { }.enterURLAndEnterToBrowser(youTubePage) {
waitForPageToLoad() waitForPageToLoad()
verifyOpenLinksInAppsCFRExists(true) verifyOpenLinksInAppsCFRExists(true)
clickOpenLinksInAppsDismissCFRButton() clickOpenLinksInAppsDismissCFRButton()
@ -308,15 +308,15 @@ class SettingsAdvancedTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2288331
@Test @Test
fun goToSettingsFromOpenLinksInAppCFRTest() { fun goToSettingsFromOpenLinksInAppCFRTest() {
activityIntentTestRule.applySettingsExceptions { activityIntentTestRule.applySettingsExceptions {
it.isOpenInAppBannerEnabled = true it.isOpenInAppBannerEnabled = true
} }
val defaultWebPage = "https://m.youtube.com/"
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.toUri()) { }.enterURLAndEnterToBrowser(youTubePage) {
waitForPageToLoad() waitForPageToLoad()
verifyOpenLinksInAppsCFRExists(true) verifyOpenLinksInAppsCFRExists(true)
}.clickOpenLinksInAppsGoToSettingsCFRButton { }.clickOpenLinksInAppsGoToSettingsCFRButton {

@ -49,8 +49,9 @@ class SettingsCustomizeTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/344212
@Test @Test
fun changeThemeSettingTest() { fun changeThemeOfTheAppTest() {
// Goes through the settings and changes the default search engine, then verifies it changes. // Goes through the settings and changes the default search engine, then verifies it changes.
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
@ -64,6 +65,7 @@ class SettingsCustomizeTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/466571
@Test @Test
fun setToolbarPositionTest() { fun setToolbarPositionTest() {
homeScreen { homeScreen {
@ -88,8 +90,9 @@ class SettingsCustomizeTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1058682
@Test @Test
fun swipeToolbarGesturePreferenceOffTest() { fun turnOffSwipeToSwitchTabsPreferenceTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
@ -114,6 +117,7 @@ class SettingsCustomizeTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1992289
@Test @Test
fun pullToRefreshPreferenceTest() { fun pullToRefreshPreferenceTest() {
homeScreen { homeScreen {

@ -60,8 +60,9 @@ class SettingsDeleteBrowsingDataOnQuitTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416048
@Test @Test
fun deleteBrowsingDataOnQuitSettingsItemsTest() { fun deleteBrowsingDataOnQuitSettingTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -88,6 +89,7 @@ class SettingsDeleteBrowsingDataOnQuitTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416049
@Test @Test
fun deleteOpenTabsOnQuitTest() { fun deleteOpenTabsOnQuitTest() {
val testPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val testPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -112,8 +114,9 @@ class SettingsDeleteBrowsingDataOnQuitTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416050
@Test @Test
fun deleteHistoryOnQuitTest() { fun deleteBrowsingHistoryOnQuitTest() {
val genericPage = val genericPage =
getStorageTestAsset(mockWebServer, "generic1.html") getStorageTestAsset(mockWebServer, "generic1.html")
@ -140,6 +143,7 @@ class SettingsDeleteBrowsingDataOnQuitTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416051
@Test @Test
fun deleteCookiesAndSiteDataOnQuitTest() { fun deleteCookiesAndSiteDataOnQuitTest() {
val storageWritePage = val storageWritePage =
@ -174,6 +178,7 @@ class SettingsDeleteBrowsingDataOnQuitTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1243096
@SmokeTest @SmokeTest
@Test @Test
fun deleteDownloadsOnQuitTest() { fun deleteDownloadsOnQuitTest() {
@ -191,7 +196,7 @@ class SettingsDeleteBrowsingDataOnQuitTest {
}.clickDownloadLink("smallZip.zip") { }.clickDownloadLink("smallZip.zip") {
verifyDownloadPrompt("smallZip.zip") verifyDownloadPrompt("smallZip.zip")
}.clickDownload { }.clickDownload {
verifyDownloadNotificationPopup() verifyDownloadCompleteNotificationPopup()
}.closeCompletedDownloadPrompt { }.closeCompletedDownloadPrompt {
}.goToHomescreen { }.goToHomescreen {
}.openThreeDotMenu { }.openThreeDotMenu {
@ -207,6 +212,7 @@ class SettingsDeleteBrowsingDataOnQuitTest {
deleteDownloadedFileOnStorage("smallZip.zip") deleteDownloadedFileOnStorage("smallZip.zip")
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416053
@SmokeTest @SmokeTest
@Test @Test
fun deleteSitePermissionsOnQuitTest() { fun deleteSitePermissionsOnQuitTest() {
@ -242,6 +248,7 @@ class SettingsDeleteBrowsingDataOnQuitTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416052
@Test @Test
fun deleteCachedFilesOnQuitTest() { fun deleteCachedFilesOnQuitTest() {
val pocketTopArticles = TestHelper.getStringResource(R.string.pocket_pinned_top_articles) val pocketTopArticles = TestHelper.getStringResource(R.string.pocket_pinned_top_articles)

@ -7,6 +7,7 @@ package org.mozilla.fenix.ui
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.R import org.mozilla.fenix.R
@ -51,6 +52,7 @@ class SettingsDeleteBrowsingDataTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/937561
@Test @Test
fun deleteBrowsingDataOptionStatesTest() { fun deleteBrowsingDataOptionStatesTest() {
homeScreen { homeScreen {
@ -109,8 +111,9 @@ class SettingsDeleteBrowsingDataTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/517811
@Test @Test
fun deleteTabsDataWithNoOpenTabsTest() { fun deleteOpenTabsBrowsingDataWithNoOpenTabsTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -126,9 +129,10 @@ class SettingsDeleteBrowsingDataTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/353531
@SmokeTest @SmokeTest
@Test @Test
fun deleteTabsDataTest() { fun deleteOpenTabsBrowsingDataTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
@ -158,6 +162,7 @@ class SettingsDeleteBrowsingDataTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/378864
@SmokeTest @SmokeTest
@Test @Test
fun deleteBrowsingHistoryTest() { fun deleteBrowsingHistoryTest() {
@ -188,6 +193,7 @@ class SettingsDeleteBrowsingDataTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416041
@SmokeTest @SmokeTest
@Test @Test
fun deleteCookiesAndSiteDataTest() { fun deleteCookiesAndSiteDataTest() {
@ -226,6 +232,8 @@ class SettingsDeleteBrowsingDataTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416042
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268")
@SmokeTest @SmokeTest
@Test @Test
fun deleteCachedFilesTest() { fun deleteCachedFilesTest() {

@ -53,8 +53,9 @@ class SettingsGeneralTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2092697
@Test @Test
fun settingsGeneralItemsTests() { fun verifyGeneralSettingsItemsTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -76,9 +77,10 @@ class SettingsGeneralTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/344213
@SmokeTest @SmokeTest
@Test @Test
fun changeAccessibiltySettings() { fun verifyFontSizingChangeTest() {
// Goes through the settings and changes the default text on a webpage, then verifies if the text has changed. // Goes through the settings and changes the default text on a webpage, then verifies if the text has changed.
val fenixApp = activityIntentTestRule.activity.applicationContext as FenixApplication val fenixApp = activityIntentTestRule.activity.applicationContext as FenixApplication
val webpage = getLoremIpsumAsset(mockWebServer).url val webpage = getLoremIpsumAsset(mockWebServer).url
@ -107,9 +109,10 @@ class SettingsGeneralTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/516079
@SmokeTest @SmokeTest
@Test @Test
fun switchLanguageTest() { fun setAppLanguageDifferentThanSystemLanguageTest() {
val enLanguageHeaderText = getStringResource(R.string.preferences_language) val enLanguageHeaderText = getStringResource(R.string.preferences_language)
homeScreen { homeScreen {
@ -132,6 +135,7 @@ class SettingsGeneralTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/516080
@Test @Test
fun searchInLanguagesListTest() { fun searchInLanguagesListTest() {
val systemLocaleDefault = getStringResource(R.string.default_locale_text) val systemLocaleDefault = getStringResource(R.string.default_locale_text)
@ -153,10 +157,11 @@ class SettingsGeneralTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/516078
// Because it requires changing system prefs, this test will run only on Debug builds // Because it requires changing system prefs, this test will run only on Debug builds
@Ignore("Failing due to app translation bug, see: https://github.com/mozilla-mobile/fenix/issues/26729") @Ignore("Failing due to app translation bug, see: https://github.com/mozilla-mobile/fenix/issues/26729")
@Test @Test
fun frenchSystemLocaleTest() { fun verifyFollowDeviceLanguageTest() {
val frenchLocale = Locale("fr", "FR") val frenchLocale = Locale("fr", "FR")
runWithSystemLocaleChanged(frenchLocale, activityIntentTestRule) { runWithSystemLocaleChanged(frenchLocale, activityIntentTestRule) {
@ -172,47 +177,18 @@ class SettingsGeneralTest {
} }
} }
@SmokeTest // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1360557
@Test
fun verifyHomepageOptionSummaryUpdatesTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
verifySettingsOptionSummary("Homepage", "Open on homepage after four hours")
}.openHomepageSubMenu {
verifySelectedOpeningScreenOption("Homepage after four hours of inactivity")
clickOpeningScreenOption("Homepage")
verifySelectedOpeningScreenOption("Homepage")
}.goBack {
verifySettingsOptionSummary("Homepage", "Open on homepage")
}.openHomepageSubMenu {
clickOpeningScreenOption("Last tab")
verifySelectedOpeningScreenOption("Last tab")
}.goBack {
verifySettingsOptionSummary("Homepage", "Open on last tab")
}
}
@Test @Test
fun tabsSettingsMenuItemsTest() { fun tabsSettingsMenuItemsTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
verifyTabsButton()
verifySettingsOptionSummary("Tabs", "Close manually")
}.openTabsSubMenu { }.openTabsSubMenu {
verifyTabViewOptions() verifyTabViewOptions()
verifyCloseTabsOptions() verifyCloseTabsOptions()
verifyMoveOldTabsToInactiveOptions() verifyMoveOldTabsToInactiveOptions()
}
}
@Test
fun verifyTabsOptionSummaryUpdatesTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
verifyTabsButton()
verifySettingsOptionSummary("Tabs", "Close manually")
}.openTabsSubMenu {
verifySelectedCloseTabsOption("Never") verifySelectedCloseTabsOption("Never")
clickClosedTabsOption("After one day") clickClosedTabsOption("After one day")
verifySelectedCloseTabsOption("After one day") verifySelectedCloseTabsOption("After one day")
@ -230,4 +206,21 @@ class SettingsGeneralTest {
verifySettingsOptionSummary("Tabs", "Close after one month") verifySettingsOptionSummary("Tabs", "Close after one month")
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243583
// For API>23
// Verifies the default browser switch opens the system default apps menu.
@SmokeTest
@Test
fun changeDefaultBrowserSetting() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
verifyDefaultBrowserToggle(false)
clickDefaultBrowserSwitch()
verifyAndroidDefaultAppsMenuAppears()
}
// Dismiss the request
mDevice.pressBack()
}
} }

@ -32,6 +32,7 @@ class SettingsHTTPSOnlyModeTest {
@get:Rule @get:Rule
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true) val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1724825
@Test @Test
fun httpsOnlyModeMenuItemsTest() { fun httpsOnlyModeMenuItemsTest() {
homeScreen { homeScreen {
@ -58,6 +59,7 @@ class SettingsHTTPSOnlyModeTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1724827
@SmokeTest @SmokeTest
@Test @Test
fun httpsOnlyModeEnabledInNormalBrowsingTest() { fun httpsOnlyModeEnabledInNormalBrowsingTest() {
@ -93,8 +95,9 @@ class SettingsHTTPSOnlyModeTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2091057
@Test @Test
fun httpsOnlyModeExceptionPersistsForCurrentSession() { fun httpsOnlyModeExceptionPersistsForCurrentSessionTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -120,6 +123,7 @@ class SettingsHTTPSOnlyModeTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1724828
@Test @Test
fun httpsOnlyModeEnabledOnlyInPrivateBrowsingTest() { fun httpsOnlyModeEnabledOnlyInPrivateBrowsingTest() {
homeScreen { homeScreen {
@ -159,6 +163,7 @@ class SettingsHTTPSOnlyModeTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2091058
@Test @Test
fun turnOffHttpsOnlyModeTest() { fun turnOffHttpsOnlyModeTest() {
homeScreen { homeScreen {

@ -49,6 +49,7 @@ class SettingsHomepageTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1564843
@Test @Test
fun verifyHomepageSettingsTest() { fun verifyHomepageSettingsTest() {
homeScreen { homeScreen {
@ -59,6 +60,7 @@ class SettingsHomepageTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1564859
@Test @Test
fun verifyShortcutOptionTest() { fun verifyShortcutOptionTest() {
// en-US defaults // en-US defaults
@ -90,6 +92,7 @@ class SettingsHomepageTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1565003
@Test @Test
fun verifyRecentlyVisitedOptionTest() { fun verifyRecentlyVisitedOptionTest() {
activityIntentTestRule.applySettingsExceptions { activityIntentTestRule.applySettingsExceptions {
@ -109,26 +112,7 @@ class SettingsHomepageTest {
} }
} }
@Test // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1564999
fun verifyPocketOptionTest() {
activityIntentTestRule.applySettingsExceptions {
it.isRecentTabsFeatureEnabled = false
it.isRecentlyVisitedFeatureEnabled = false
}
val genericURL = getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
}.goToHomescreen {
verifyPocketSectionIsDisplayed()
}.openThreeDotMenu {
}.openCustomizeHome {
clickPocketButton()
}.goBackToHomeScreen {
verifyPocketSectionIsNotDisplayed()
}
}
@SmokeTest @SmokeTest
@Test @Test
fun jumpBackInOptionTest() { fun jumpBackInOptionTest() {
@ -146,6 +130,7 @@ class SettingsHomepageTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1565000
@SmokeTest @SmokeTest
@Test @Test
fun recentBookmarksOptionTest() { fun recentBookmarksOptionTest() {
@ -165,48 +150,47 @@ class SettingsHomepageTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1569831
@SmokeTest @SmokeTest
@Test @Test
fun startOnHomepageTest() { fun verifyOpeningScreenOptionsTest() {
val genericURL = getGenericAsset(mockWebServer, 1) val genericURL = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) { }.enterURLAndEnterToBrowser(genericURL.url) {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
verifySettingsOptionSummary("Homepage", "Open on homepage after four hours")
}.openHomepageSubMenu { }.openHomepageSubMenu {
verifySelectedOpeningScreenOption("Homepage after four hours of inactivity")
clickOpeningScreenOption("Homepage") clickOpeningScreenOption("Homepage")
verifySelectedOpeningScreenOption("Homepage")
} }
restartApp(activityIntentTestRule) restartApp(activityIntentTestRule)
homeScreen { homeScreen {
verifyHomeScreen() verifyHomeScreen()
}
}
@SmokeTest
@Test
fun startOnLastTabTest() {
val firstWebPage = getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(firstWebPage.url) {
}.goToHomescreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openCustomizeHome { }.openSettings {
verifySettingsOptionSummary("Homepage", "Open on homepage")
}.openHomepageSubMenu {
clickOpeningScreenOption("Last tab") clickOpeningScreenOption("Last tab")
verifySelectedOpeningScreenOption("Last tab")
}.goBack {
verifySettingsOptionSummary("Homepage", "Open on last tab")
} }
restartApp(activityIntentTestRule) restartApp(activityIntentTestRule)
browserScreen { browserScreen {
verifyUrl(firstWebPage.url.toString()) verifyUrl(genericURL.url.toString())
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1569843
@Test @Test
fun ignoreStartOnHomeWhenLaunchedByExternalLinkTest() { fun verifyOpeningScreenAfterLaunchingExternalLinkTest() {
val genericPage = getGenericAsset(mockWebServer, 1) val genericPage = getGenericAsset(mockWebServer, 1)
homeScreen { homeScreen {
@ -230,9 +214,10 @@ class SettingsHomepageTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1676359
@Ignore("Intermittent test: https://github.com/mozilla-mobile/fenix/issues/26559") @Ignore("Intermittent test: https://github.com/mozilla-mobile/fenix/issues/26559")
@Test @Test
fun setWallpaperTest() { fun verifyWallpaperChangeTest() {
val wallpapers = listOf( val wallpapers = listOf(
"Wallpaper Item: amethyst", "Wallpaper Item: amethyst",
"Wallpaper Item: cerulean", "Wallpaper Item: cerulean",

@ -44,6 +44,7 @@ class SettingsPrivacyTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2092698
@Test @Test
fun settingsPrivacyItemsTest() { fun settingsPrivacyItemsTest() {
homeScreen { homeScreen {
@ -68,8 +69,9 @@ class SettingsPrivacyTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243362
@Test @Test
fun verifyDataCollectionTest() { fun verifyDataCollectionSettingsTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -79,44 +81,14 @@ class SettingsPrivacyTest {
true, true,
"On", "On",
) )
}
}
@Test
fun verifyUsageAndTechnicalDataToggleTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSettingsSubMenuDataCollection {
verifyUsageAndTechnicalDataToggle(true)
clickUsageAndTechnicalDataToggle() clickUsageAndTechnicalDataToggle()
verifyUsageAndTechnicalDataToggle(false) verifyUsageAndTechnicalDataToggle(false)
} clickUsageAndTechnicalDataToggle()
} verifyUsageAndTechnicalDataToggle(true)
@Test
fun verifyMarketingDataToggleTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSettingsSubMenuDataCollection {
verifyMarketingDataToggle(true)
clickMarketingDataToggle() clickMarketingDataToggle()
verifyMarketingDataToggle(false) verifyMarketingDataToggle(false)
} clickMarketingDataToggle()
} verifyMarketingDataToggle(true)
@Test
fun verifyStudiesToggleTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSettingsSubMenuDataCollection {
verifyDataCollectionView(
true,
true,
"On",
)
clickStudiesOption() clickStudiesOption()
verifyStudiesToggle(true) verifyStudiesToggle(true)
clickStudiesToggle() clickStudiesToggle()
@ -126,26 +98,7 @@ class SettingsPrivacyTest {
} }
} }
@Test // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1024594
fun sitePermissionsItemsTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSettingsSubMenuSitePermissions {
verifySitePermissionsToolbarTitle()
verifyToolbarGoBackButton()
verifySitePermissionOption("Autoplay", "Block audio only")
verifySitePermissionOption("Camera", "Blocked by Android")
verifySitePermissionOption("Location", "Blocked by Android")
verifySitePermissionOption("Microphone", "Blocked by Android")
verifySitePermissionOption("Notification", "Ask to allow")
verifySitePermissionOption("Persistent Storage", "Ask to allow")
verifySitePermissionOption("Cross-site cookies", "Ask to allow")
verifySitePermissionOption("DRM-controlled content", "Ask to allow")
verifySitePermissionOption("Exceptions")
}
}
@Test @Test
fun verifyNotificationsSettingsTest() { fun verifyNotificationsSettingsTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)

@ -39,6 +39,7 @@ class SettingsPrivateBrowsingTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/555822
@Test @Test
fun verifyPrivateBrowsingMenuItemsTest() { fun verifyPrivateBrowsingMenuItemsTest() {
homeScreen { homeScreen {
@ -145,8 +146,9 @@ class SettingsPrivateBrowsingTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/414583
@Test @Test
fun addPrivateBrowsingShortcut() { fun addPrivateBrowsingShortcutFromSettingsTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {

@ -160,7 +160,7 @@ class SettingsSearchTest {
homeScreen { homeScreen {
}.openSearch { }.openSearch {
typeSearch("test") typeSearch("test")
verifyNoSuggestionsAreDisplayed( verifySuggestionsAreNotDisplayed(
activityTestRule, activityTestRule,
"Firefox Suggest", "Firefox Suggest",
websiteURL, websiteURL,
@ -188,7 +188,7 @@ class SettingsSearchTest {
homeScreen { homeScreen {
}.openSearch { }.openSearch {
typeSearch("test") typeSearch("test")
verifyNoSuggestionsAreDisplayed( verifySuggestionsAreNotDisplayed(
activityTestRule, activityTestRule,
"Firefox Suggest", "Firefox Suggest",
website.title, website.title,
@ -426,7 +426,7 @@ class SettingsSearchTest {
}.goBack { }.goBack {
}.openSearch { }.openSearch {
typeSearch("mozilla") typeSearch("mozilla")
verifyNoSuggestionsAreDisplayed(activityTestRule, "mozilla firefox") verifySuggestionsAreNotDisplayed(activityTestRule, "mozilla firefox")
} }
} }
@ -439,7 +439,7 @@ class SettingsSearchTest {
typeSearch("mozilla") typeSearch("mozilla")
verifyAllowSuggestionsInPrivateModeDialog() verifyAllowSuggestionsInPrivateModeDialog()
denySuggestionsInPrivateMode() denySuggestionsInPrivateMode()
verifyNoSuggestionsAreDisplayed(activityTestRule, "mozilla firefox") verifySuggestionsAreNotDisplayed(activityTestRule, "mozilla firefox")
} }
} }
@ -466,7 +466,7 @@ class SettingsSearchTest {
}.goBack { }.goBack {
}.openSearch { }.openSearch {
typeSearch("mozilla") typeSearch("mozilla")
verifyNoSuggestionsAreDisplayed(activityTestRule, "mozilla firefox") verifySuggestionsAreNotDisplayed(activityTestRule, "mozilla firefox")
} }
} }

@ -69,11 +69,33 @@ class SettingsSitePermissionsTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/246974
@Test
fun sitePermissionsItemsTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSettingsSubMenuSitePermissions {
verifySitePermissionsToolbarTitle()
verifyToolbarGoBackButton()
verifySitePermissionOption("Autoplay", "Block audio only")
verifySitePermissionOption("Camera", "Blocked by Android")
verifySitePermissionOption("Location", "Blocked by Android")
verifySitePermissionOption("Microphone", "Blocked by Android")
verifySitePermissionOption("Notification", "Ask to allow")
verifySitePermissionOption("Persistent Storage", "Ask to allow")
verifySitePermissionOption("Cross-site cookies", "Ask to allow")
verifySitePermissionOption("DRM-controlled content", "Ask to allow")
verifySitePermissionOption("Exceptions")
}
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/247680
// Verifies that you can go to System settings and change app's permissions from inside the app // Verifies that you can go to System settings and change app's permissions from inside the app
@SmokeTest @SmokeTest
@Test @Test
@SdkSuppress(minSdkVersion = 29) @SdkSuppress(minSdkVersion = 29)
fun redirectToAppPermissionsSystemSettingsTest() { fun systemBlockedPermissionsRedirectToSystemAppSettingsTest() {
homeScreen { homeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
@ -108,9 +130,10 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2095125
@SmokeTest @SmokeTest
@Test @Test
fun verifyAutoplayBlockAudioOnlySettingTest() { fun verifyAutoplayBlockAudioOnlySettingOnNotMutedVideoTest() {
val genericPage = getGenericAsset(mockWebServer, 1) val genericPage = getGenericAsset(mockWebServer, 1)
val videoTestPage = getVideoPageAsset(mockWebServer) val videoTestPage = getVideoPageAsset(mockWebServer)
@ -146,6 +169,7 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2286807
@Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1827599") @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1827599")
@SmokeTest @SmokeTest
@Test @Test
@ -173,8 +197,9 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2095124
@Test @Test
fun verifyAutoplayAllowAudioVideoSettingTest() { fun verifyAutoplayAllowAudioVideoSettingOnNotMutedVideoTestTest() {
val genericPage = getGenericAsset(mockWebServer, 1) val genericPage = getGenericAsset(mockWebServer, 1)
val videoTestPage = getVideoPageAsset(mockWebServer) val videoTestPage = getVideoPageAsset(mockWebServer)
@ -208,6 +233,7 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2286806
@Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1827599") @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1827599")
@Test @Test
fun verifyAutoplayAllowAudioVideoSettingOnMutedVideoTest() { fun verifyAutoplayAllowAudioVideoSettingOnMutedVideoTest() {
@ -235,8 +261,9 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2095126
@Test @Test
fun verifyAutoplayBlockAudioAndVideoSettingTest() { fun verifyAutoplayBlockAudioAndVideoSettingOnNotMutedVideoTest() {
val videoTestPage = getVideoPageAsset(mockWebServer) val videoTestPage = getVideoPageAsset(mockWebServer)
homeScreen { homeScreen {
@ -265,6 +292,7 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2286808
@Test @Test
fun verifyAutoplayBlockAudioAndVideoSettingOnMutedVideoTest() { fun verifyAutoplayBlockAudioAndVideoSettingOnMutedVideoTest() {
val mutedVideoTestPage = getMutedVideoPageAsset(mockWebServer) val mutedVideoTestPage = getMutedVideoPageAsset(mockWebServer)
@ -294,6 +322,7 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/247362
@Test @Test
fun verifyCameraPermissionSettingsTest() { fun verifyCameraPermissionSettingsTest() {
navigationToolbar { navigationToolbar {
@ -319,6 +348,7 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/247364
@Test @Test
fun verifyMicrophonePermissionSettingsTest() { fun verifyMicrophonePermissionSettingsTest() {
navigationToolbar { navigationToolbar {
@ -344,6 +374,7 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/247363
@Test @Test
fun verifyLocationPermissionSettingsTest() { fun verifyLocationPermissionSettingsTest() {
navigationToolbar { navigationToolbar {
@ -368,6 +399,7 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/247365
@Test @Test
fun verifyNotificationsPermissionSettingsTest() { fun verifyNotificationsPermissionSettingsTest() {
navigationToolbar { navigationToolbar {
@ -392,6 +424,7 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1923415
@Test @Test
fun verifyPersistentStoragePermissionSettingsTest() { fun verifyPersistentStoragePermissionSettingsTest() {
navigationToolbar { navigationToolbar {
@ -416,6 +449,7 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1923417
@Ignore("Flaky, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1829889") @Ignore("Flaky, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1829889")
@Test @Test
fun verifyDRMControlledContentPermissionSettingsTest() { fun verifyDRMControlledContentPermissionSettingsTest() {
@ -454,6 +488,7 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/246976
@SmokeTest @SmokeTest
@Test @Test
fun clearAllSitePermissionsExceptionsTest() { fun clearAllSitePermissionsExceptionsTest() {
@ -476,8 +511,9 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/247007
@Test @Test
fun clearOneSiteAllPermissionsExceptionsTest() { fun addAndClearOneWebPagePermission() {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) { }.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) {
}.clickOpenNotificationButton { }.clickOpenNotificationButton {
@ -498,8 +534,9 @@ class SettingsSitePermissionsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/326477
@Test @Test
fun clearOneSiteOnePermissionExceptionTest() { fun clearIndividuallyAWebPagePermission() {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) { }.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) {
}.clickOpenNotificationButton { }.clickOpenNotificationButton {

@ -1,380 +1,236 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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, You can obtain one at http://mozilla.org/MPL/2.0/. */
@file:Suppress("DEPRECATION") @file:Suppress("DEPRECATION")
package org.mozilla.fenix.ui package org.mozilla.fenix.ui
import android.view.View import android.view.View
import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.ActivityTestRule import androidx.test.rule.ActivityTestRule
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.mediasession.MediaSession 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.IntentReceiverActivity import org.mozilla.fenix.IntentReceiverActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.ext.components 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.itemWithText import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
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.assertYoutubeAppOpens import org.mozilla.fenix.helpers.TestHelper.registerAndCleanupIdlingResources
import org.mozilla.fenix.helpers.TestHelper.registerAndCleanupIdlingResources import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource
import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource 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.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
/**
/** * Test Suite that contains a part of the Smoke and Sanity tests defined in TestRail:
* 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
* 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.
* 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
* These tests will verify different functionalities of the app as a way to quickly detect regressions in main areas */
*/ @Suppress("ForbiddenComment")
@Suppress("ForbiddenComment") @SmokeTest
@SmokeTest class SmokeTest {
class SmokeTest { 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
private lateinit var browserStore: BrowserStore
@get:Rule(order = 0)
@get:Rule(order = 0) val activityTestRule = AndroidComposeTestRule(
val activityTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides(),
HomeActivityIntentTestRule.withDefaultSettingsOverrides(), { it.activity },
{ it.activity }, )
)
@get: Rule(order = 1)
@get: Rule(order = 1) val intentReceiverActivityTestRule = ActivityTestRule(
val intentReceiverActivityTestRule = ActivityTestRule( IntentReceiverActivity::class.java,
IntentReceiverActivity::class.java, true,
true, false,
false, )
)
@Rule(order = 2)
@Rule(order = 2) @JvmField
@JvmField val retryTestRule = RetryTestRule(3)
val retryTestRule = RetryTestRule(3)
@Before
@Before fun setUp() {
fun setUp() { // Initializing this as part of class construction, below the rule would throw a NPE
// 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.
// So we are initializing this here instead of in all related tests. browserStore = activityTestRule.activity.components.core.store
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() start()
start() }
} }
}
@After
@After fun tearDown() {
fun tearDown() { mockWebServer.shutdown()
mockWebServer.shutdown() }
}
@Test
// Device or AVD requires a Google Services Android OS installation with Play Store installed fun shareTabsFromTabsTrayTest() {
// Verifies the Open in app button when an app is installed val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@Test val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2)
fun mainMenuOpenInAppTest() { val firstWebsiteTitle = firstWebsite.title
val youtubeURL = "vnd.youtube://".toUri() val secondWebsiteTitle = secondWebsite.title
val sharingApp = "Gmail"
navigationToolbar { val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}"
}.enterURLAndEnterToBrowser(youtubeURL) {
verifyNotificationDotOnMainMenu() homeScreen {
}.openThreeDotMenu { }.openNavigationToolbar {
}.clickOpenInApp { }.enterURLAndEnterToBrowser(firstWebsite.url) {
assertYoutubeAppOpens() verifyPageContent(firstWebsite.content)
} }.openTabDrawer {
} }.openNewTab {
}.submitQuery(secondWebsite.url.toString()) {
// Verifies that deleting a Bookmarks folder also removes the item from inside it. verifyPageContent(secondWebsite.content)
@Test }.openTabDrawer {
fun deleteNonEmptyBookmarkFolderTest() { verifyExistingOpenTabs("Test_Page_1")
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) verifyExistingOpenTabs("Test_Page_2")
}.openTabsListThreeDotMenu {
browserScreen { verifyShareAllTabsButton()
createBookmark(website.url) }.clickShareAllTabsButton {
}.openThreeDotMenu { verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle)
}.openBookmarks { verifySharingWithSelectedApp(
verifyBookmarkTitle("Test_Page_1") sharingApp,
createFolder("My Folder") sharedUrlsString,
verifyFolderTitle("My Folder") "$firstWebsiteTitle, $secondWebsiteTitle",
}.openThreeDotMenu("Test_Page_1") { )
}.clickEdit { }
clickParentFolderSelector() }
selectFolder("My Folder")
navigateUp() @Test
saveEditBookmark() fun privateTabsTrayWithOpenedTabTest() {
createFolder("My Folder 2") val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
verifyFolderTitle("My Folder 2")
}.openThreeDotMenu("My Folder 2") { homeScreen {
}.clickEdit { }.togglePrivateBrowsingMode()
clickParentFolderSelector()
selectFolder("My Folder") homeScreen {
navigateUp() }.openNavigationToolbar {
saveEditBookmark() }.enterURLAndEnterToBrowser(website.url) {
}.openThreeDotMenu("My Folder") { }.openTabDrawer {
}.clickDelete { verifyNormalBrowsingButtonIsSelected(false)
cancelFolderDeletion() verifyPrivateBrowsingButtonIsSelected(true)
verifyFolderTitle("My Folder") verifySyncedTabsButtonIsSelected(false)
}.openThreeDotMenu("My Folder") { verifyTabTrayOverflowMenu(true)
}.clickDelete { verifyTabsTrayCounter()
confirmDeletion() verifyExistingTabList()
verifyDeleteSnackBarText() verifyExistingOpenTabs(website.title)
verifyBookmarkIsDeleted("My Folder") verifyCloseTabsButton(website.title)
verifyBookmarkIsDeleted("My Folder 2") verifyOpenedTabThumbnail()
verifyBookmarkIsDeleted("Test_Page_1") verifyPrivateBrowsingNewTabButton()
navigateUp() }
} }
browserScreen { // Test running on beta/release builds in CI:
}.openThreeDotMenu { // caution when making changes to it, so they don't block the builds
verifyAddBookmarkButton() @Test
} fun noHistoryInPrivateBrowsingTest() {
} val website = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@Test homeScreen {
fun shareTabsFromTabsTrayTest() { }.togglePrivateBrowsingMode()
val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2) homeScreen {
val firstWebsiteTitle = firstWebsite.title }.openNavigationToolbar {
val secondWebsiteTitle = secondWebsite.title }.enterURLAndEnterToBrowser(website.url) {
val sharingApp = "Gmail" mDevice.waitForIdle()
val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}" }.openThreeDotMenu {
}.openHistory {
homeScreen { verifyEmptyHistoryView()
}.openNavigationToolbar { }
}.enterURLAndEnterToBrowser(firstWebsite.url) { }
verifyPageContent(firstWebsite.content)
}.openTabDrawer { @Test
}.openNewTab { fun mainMenuInstallPWATest() {
}.submitQuery(secondWebsite.url.toString()) { val pwaPage = "https://mozilla-mobile.github.io/testapp/"
verifyPageContent(secondWebsite.content)
}.openTabDrawer { navigationToolbar {
verifyExistingOpenTabs("Test_Page_1") }.enterURLAndEnterToBrowser(pwaPage.toUri()) {
verifyExistingOpenTabs("Test_Page_2") verifyNotificationDotOnMainMenu()
}.openTabsListThreeDotMenu { }.openThreeDotMenu {
verifyShareAllTabsButton() }.clickInstall {
}.clickShareAllTabsButton { clickAddAutomaticallyButton()
verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle) }.openHomeScreenShortcut("TEST_APP") {
verifySharingWithSelectedApp( mDevice.waitForIdle()
sharingApp, verifyNavURLBarHidden()
sharedUrlsString, }
"$firstWebsiteTitle, $secondWebsiteTitle", }
)
} // Verifies that reader mode is detected and the custom appearance controls are displayed
} @Test
fun verifyReaderViewAppearanceUI() {
@Test val readerViewPage =
fun privateTabsTrayWithOpenedTabTest() { TestAssetHelper.getLoremIpsumAsset(mockWebServer)
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) val estimatedReadingTime = "1 - 2 minutes"
homeScreen { navigationToolbar {
}.togglePrivateBrowsingMode() }.enterURLAndEnterToBrowser(readerViewPage.url) {
mDevice.waitForIdle()
homeScreen { }
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(website.url) { registerAndCleanupIdlingResources(
}.openTabDrawer { ViewVisibilityIdlingResource(
verifyNormalBrowsingButtonIsSelected(false) activityTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions),
verifyPrivateBrowsingButtonIsSelected(true) View.VISIBLE,
verifySyncedTabsButtonIsSelected(false) ),
verifyTabTrayOverflowMenu(true) ) {}
verifyTabsTrayCounter()
verifyExistingTabList() navigationToolbar {
verifyExistingOpenTabs(website.title) verifyReaderViewDetected(true)
verifyCloseTabsButton(website.title) toggleReaderView()
verifyOpenedTabThumbnail() }
verifyPrivateBrowsingNewTabButton()
} browserScreen {
} waitForPageToLoad()
verifyPageContent(estimatedReadingTime)
// Test running on beta/release builds in CI: }.openThreeDotMenu {
// caution when making changes to it, so they don't block the builds verifyReaderViewAppearance(true)
@Test }.openReaderViewAppearance {
fun noHistoryInPrivateBrowsingTest() { verifyAppearanceFontGroup(true)
val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) verifyAppearanceFontSansSerif(true)
verifyAppearanceFontSerif(true)
homeScreen { verifyAppearanceFontIncrease(true)
}.togglePrivateBrowsingMode() verifyAppearanceFontDecrease(true)
verifyAppearanceColorGroup(true)
homeScreen { verifyAppearanceColorDark(true)
}.openNavigationToolbar { verifyAppearanceColorLight(true)
}.enterURLAndEnterToBrowser(website.url) { verifyAppearanceColorSepia(true)
mDevice.waitForIdle() }
}.openThreeDotMenu { }
}.openHistory {
verifyEmptyHistoryView() @Test
} fun tabMediaControlButtonTest() {
} val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
@Test navigationToolbar {
fun mainMenuInstallPWATest() { }.enterURLAndEnterToBrowser(audioTestPage.url) {
val pwaPage = "https://mozilla-mobile.github.io/testapp/" mDevice.waitForIdle()
clickPageObject(itemWithText("Play"))
navigationToolbar { assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING)
}.enterURLAndEnterToBrowser(pwaPage.toUri()) { }.openTabDrawer {
verifyNotificationDotOnMainMenu() verifyTabMediaControlButtonState("Pause")
}.openThreeDotMenu { clickTabMediaControlButton("Pause")
}.clickInstall { verifyTabMediaControlButtonState("Play")
clickAddAutomaticallyButton() }.openTab(audioTestPage.title) {
}.openHomeScreenShortcut("TEST_APP") { assertPlaybackState(browserStore, MediaSession.PlaybackState.PAUSED)
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)
}
}
// For API>23
// Verifies the default browser switch opens the system default apps menu.
@Test
fun changeDefaultBrowserSetting() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
verifyDefaultBrowserToggle(false)
clickDefaultBrowserSwitch()
verifyAndroidDefaultAppsMenuAppears()
}
// Dismiss the request
mDevice.pressBack()
}
@Test
fun goToHomeScreenBottomToolbarTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
mDevice.waitForIdle()
}.goToHomescreen {
verifyHomeScreen()
}
}
@Test
fun goToHomeScreenTopToolbarTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openCustomizeSubMenu {
clickTopToolbarToggle()
}.goBack {
}.goBack {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
mDevice.waitForIdle()
}.goToHomescreen {
verifyHomeScreen()
}
}
@Test
fun goToHomeScreenBottomToolbarPrivateModeTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
togglePrivateBrowsingModeOnOff()
}
navigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
mDevice.waitForIdle()
}.goToHomescreen {
verifyHomeScreen()
}
}
@Test
fun goToHomeScreenTopToolbarPrivateModeTest() {
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
togglePrivateBrowsingModeOnOff()
}.openThreeDotMenu {
}.openSettings {
}.openCustomizeSubMenu {
clickTopToolbarToggle()
}.goBack {
}.goBack {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(genericURL.url) {
mDevice.waitForIdle()
}.goToHomescreen {
verifyHomeScreen()
}
}
}

@ -49,6 +49,7 @@ class SponsoredShortcutsTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1729331
// Expected for en-us defaults // Expected for en-us defaults
@SmokeTest @SmokeTest
@Test @Test
@ -67,6 +68,7 @@ class SponsoredShortcutsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1729338
@Test @Test
fun openSponsoredShortcutTest() { fun openSponsoredShortcutTest() {
homeScreen { homeScreen {
@ -76,8 +78,9 @@ class SponsoredShortcutsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1729334
@Test @Test
fun openSponsoredShortcutInPrivateBrowsingTest() { fun openSponsoredShortcutInPrivateTabTest() {
homeScreen { homeScreen {
sponsoredShortcutTitle = getSponsoredShortcutTitle(2) sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
}.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) { }.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) {
@ -86,9 +89,10 @@ class SponsoredShortcutsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1729335
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/25926") @Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/25926")
@Test @Test
fun verifySponsorsAndPrivacyLinkTest() { fun openSponsorsAndYourPrivacyOptionTest() {
homeScreen { homeScreen {
sponsoredShortcutTitle = getSponsoredShortcutTitle(2) sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
}.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) { }.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) {
@ -97,9 +101,10 @@ class SponsoredShortcutsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1729336
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268") @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268")
@Test @Test
fun verifySponsoredShortcutsSettingsOptionTest() { fun openSponsoredShortcutsSettingsOptionTest() {
homeScreen { homeScreen {
sponsoredShortcutTitle = getSponsoredShortcutTitle(2) sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
}.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) { }.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) {
@ -108,6 +113,7 @@ class SponsoredShortcutsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1729337
@Test @Test
fun verifySponsoredShortcutsDetailsTest() { fun verifySponsoredShortcutsDetailsTest() {
homeScreen { homeScreen {
@ -119,6 +125,7 @@ class SponsoredShortcutsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1729328
// 1 sponsored shortcut should be displayed if there are 7 pinned top sites // 1 sponsored shortcut should be displayed if there are 7 pinned top sites
@Test @Test
fun verifySponsoredShortcutsListWithSevenPinnedSitesTest() { fun verifySponsoredShortcutsListWithSevenPinnedSitesTest() {
@ -169,6 +176,7 @@ class SponsoredShortcutsTest {
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1729329
// No sponsored shortcuts should be displayed if there are 8 pinned top sites // No sponsored shortcuts should be displayed if there are 8 pinned top sites
@Test @Test
fun verifySponsoredShortcutsListWithEightPinnedSitesTest() { fun verifySponsoredShortcutsListWithEightPinnedSitesTest() {

@ -1,203 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.ui
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
import org.mozilla.fenix.ui.robots.clickContextMenuItem
import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.longClickPageObject
/**
* Tests for verifying the main three dot menu options
*
*/
class ThreeDotMenuMainTest {
private lateinit var mockWebServer: MockWebServer
@get:Rule
val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides()
@Before
fun setUp() {
mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher()
start()
}
}
@After
fun tearDown() {
mockWebServer.shutdown()
}
// Verifies the list of items in the homescreen's 3 dot main menu
@Test
fun homeThreeDotMenuItemsTest() {
homeScreen {
}.openThreeDotMenu {
verifyHomeThreeDotMainMenuItems(isRequestDesktopSiteEnabled = false)
}.openBookmarks {
verifyBookmarksMenuView()
}.goBack {
}.openThreeDotMenu {
}.openHistory {
verifyHistoryMenuView()
}.goBack {
}.openThreeDotMenu {
}.openDownloadsManager {
verifyEmptyDownloadsList()
}.goBack {
}.openThreeDotMenu {
}.openAddonsManagerMenu {
verifyAddonsItems()
}.goBack {
}.openThreeDotMenu {
}.openSyncSignIn {
verifyTurnOnSyncMenu()
}.goBack {
// Desktop toggle
}.openThreeDotMenu {
}.switchDesktopSiteMode {
}
homeScreen {
}.openThreeDotMenu {
verifyDesktopSiteModeEnabled(isRequestDesktopSiteEnabled = true)
}.openWhatsNew {
verifyWhatsNewURL()
}.goToHomescreen {
}.openThreeDotMenu {
}.openHelp {
verifyHelpUrl()
}.goToHomescreen {
}.openThreeDotMenu {
}.openCustomizeHome {
verifyHomePageView()
}.goBackToHomeScreen {
}.openThreeDotMenu {
}.openSettings {
verifySettingsView()
}
}
// Verifies the list of items in the homescreen's 3 dot main menu in private browsing
@Test
fun privateHomeThreeDotMenuItemsTest() {
homeScreen {
}.togglePrivateBrowsingMode()
homeScreen {
}.openThreeDotMenu {
verifyHomeThreeDotMainMenuItems(isRequestDesktopSiteEnabled = false)
}.openBookmarks {
verifyBookmarksMenuView()
}.goBack {
}.openThreeDotMenu {
}.openHistory {
verifyHistoryMenuView()
}.goBack {
}.openThreeDotMenu {
}.openDownloadsManager {
verifyEmptyDownloadsList()
}.goBack {
}.openThreeDotMenu {
}.openAddonsManagerMenu {
verifyAddonsItems()
}.goBack {
}.openThreeDotMenu {
}.openSyncSignIn {
verifyTurnOnSyncMenu()
}.goBack {
// Desktop toggle
}.openThreeDotMenu {
}.switchDesktopSiteMode {
}
homeScreen {
}.openThreeDotMenu {
verifyDesktopSiteModeEnabled(isRequestDesktopSiteEnabled = true)
}.openWhatsNew {
verifyWhatsNewURL()
}.goToHomescreen {
}.openThreeDotMenu {
}.openHelp {
verifyHelpUrl()
}.goToHomescreen {
}.openThreeDotMenu {
}.openCustomizeHome {
verifyHomePageView()
}.goBackToHomeScreen {
}.openThreeDotMenu {
}.openSettings {
verifySettingsView()
}
}
@Test
fun setDesktopSiteBeforePageLoadTest() {
val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 4)
homeScreen {
}.openThreeDotMenu {
verifyDesktopSiteModeEnabled(false)
}.switchDesktopSiteMode {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(webPage.url) {
}.openThreeDotMenu {
verifyDesktopSiteModeEnabled(true)
}.closeBrowserMenuToBrowser {
clickPageObject(itemContainingText("Link 1"))
}.openThreeDotMenu {
verifyDesktopSiteModeEnabled(true)
}.closeBrowserMenuToBrowser {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(webPage.url) {
longClickPageObject(itemWithText("Link 2"))
clickContextMenuItem("Open link in new tab")
clickSnackbarButton("SWITCH")
}.openThreeDotMenu {
verifyDesktopSiteModeEnabled(false)
}
}
@Test
fun privateBrowsingSetDesktopSiteBeforePageLoadTest() {
val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 4)
homeScreen {
}.togglePrivateBrowsingMode()
homeScreen {
}.openThreeDotMenu {
verifyDesktopSiteModeEnabled(false)
}.switchDesktopSiteMode {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(webPage.url) {
}.openThreeDotMenu {
verifyDesktopSiteModeEnabled(true)
}.closeBrowserMenuToBrowser {
clickPageObject(itemContainingText("Link 1"))
}.openThreeDotMenu {
verifyDesktopSiteModeEnabled(true)
}.closeBrowserMenuToBrowser {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(webPage.url) {
longClickPageObject(itemWithText("Link 2"))
clickContextMenuItem("Open link in private tab")
clickSnackbarButton("SWITCH")
}.openThreeDotMenu {
verifyDesktopSiteModeEnabled(false)
}
}
}

@ -16,7 +16,6 @@ import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.Constants.defaultTopSitesList import org.mozilla.fenix.helpers.Constants.defaultTopSitesList
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RetryTestRule
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
import org.mozilla.fenix.helpers.TestHelper.generateRandomString import org.mozilla.fenix.helpers.TestHelper.generateRandomString
@ -42,9 +41,6 @@ class TopSitesTest {
@get:Rule @get:Rule
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true) val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
@get:Rule
val retryTestRule = RetryTestRule(3)
@Before @Before
fun setUp() { fun setUp() {
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@ -218,8 +214,6 @@ class TopSitesTest {
// Expected for en-us defaults // Expected for en-us defaults
@Test @Test
fun verifyDefaultTopSitesList() { fun verifyDefaultTopSitesList() {
homeScreen { }.dismissOnboarding()
homeScreen { homeScreen {
verifyExistingTopSitesList() verifyExistingTopSitesList()
defaultTopSitesList.values.forEach { value -> defaultTopSitesList.values.forEach { value ->

@ -4,19 +4,16 @@
package org.mozilla.fenix.ui package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
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.R import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
import org.mozilla.fenix.helpers.TestHelper.getStringResource
import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.navigationToolbar
/** /**
@ -24,17 +21,16 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
* Note: This involves setting the feature flags On for CFRs which are disabled elsewhere. * Note: This involves setting the feature flags On for CFRs which are disabled elsewhere.
* *
*/ */
class ContextualHintsTest { class TotalCookieProtectionTest {
private lateinit var mockWebServer: MockWebServer private lateinit var mockWebServer: MockWebServer
@get:Rule @get:Rule
val activityTestRule = HomeActivityTestRule( val composeTestRule = AndroidComposeTestRule(
isJumpBackInCFREnabled = true, HomeActivityTestRule(
isTCPCFREnabled = true, isTCPCFREnabled = true,
isPocketEnabled = false, isCookieBannerReductionDialogEnabled = false,
isRecentlyVisitedFeatureEnabled = false, ),
isCookieBannerReductionDialogEnabled = false, ) { it.activity }
)
@Before @Before
fun setUp() { fun setUp() {
@ -49,27 +45,33 @@ class ContextualHintsTest {
mockWebServer.shutdown() mockWebServer.shutdown()
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2260552
@Test @Test
fun openTotalCookieProtectionLearnMoreLinkTest() { fun openTotalCookieProtectionLearnMoreLinkTest() {
val genericPage = getGenericAsset(mockWebServer, 1) val genericPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(genericPage.url) { }.enterURLAndEnterToBrowserForTCPCFR(genericPage.url) {
verifyCookiesProtectionHintIsDisplayed(true) waitForPageToLoad()
clickPageObject(itemContainingText(getStringResource(R.string.tcp_cfr_learn_more))) verifyCookiesProtectionHintIsDisplayed(composeTestRule, true)
clickTCPCFRLearnMore(composeTestRule)
verifyUrl("support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-android") verifyUrl("support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-android")
verifyShouldShowCFRTCP(false, composeTestRule.activity.settings())
} }
} }
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1913589
@Test @Test
fun dismissTotalCookieProtectionHintTest() { fun dismissTotalCookieProtectionHintTest() {
val genericPage = getGenericAsset(mockWebServer, 1) val genericPage = getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(genericPage.url) { }.enterURLAndEnterToBrowserForTCPCFR(genericPage.url) {
verifyCookiesProtectionHintIsDisplayed(true) waitForPageToLoad()
clickPageObject(itemWithDescription(getStringResource(R.string.mozac_cfr_dismiss_button_content_description))) verifyCookiesProtectionHintIsDisplayed(composeTestRule, true)
verifyCookiesProtectionHintIsDisplayed(false) dismissTCPCFRPopup(composeTestRule)
verifyCookiesProtectionHintIsDisplayed(composeTestRule, false)
verifyShouldShowCFRTCP(false, composeTestRule.activity.settings())
} }
} }
} }

@ -5,23 +5,21 @@
package org.mozilla.fenix.ui.robots package org.mozilla.fenix.ui.robots
import android.os.Build import android.os.Build
import androidx.test.espresso.Espresso.onView import androidx.compose.ui.test.assertIsDisplayed
import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.test.espresso.matcher.ViewMatchers import androidx.compose.ui.test.onNodeWithTag
import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.compose.ui.test.performClick
import androidx.test.uiautomator.By import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until import androidx.test.uiautomator.Until
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
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
import org.mozilla.fenix.helpers.click
import java.util.regex.Pattern import java.util.regex.Pattern
/** /**
@ -29,11 +27,14 @@ import java.util.regex.Pattern
*/ */
class AddToHomeScreenRobot { class AddToHomeScreenRobot {
fun verifyAddPrivateBrowsingShortcutButton() = assertAddPrivateBrowsingShortcutButton() fun verifyAddPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) =
composeTestRule.onNodeWithTag("private.add").assertIsDisplayed()
fun verifyNoThanksPrivateBrowsingShortcutButton() = assertNoThanksPrivateBrowsingShortcutButton() fun verifyNoThanksPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) =
composeTestRule.onNodeWithTag("private.cancel").assertIsDisplayed()
fun clickAddPrivateBrowsingShortcutButton() = addPrivateBrowsingShortcutButton().click() fun clickAddPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) =
composeTestRule.onNodeWithTag("private.add").performClick()
fun addShortcutName(title: String) = shortcutTextField.setText(title) fun addShortcutName(title: String) = shortcutTextField.setText(title)
@ -104,16 +105,6 @@ fun addToHomeScreen(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenR
private fun addAutomaticallyButton() = private fun addAutomaticallyButton() =
mDevice.findObject(UiSelector().textContains("add automatically")) mDevice.findObject(UiSelector().textContains("add automatically"))
private fun addPrivateBrowsingShortcutButton() = onView(withId(R.id.cfr_pos_button))
private fun assertAddPrivateBrowsingShortcutButton() = addPrivateBrowsingShortcutButton()
.check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun noThanksPrivateBrowsingShortcutButton() = onView(withId(R.id.cfr_neg_button))
private fun assertNoThanksPrivateBrowsingShortcutButton() = noThanksPrivateBrowsingShortcutButton()
.check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private val cancelAddToHomeScreenButton = private val cancelAddToHomeScreenButton =
itemWithResId("$packageName:id/cancel_button") itemWithResId("$packageName:id/cancel_button")
private val confirmAddToHomeScreenButton = private val confirmAddToHomeScreenButton =

@ -188,6 +188,13 @@ class BookmarksRobot {
addFolderButton().click() addFolderButton().click()
} }
fun clickAddNewFolderButtonFromSelectFolderView() =
itemWithResId("$packageName:id/add_folder_button")
.also {
it.waitForExists(waitingTime)
it.click()
}
fun addNewFolderName(name: String) { fun addNewFolderName(name: String) {
addFolderTitleField() addFolderTitleField()
.click() .click()

@ -11,7 +11,9 @@ import android.net.Uri
import android.os.SystemClock import android.os.SystemClock
import android.util.Log import android.util.Log
import android.widget.TimePicker import android.widget.TimePicker
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.assertion.ViewAssertions.matches
@ -41,7 +43,6 @@ import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION
import org.mozilla.fenix.helpers.Constants.RETRY_COUNT import org.mozilla.fenix.helpers.Constants.RETRY_COUNT
import org.mozilla.fenix.helpers.HomeActivityComposeTestRule import org.mozilla.fenix.helpers.HomeActivityComposeTestRule
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithDescriptionExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
@ -60,6 +61,7 @@ import org.mozilla.fenix.helpers.TestHelper.packageName
import org.mozilla.fenix.helpers.TestHelper.waitForObjects import org.mozilla.fenix.helpers.TestHelper.waitForObjects
import org.mozilla.fenix.helpers.ext.waitNotNull import org.mozilla.fenix.helpers.ext.waitNotNull
import org.mozilla.fenix.tabstray.TabsTrayTestTag import org.mozilla.fenix.tabstray.TabsTrayTestTag
import org.mozilla.fenix.utils.Settings
import java.time.LocalDate import java.time.LocalDate
class BrowserRobot { class BrowserRobot {
@ -190,11 +192,11 @@ class BrowserRobot {
) )
} }
fun verifyContextMenuForLinksToOtherApps(containsURL: Uri) { fun verifyContextMenuForLinksToOtherApps(containsURL: String) {
// If the link is re-directing to an external app the "Open link in external app" option is available // If the link is re-directing to an external app the "Open link in external app" option is available
// If the link is not directing to another local asset the "Download link" option is not available // If the link is not directing to another local asset the "Download link" option is not available
assertItemContainingTextExists( assertItemContainingTextExists(
contextMenuLinkUrl(containsURL.toString()), contextMenuLinkUrl(containsURL),
contextMenuOpenLinkInNewTab, contextMenuOpenLinkInNewTab,
contextMenuOpenLinkInPrivateTab, contextMenuOpenLinkInPrivateTab,
contextMenuCopyLink, contextMenuCopyLink,
@ -249,15 +251,6 @@ class BrowserRobot {
fun verifyMenuButton() = threeDotButton().check(matches(isDisplayed())) fun verifyMenuButton() = threeDotButton().check(matches(isDisplayed()))
fun verifyNavURLBarItems() {
navURLBar().waitForExists(waitingTime)
verifyMenuButton()
verifyTabCounter("1")
verifySearchBar()
verifySecureConnectionLockIcon()
verifyHomeScreenButton()
}
fun verifyNoLinkImageContextMenuItems(containsURL: Uri) { fun verifyNoLinkImageContextMenuItems(containsURL: Uri) {
mDevice.waitNotNull(Until.findObject(By.textContains(containsURL.toString()))) mDevice.waitNotNull(Until.findObject(By.textContains(containsURL.toString())))
mDevice.waitNotNull( mDevice.waitNotNull(
@ -590,16 +583,32 @@ class BrowserRobot {
} }
} }
fun verifyCookiesProtectionHintIsDisplayed(isDisplayed: Boolean) { fun verifyCookiesProtectionHintIsDisplayed(composeTestRule: HomeActivityComposeTestRule, isDisplayed: Boolean) {
assertItemContainingTextExists( if (isDisplayed) {
totalCookieProtectionHintMessage, composeTestRule.onNodeWithTag("tcp_cfr.message").assertIsDisplayed()
totalCookieProtectionHintLearnMoreLink, composeTestRule.onNodeWithTag("tcp_cfr.action").assertIsDisplayed()
exists = isDisplayed, composeTestRule.onNodeWithTag("cfr.dismiss").assertIsDisplayed()
) } else {
assertItemWithDescriptionExists( composeTestRule.onNodeWithTag("tcp_cfr.message").assertDoesNotExist()
totalCookieProtectionHintCloseButton, composeTestRule.onNodeWithTag("tcp_cfr.action").assertDoesNotExist()
exists = isDisplayed, composeTestRule.onNodeWithTag("cfr.dismiss").assertDoesNotExist()
) }
}
fun clickTCPCFRLearnMore(composeTestRule: HomeActivityComposeTestRule) {
composeTestRule.onNodeWithTag("tcp_cfr.action").performClick()
}
fun dismissTCPCFRPopup(composeTestRule: HomeActivityComposeTestRule) {
composeTestRule.onNodeWithTag("cfr.dismiss").performClick()
}
fun verifyShouldShowCFRTCP(shouldShow: Boolean, settings: Settings) {
if (shouldShow) {
assertTrue(settings.shouldShowTotalCookieProtectionCFR)
} else {
assertFalse(settings.shouldShowTotalCookieProtectionCFR)
}
} }
fun selectTime(hour: Int, minute: Int) = fun selectTime(hour: Int, minute: Int) =
@ -873,6 +882,17 @@ class BrowserRobot {
assertTrue(button.waitForExists(waitingTime)) assertTrue(button.waitForExists(waitingTime))
} }
fun verifySurveyNoThanksButton() {
val button = mDevice.findObject(
UiSelector().text(
getStringResource(
R.string.preferences_not_take_survey,
),
),
)
assertTrue(button.waitForExists(waitingTime))
}
fun clickOpenLinksInAppsDismissCFRButton() = fun clickOpenLinksInAppsDismissCFRButton() =
itemWithResIdContainingText( itemWithResIdContainingText(
"$packageName:id/dismiss", "$packageName:id/dismiss",
@ -891,6 +911,18 @@ class BrowserRobot {
button.click() button.click()
} }
fun clickNoThanksSurveyButton() {
val button = mDevice.findObject(
UiSelector().text(
getStringResource(
R.string.preferences_not_take_survey,
),
),
)
button.waitForExists(waitingTime)
button.click()
}
fun longClickToolbar() = mDevice.findObject(By.res("$packageName:id/mozac_browser_toolbar_url_view")).click(LONG_CLICK_DURATION) fun longClickToolbar() = mDevice.findObject(By.res("$packageName:id/mozac_browser_toolbar_url_view")).click(LONG_CLICK_DURATION)
fun verifyDownloadPromptIsDismissed() = fun verifyDownloadPromptIsDismissed() =
@ -1066,6 +1098,21 @@ class BrowserRobot {
return HomeScreenRobot.Transition() return HomeScreenRobot.Transition()
} }
fun goToHomescreenWithComposeTopSites(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTopSitesRobot.() -> Unit): ComposeTopSitesRobot.Transition {
clickPageObject(itemWithDescription("Home screen"))
mDevice.findObject(UiSelector().resourceId("$packageName:id/homeLayout"))
.waitForExists(waitingTime) ||
mDevice.findObject(
UiSelector().text(
getStringResource(R.string.onboarding_home_screen_jump_back_contextual_hint_2),
),
).waitForExists(waitingTime)
ComposeTopSitesRobot(composeTestRule).interact()
return ComposeTopSitesRobot.Transition(composeTestRule)
}
fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
mDevice.pressBack() mDevice.pressBack()
@ -1211,6 +1258,14 @@ class BrowserRobot {
BrowserRobot().interact() BrowserRobot().interact()
return Transition() return Transition()
} }
fun clickNoThanksSurveyButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
surveyNoThanksButton.waitForExists(waitingTime)
surveyNoThanksButton.click()
BrowserRobot().interact()
return Transition()
}
} }
} }
@ -1331,12 +1386,6 @@ private val currentDay = currentDate.dayOfMonth
private val currentMonth = currentDate.month private val currentMonth = currentDate.month
private val currentYear = currentDate.year private val currentYear = currentDate.year
private val cookieBanner = itemWithResId("startsiden-gdpr-disclaimer") private val cookieBanner = itemWithResId("startsiden-gdpr-disclaimer")
private val totalCookieProtectionHintMessage =
itemContainingText(getStringResource(R.string.tcp_cfr_message))
private val totalCookieProtectionHintLearnMoreLink =
itemContainingText(getStringResource(R.string.tcp_cfr_learn_more))
private val totalCookieProtectionHintCloseButton =
itemWithDescription(getStringResource(R.string.mozac_cfr_dismiss_button_content_description))
// Context menu items // Context menu items
// Link URL // Link URL
@ -1369,3 +1418,6 @@ private val contextMenuOpenInExternalApp =
private val surveyButton = private val surveyButton =
itemContainingText(getStringResource(R.string.preferences_take_survey)) itemContainingText(getStringResource(R.string.preferences_take_survey))
private val surveyNoThanksButton =
itemContainingText(getStringResource(R.string.preferences_not_take_survey))

@ -14,6 +14,7 @@ import androidx.compose.ui.test.assertIsNotSelected
import androidx.compose.ui.test.assertIsSelected import androidx.compose.ui.test.assertIsSelected
import androidx.compose.ui.test.filter import androidx.compose.ui.test.filter
import androidx.compose.ui.test.hasAnyChild import androidx.compose.ui.test.hasAnyChild
import androidx.compose.ui.test.hasContentDescription
import androidx.compose.ui.test.hasParent import androidx.compose.ui.test.hasParent
import androidx.compose.ui.test.hasTestTag import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.hasText import androidx.compose.ui.test.hasText
@ -272,7 +273,9 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest
/** /**
* Verifies a tab's media button matches [action] when there is only one tab with media. * Verifies a tab's media button matches [action] when there is only one tab with media.
*/ */
@OptIn(ExperimentalTestApi::class)
fun verifyTabMediaControlButtonState(action: String) { fun verifyTabMediaControlButtonState(action: String) {
composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(action), waitingTime)
composeTestRule.tabMediaControlButton(action) composeTestRule.tabMediaControlButton(action)
.assertExists() .assertExists()
} }
@ -280,7 +283,9 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest
/** /**
* Clicks a tab's media button when there is only one tab with media. * Clicks a tab's media button when there is only one tab with media.
*/ */
@OptIn(ExperimentalTestApi::class)
fun clickTabMediaControlButton(action: String) { fun clickTabMediaControlButton(action: String) {
composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(action), waitingTime)
composeTestRule.tabMediaControlButton(action) composeTestRule.tabMediaControlButton(action)
.performClick() .performClick()
} }

@ -0,0 +1,164 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.ui.robots
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.filter
import androidx.compose.ui.test.hasAnyChild
import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.compose.ui.test.longClick
import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onFirst
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollTo
import androidx.compose.ui.test.performTouchInput
import org.mozilla.fenix.helpers.HomeActivityComposeTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
import org.mozilla.fenix.helpers.TestHelper.packageName
import org.mozilla.fenix.home.topsites.TopSitesTestTag
/**
* Implementation of Robot Pattern for the Compose Top Sites.
*/
class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestRule) {
fun verifyExistingTopSitesList() =
composeTestRule.onNodeWithTag(TopSitesTestTag.topSites).assertExists()
@OptIn(ExperimentalTestApi::class)
fun verifyExistingTopSiteItem(vararg titles: String) {
titles.forEach { title ->
composeTestRule.waitUntilAtLeastOneExists(hasText(title), waitingTime)
composeTestRule.topSiteItem(title).assertExists()
}
}
fun verifyNotExistingTopSiteItem(vararg titles: String) {
titles.forEach { title ->
itemContainingText(title).waitForExists(waitingTime)
composeTestRule.topSiteItem(title).assertDoesNotExist()
}
}
fun verifyTopSiteContextMenuItems() {
verifyTopSiteContextMenuOpenInPrivateTabButton()
verifyTopSiteContextMenuRemoveButton()
verifyTopSiteContextMenuRenameButton()
}
fun verifyTopSiteContextMenuOpenInPrivateTabButton() {
composeTestRule.contextMenuItemOpenInPrivateTab().assertExists()
}
fun verifyTopSiteContextMenuRenameButton() {
composeTestRule.contextMenuItemRename().assertExists()
}
fun verifyTopSiteContextMenuRemoveButton() {
composeTestRule.contextMenuItemRemove().assertExists()
}
class Transition(private val composeTestRule: HomeActivityComposeTestRule) {
fun openTopSiteTabWithTitle(
title: String,
interact: BrowserRobot.() -> Unit,
): BrowserRobot.Transition {
composeTestRule.topSiteItem(title).performScrollTo().performClick()
BrowserRobot().interact()
return BrowserRobot.Transition()
}
fun openTopSiteInPrivate(
interact: BrowserRobot.() -> Unit,
): BrowserRobot.Transition {
composeTestRule.contextMenuItemOpenInPrivateTab().performClick()
composeTestRule.waitForIdle()
BrowserRobot().interact()
return BrowserRobot.Transition()
}
fun openContextMenuOnTopSitesWithTitle(
title: String,
interact: ComposeTopSitesRobot.() -> Unit,
): Transition {
composeTestRule.topSiteItem(title).performScrollTo().performTouchInput {
longClick()
}
ComposeTopSitesRobot(composeTestRule).interact()
return Transition(composeTestRule)
}
fun renameTopSite(
title: String,
interact: ComposeTopSitesRobot.() -> Unit,
): Transition {
composeTestRule.contextMenuItemRename().performClick()
itemWithResId("$packageName:id/top_site_title")
.also {
it.waitForExists(waitingTimeShort)
it.setText(title)
}
itemWithResIdContainingText("android:id/button1", "OK").click()
ComposeTopSitesRobot(composeTestRule).interact()
return Transition(composeTestRule)
}
@OptIn(ExperimentalTestApi::class)
fun removeTopSite(
interact: ComposeTopSitesRobot.() -> Unit,
): Transition {
composeTestRule.contextMenuItemRemove().performClick()
composeTestRule.waitUntilDoesNotExist(hasTestTag(TopSitesTestTag.remove), waitingTime)
ComposeTopSitesRobot(composeTestRule).interact()
return Transition(composeTestRule)
}
@OptIn(ExperimentalTestApi::class)
fun deleteTopSiteFromHistory(
interact: BrowserRobot.() -> Unit,
): BrowserRobot.Transition {
composeTestRule.contextMenuItemRemove().performClick()
composeTestRule.waitUntilDoesNotExist(hasTestTag(TopSitesTestTag.remove), waitingTime)
BrowserRobot().interact()
return BrowserRobot.Transition()
}
}
}
/**
* Obtains the top site with the provided [title].
*/
private fun ComposeTestRule.topSiteItem(title: String) =
onAllNodesWithTag(TopSitesTestTag.topSiteItemRoot).filter(hasAnyChild(hasText(title))).onFirst()
/**
* Obtains the option to open in private tab the top site
*/
private fun ComposeTestRule.contextMenuItemOpenInPrivateTab() =
onAllNodesWithTag(TopSitesTestTag.openInPrivateTab).onFirst()
/**
* Obtains the option to rename the top site
*/
private fun ComposeTestRule.contextMenuItemRename() = onAllNodesWithTag(TopSitesTestTag.rename).onFirst()
/**
* Obtains the option to remove the top site
*/
private fun ComposeTestRule.contextMenuItemRemove() = onAllNodesWithTag(TopSitesTestTag.remove).onFirst()

@ -167,13 +167,6 @@ class CustomTabRobot {
ShareOverlayRobot().interact() ShareOverlayRobot().interact()
return ShareOverlayRobot.Transition() return ShareOverlayRobot.Transition()
} }
fun goBackToOnboardingScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
mDevice.pressBack()
HomeScreenRobot().interact()
return HomeScreenRobot.Transition()
}
} }
} }

@ -29,6 +29,7 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_APPS_PHOTOS import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_APPS_PHOTOS
import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText
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.waitingTimeLong import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong
@ -48,7 +49,58 @@ class DownloadRobot {
fun verifyDownloadPrompt(fileName: String) = assertDownloadPrompt(fileName) fun verifyDownloadPrompt(fileName: String) = assertDownloadPrompt(fileName)
fun verifyDownloadNotificationPopup() = assertDownloadNotificationPopup() fun verifyDownloadCompleteNotificationPopup() {
assertTrue(
"Download notification Open button not found",
mDevice.findObject(UiSelector().text("Open"))
.waitForExists(waitingTime),
)
assertTrue(
"Download completed notification text doesn't match",
mDevice.findObject(UiSelector().textContains("Download completed"))
.waitForExists(waitingTime),
)
assertTrue(
"Downloaded file name not visible",
mDevice.findObject(UiSelector().resourceId("$packageName:id/download_dialog_filename"))
.waitForExists(waitingTime),
)
}
fun verifyDownloadFailedPrompt(fileName: String) {
assertTrue(
itemWithResId("$packageName:id/download_dialog_icon")
.waitForExists(waitingTime),
)
assertTrue(
"Download dialog title not displayed",
itemWithResIdAndText(
"$packageName:id/download_dialog_title",
"Download failed",
).waitForExists(waitingTime),
)
assertTrue(
"Download file name not displayed",
itemWithResIdContainingText(
"$packageName:id/download_dialog_filename",
fileName,
).waitForExists(waitingTime),
)
assertTrue(
"Try again button not displayed",
itemWithResIdAndText(
"$packageName:id/download_dialog_action_button",
"Try Again",
).waitForExists(waitingTime),
)
}
fun clickTryAgainButton() {
itemWithResIdAndText(
"$packageName:id/download_dialog_action_button",
"Try Again",
).click()
}
fun verifyPhotosAppOpens() = assertExternalAppOpens(GOOGLE_APPS_PHOTOS) fun verifyPhotosAppOpens() = assertExternalAppOpens(GOOGLE_APPS_PHOTOS)
@ -126,13 +178,6 @@ class DownloadRobot {
return BrowserRobot.Transition() return BrowserRobot.Transition()
} }
fun closePrompt(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
closePromptButton().click()
BrowserRobot().interact()
return BrowserRobot.Transition()
}
fun closeDownloadPrompt(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { fun closeDownloadPrompt(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
itemWithResId("$packageName:id/download_dialog_close_button").click() itemWithResId("$packageName:id/download_dialog_close_button").click()
@ -216,24 +261,6 @@ private fun assertDownloadPrompt(fileName: String) {
} }
} }
private fun assertDownloadNotificationPopup() {
assertTrue(
"Download notification Open button not found",
mDevice.findObject(UiSelector().text("Open"))
.waitForExists(waitingTime),
)
assertTrue(
"Download completed notification text doesn't match",
mDevice.findObject(UiSelector().textContains("Download completed"))
.waitForExists(waitingTime),
)
assertTrue(
"Downloaded file name not visible",
mDevice.findObject(UiSelector().resourceId("$packageName:id/download_dialog_filename"))
.waitForExists(waitingTime),
)
}
private fun closeCompletedDownloadButton() = private fun closeCompletedDownloadButton() =
onView(withId(R.id.download_dialog_close_button)) onView(withId(R.id.download_dialog_close_button))

@ -82,6 +82,9 @@ class HistoryRobot {
deleteButton(item).click() deleteButton(item).click()
} }
fun verifyDeleteHistoryItemButton(historyItemTitle: String) =
deleteButton(historyItemTitle).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
fun clickDeleteAllHistoryButton() = deleteButton().click() fun clickDeleteAllHistoryButton() = deleteButton().click()
fun selectEverythingOption() = deleteHistoryEverythingOption().click() fun selectEverythingOption() = deleteHistoryEverythingOption().click()

@ -494,10 +494,6 @@ class HomeScreenRobot {
return SearchRobot.Transition() return SearchRobot.Transition()
} }
fun dismissOnboarding() {
openThreeDotMenu { }.openSettings { }.goBack { }
}
fun clickUpgradingUserOnboardingSignInButton( fun clickUpgradingUserOnboardingSignInButton(
testRule: ComposeTestRule, testRule: ComposeTestRule,
interact: SyncSignInRobot.() -> Unit, interact: SyncSignInRobot.() -> Unit,
@ -785,6 +781,11 @@ fun homeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition
return HomeScreenRobot.Transition() return HomeScreenRobot.Transition()
} }
fun homeScreenWithComposeTopSites(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTopSitesRobot.() -> Unit): ComposeTopSitesRobot.Transition {
ComposeTopSitesRobot(composeTestRule).interact()
return ComposeTopSitesRobot.Transition(composeTestRule)
}
private fun homeScreenList() = private fun homeScreenList() =
UiScrollable( UiScrollable(
UiSelector() UiSelector()

@ -191,6 +191,19 @@ class NavigationToolbarRobot {
return BrowserRobot.Transition() return BrowserRobot.Transition()
} }
fun enterURLAndEnterToBrowserForTCPCFR(
url: Uri,
interact: BrowserRobot.() -> Unit,
): BrowserRobot.Transition {
openEditURLView()
awesomeBar().setText(url.toString())
mDevice.pressEnter()
BrowserRobot().interact()
return BrowserRobot.Transition()
}
fun openTabCrashReporter(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { fun openTabCrashReporter(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
val crashUrl = "about:crashcontent" val crashUrl = "about:crashcontent"

@ -165,6 +165,11 @@ class NotificationRobot {
} }
} }
fun clickNotification(notificationMessage: String) {
mDevice.findObject(UiSelector().text(notificationMessage)).waitForExists(waitingTime)
mDevice.findObject(UiSelector().text(notificationMessage)).click()
}
class Transition { class Transition {
fun clickClosePrivateTabsNotification(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { fun clickClosePrivateTabsNotification(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {

@ -6,7 +6,11 @@
package org.mozilla.fenix.ui.robots package org.mozilla.fenix.ui.robots
import androidx.compose.ui.test.ComposeTimeoutException
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.assertAny import androidx.compose.ui.test.assertAny
import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.hasText import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.compose.ui.test.onAllNodesWithTag import androidx.compose.ui.test.onAllNodesWithTag
@ -117,7 +121,7 @@ class SearchRobot {
} }
} }
fun verifyNoSuggestionsAreDisplayed(rule: ComposeTestRule, vararg searchSuggestions: String) { fun verifySuggestionsAreNotDisplayed(rule: ComposeTestRule, vararg searchSuggestions: String) {
rule.waitForIdle() rule.waitForIdle()
for (searchSuggestion in searchSuggestions) { for (searchSuggestion in searchSuggestions) {
rule.onAllNodesWithTag("mozac.awesomebar.suggestions") rule.onAllNodesWithTag("mozac.awesomebar.suggestions")
@ -128,6 +132,28 @@ class SearchRobot {
} }
} }
@OptIn(ExperimentalTestApi::class)
fun verifySearchSuggestionsCount(rule: ComposeTestRule, numberOfSuggestions: Int, searchTerm: String) {
for (i in 1..RETRY_COUNT) {
try {
rule.waitUntilNodeCount(hasTestTag("mozac.awesomebar.suggestion"), numberOfSuggestions, waitingTime)
rule.onAllNodesWithTag("mozac.awesomebar.suggestion").assertCountEquals(numberOfSuggestions)
break
} catch (e: ComposeTimeoutException) {
if (i == RETRY_COUNT) {
throw e
} else {
mDevice.pressBack()
homeScreen {
}.openSearch {
typeSearch(searchTerm)
}
}
}
}
}
fun verifyAllowSuggestionsInPrivateModeDialog() { fun verifyAllowSuggestionsInPrivateModeDialog() {
assertTrue( assertTrue(
mDevice.findObject( mDevice.findObject(

@ -35,7 +35,6 @@ import org.mozilla.fenix.helpers.TestHelper
import org.mozilla.fenix.helpers.TestHelper.appName import org.mozilla.fenix.helpers.TestHelper.appName
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
import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.settings.SupportUtils
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.time.LocalDateTime import java.time.LocalDateTime
@ -48,8 +47,12 @@ import java.util.Date
* Implementation of Robot Pattern for the settings search sub menu. * Implementation of Robot Pattern for the settings search sub menu.
*/ */
class SettingsSubMenuAboutRobot { class SettingsSubMenuAboutRobot {
fun verifyAboutFirefoxPreviewInfo() {
fun verifyAboutFirefoxPreview() = assertFirefoxPreviewPage() assertVersionNumber()
assertProductCompany()
assertCurrentTimestamp()
verifyTheLinksList()
}
class Transition { class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
@ -61,13 +64,6 @@ class SettingsSubMenuAboutRobot {
} }
} }
private fun assertFirefoxPreviewPage() {
assertVersionNumber()
assertProductCompany()
assertCurrentTimestamp()
verifyListElements()
}
private fun navigateBackToAboutPage(itemToInteract: () -> Unit) { private fun navigateBackToAboutPage(itemToInteract: () -> Unit) {
navigationToolbar { navigationToolbar {
}.openThreeDotMenu { }.openThreeDotMenu {
@ -77,7 +73,7 @@ private fun navigateBackToAboutPage(itemToInteract: () -> Unit) {
} }
} }
private fun verifyListElements() { private fun verifyTheLinksList() {
assertAboutToolbar() assertAboutToolbar()
assertWhatIsNewInFirefoxPreview() assertWhatIsNewInFirefoxPreview()
navigateBackToAboutPage(::assertSupport) navigateBackToAboutPage(::assertSupport)

@ -41,6 +41,7 @@ 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.appName
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.restartApp import org.mozilla.fenix.helpers.TestHelper.restartApp
import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText
import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.click
@ -51,6 +52,22 @@ import org.mozilla.fenix.helpers.ext.waitNotNull
*/ */
class SettingsSubMenuAddonsManagerRobot { class SettingsSubMenuAddonsManagerRobot {
fun verifyAddonsListIsDisplayed(shouldBeDisplayed: Boolean) {
if (shouldBeDisplayed) {
assertTrue(
mDevice.findObject(
UiSelector().resourceId("$packageName:id/add_ons_list"),
).waitForExists(waitingTime),
)
} else {
assertTrue(
mDevice.findObject(
UiSelector().resourceId("$packageName:id/add_ons_list"),
).waitUntilGone(waitingTime),
)
}
}
fun verifyAddonPermissionPrompt(addonName: String) { fun verifyAddonPermissionPrompt(addonName: String) {
mDevice.waitNotNull(Until.findObject(By.text("Add $addonName?")), waitingTime) mDevice.waitNotNull(Until.findObject(By.text("Add $addonName?")), waitingTime)

@ -40,7 +40,6 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION
import org.mozilla.fenix.helpers.Constants.RETRY_COUNT import org.mozilla.fenix.helpers.Constants.RETRY_COUNT
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndDescriptionExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
@ -297,12 +296,6 @@ class TabDrawerRobot {
itemContainingText(getStringResource(R.string.synced_tabs_sign_in_message)), itemContainingText(getStringResource(R.string.synced_tabs_sign_in_message)),
itemContainingText(getStringResource(R.string.sync_sign_in)), itemContainingText(getStringResource(R.string.sync_sign_in)),
) )
assertItemWithResIdAndDescriptionExists(
itemWithResIdAndDescription(
"$packageName:id/new_tab_button",
getStringResource(R.string.resync_button_content_description),
),
)
} }
class Transition { class Transition {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 63 KiB

@ -1,3 +1,6 @@
<!-- 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/. -->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt" > xmlns:aapt="http://schemas.android.com/aapt" >
<aapt:attr name="android:drawable"> <aapt:attr name="android:drawable">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

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

Loading…
Cancel
Save