diff --git a/.buildconfig.yml b/.buildconfig.yml index 808a4246c..8d4747695 100644 --- a/.buildconfig.yml +++ b/.buildconfig.yml @@ -35,6 +35,7 @@ projects: - feature-customtabs - feature-downloads - feature-findinpage + - feature-fxsuggest - feature-intent - feature-logins - feature-media diff --git a/app/.experimenter.yaml b/app/.experimenter.yaml index 3cb3f80e4..6689c7550 100644 --- a/app/.experimenter.yaml +++ b/app/.experimenter.yaml @@ -15,6 +15,14 @@ extensions-process: enabled: type: boolean 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: description: A feature that provides server-side configurations for Glean metrics (aka Server Knobs). hasExposure: true @@ -47,9 +55,6 @@ juno-onboarding: cards: type: json description: Collection of user facing onboarding cards. - enabled: - type: boolean - description: "if true, juno onboarding is shown to the user." messaging: description: "The in-app messaging system.\n" hasExposure: true @@ -199,6 +204,9 @@ shopping-experience: enabled: type: boolean 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: description: "A feature that extends splash screen duration, allowing additional data fetching time for the app's initial run." hasExposure: true diff --git a/app/build.gradle b/app/build.gradle index 0d5e62be5..3308feb7c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,3 +1,4 @@ +import com.android.build.api.variant.FilterConfiguration import org.apache.tools.ant.util.StringUtils plugins { @@ -12,18 +13,16 @@ apply plugin: 'jacoco' apply plugin: 'androidx.navigation.safeargs.kotlin' apply plugin: 'com.google.android.gms.oss-licenses-plugin' -import com.android.build.OutputFile import groovy.json.JsonOutput import org.gradle.internal.logging.text.StyledTextOutput.Style import org.gradle.internal.logging.text.StyledTextOutputFactory +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import static org.gradle.api.tasks.testing.TestResult.ResultType apply from: 'benchmark.gradle' android { - compileSdkVersion config.compileSdkVersion - project.maybeConfigForJetpackBenchmark(it) if (project.hasProperty("testBuildType")) { // Allowing to configure the test build type via command line flag (./gradlew -PtestBuildType=beta ..) @@ -34,6 +33,7 @@ android { defaultConfig { applicationId "io.github.forkmaintainers" minSdkVersion config.minSdkVersion + compileSdk config.compileSdkVersion targetSdkVersion config.targetSdkVersion versionCode 1 versionName Config.generateDebugVersionName() @@ -218,9 +218,7 @@ android { animationsDisabled = true } - flavorDimensions "engine" - - flavorDimensions "product" + flavorDimensions.add("product") productFlavors { fenix { @@ -286,7 +284,7 @@ android { namespace 'org.mozilla.fenix' } -android.applicationVariants.all { variant -> +android.applicationVariants.configureEach { variant -> // ------------------------------------------------------------------------------------------------- // Generate version codes for builds @@ -312,7 +310,7 @@ android.applicationVariants.all { variant -> variant.outputs.each { output -> 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 def arch = (isMozillaOnline) ? "armeabi-v7a" : abi // 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" } -tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { - kotlinOptions { - freeCompilerArgs += [ - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - ] - } +tasks.withType(KotlinCompile).configureEach { + kotlinOptions.freeCompilerArgs += "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi" } dependencies { @@ -559,6 +553,7 @@ dependencies { implementation project(':feature-contextmenu') implementation project(':feature-customtabs') implementation project(':feature-downloads') + implementation project(':feature-fxsuggest') implementation project(':feature-intent') implementation project(':feature-media') implementation project(':feature-prompts') @@ -635,7 +630,7 @@ dependencies { implementation FenixDependencies.androidx_navigation_fragment implementation FenixDependencies.androidx_navigation_ui implementation ComponentsDependencies.androidx_recyclerview - implementation FenixDependencies.androidx_lifecycle_common + implementation ComponentsDependencies.androidx_lifecycle_common implementation ComponentsDependencies.androidx_lifecycle_livedata implementation ComponentsDependencies.androidx_lifecycle_process implementation ComponentsDependencies.androidx_lifecycle_runtime @@ -737,13 +732,13 @@ if (project.hasProperty("coverage")) { toolVersion = Versions.jacoco } - android.applicationVariants.all { variant -> + android.applicationVariants.configureEach { variant -> tasks.register("jacoco${variant.name.capitalize()}TestReport", JacocoReport) { dependsOn "test${variant.name.capitalize()}UnitTest" reports { - xml.enabled = true - html.enabled = true + xml.required = true + html.required = true } def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', @@ -782,7 +777,7 @@ tasks.register('printVariants') { doLast { def variants = android.applicationVariants.collect { variant -> [ 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 ]}, 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. // https://github.com/mozilla-mobile/fenix/issues/14175 def foundLocales = new StringBuilder() foundLocales.append("new String[]{") fileTree("src/main/res").visit { FileVisitDetails details -> - if(details.file.path.endsWith("${File.separator}strings.xml")){ - def languageCode = details.file.parent.tokenize(File.separator).last().replaceAll('values-','').replaceAll('-r','-') + if (details.file.path.endsWith("${File.separator}strings.xml")) { + def languageCode = details.file.parent.tokenize(File.separator).last().replaceAll('values-', '').replaceAll('-r', '-') languageCode = (languageCode == "values") ? "en-US" : languageCode foundLocales.append("\"").append(languageCode).append("\"").append(",") } } foundLocales.append("}") - def foundLocalesString = foundLocales.toString().replaceAll(',}','}') + def foundLocalesString = foundLocales.toString().replaceAll(',}', '}') 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" } -android.applicationVariants.all { variant -> +android.applicationVariants.configureEach { variant -> tasks.register("apkSize${variant.name.capitalize()}", ApkSizeTask) { variantName = variant.name apks = variant.outputs.collect { output -> output.outputFile.name } diff --git a/app/metrics.yaml b/app/metrics.yaml index 8aeb63e4a..a578c7c45 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -2539,6 +2539,28 @@ metrics: metadata: tags: - 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: type: timing_distribution time_unit: millisecond diff --git a/app/nimbus.fml.yaml b/app/nimbus.fml.yaml index e4bf82adf..697f5a718 100644 --- a/app/nimbus.fml.yaml +++ b/app/nimbus.fml.yaml @@ -348,6 +348,10 @@ features: description: if true, the shopping experience feature is shown to the user. type: Boolean 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: - channel: developer value: @@ -384,6 +388,24 @@ features: description: The channel Id param name with arg. type: Map 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: objects: {} diff --git a/app/onboarding.fml.yaml b/app/onboarding.fml.yaml index 4382e17dc..cb6be10ec 100644 --- a/app/onboarding.fml.yaml +++ b/app/onboarding.fml.yaml @@ -5,10 +5,6 @@ features: description: A feature that shows juno onboarding flow. variables: - enabled: - description: if true, juno onboarding is shown to the user. - type: Boolean - default: false cards: description: Collection of user facing onboarding cards. type: Map @@ -51,14 +47,6 @@ features: primary-button-label: juno_onboarding_enable_notifications_positive_button secondary-button-label: juno_onboarding_enable_notifications_negative_button - defaults: - - channel: developer - value: - enabled: false - - channel: nightly - value: - enabled: true - objects: OnboardingCardData: diff --git a/app/pbm.fml.yaml b/app/pbm.fml.yaml index 46055d61f..7b22ed8a3 100644 --- a/app/pbm.fml.yaml +++ b/app/pbm.fml.yaml @@ -13,7 +13,7 @@ features: defaults: - channel: developer value: - felt-privacy-enabled: true + felt-privacy-enabled: false - channel: nightly value: felt-privacy-enabled: false diff --git a/app/src/androidTest/assets/pages/externalLinks.html b/app/src/androidTest/assets/pages/externalLinks.html index 9007f99b2..755d15ac8 100644 --- a/app/src/androidTest/assets/pages/externalLinks.html +++ b/app/src/androidTest/assets/pages/externalLinks.html @@ -8,19 +8,22 @@

Misc Link Types

- External link + Email link
- Email link + Telephone link
- Telephone link + Youtube schema link
- Youtube link + Youtube full link
+
+ Playstore link +
diff --git a/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/Pipfile b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/Pipfile index 03f589cad..d21a2e8f6 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/Pipfile +++ b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/Pipfile @@ -7,6 +7,8 @@ name = "pypi" pytest = "*" pytest-html = "*" pytest-metadata = "*" +pytest-variables = "*" +pyyaml = "*" requests = "*" [dev-packages] diff --git a/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/Pipfile.lock b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/Pipfile.lock index a40cf3ffe..0fb380689 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/Pipfile.lock +++ b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "917d5c85bd6545dedfbce6aedbd76bd1516993e65943ecfbf7affbece9a2a0ab" + "sha256": "53501c7e751ae79697bf8c7289b6095f49fed97242fe186fea42989e800c39d5" }, "pipfile-spec": 6, "requires": { @@ -16,141 +16,94 @@ ] }, "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": { "hashes": [ - "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7", - "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716" + "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", + "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" ], "markers": "python_version >= '3.6'", - "version": "==2023.5.7" + "version": "==2023.7.22" }, "charset-normalizer": { "hashes": [ - "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6", - "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1", - "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e", - "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373", - "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62", - "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230", - "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be", - "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c", - "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0", - "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448", - "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f", - "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649", - "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d", - "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0", - "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706", - "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a", - "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59", - "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23", - "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5", - "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb", - "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e", - "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e", - "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c", - "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28", - "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d", - "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41", - "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974", - "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce", - "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f", - "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1", - "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d", - "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8", - "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017", - "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31", - "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7", - "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8", - "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e", - "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14", - "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd", - "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d", - "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795", - "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b", - "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b", - "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b", - "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203", - "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f", - "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19", - "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1", - "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a", - "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac", - "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9", - "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0", - "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137", - "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f", - "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6", - "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5", - "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909", - "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f", - "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0", - "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324", - "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755", - "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb", - "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854", - "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c", - "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60", - "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84", - "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0", - "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b", - "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1", - "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531", - "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1", - "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11", - "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326", - "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df", - "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab" + "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96", + "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c", + "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710", + "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706", + "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020", + "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252", + "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad", + "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329", + "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a", + "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f", + "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6", + "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4", + "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a", + "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46", + "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2", + "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23", + "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace", + "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd", + "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982", + "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10", + "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2", + "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea", + "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09", + "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5", + "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149", + "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489", + "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9", + "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80", + "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592", + "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3", + "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6", + "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed", + "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c", + "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200", + "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a", + "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e", + "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d", + "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6", + "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623", + "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669", + "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3", + "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa", + "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9", + "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2", + "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f", + "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1", + "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4", + "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a", + "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8", + "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3", + "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029", + "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f", + "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959", + "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22", + "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7", + "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952", + "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346", + "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e", + "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d", + "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299", + "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd", + "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a", + "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3", + "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037", + "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94", + "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c", + "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858", + "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a", + "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449", + "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c", + "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918", + "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1", + "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c", + "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", + "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" ], "markers": "python_full_version >= '3.7.0'", - "version": "==3.1.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" + "version": "==3.2.0" }, "idna": { "hashes": [ @@ -168,21 +121,69 @@ "markers": "python_version >= '3.7'", "version": "==2.0.0" }, - "mccabe": { + "jinja2": { "hashes": [ - "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", - "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" + "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", + "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" ], - "markers": "python_version >= '3.6'", - "version": "==0.7.0" + "markers": "python_version >= '3.7'", + "version": "==3.1.2" }, - "mypy-extensions": { + "markupsafe": { "hashes": [ - "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", - "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" + "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e", + "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'", - "version": "==1.0.0" + "markers": "python_version >= '3.7'", + "version": "==2.1.3" }, "packaging": { "hashes": [ @@ -192,94 +193,219 @@ "markers": "python_version >= '3.7'", "version": "==23.1" }, - "pathspec": { + "pluggy": { "hashes": [ - "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687", - "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293" + "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", + "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" ], - "markers": "python_version >= '3.7'", - "version": "==0.11.1" + "markers": "python_version >= '3.8'", + "version": "==1.3.0" }, - "platformdirs": { + "pytest": { "hashes": [ - "sha256:b0cabcb11063d21a0b261d557acb0a9d2126350e63b70cdf7db6347baea456dc", - "sha256:ca9ed98ce73076ba72e092b23d3c93ea6c4e186b3f1c3dad6edd98ff6ffcca2e" + "sha256:2f2301e797521b23e4d2585a0a3d7b5e50fdddaaf7e7d6773ea26ddb17c213ab", + "sha256:460c9a59b14e27c602eb5ece2e47bec99dc5fc5f6513cf924a7d03a578991b1f" ], - "markers": "python_version >= '3.7'", - "version": "==3.8.0" + "index": "pypi", + "version": "==7.4.1" }, - "pluggy": { + "pytest-html": { "hashes": [ - "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849", - "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3" + "sha256:3b473cc278272f8b5a34cd3bf10f88ac5fcb17cb5af22f9323514af00c310e64", + "sha256:79c4677ed6196417bf290d8b81f706342ae49f726f623728efa3f7dfff09f8eb" ], - "markers": "python_version >= '3.7'", - "version": "==1.2.0" + "index": "pypi", + "version": "==4.0.0" }, - "py": { + "pytest-metadata": { "hashes": [ - "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", - "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" + "sha256:769a9c65d2884bd583bc626b0ace77ad15dbe02dd91a9106d47fd46d9c2569ca", + "sha256:a17b1e40080401dc23177599208c52228df463db191c1a573ccdffacd885e190" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.11.0" + "index": "pypi", + "version": "==3.0.0" }, - "pycodestyle": { + "pytest-variables": { "hashes": [ - "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053", - "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610" + "sha256:190d9d4da5a6013eb02df2049f6047d911cdbe44c5b1734a6acc1748433c93d0", + "sha256:ab84235417afac5a0a7dd4c3918287d9c7329d2e16d570d6e943f8d8e02533b9" ], - "markers": "python_version >= '3.6'", - "version": "==2.10.0" + "index": "pypi", + "version": "==3.0.0" }, - "pyflakes": { + "pyyaml": { "hashes": [ - "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf", - "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd" + "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", + "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'", - "version": "==3.0.1" + "index": "pypi", + "version": "==6.0.1" }, - "pytest": { + "requests": { "hashes": [ - "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32", - "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a" + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" ], "index": "pypi", - "version": "==7.4.0" + "version": "==2.31.0" }, - "pytest-html": { + "urllib3": { "hashes": [ - "sha256:868c08564a68d8b2c26866f1e33178419bb35b1e127c33784a28622eb827f3f3", - "sha256:c4e2f4bb0bffc437f51ad2174a8a3e71df81bbc2f6894604e604af18fbe687c3" + "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11", + "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", - "version": "==3.2.0" + "version": "==23.7.0" }, - "pytest-metadata": { + "click": { "hashes": [ - "sha256:769a9c65d2884bd583bc626b0ace77ad15dbe02dd91a9106d47fd46d9c2569ca", - "sha256:a17b1e40080401dc23177599208c52228df463db191c1a573ccdffacd885e190" + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" ], - "index": "pypi", - "version": "==3.0.0" + "markers": "python_version >= '3.7'", + "version": "==8.1.7" }, - "requests": { + "flake8": { "hashes": [ - "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", - "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" + "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23", + "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5" ], "index": "pypi", - "version": "==2.31.0" + "version": "==6.1.0" }, - "urllib3": { + "mccabe": { "hashes": [ - "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1", - "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825" + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "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'", - "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": {} + } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/SurveyExperimentIntegrationTest.kt b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/SurveyExperimentIntegrationTest.kt index 277135cb7..18fb39105 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/SurveyExperimentIntegrationTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/SurveyExperimentIntegrationTest.kt @@ -22,7 +22,11 @@ class SurveyExperimentIntegrationTest { private val experimentName = "Viewpoint" @get:Rule - val activityTestRule = HomeActivityTestRule() + val activityTestRule = HomeActivityTestRule( + isJumpBackInCFREnabled = false, + isPWAsPromptEnabled = false, + isTCPCFREnabled = false, + ) @Before fun setUp() { @@ -38,7 +42,25 @@ class SurveyExperimentIntegrationTest { fun checkSurveyNavigatesCorrectly() { browserScreen { verifySurveyButton() - }.clickSurveyButton {} + }.clickSurveyButton { + verifyUrl(surveyURL) + } + + homeScreen { + }.openThreeDotMenu { + }.openSettings { + }.openExperimentsMenu { + verifyExperimentExists(experimentName) + } + } + + @Test + fun checkSurveyNoThanksNavigatesCorrectly() { + browserScreen { + verifySurveyNoThanksButton() + }.clickNoThanksSurveyButton { + verifyTabCounter("0") + } homeScreen { }.openThreeDotMenu { diff --git a/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/conftest.py b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/conftest.py index 19ddbf691..27b2f2f1f 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/conftest.py +++ b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/conftest.py @@ -1,4 +1,5 @@ import json +import logging import os from pathlib import Path import subprocess @@ -15,15 +16,32 @@ KLAATU_LOCAL_SERVER_URL = "http://localhost:1378" 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 = [] - data = requests.get(f"{KLAATU_SERVER_URL}/experiment").json() - for item in reversed(data): - if isinstance(item, dict): + + if experiment_url: + 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() else: - data = item - break + for item in reversed(data): + data = item + break experiment = requests.get(data).json() for item in experiment["branches"]: branches.append(item["slug"]) @@ -45,7 +63,6 @@ def gradlewbuild(gradlewbuild_log): @pytest.fixture(name="experiment_data") def fixture_experiment_data(experiment_url): 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 count, trigger in enumerate(item["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") -def fixture_experiment_url(): - data = requests.get(f"{KLAATU_LOCAL_SERVER_URL}/experiment").json() +def fixture_experiment_url(request, variables): url = None - for item in data: - if isinstance(item, dict): - continue + + if slug := request.config.getoption("--experiment"): + # Build URL from slug + if request.config.getoption("--stage"): + url = f"{variables['urls']['stage_server']}/api/v6/experiments/{slug}" 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 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") @@ -116,13 +149,17 @@ def fixture_send_test_results(): with open(f"{here.resolve()}/results/index.html", "rb") as 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) -def fixture_setup_experiment(experiment_slug, json_data, gradlewbuild_log, request): - def _(): - command = f"nimbus-cli --app fenix --channel developer enroll {experiment_slug} --branch {request.param} --file {json_data} --reset-app" +@pytest.fixture(name="setup_experiment") +def fixture_setup_experiment(experiment_slug, json_data, gradlewbuild_log): + def _(branch): + 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: out = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: diff --git a/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/pytest.ini b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/pytest.ini index 465cd779e..40a205fb0 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/pytest.ini +++ b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/pytest.ini @@ -1,4 +1,4 @@ [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_level = info diff --git a/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/test_integration.py b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/test_integration.py index 63ef8a494..9e88c5df6 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/test_integration.py +++ b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/test_integration.py @@ -1,3 +1,12 @@ -def test_survey_navigates_correctly(setup_experiment, gradlewbuild): - setup_experiment() +import pytest + + +@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") + +@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") diff --git a/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/variables.yaml b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/variables.yaml new file mode 100644 index 000000000..54e26e502 --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/variables.yaml @@ -0,0 +1,3 @@ +urls: + stage_server: "https://stage.experimenter.nonprod.dataops.mozgcp.net" + prod_server: "https://experimenter.services.mozilla.com" diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelper.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelper.kt index a95fb9216..a42fe1a31 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelper.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelper.kt @@ -82,6 +82,11 @@ interface FeatureSettingsHelper { */ var tabsTrayRewriteEnabled: Boolean + /** + * Enable or disable the Top Sites to Compose rewrite. + */ + var composeTopSitesEnabled: Boolean + fun applyFlagUpdates() fun resetAllFeatureFlags() diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelperDelegate.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelperDelegate.kt index cf1828002..c31fcf756 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelperDelegate.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelperDelegate.kt @@ -37,6 +37,7 @@ class FeatureSettingsHelperDelegate() : FeatureSettingsHelper { isOpenInAppBannerEnabled = settings.shouldShowOpenInAppBanner, etpPolicy = getETPPolicy(settings), tabsTrayRewriteEnabled = settings.enableTabsTrayToCompose, + composeTopSitesEnabled = settings.enableComposeTopSites, ) /** @@ -66,6 +67,7 @@ class FeatureSettingsHelperDelegate() : FeatureSettingsHelper { override var isOpenInAppBannerEnabled: Boolean by updatedFeatureFlags::isOpenInAppBannerEnabled override var etpPolicy: ETPPolicy by updatedFeatureFlags::etpPolicy override var tabsTrayRewriteEnabled: Boolean by updatedFeatureFlags::tabsTrayRewriteEnabled + override var composeTopSitesEnabled: Boolean by updatedFeatureFlags::composeTopSitesEnabled override fun applyFlagUpdates() { applyFeatureFlags(updatedFeatureFlags) @@ -91,6 +93,7 @@ class FeatureSettingsHelperDelegate() : FeatureSettingsHelper { settings.userOptOutOfReEngageCookieBannerDialog = !featureFlags.isCookieBannerReductionDialogEnabled settings.shouldShowOpenInAppBanner = featureFlags.isOpenInAppBannerEnabled settings.enableTabsTrayToCompose = featureFlags.tabsTrayRewriteEnabled + settings.enableComposeTopSites = featureFlags.composeTopSitesEnabled setETPPolicy(featureFlags.etpPolicy) } } @@ -110,6 +113,7 @@ private data class FeatureFlags( var isOpenInAppBannerEnabled: Boolean, var etpPolicy: ETPPolicy, var tabsTrayRewriteEnabled: Boolean, + var composeTopSitesEnabled: Boolean, ) internal fun getETPPolicy(settings: Settings): ETPPolicy { diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt index dd8b13e14..9243a102f 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt @@ -56,6 +56,7 @@ class HomeActivityTestRule( isOpenInAppBannerEnabled: Boolean = settings.shouldShowOpenInAppBanner, etpPolicy: ETPPolicy = getETPPolicy(settings), tabsTrayRewriteEnabled: Boolean = false, + composeTopSitesEnabled: Boolean = false, ) : this(initialTouchMode, launchActivity, skipOnboarding) { this.isHomeOnboardingDialogEnabled = isHomeOnboardingDialogEnabled this.isPocketEnabled = isPocketEnabled @@ -70,6 +71,7 @@ class HomeActivityTestRule( this.isOpenInAppBannerEnabled = isOpenInAppBannerEnabled this.etpPolicy = etpPolicy this.tabsTrayRewriteEnabled = tabsTrayRewriteEnabled + this.composeTopSitesEnabled = composeTopSitesEnabled } /** @@ -114,6 +116,7 @@ class HomeActivityTestRule( launchActivity: Boolean = true, skipOnboarding: Boolean = false, tabsTrayRewriteEnabled: Boolean = false, + composeTopSitesEnabled: Boolean = false, ) = HomeActivityTestRule( initialTouchMode = initialTouchMode, launchActivity = launchActivity, @@ -125,6 +128,7 @@ class HomeActivityTestRule( isWallpaperOnboardingEnabled = false, isCookieBannerReductionDialogEnabled = false, isOpenInAppBannerEnabled = false, + composeTopSitesEnabled = composeTopSitesEnabled, ) } } @@ -164,6 +168,7 @@ class HomeActivityIntentTestRule internal constructor( isOpenInAppBannerEnabled: Boolean = settings.shouldShowOpenInAppBanner, etpPolicy: ETPPolicy = getETPPolicy(settings), tabsTrayRewriteEnabled: Boolean = false, + composeTopSitesEnabled: Boolean = false, ) : this(initialTouchMode, launchActivity, skipOnboarding) { this.isHomeOnboardingDialogEnabled = isHomeOnboardingDialogEnabled this.isPocketEnabled = isPocketEnabled @@ -178,6 +183,7 @@ class HomeActivityIntentTestRule internal constructor( this.isOpenInAppBannerEnabled = isOpenInAppBannerEnabled this.etpPolicy = etpPolicy this.tabsTrayRewriteEnabled = tabsTrayRewriteEnabled + this.composeTopSitesEnabled = composeTopSitesEnabled } private val longTapUserPreference = getLongPressTimeout() @@ -259,6 +265,7 @@ class HomeActivityIntentTestRule internal constructor( launchActivity: Boolean = true, skipOnboarding: Boolean = false, tabsTrayRewriteEnabled: Boolean = false, + composeTopSitesEnabled: Boolean = false, ) = HomeActivityIntentTestRule( initialTouchMode = initialTouchMode, launchActivity = launchActivity, @@ -270,6 +277,7 @@ class HomeActivityIntentTestRule internal constructor( isWallpaperOnboardingEnabled = false, isCookieBannerReductionDialogEnabled = false, isOpenInAppBannerEnabled = false, + composeTopSitesEnabled = composeTopSitesEnabled, ) } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/MockWebServer.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/MockWebServer.kt index 5bbc5f318..9e919a72f 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/MockWebServer.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/MockWebServer.kt @@ -56,7 +56,7 @@ object MockWebServerHelper { * If the dispatcher is unable to read a requested asset, it will fail the test by throwing an * 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_NOT_FOUND = 404 diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt index 92ab6bb5a..af0528849 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt @@ -187,9 +187,11 @@ object TestHelper { val storageVolume: StorageVolume = storageVolumes[0] val file = File(storageVolume.directory!!.path + "/Download/" + fileName) try { - file.delete() - Log.d("TestLog", "File delete try 1") - assertFalse("The file was not deleted", file.exists()) + if (file.exists()) { + file.delete() + Log.d("TestLog", "File delete try 1") + assertFalse("The file was not deleted", file.exists()) + } } catch (e: AssertionError) { file.delete() Log.d("TestLog", "File delete retried") diff --git a/app/src/androidTest/java/org/mozilla/fenix/syncintegration/Pipfile.lock b/app/src/androidTest/java/org/mozilla/fenix/syncintegration/Pipfile.lock index 318047890..37fe811b5 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/syncintegration/Pipfile.lock +++ b/app/src/androidTest/java/org/mozilla/fenix/syncintegration/Pipfile.lock @@ -37,7 +37,7 @@ "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" ], - "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==2023.7.22" }, "cffi": { @@ -192,32 +192,32 @@ }, "cryptography": { "hashes": [ - "sha256:01f1d9e537f9a15b037d5d9ee442b8c22e3ae11ce65ea1f3316a41c78756b711", - "sha256:079347de771f9282fbfe0e0236c716686950c19dee1b76240ab09ce1624d76d7", - "sha256:182be4171f9332b6741ee818ec27daff9fb00349f706629f5cbf417bd50e66fd", - "sha256:192255f539d7a89f2102d07d7375b1e0a81f7478925b3bc2e0549ebf739dae0e", - "sha256:2a034bf7d9ca894720f2ec1d8b7b5832d7e363571828037f9e0c4f18c1b58a58", - "sha256:342f3767e25876751e14f8459ad85e77e660537ca0a066e10e75df9c9e9099f0", - "sha256:439c3cc4c0d42fa999b83ded80a9a1fb54d53c58d6e59234cfe97f241e6c781d", - "sha256:49c3222bb8f8e800aead2e376cbef687bc9e3cb9b58b29a261210456a7783d83", - "sha256:674b669d5daa64206c38e507808aae49904c988fa0a71c935e7006a3e1e83831", - "sha256:7a9a3bced53b7f09da251685224d6a260c3cb291768f54954e28f03ef14e3766", - "sha256:7af244b012711a26196450d34f483357e42aeddb04128885d95a69bd8b14b69b", - "sha256:7d230bf856164de164ecb615ccc14c7fc6de6906ddd5b491f3af90d3514c925c", - "sha256:84609ade00a6ec59a89729e87a503c6e36af98ddcd566d5f3be52e29ba993182", - "sha256:9a6673c1828db6270b76b22cc696f40cde9043eb90373da5c2f8f2158957f42f", - "sha256:9b6d717393dbae53d4e52684ef4f022444fc1cce3c48c38cb74fca29e1f08eaa", - "sha256:9c3fe6534d59d071ee82081ca3d71eed3210f76ebd0361798c74abc2bcf347d4", - "sha256:a719399b99377b218dac6cf547b6ec54e6ef20207b6165126a280b0ce97e0d2a", - "sha256:b332cba64d99a70c1e0836902720887fb4529ea49ea7f5462cf6640e095e11d2", - "sha256:d124682c7a23c9764e54ca9ab5b308b14b18eba02722b8659fb238546de83a76", - "sha256:d73f419a56d74fef257955f51b18d046f3506270a5fd2ac5febbfa259d6c0fa5", - "sha256:f0dc40e6f7aa37af01aba07277d3d64d5a03dc66d682097541ec4da03cc140ee", - "sha256:f14ad275364c8b4e525d018f6716537ae7b6d369c094805cae45300847e0894f", - "sha256:f772610fe364372de33d76edcd313636a25684edb94cee53fd790195f5989d14" + "sha256:0d09fb5356f975974dbcb595ad2d178305e5050656affb7890a1583f5e02a306", + "sha256:23c2d778cf829f7d0ae180600b17e9fceea3c2ef8b31a99e3c694cbbf3a24b84", + "sha256:3fb248989b6363906827284cd20cca63bb1a757e0a2864d4c1682a985e3dca47", + "sha256:41d7aa7cdfded09b3d73a47f429c298e80796c8e825ddfadc84c8a7f12df212d", + "sha256:42cb413e01a5d36da9929baa9d70ca90d90b969269e5a12d39c1e0d475010116", + "sha256:4c2f0d35703d61002a2bbdcf15548ebb701cfdd83cdc12471d2bae80878a4207", + "sha256:4fd871184321100fb400d759ad0cddddf284c4b696568204d281c902fc7b0d81", + "sha256:5259cb659aa43005eb55a0e4ff2c825ca111a0da1814202c64d28a985d33b087", + "sha256:57a51b89f954f216a81c9d057bf1a24e2f36e764a1ca9a501a6964eb4a6800dd", + "sha256:652627a055cb52a84f8c448185922241dd5217443ca194d5739b44612c5e6507", + "sha256:67e120e9a577c64fe1f611e53b30b3e69744e5910ff3b6e97e935aeb96005858", + "sha256:6af1c6387c531cd364b72c28daa29232162010d952ceb7e5ca8e2827526aceae", + "sha256:6d192741113ef5e30d89dcb5b956ef4e1578f304708701b8b73d38e3e1461f34", + "sha256:7efe8041897fe7a50863e51b77789b657a133c75c3b094e51b5e4b5cec7bf906", + "sha256:84537453d57f55a50a5b6835622ee405816999a7113267739a1b4581f83535bd", + "sha256:8f09daa483aedea50d249ef98ed500569841d6498aa9c9f4b0531b9964658922", + "sha256:95dd7f261bb76948b52a5330ba5202b91a26fbac13ad0e9fc8a3ac04752058c7", + "sha256:a74fbcdb2a0d46fe00504f571a2a540532f4c188e6ccf26f1f178480117b33c4", + "sha256:a983e441a00a9d57a4d7c91b3116a37ae602907a7618b882c8013b5762e80574", + "sha256:ab8de0d091acbf778f74286f4989cf3d1528336af1b59f3e5d2ebca8b5fe49e1", + "sha256:aeb57c421b34af8f9fe830e1955bf493a86a7996cc1338fe41b30047d16e962c", + "sha256:ce785cf81a7bdade534297ef9e490ddff800d956625020ab2ec2780a556c313e", + "sha256:d0d651aa754ef58d75cec6edfbd21259d93810b73f6ec246436a21b7841908de" ], - "markers": "python_version >= '3.7'", - "version": "==41.0.2" + "index": "pypi", + "version": "==41.0.3" }, "distro": { "hashes": [ @@ -229,11 +229,11 @@ }, "exceptiongroup": { "hashes": [ - "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5", - "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f" + "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9", + "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3" ], "markers": "python_version < '3.11'", - "version": "==1.1.2" + "version": "==1.1.3" }, "fxapom": { "hashes": [ @@ -373,11 +373,11 @@ }, "pluggy": { "hashes": [ - "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849", - "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3" + "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", + "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" ], - "markers": "python_version >= '3.7'", - "version": "==1.2.0" + "markers": "python_version >= '3.8'", + "version": "==1.3.0" }, "progressbar2": { "hashes": [ @@ -495,19 +495,19 @@ }, "selenium": { "hashes": [ - "sha256:40241b9d872f58959e9b34e258488bf11844cd86142fd68182bd41db9991fc5c", - "sha256:871bf800c4934f745b909c8dfc7d15c65cf45bd2e943abd54451c810ada395e3" + "sha256:95be6aa449a0ab4ac1198bb9de71bbe9170405e04b9752f4b450dc7292a21828", + "sha256:b2c48b1440db54a0653300d9955f5421390723d53b36ec835e18de8e13bbd401" ], - "markers": "python_version >= '3.7'", - "version": "==4.10.0" + "markers": "python_version >= '3.8'", + "version": "==4.12.0" }, "setuptools": { "hashes": [ - "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f", - "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235" + "sha256:00478ca80aeebeecb2f288d3206b0de568df5cd2b8fada1209843cc9a8d88a48", + "sha256:af3d5949030c3f493f550876b2fd1dd5ec66689c4ee5d5344f009746f71fd5a8" ], - "markers": "python_version >= '3.7'", - "version": "==68.0.0" + "markers": "python_version >= '3.8'", + "version": "==68.2.0" }, "six": { "hashes": [ @@ -557,11 +557,11 @@ }, "trio-websocket": { "hashes": [ - "sha256:1a748604ad906a7dcab9a43c6eb5681e37de4793ba0847ef0bc9486933ed027b", - "sha256:a9937d48e8132ebf833019efde2a52ca82d223a30a7ea3e8d60a7d28f75a4e3a" + "sha256:c7a620c4013c34b7e4477d89fe76695da1e455e4510a8d7ae13f81c632bdce1d", + "sha256:e66b3db3e2453017431dfbd352081006654e1241c2a6800dc2f43d7df54d55c5" ], "markers": "python_version >= '3.7'", - "version": "==0.10.3" + "version": "==0.10.4" }, "typing-extensions": { "hashes": [ diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/AddToHomeScreenTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/AddToHomeScreenTest.kt index f1fa8d9b6..4e03051f7 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/AddToHomeScreenTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/AddToHomeScreenTest.kt @@ -4,34 +4,28 @@ package org.mozilla.fenix.ui -import androidx.core.net.toUri +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import okhttp3.mockwebserver.MockWebServer import org.junit.After import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AndroidAssetDispatcher -import org.mozilla.fenix.helpers.HomeActivityIntentTestRule -import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText +import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper import org.mozilla.fenix.ui.robots.browserScreen -import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen -import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.searchScreen class AddToHomeScreenTest { 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 - val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + val composeTestRule = + AndroidComposeTestRule(HomeActivityTestRule.withDefaultSettingsOverrides()) { it.activity } @Before fun setUp() { @@ -76,17 +70,15 @@ class AddToHomeScreenTest { } } + @Ignore("Failure, more details at: https://bugzilla.mozilla.org/show_bug.cgi?id=1830005") @SmokeTest @Test fun addPrivateBrowsingShortcutTest() { - homeScreen { - }.dismissOnboarding() - homeScreen { }.triggerPrivateBrowsingShortcutPrompt { - verifyNoThanksPrivateBrowsingShortcutButton() - verifyAddPrivateBrowsingShortcutButton() - clickAddPrivateBrowsingShortcutButton() + verifyNoThanksPrivateBrowsingShortcutButton(composeTestRule) + verifyAddPrivateBrowsingShortcutButton(composeTestRule) + clickAddPrivateBrowsingShortcutButton(composeTestRule) clickAddAutomaticallyButton() }.openHomeScreenShortcut("Private ${TestHelper.appName}") {} searchScreen { @@ -95,23 +87,4 @@ class AddToHomeScreenTest { 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) - } - } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt index f326b1abb..b6244395b 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt @@ -41,6 +41,7 @@ class AddressAutofillTest { mockWebServer.shutdown() } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836845 @SmokeTest @Test fun verifyAddressAutofillTest() { @@ -81,6 +82,7 @@ class AddressAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836856 @SmokeTest @Test fun deleteSavedAddressTest() { @@ -111,6 +113,7 @@ class AddressAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836840 @Test fun verifyAddAddressViewTest() { homeScreen { @@ -124,6 +127,7 @@ class AddressAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836841 @Test fun verifyEditAddressViewTest() { homeScreen { @@ -149,6 +153,7 @@ class AddressAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836839 @Test fun verifyAddressAutofillToggleTest() { val addressFormPage = @@ -196,6 +201,7 @@ class AddressAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836847 @Test fun verifyManageAddressesPromptOptionTest() { 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") @Test - fun verifyAddressAutofillSelectionTest() { + fun verifyMultipleAddressesSelectionTest() { val addressFormPage = TestAssetHelper.getAddressFormAsset(mockWebServer) @@ -301,6 +308,7 @@ class AddressAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836850 @Test fun verifySavedAddressCanBeEditedTest() { homeScreen { @@ -339,6 +347,7 @@ class AddressAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836848 @Test fun verifyStateFieldUpdatesInAccordanceWithCountryFieldTest() { homeScreen { @@ -355,6 +364,7 @@ class AddressAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836858 @Test fun verifyFormFieldCanBeFilledManuallyTest() { val addressFormPage = @@ -397,6 +407,7 @@ class AddressAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836838 @Test fun verifyAutofillAddressSectionTest() { homeScreen { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt index a4c2da8c0..5771bf96d 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt @@ -27,7 +27,6 @@ import org.mozilla.fenix.helpers.MockBrowserDataHelper.createBookmarkItem import org.mozilla.fenix.helpers.RecyclerViewIdlingResource import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestAssetHelper -import org.mozilla.fenix.helpers.TestHelper import org.mozilla.fenix.helpers.TestHelper.appContext import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton 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 fun verifyEmptyBookmarksMenuTest() { homeScreen { @@ -93,18 +93,6 @@ class BookmarksTest { verifyAddFolderButton() verifyCloseButton() verifyBookmarkTitle("Desktop Bookmarks") - } - } - } - - @Test - fun defaultDesktopBookmarksFoldersTest() { - homeScreen { - }.openThreeDotMenu { - }.openBookmarks { - registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1), - ) { selectFolder("Desktop Bookmarks") verifyFolderTitle("Bookmarks Menu") verifyFolderTitle("Bookmarks Toolbar") @@ -116,54 +104,31 @@ class BookmarksTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2301370 @Test - fun verifyBookmarkButtonTest() { + fun verifyAddBookmarkButtonTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { }.bookmarkPage { + verifySnackBarText("Bookmark saved!") }.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), ) { + verifyBookmarksMenuView() + verifyBookmarkTitle(defaultWebPage.title) 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() - } - } - } - + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/522920 @Test fun cancelCreateBookmarkFolderTest() { homeScreen { @@ -177,9 +142,9 @@ class BookmarksTest { } } - @SmokeTest + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2299619 @Test - fun cancelEditBookmarkTest() { + fun cancelingChangesInEditModeAreNotSavedTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -202,9 +167,10 @@ class BookmarksTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325633 @SmokeTest @Test - fun editBookmarkTest() { + fun editBookmarksNameAndUrlTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) browserScreen { @@ -229,6 +195,7 @@ class BookmarksTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/341696 @Test fun copyBookmarkURLTest() { 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 - fun threeDotMenuShareBookmarkTest() { + fun shareBookmarkTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) browserScreen { @@ -275,6 +243,7 @@ class BookmarksTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325636 @Test fun openBookmarkInNewTabTest() { 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") @Test - fun openAllInTabsTest() { + fun verifyOpenAllInNewTabsOptionTest() { val webPages = listOf( TestAssetHelper.getGenericAsset(mockWebServer, 1), 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") @Test - fun openAllInPrivateTabsTest() { + fun verifyOpenAllInPrivateTabsTest() { val webPages = listOf( TestAssetHelper.getGenericAsset(mockWebServer, 1), TestAssetHelper.getGenericAsset(mockWebServer, 2), @@ -372,6 +343,7 @@ class BookmarksTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325637 @Test fun openBookmarkInPrivateTabTest() { 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 fun deleteBookmarkTest() { 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 { createBookmark(defaultWebPage.url) }.openThreeDotMenu { @@ -431,10 +384,13 @@ class BookmarksTest { ) { 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 fun bookmarksMultiSelectionToolbarItemsTest() { 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 @Test - fun openSelectionInNewTabTest() { + fun openMultipleSelectedBookmarksInANewTabTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) browserScreen { @@ -489,9 +446,9 @@ class BookmarksTest { } } - @SmokeTest + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2300277 @Test - fun openSelectionInPrivateTabTest() { + fun openMultipleSelectedBookmarksInPrivateTabTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) browserScreen { @@ -513,9 +470,10 @@ class BookmarksTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325644 @SmokeTest @Test - fun deleteMultipleSelectionTest() { + fun deleteMultipleSelectedBookmarksTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) @@ -539,20 +497,9 @@ class BookmarksTest { bookmarksMenu { verifyDeleteMultipleBookmarksSnackBar() - } - } - - @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 { + clickUndoDeleteButton() + verifyBookmarkedURL(firstWebPage.url.toString()) + verifyBookmarkedURL(secondWebPage.url.toString()) registerAndCleanupIdlingResources( RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 3), ) { @@ -568,14 +515,12 @@ class BookmarksTest { bookmarksMenu { verifyDeleteMultipleBookmarksSnackBar() - clickUndoDeleteButton() - verifyBookmarkedURL(firstWebPage.url.toString()) - verifyBookmarkedURL(secondWebPage.url.toString()) } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2301355 @Test - fun multipleSelectionShareButtonTest() { + fun shareMultipleSelectedBookmarksTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) browserScreen { @@ -598,43 +543,9 @@ class BookmarksTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325639 @Test - fun multipleBookmarkDeletionsTest() { - 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() { + fun createBookmarkFolderTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) browserScreen { @@ -643,13 +554,13 @@ class BookmarksTest { }.openBookmarks { registerAndCleanupIdlingResources( RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2), - ) { - createFolder(bookmarksFolderName) - } + ) {} }.openThreeDotMenu(defaultWebPage.title) { }.clickEdit { clickParentFolderSelector() - selectFolder(bookmarksFolderName) + clickAddNewFolderButtonFromSelectFolderView() + addNewFolderName(bookmarksFolderName) + saveNewFolder() navigateUp() saveEditBookmark() selectFolder(bookmarksFolderName) @@ -657,6 +568,7 @@ class BookmarksTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/325645 @Test fun navigateBookmarksFoldersTest() { homeScreen { @@ -680,8 +592,9 @@ class BookmarksTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/374855 @Test - fun cantSelectDesktopFoldersTest() { + fun cantSelectDefaultFoldersTest() { homeScreen { }.openThreeDotMenu { }.openBookmarks { @@ -694,16 +607,7 @@ class BookmarksTest { } } - @Test - fun verifyCloseMenuTest() { - homeScreen { - }.openThreeDotMenu { - }.openBookmarks { - }.closeMenu { - verifyHomeScreen() - } - } - + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2299703 @Test fun deleteBookmarkInEditModeTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) @@ -726,31 +630,7 @@ class BookmarksTest { } } - @SmokeTest - @Test - fun undoDeleteBookmarkFolderTest() { - browserScreen { - }.openThreeDotMenu { - }.openBookmarks { - registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1), - ) { - createFolder("My Folder") - verifyFolderTitle("My Folder") - } - }.openThreeDotMenu("My Folder") { - }.clickDelete { - cancelFolderDeletion() - verifyFolderTitle("My Folder") - }.openThreeDotMenu("My Folder") { - }.clickDelete { - confirmDeletion() - verifyDeleteSnackBarText() - clickUndoDeleteButton() - verifyFolderTitle("My Folder") - } - } - + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715710 @Test fun verifySearchBookmarksViewTest() { 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 fun verifySearchForBookmarkedItemsTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) @@ -803,13 +684,13 @@ class BookmarksTest { // Search for a valid term typeSearch(firstWebPage.title) verifySearchEngineSuggestionResults(activityTestRule, firstWebPage.url.toString(), searchTerm = firstWebPage.title) - verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString()) }.dismissSearchBar {} bookmarksMenu { }.clickSearchButton { // Search for invalid term typeSearch("Android") - verifyNoSuggestionsAreDisplayed( + verifySuggestionsAreNotDisplayed( activityTestRule, firstWebPage.url.toString(), secondWebPage.url.toString(), @@ -817,6 +698,7 @@ class BookmarksTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715711 @Test fun verifyVoiceSearchInBookmarksTest() { 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 - fun verifyDeletedBookmarksCanNotBeSearchedTest() { + fun verifyDeletedBookmarksAreNotDisplayedAsSearchResultsTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) val thirdWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3) @@ -853,8 +736,8 @@ class BookmarksTest { }.clickSearchButton { // Search for a valid term typeSearch("generic") - verifyNoSuggestionsAreDisplayed(activityTestRule, firstWebPage.url.toString()) - verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString()) verifySearchEngineSuggestionResults(activityTestRule, thirdWebPage.url.toString(), searchTerm = "generic") pressBack() } @@ -865,7 +748,54 @@ class BookmarksTest { }.clickSearchButton { // Search for a valid term 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") } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt index ad0572471..fd34537b0 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt @@ -15,6 +15,7 @@ import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityIntentTestRule +import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton 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 @Test fun verifyExpandedCollectionItemsTest() { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeBookmarksTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeBookmarksTest.kt index 82bfc6010..e4fe0e4a8 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeBookmarksTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeBookmarksTest.kt @@ -24,7 +24,6 @@ import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.RecyclerViewIdlingResource import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestAssetHelper -import org.mozilla.fenix.helpers.TestHelper import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem @@ -91,18 +90,6 @@ class ComposeBookmarksTest { verifyAddFolderButton() verifyCloseButton() verifyBookmarkTitle("Desktop Bookmarks") - } - } - } - - @Test - fun defaultDesktopBookmarksFoldersTest() { - homeScreen { - }.openThreeDotMenu { - }.openBookmarks { - registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 1), - ) { selectFolder("Desktop Bookmarks") verifyFolderTitle("Bookmarks Menu") 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 fun cancelCreateBookmarkFolderTest() { homeScreen { @@ -175,9 +114,8 @@ class ComposeBookmarksTest { } } - @SmokeTest @Test - fun cancelEditBookmarkTest() { + fun cancelingChangesInEditModeAreNotSavedTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -202,7 +140,7 @@ class ComposeBookmarksTest { @SmokeTest @Test - fun editBookmarkTest() { + fun editBookmarksNameAndUrlTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) browserScreen { @@ -292,7 +230,7 @@ class ComposeBookmarksTest { } @Test - fun openAllInTabsTest() { + fun verifyOpenAllInNewTabsOptionTest() { val webPages = listOf( TestAssetHelper.getGenericAsset(mockWebServer, 1), TestAssetHelper.getGenericAsset(mockWebServer, 2), @@ -334,7 +272,7 @@ class ComposeBookmarksTest { } @Test - fun openAllInPrivateTabsTest() { + fun verifyOpenAllInPrivateTabsTest() { val webPages = listOf( TestAssetHelper.getGenericAsset(mockWebServer, 1), TestAssetHelper.getGenericAsset(mockWebServer, 2), @@ -386,30 +324,10 @@ class ComposeBookmarksTest { } } - @SmokeTest @Test fun deleteBookmarkTest() { 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 { createBookmark(defaultWebPage.url) }.openThreeDotMenu { @@ -427,10 +345,12 @@ class ComposeBookmarksTest { ) { verifyBookmarkedURL(defaultWebPage.url.toString()) } + }.openThreeDotMenu(defaultWebPage.title) { + }.clickDelete { + verifyBookmarkIsDeleted(defaultWebPage.title) } } - @SmokeTest @Test fun bookmarksMultiSelectionToolbarItemsTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) @@ -458,7 +378,7 @@ class ComposeBookmarksTest { @SmokeTest @Test - fun openSelectionInNewTabTest() { + fun openMultipleSelectedBookmarksInANewTabTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) browserScreen { @@ -486,9 +406,8 @@ class ComposeBookmarksTest { } } - @SmokeTest @Test - fun openSelectionInPrivateTabTest() { + fun openMultipleSelectedBookmarksInPrivateTabTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) browserScreen { @@ -512,7 +431,7 @@ class ComposeBookmarksTest { @SmokeTest @Test - fun deleteMultipleSelectionTest() { + fun deleteMultipleSelectedBookmarksTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) @@ -536,20 +455,9 @@ class ComposeBookmarksTest { bookmarksMenu { verifyDeleteMultipleBookmarksSnackBar() - } - } - - @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 { + clickUndoDeleteButton() + verifyBookmarkedURL(firstWebPage.url.toString()) + verifyBookmarkedURL(secondWebPage.url.toString()) registerAndCleanupIdlingResources( RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 3), ) { @@ -565,9 +473,6 @@ class ComposeBookmarksTest { bookmarksMenu { verifyDeleteMultipleBookmarksSnackBar() - clickUndoDeleteButton() - verifyBookmarkedURL(firstWebPage.url.toString()) - verifyBookmarkedURL(secondWebPage.url.toString()) } } @@ -596,42 +501,7 @@ class ComposeBookmarksTest { } @Test - fun multipleBookmarkDeletionsTest() { - 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() { + fun createBookmarkFolderTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) browserScreen { @@ -640,13 +510,13 @@ class ComposeBookmarksTest { }.openBookmarks { registerAndCleanupIdlingResources( RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list), 2), - ) { - createFolder(bookmarksFolderName) - } + ) {} }.openThreeDotMenu(defaultWebPage.title) { }.clickEdit { clickParentFolderSelector() - selectFolder(bookmarksFolderName) + clickAddNewFolderButtonFromSelectFolderView() + addNewFolderName(bookmarksFolderName) + saveNewFolder() navigateUp() saveEditBookmark() selectFolder(bookmarksFolderName) @@ -691,16 +561,6 @@ class ComposeBookmarksTest { } } - @Test - fun verifyCloseMenuTest() { - homeScreen { - }.openThreeDotMenu { - }.openBookmarks { - }.closeMenu { - verifyHomeScreen() - } - } - @Test fun deleteBookmarkInEditModeTest() { 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 fun verifySearchBookmarksViewTest() { 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 fun verifySearchForBookmarkedItemsTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) @@ -810,11 +646,11 @@ class ComposeBookmarksTest { // Search for a valid term typeSearch(firstWebPage.title) verifySearchEngineSuggestionResults(activityTestRule, firstWebPage.url.toString(), searchTerm = firstWebPage.title) - verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString()) // Search for invalid term typeSearch("Android") - verifyNoSuggestionsAreDisplayed(activityTestRule, firstWebPage.url.toString()) - verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.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 - fun verifyDeletedBookmarksCanNotBeSearchedTest() { + fun verifyDeletedBookmarksAreNotDisplayedAsSearchResultsTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) val thirdWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3) @@ -854,8 +691,8 @@ class ComposeBookmarksTest { }.clickSearchButton { // Search for a valid term typeSearch("generic") - verifyNoSuggestionsAreDisplayed(activityTestRule, firstWebPage.url.toString()) - verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString()) verifySearchEngineSuggestionResults(activityTestRule, thirdWebPage.url.toString(), searchTerm = "generic") pressBack() } @@ -866,7 +703,55 @@ class ComposeBookmarksTest { }.clickSearchButton { // Search for a valid term 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() } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeContextMenusTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeContextMenusTest.kt index 83528d0ab..ee18d45fd 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeContextMenusTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeContextMenusTest.kt @@ -15,12 +15,13 @@ import org.junit.Rule import org.junit.Test import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.AndroidAssetDispatcher +import org.mozilla.fenix.helpers.Constants import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemWithText import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestAssetHelper -import org.mozilla.fenix.helpers.TestHelper.assertYoutubeAppOpens +import org.mozilla.fenix.helpers.TestHelper.assertExternalAppOpens import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.ui.robots.clickContextMenuItem import org.mozilla.fenix.ui.robots.clickPageObject @@ -235,7 +236,7 @@ class ComposeContextMenusTest { } downloadRobot { - verifyDownloadNotificationPopup() + verifyDownloadCompleteNotificationPopup() }.clickOpen("image/jpeg") {} // verify open intent is matched with associated data type downloadRobot { verifyPhotosAppOpens() @@ -291,9 +292,10 @@ class ComposeContextMenusTest { navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { - longClickPageObject(itemContainingText("Youtube link")) + longClickPageObject(itemContainingText("Youtube full link")) + verifyContextMenuForLinksToOtherApps("youtube.com") clickContextMenuItem("Open link in external app") - assertYoutubeAppOpens() + assertExternalAppOpens(Constants.PackageName.YOUTUBE_APP) } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHistoryTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHistoryTest.kt index 92b1e1d45..7ad95d13e 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHistoryTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHistoryTest.kt @@ -75,7 +75,7 @@ class ComposeHistoryTest { } @Test - fun noHistoryItemsInCacheTest() { + fun verifyEmptyHistoryMenuTest() { homeScreen { }.openThreeDotMenu { verifyHistoryButton() @@ -87,8 +87,9 @@ class ComposeHistoryTest { // Test running on beta/release builds in CI: // caution when making changes to it, so they don't block the builds + @SmokeTest @Test - fun visitedUrlHistoryTest() { + fun verifyHistoryMenuWithHistoryItemsTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -104,6 +105,7 @@ class ComposeHistoryTest { verifyVisitedTimeTitle() verifyFirstTestPageTitle("Test_Page_1") 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 @Test fun deleteAllHistoryTest() { @@ -226,7 +184,7 @@ class ComposeHistoryTest { @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268") @Test - fun openHistoryInNewTabTest() { + fun openMultipleSelectedHistoryItemsInANewTabTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -255,7 +213,7 @@ class ComposeHistoryTest { } @Test - fun openHistoryInPrivateTabTest() { + fun openMultipleSelectedHistoryItemsInPrivateTabTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -280,7 +238,7 @@ class ComposeHistoryTest { } @Test - fun deleteMultipleSelectionTest() { + fun deleteMultipleSelectedHistoryItemsTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) @@ -314,7 +272,7 @@ class ComposeHistoryTest { } @Test - fun shareButtonTest() { + fun shareMultipleSelectedHistoryItemsTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -409,12 +367,12 @@ class ComposeHistoryTest { // Search for a valid term typeSearch(firstWebPage.title) verifySearchEngineSuggestionResults(activityTestRule, firstWebPage.url.toString(), searchTerm = firstWebPage.title) - verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString()) clickClearButton() // Search for invalid term typeSearch("Android") - verifyNoSuggestionsAreDisplayed(activityTestRule, firstWebPage.url.toString()) - verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString()) } } @@ -445,8 +403,8 @@ class ComposeHistoryTest { }.clickSearchButton { // Search for a valid term typeSearch("generic") - verifyNoSuggestionsAreDisplayed(activityTestRule, firstWebPage.url.toString()) - verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString()) verifySearchEngineSuggestionResults(activityTestRule, thirdWebPage.url.toString(), searchTerm = "generic") pressBack() } @@ -456,7 +414,7 @@ class ComposeHistoryTest { }.clickSearchButton { // Search for a valid term typeSearch("generic") - verifyNoSuggestionsAreDisplayed(activityTestRule, thirdWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, thirdWebPage.url.toString()) } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHomeScreenTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHomeScreenTest.kt index 5a620ea0c..f9e350dcc 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHomeScreenTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHomeScreenTest.kt @@ -63,7 +63,6 @@ class ComposeHomeScreenTest { @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1844580") @Test fun homeScreenItemsTest() { - homeScreen {}.dismissOnboarding() homeScreen { verifyHomeWordmark() verifyHomePrivateBrowsingButton() @@ -86,7 +85,6 @@ class ComposeHomeScreenTest { // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/244199 @Test fun privateBrowsingHomeScreenItemsTest() { - homeScreen { }.dismissOnboarding() homeScreen { }.togglePrivateBrowsingMode() homeScreen { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeNavigationToolbarTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeNavigationToolbarTest.kt index 6a1644c1e..35a912596 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeNavigationToolbarTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeNavigationToolbarTest.kt @@ -5,7 +5,6 @@ package org.mozilla.fenix.ui import androidx.compose.ui.test.junit4.AndroidComposeTestRule -import androidx.core.net.toUri import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import okhttp3.mockwebserver.MockWebServer @@ -16,11 +15,8 @@ import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityTestRule -import org.mozilla.fenix.helpers.MatcherHelper.itemWithText import org.mozilla.fenix.helpers.TestAssetHelper 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 java.util.Locale @@ -60,51 +56,6 @@ class ComposeNavigationToolbarTest { 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 @SmokeTest @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) - } - } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSearchTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSearchTest.kt index 387380fcd..0a4ceaafa 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSearchTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSearchTest.kt @@ -666,7 +666,7 @@ class ComposeSearchTest { clickSearchSelectorButton() selectTemporarySearchMethod(searchEngineName = "Tabs") typeSearch(searchTerm = "Mozilla") - verifyNoSuggestionsAreDisplayed(rule = activityTestRule, "Mozilla") + verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla") clickClearButton() verifySearchBarPlaceholder("Search tabs") } @@ -686,7 +686,7 @@ class ComposeSearchTest { clickSearchSelectorButton() selectTemporarySearchMethod(searchEngineName = "Tabs") typeSearch(searchTerm = "Mozilla") - verifyNoSuggestionsAreDisplayed(rule = activityTestRule, "Mozilla") + verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla") clickClearButton() typeSearch(searchTerm = "generic") verifyTypedToolbarText("generic") @@ -725,7 +725,7 @@ class ComposeSearchTest { }.clickSearchSelectorButton { selectTemporarySearchMethod("Bookmarks") typeSearch("test") - verifyNoSuggestionsAreDisplayed(activityTestRule, "test") + verifySuggestionsAreNotDisplayed(activityTestRule, "test") } } @@ -752,7 +752,7 @@ class ComposeSearchTest { }.dismissSearchBar { }.openSearch { typeSearch("mozilla ") - verifyNoSuggestionsAreDisplayed(activityTestRule, "Test1", "Test2") + verifySuggestionsAreNotDisplayed(activityTestRule, "Test1", "Test2") } } @@ -776,7 +776,7 @@ class ComposeSearchTest { clickSearchSelectorButton() selectTemporarySearchMethod(searchEngineName = "History") typeSearch(searchTerm = "Mozilla") - verifyNoSuggestionsAreDisplayed(rule = activityTestRule, "Mozilla") + verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla") clickClearButton() verifySearchBarPlaceholder("Search history") } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataOnQuitTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataOnQuitTest.kt index 57ce9115a..4ed0adadb 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataOnQuitTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataOnQuitTest.kt @@ -68,7 +68,7 @@ class ComposeSettingsDeleteBrowsingDataOnQuitTest { } @Test - fun deleteBrowsingDataOnQuitSettingsItemsTest() { + fun deleteBrowsingDataOnQuitSettingTest() { homeScreen { }.openThreeDotMenu { }.openSettings { @@ -120,7 +120,7 @@ class ComposeSettingsDeleteBrowsingDataOnQuitTest { } @Test - fun deleteHistoryOnQuitTest() { + fun deleteBrowsingHistoryOnQuitTest() { val genericPage = getStorageTestAsset(mockWebServer, "generic1.html") @@ -147,6 +147,7 @@ class ComposeSettingsDeleteBrowsingDataOnQuitTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416051 @Test fun deleteCookiesAndSiteDataOnQuitTest() { val storageWritePage = @@ -198,7 +199,7 @@ class ComposeSettingsDeleteBrowsingDataOnQuitTest { }.clickDownloadLink("smallZip.zip") { verifyDownloadPrompt("smallZip.zip") }.clickDownload { - verifyDownloadNotificationPopup() + verifyDownloadCompleteNotificationPopup() }.closeCompletedDownloadPrompt { }.goToHomescreen { }.openThreeDotMenu { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataTest.kt index 78f777eaf..7b092bbb5 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataTest.kt @@ -117,7 +117,7 @@ class ComposeSettingsDeleteBrowsingDataTest { } @Test - fun deleteTabsDataWithNoOpenTabsTest() { + fun deleteOpenTabsBrowsingDataWithNoOpenTabsTest() { homeScreen { }.openThreeDotMenu { }.openSettings { @@ -135,7 +135,7 @@ class ComposeSettingsDeleteBrowsingDataTest { @SmokeTest @Test - fun deleteTabsDataTest() { + fun deleteOpenTabsBrowsingDataTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSmokeTest.kt index 8adf0f1c2..d4a9cbcc9 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSmokeTest.kt @@ -1,384 +1,238 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -@file:Suppress("DEPRECATION") - -package org.mozilla.fenix.ui - -import android.view.View -import androidx.compose.ui.test.junit4.AndroidComposeTestRule -import androidx.core.net.toUri -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.rule.ActivityTestRule -import androidx.test.uiautomator.UiDevice -import mozilla.components.browser.state.store.BrowserStore -import mozilla.components.concept.engine.mediasession.MediaSession -import okhttp3.mockwebserver.MockWebServer -import org.junit.After -import org.junit.Before -import org.junit.Ignore -import org.junit.Rule -import org.junit.Test -import org.mozilla.fenix.IntentReceiverActivity -import org.mozilla.fenix.R -import org.mozilla.fenix.customannotations.SmokeTest -import org.mozilla.fenix.ext.components -import org.mozilla.fenix.helpers.AndroidAssetDispatcher -import org.mozilla.fenix.helpers.HomeActivityIntentTestRule -import org.mozilla.fenix.helpers.MatcherHelper.itemWithText -import org.mozilla.fenix.helpers.RetryTestRule -import org.mozilla.fenix.helpers.TestAssetHelper -import org.mozilla.fenix.helpers.TestHelper.assertYoutubeAppOpens -import org.mozilla.fenix.helpers.TestHelper.registerAndCleanupIdlingResources -import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource -import org.mozilla.fenix.ui.robots.browserScreen -import org.mozilla.fenix.ui.robots.clickPageObject -import org.mozilla.fenix.ui.robots.homeScreen -import org.mozilla.fenix.ui.robots.navigationToolbar - -/** - * Test Suite that contains a part of the Smoke and Sanity tests defined in TestRail: - * https://testrail.stage.mozaws.net/index.php?/suites/view/3192 - * Other smoke tests have been marked with the @SmokeTest annotation throughout the ui package in order to limit this class expansion. - * These tests will verify different functionalities of the app as a way to quickly detect regressions in main areas - */ -@Suppress("ForbiddenComment") -@SmokeTest -class ComposeSmokeTest { - private lateinit var mDevice: UiDevice - private lateinit var mockWebServer: MockWebServer - private val customMenuItem = "TestMenuItem" - private lateinit var browserStore: BrowserStore - - @get:Rule(order = 0) - val activityTestRule = AndroidComposeTestRule( - HomeActivityIntentTestRule.withDefaultSettingsOverrides( - tabsTrayRewriteEnabled = true, - ), - ) { it.activity } - - @get: Rule(order = 1) - val intentReceiverActivityTestRule = ActivityTestRule( - IntentReceiverActivity::class.java, - true, - false, - ) - - @Rule(order = 2) - @JvmField - val retryTestRule = RetryTestRule(3) - - @Before - fun setUp() { - // Initializing this as part of class construction, below the rule would throw a NPE - // So we are initializing this here instead of in all related tests. - browserStore = activityTestRule.activity.components.core.store - - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - } - - // Device or AVD requires a Google Services Android OS installation with Play Store installed - // Verifies the Open in app button when an app is installed - @Test - fun mainMenuOpenInAppTest() { - val youtubeURL = "vnd.youtube://".toUri() - - navigationToolbar { - }.enterURLAndEnterToBrowser(youtubeURL) { - verifyNotificationDotOnMainMenu() - }.openThreeDotMenu { - }.clickOpenInApp { - assertYoutubeAppOpens() - } - } - - // Verifies that deleting a Bookmarks folder also removes the item from inside it. - @Test - fun deleteNonEmptyBookmarkFolderTest() { - 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() - verifyBookmarkIsDeleted("My Folder") - verifyBookmarkIsDeleted("My Folder 2") - verifyBookmarkIsDeleted("Test_Page_1") - navigateUp() - } - - browserScreen { - }.openThreeDotMenu { - verifyAddBookmarkButton() - } - } - - @Test - fun shareTabsFromTabsTrayTest() { - val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1) - val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2) - val firstWebsiteTitle = firstWebsite.title - val secondWebsiteTitle = secondWebsite.title - val sharingApp = "Gmail" - val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}" - - homeScreen { - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(firstWebsite.url) { - verifyPageContent(firstWebsite.content) - }.openComposeTabDrawer(activityTestRule) { - }.openNewTab { - }.submitQuery(secondWebsite.url.toString()) { - verifyPageContent(secondWebsite.content) - }.openComposeTabDrawer(activityTestRule) { - verifyExistingOpenTabs("Test_Page_1") - verifyExistingOpenTabs("Test_Page_2") - }.openThreeDotMenu { - verifyShareAllTabsButton() - }.clickShareAllTabsButton { - verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle) - verifySharingWithSelectedApp( - sharingApp, - sharedUrlsString, - "$firstWebsiteTitle, $secondWebsiteTitle", - ) - } - } - - @Test - fun privateTabsTrayWithOpenedTabTest() { - val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) - - homeScreen { - }.togglePrivateBrowsingMode() - - homeScreen { - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(website.url) { - }.openComposeTabDrawer(activityTestRule) { - verifyNormalBrowsingButtonIsSelected(false) - verifyPrivateBrowsingButtonIsSelected(true) - verifySyncedTabsButtonIsSelected(false) - verifyThreeDotButton() - verifyNormalTabCounter() - verifyPrivateTabsList() - verifyExistingOpenTabs(website.title) - verifyTabCloseButton() - verifyTabThumbnail() - verifyFab() - } - } - - // Test running on beta/release builds in CI: - // caution when making changes to it, so they don't block the builds - @Test - fun noHistoryInPrivateBrowsingTest() { - val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) - - homeScreen { - }.togglePrivateBrowsingMode() - - homeScreen { - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(website.url) { - mDevice.waitForIdle() - }.openThreeDotMenu { - }.openHistory { - verifyEmptyHistoryView() - } - } - - @Test - fun mainMenuInstallPWATest() { - val pwaPage = "https://mozilla-mobile.github.io/testapp/" - - navigationToolbar { - }.enterURLAndEnterToBrowser(pwaPage.toUri()) { - verifyNotificationDotOnMainMenu() - }.openThreeDotMenu { - }.clickInstall { - clickAddAutomaticallyButton() - }.openHomeScreenShortcut("TEST_APP") { - mDevice.waitForIdle() - verifyNavURLBarHidden() - } - } - - // Verifies that reader mode is detected and the custom appearance controls are displayed - @Test - fun verifyReaderViewAppearanceUI() { - val readerViewPage = - TestAssetHelper.getLoremIpsumAsset(mockWebServer) - val estimatedReadingTime = "1 - 2 minutes" - - navigationToolbar { - }.enterURLAndEnterToBrowser(readerViewPage.url) { - mDevice.waitForIdle() - } - - registerAndCleanupIdlingResources( - ViewVisibilityIdlingResource( - activityTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions), - View.VISIBLE, - ), - ) {} - - navigationToolbar { - verifyReaderViewDetected(true) - toggleReaderView() - } - - browserScreen { - waitForPageToLoad() - verifyPageContent(estimatedReadingTime) - }.openThreeDotMenu { - verifyReaderViewAppearance(true) - }.openReaderViewAppearance { - verifyAppearanceFontGroup(true) - verifyAppearanceFontSansSerif(true) - verifyAppearanceFontSerif(true) - verifyAppearanceFontIncrease(true) - verifyAppearanceFontDecrease(true) - verifyAppearanceColorGroup(true) - verifyAppearanceColorDark(true) - verifyAppearanceColorLight(true) - verifyAppearanceColorSepia(true) - } - } - - @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() - } - } -} +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +@file:Suppress("DEPRECATION") + +package org.mozilla.fenix.ui + +import android.view.View +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.core.net.toUri +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.rule.ActivityTestRule +import androidx.test.uiautomator.UiDevice +import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.concept.engine.mediasession.MediaSession +import okhttp3.mockwebserver.MockWebServer +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mozilla.fenix.IntentReceiverActivity +import org.mozilla.fenix.R +import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.ext.components +import org.mozilla.fenix.helpers.AndroidAssetDispatcher +import org.mozilla.fenix.helpers.HomeActivityIntentTestRule +import org.mozilla.fenix.helpers.MatcherHelper.itemWithText +import org.mozilla.fenix.helpers.RetryTestRule +import org.mozilla.fenix.helpers.TestAssetHelper +import org.mozilla.fenix.helpers.TestHelper.registerAndCleanupIdlingResources +import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource +import org.mozilla.fenix.ui.robots.browserScreen +import org.mozilla.fenix.ui.robots.clickPageObject +import org.mozilla.fenix.ui.robots.homeScreen +import org.mozilla.fenix.ui.robots.navigationToolbar + +/** + * Test Suite that contains a part of the Smoke and Sanity tests defined in TestRail: + * https://testrail.stage.mozaws.net/index.php?/suites/view/3192 + * Other smoke tests have been marked with the @SmokeTest annotation throughout the ui package in order to limit this class expansion. + * These tests will verify different functionalities of the app as a way to quickly detect regressions in main areas + */ +@Suppress("ForbiddenComment") +@SmokeTest +class ComposeSmokeTest { + private lateinit var mDevice: UiDevice + private lateinit var mockWebServer: MockWebServer + private val customMenuItem = "TestMenuItem" + private lateinit var browserStore: BrowserStore + + @get:Rule(order = 0) + val activityTestRule = AndroidComposeTestRule( + HomeActivityIntentTestRule.withDefaultSettingsOverrides( + tabsTrayRewriteEnabled = true, + ), + ) { it.activity } + + @get: Rule(order = 1) + val intentReceiverActivityTestRule = ActivityTestRule( + IntentReceiverActivity::class.java, + true, + false, + ) + + @Rule(order = 2) + @JvmField + val retryTestRule = RetryTestRule(3) + + @Before + fun setUp() { + // Initializing this as part of class construction, below the rule would throw a NPE + // So we are initializing this here instead of in all related tests. + browserStore = activityTestRule.activity.components.core.store + + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + start() + } + } + + @After + fun tearDown() { + mockWebServer.shutdown() + } + + @Test + fun shareTabsFromTabsTrayTest() { + val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1) + val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2) + val firstWebsiteTitle = firstWebsite.title + val secondWebsiteTitle = secondWebsite.title + val sharingApp = "Gmail" + val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}" + + homeScreen { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(firstWebsite.url) { + verifyPageContent(firstWebsite.content) + }.openComposeTabDrawer(activityTestRule) { + }.openNewTab { + }.submitQuery(secondWebsite.url.toString()) { + verifyPageContent(secondWebsite.content) + }.openComposeTabDrawer(activityTestRule) { + verifyExistingOpenTabs("Test_Page_1") + verifyExistingOpenTabs("Test_Page_2") + }.openThreeDotMenu { + verifyShareAllTabsButton() + }.clickShareAllTabsButton { + verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle) + verifySharingWithSelectedApp( + sharingApp, + sharedUrlsString, + "$firstWebsiteTitle, $secondWebsiteTitle", + ) + } + } + + @Test + fun privateTabsTrayWithOpenedTabTest() { + val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) + + homeScreen { + }.togglePrivateBrowsingMode() + + homeScreen { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(website.url) { + }.openComposeTabDrawer(activityTestRule) { + verifyNormalBrowsingButtonIsSelected(false) + verifyPrivateBrowsingButtonIsSelected(true) + verifySyncedTabsButtonIsSelected(false) + verifyThreeDotButton() + verifyNormalTabCounter() + verifyPrivateTabsList() + verifyExistingOpenTabs(website.title) + verifyTabCloseButton() + verifyTabThumbnail() + verifyFab() + } + } + + // Test running on beta/release builds in CI: + // caution when making changes to it, so they don't block the builds + @Test + fun noHistoryInPrivateBrowsingTest() { + val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) + + homeScreen { + }.togglePrivateBrowsingMode() + + homeScreen { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(website.url) { + mDevice.waitForIdle() + }.openThreeDotMenu { + }.openHistory { + verifyEmptyHistoryView() + } + } + + @Test + fun mainMenuInstallPWATest() { + val pwaPage = "https://mozilla-mobile.github.io/testapp/" + + navigationToolbar { + }.enterURLAndEnterToBrowser(pwaPage.toUri()) { + verifyNotificationDotOnMainMenu() + }.openThreeDotMenu { + }.clickInstall { + clickAddAutomaticallyButton() + }.openHomeScreenShortcut("TEST_APP") { + mDevice.waitForIdle() + verifyNavURLBarHidden() + } + } + + // Verifies that reader mode is detected and the custom appearance controls are displayed + @Test + fun verifyReaderViewAppearanceUI() { + val readerViewPage = + TestAssetHelper.getLoremIpsumAsset(mockWebServer) + val estimatedReadingTime = "1 - 2 minutes" + + navigationToolbar { + }.enterURLAndEnterToBrowser(readerViewPage.url) { + mDevice.waitForIdle() + } + + registerAndCleanupIdlingResources( + ViewVisibilityIdlingResource( + activityTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions), + View.VISIBLE, + ), + ) {} + + navigationToolbar { + verifyReaderViewDetected(true) + toggleReaderView() + } + + browserScreen { + waitForPageToLoad() + verifyPageContent(estimatedReadingTime) + }.openThreeDotMenu { + verifyReaderViewAppearance(true) + }.openReaderViewAppearance { + verifyAppearanceFontGroup(true) + verifyAppearanceFontSansSerif(true) + verifyAppearanceFontSerif(true) + verifyAppearanceFontIncrease(true) + verifyAppearanceFontDecrease(true) + verifyAppearanceColorGroup(true) + verifyAppearanceColorDark(true) + verifyAppearanceColorLight(true) + verifyAppearanceColorSepia(true) + } + } + + @Test + fun tabMediaControlButtonTest() { + val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer) + + navigationToolbar { + }.enterURLAndEnterToBrowser(audioTestPage.url) { + mDevice.waitForIdle() + clickPageObject(itemWithText("Play")) + assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) + }.openComposeTabDrawer(activityTestRule) { + verifyTabMediaControlButtonState("Pause") + clickTabMediaControlButton("Pause") + verifyTabMediaControlButtonState("Play") + }.openTab(audioTestPage.title) { + assertPlaybackState(browserStore, MediaSession.PlaybackState.PAUSED) + } + } +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeTopSitesTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeTopSitesTest.kt new file mode 100644 index 000000000..5b953f930 --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeTopSitesTest.kt @@ -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() + } + } +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt index 7cdfe00e1..edc4b5d48 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt @@ -15,12 +15,13 @@ import org.junit.Rule import org.junit.Test import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.AndroidAssetDispatcher +import org.mozilla.fenix.helpers.Constants.PackageName.YOUTUBE_APP import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemWithText import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestAssetHelper -import org.mozilla.fenix.helpers.TestHelper.assertYoutubeAppOpens +import org.mozilla.fenix.helpers.TestHelper.assertExternalAppOpens import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.ui.robots.clickContextMenuItem import org.mozilla.fenix.ui.robots.clickPageObject @@ -231,7 +232,7 @@ class ContextMenusTest { } downloadRobot { - verifyDownloadNotificationPopup() + verifyDownloadCompleteNotificationPopup() }.clickOpen("image/jpeg") {} // verify open intent is matched with associated data type downloadRobot { verifyPhotosAppOpens() @@ -287,10 +288,10 @@ class ContextMenusTest { navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { - longClickPageObject(itemContainingText("Youtube link")) - verifyContextMenuForLinksToOtherApps("youtube.com".toUri()) + longClickPageObject(itemContainingText("Youtube full link")) + verifyContextMenuForLinksToOtherApps("youtube.com") clickContextMenuItem("Open link in external app") - assertYoutubeAppOpens() + assertExternalAppOpens(YOUTUBE_APP) } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerReductionTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerReductionTest.kt index 5dbf3e417..72176cea7 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerReductionTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerReductionTest.kt @@ -14,17 +14,17 @@ import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.restartApp import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.homeScreen -import org.mozilla.fenix.ui.robots.navigationToolbar class CookieBannerReductionTest { @get:Rule 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 @Ignore("Disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1852803") @SmokeTest @Test - fun verifyCookieBannerReductionTest() { + fun verifyCookieBannerReductionFunctionalityTest() { val webSite = "startsiden.no" homeScreen { @@ -69,55 +69,4 @@ class CookieBannerReductionTest { 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) - } - } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt index 46c8557eb..0afcf7d06 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt @@ -62,6 +62,7 @@ class CreditCardAutofillTest { mockWebServer.shutdown() } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512792 @SmokeTest @Test fun verifyCreditCardAutofillTest() { @@ -99,32 +100,10 @@ class CreditCardAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512798 @SmokeTest @Test 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 { }.openThreeDotMenu { }.openSettings { @@ -142,35 +121,16 @@ class CreditCardAutofillTest { clickDeleteCreditCardToolbarButton() clickCancelDeleteCreditCardButton() verifyEditCreditCardToolbarTitle() - } - } - - @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() + clickDeleteCreditCardToolbarButton() clickConfirmDeleteCreditCardButton() verifyAddCreditCardsButton() } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2271192 @SmokeTest @Test - fun cancelDeleteSavedCreditCardUsingMenuButtonTest() { + fun deleteSavedCreditCardUsingMenuButtonTest() { homeScreen { }.openThreeDotMenu { }.openSettings { @@ -188,9 +148,13 @@ class CreditCardAutofillTest { clickDeleteCreditCardMenuButton() clickCancelDeleteCreditCardButton() verifyEditCreditCardToolbarTitle() + clickDeleteCreditCardMenuButton() + clickConfirmDeleteCreditCardButton() + verifyAddCreditCardsButton() } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512788 @Test fun verifyCreditCardsSectionTest() { homeScreen { @@ -214,6 +178,7 @@ class CreditCardAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1859917 @Test fun verifyManageCreditCardsPromptOptionTest() { val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) @@ -243,6 +208,7 @@ class CreditCardAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512790 @Test fun verifyCreditCardsAutofillToggleTest() { val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) @@ -283,6 +249,7 @@ class CreditCardAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512795 @Test fun verifyEditCardsViewTest() { homeScreen { @@ -318,6 +285,7 @@ class CreditCardAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512796 @Test fun verifyEditedCardIsSavedTest() { val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) @@ -365,8 +333,9 @@ class CreditCardAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512797 @Test - fun verifyCreditCardCannotBeSavedWithoutCardNumberTest() { + fun verifyCreditCardCannotBeSavedWithoutCardNumberOrNameTest() { homeScreen { }.openThreeDotMenu { }.openSettings { @@ -390,29 +359,7 @@ class CreditCardAutofillTest { clickSaveCreditCardToolbarButton() verifyEditCreditCardToolbarTitle() verifyCreditCardNumberErrorMessage() - } - } - - @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, - ) + }.goBackToSavedCreditCards { clickSavedCreditCard() clearNameOnCreditCard() clickSaveCreditCardToolbarButton() @@ -421,8 +368,9 @@ class CreditCardAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512794 @Test - fun verifyMultipleCreditCardsCanBeSavedTest() { + fun verifyMultipleCreditCardsCanBeAddedTest() { val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) homeScreen { @@ -476,8 +424,9 @@ class CreditCardAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2271304 @Test - fun verifyDoNotSaveCreditCardFromFormTest() { + fun verifyDoNotSaveCreditCardFromPromptTest() { val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) navigationToolbar { @@ -496,8 +445,9 @@ class CreditCardAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1779194 @Test - fun verifySaveCreditCardFromFormTest() { + fun verifySaveCreditCardFromPromptTest() { val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) navigationToolbar { @@ -522,6 +472,7 @@ class CreditCardAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2271305 @Test fun verifyCancelCreditCardUpdatePromptTest() { val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) @@ -572,6 +523,7 @@ class CreditCardAutofillTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1779195 @Test fun verifyConfirmCreditCardUpdatePromptTest() { 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 - fun verifySavedCreditCardsRedirectionToAutofillAfterInterruptionTest() { + fun verifyCreditCardRedirectionsToAutofillSectionAfterInterruptionTest() { homeScreen { }.openThreeDotMenu { }.openSettings { @@ -639,33 +592,15 @@ class CreditCardAutofillTest { ) clickManageSavedCreditCardsButton() clickSecuredCreditCardsLaterButton() - verifySavedCreditCardsSection( - MockCreditCard1.MOCK_LAST_CARD_DIGITS, - MockCreditCard1.MOCK_EXPIRATION_MONTH_AND_YEAR, - ) + clickSavedCreditCard() putAppToBackground() bringAppToForeground() 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() - clickSecuredCreditCardsLaterButton() - clickSavedCreditCard() + verifySavedCreditCardsSection( + MockCreditCard1.MOCK_LAST_CARD_DIGITS, + MockCreditCard1.MOCK_EXPIRATION_MONTH_AND_YEAR, + ) putAppToBackground() bringAppToForeground() verifyAutofillToolbarTitle() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt index 1a6c62bfe..103e0af44 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt @@ -206,7 +206,7 @@ class CustomTabsTest { }.clickDownloadLink(downloadFile) { verifyDownloadPrompt(downloadFile) }.clickDownload { - verifyDownloadNotificationPopup() + verifyDownloadCompleteNotificationPopup() } mDevice.openNotification() notificationShade { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/DeepLinkTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/DeepLinkTest.kt index 7a5b955f1..258adb4cb 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/DeepLinkTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/DeepLinkTest.kt @@ -91,7 +91,6 @@ class DeepLinkTest { @Test fun openCollections() { - robot.openHomeScreen { /* do nothing */ }.dismissOnboarding() robot.openCollections { verifyCollectionsHeader() } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt index 9ba18a138..547d1b2ba 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt @@ -41,18 +41,20 @@ class DownloadFileTypesTest(fileName: String) { "videoSample.webm", "CSVfile.csv", "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 @Test - fun downloadMultipleFileTypesTest() { + fun allFilesAppearInDownloadsMenuTest() { navigationToolbar { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { }.clickDownloadLink(downloadFile) { verifyDownloadPrompt(downloadFile) }.clickDownload { - verifyDownloadNotificationPopup() + verifyDownloadCompleteNotificationPopup() }.closeCompletedDownloadPrompt { }.openThreeDotMenu { }.openDownloadsManager { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt index 41ac1b437..3b64d7af8 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt @@ -13,6 +13,7 @@ import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AndroidAssetDispatcher +import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_APPS_PHOTOS import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_DOCS import org.mozilla.fenix.helpers.HomeActivityIntentTestRule 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.clickSnackbarButton 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.setNetworkEnabled import org.mozilla.fenix.ui.robots.browserScreen @@ -72,8 +74,9 @@ class DownloadTest { setNetworkEnabled(enabled = true) } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243844 @Test - fun testDownloadPrompt() { + fun verifyTheDownloadPromptsTest() { downloadFile = "web_icon.png" navigationToolbar { @@ -82,7 +85,7 @@ class DownloadTest { }.clickDownloadLink(downloadFile) { verifyDownloadPrompt(downloadFile) }.clickDownload { - verifyDownloadNotificationPopup() + verifyDownloadCompleteNotificationPopup() }.clickOpen("image/png") {} downloadRobot { verifyPhotosAppOpens() @@ -91,25 +94,34 @@ class DownloadTest { deleteDownloadedFileOnStorage(downloadFile) } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2299405 @Test - fun testCloseDownloadPrompt() { - downloadFile = "smallZip.zip" + fun verifyTheDownloadFailedNotificationsTest() { + downloadFile = "1GB.zip" navigationToolbar { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { waitForPageToLoad() }.clickDownloadLink(downloadFile) { verifyDownloadPrompt(downloadFile) - }.closePrompt { - }.openThreeDotMenu { - }.openDownloadsManager { - verifyEmptyDownloadsList() + }.clickDownload { + setNetworkEnabled(enabled = false) + verifyDownloadFailedPrompt(downloadFile) + 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 - fun testDownloadCompleteNotification() { - downloadFile = "smallZip.zip" + fun verifyDownloadCompleteNotificationTest() { + downloadFile = "web_icon.png" navigationToolbar { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { @@ -117,15 +129,26 @@ class DownloadTest { }.clickDownloadLink(downloadFile) { verifyDownloadPrompt(downloadFile) }.clickDownload { - verifyDownloadNotificationPopup() + verifyDownloadCompleteNotificationPopup() } mDevice.openNotification() notificationShade { 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) } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/451563 @Ignore("Failing: Bug https://bugzilla.mozilla.org/show_bug.cgi?id=1813521") @SmokeTest @Test @@ -148,8 +171,10 @@ class DownloadTest { verifySystemNotificationExists("Firefox Fenix") expandNotificationMessage() clickDownloadNotificationControlButton("PAUSE") + verifySystemNotificationExists("Download paused") clickDownloadNotificationControlButton("RESUME") clickDownloadNotificationControlButton("CANCEL") + verifySystemNotificationDoesNotExist(downloadFile) mDevice.pressBack() } browserScreen { @@ -160,42 +185,9 @@ class DownloadTest { deleteDownloadedFileOnStorage(downloadFile) } - /* Verifies downloads in the Downloads Menu: - - downloads appear in the list - - deleting a download from device storage, removes it from the Downloads Menu too - */ - @SmokeTest + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2301474 @Test - fun manageDownloadsInDownloadsMenuTest() { - // 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() { + fun openDownloadedFileFromDownloadsMenuTest() { downloadFile = "web_icon.png" navigationToolbar { @@ -204,7 +196,7 @@ class DownloadTest { }.clickDownloadLink(downloadFile) { verifyDownloadPrompt(downloadFile) }.clickDownload { - verifyDownloadNotificationPopup() + verifyDownloadCompleteNotificationPopup() } browserScreen { }.openThreeDotMenu { @@ -239,32 +231,11 @@ class DownloadTest { deleteDownloadedFileOnStorage(downloadFile) } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1114970 @Test fun deleteDownloadedFileTest() { 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 { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { waitForPageToLoad() @@ -280,10 +251,13 @@ class DownloadTest { deleteDownloadedItem(downloadFile) clickSnackbarButton("UNDO") verifyDownloadedFileName(downloadFile) + deleteDownloadedItem(downloadFile) + verifyEmptyDownloadsList() } deleteDownloadedFileOnStorage(downloadFile) } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2302662 @Test fun deleteMultipleDownloadedFilesTest() { val firstDownloadedFile = "smallZip.zip" @@ -305,6 +279,13 @@ class DownloadTest { browserScreen { }.openThreeDotMenu { }.openDownloadsManager { + verifyDownloadedFileName(firstDownloadedFile) + verifyDownloadedFileName(secondDownloadedFile) + longClickDownloadedItem(firstDownloadedFile) + selectDownloadedItem(secondDownloadedFile) + openMultiSelectMoreOptionsMenu() + clickMultiSelectRemoveButton() + clickSnackbarButton("UNDO") verifyDownloadedFileName(firstDownloadedFile) verifyDownloadedFileName(secondDownloadedFile) longClickDownloadedItem(firstDownloadedFile) @@ -317,70 +298,52 @@ class DownloadTest { deleteDownloadedFileOnStorage(secondDownloadedFile) } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2301537 @Test - fun undoDeleteMultipleDownloadedFilesTest() { - val firstDownloadedFile = "smallZip.zip" - val secondDownloadedFile = "textfile.txt" + fun fileDeletedFromStorageIsDeletedEverywhereTest() { + val downloadFile = "smallZip.zip" navigationToolbar { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { waitForPageToLoad() - }.clickDownloadLink(firstDownloadedFile) { - verifyDownloadPrompt(firstDownloadedFile) - }.clickDownload { - verifyDownloadedFileName(firstDownloadedFile) - }.closeCompletedDownloadPrompt { - }.clickDownloadLink(secondDownloadedFile) { - verifyDownloadPrompt(secondDownloadedFile) + }.clickDownloadLink(downloadFile) { + verifyDownloadPrompt(downloadFile) }.clickDownload { - verifyDownloadedFileName(secondDownloadedFile) + verifyDownloadCompleteNotificationPopup() } browserScreen { }.openThreeDotMenu { }.openDownloadsManager { - verifyDownloadedFileName(firstDownloadedFile) - verifyDownloadedFileName(secondDownloadedFile) - longClickDownloadedItem(firstDownloadedFile) - selectDownloadedItem(secondDownloadedFile) - openMultiSelectMoreOptionsMenu() - clickMultiSelectRemoveButton() - clickSnackbarButton("UNDO") - verifyDownloadedFileName(firstDownloadedFile) - 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() + waitForDownloadsListToExist() + verifyDownloadedFileName(downloadFile) + deleteDownloadedFileOnStorage(downloadFile) + }.exitDownloadsManagerToBrowser { + }.openThreeDotMenu { + }.openDownloadsManager { + verifyEmptyDownloadsList() + exitMenu() } - downloadFile = "1GB.zip" - navigationToolbar { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { waitForPageToLoad() }.clickDownloadLink(downloadFile) { verifyDownloadPrompt(downloadFile) }.clickDownload { + verifyDownloadCompleteNotificationPopup() } browserScreen { - }.openNotificationShade { - verifySystemNotificationExists("Firefox Fenix") - expandNotificationMessage() - swipeDownloadNotification("Left", false) - clickDownloadNotificationControlButton("CANCEL") + }.openThreeDotMenu { + }.openDownloadsManager { + waitForDownloadsListToExist() + verifyDownloadedFileName(downloadFile) } deleteDownloadedFileOnStorage(downloadFile) } + @Ignore("Failing: https://bugzilla.mozilla.org/show_bug.cgi?id=1840994") @Test - fun systemNotificationCantBeDismissedWhileDownloadIsPausedTest() { + fun systemNotificationCantBeDismissedWhileInProgressTest() { // Clear the "Firefox Fenix default browser notification" notificationShade { cancelAllShownNotifications() @@ -399,15 +362,9 @@ class DownloadTest { }.openNotificationShade { verifySystemNotificationExists("Firefox Fenix") expandNotificationMessage() + swipeDownloadNotification(direction = "Left", shouldDismissNotification = false) clickDownloadNotificationControlButton("PAUSE") - swipeDownloadNotification("Left", false) - verifySystemNotificationExists("Firefox Fenix") - }.closeNotificationTray { - }.openNotificationShade { - verifySystemNotificationExists("Firefox Fenix") - expandNotificationMessage() - swipeDownloadNotification("Right", false) - verifySystemNotificationExists("Firefox Fenix") + swipeDownloadNotification(direction = "Right", shouldDismissNotification = false) clickDownloadNotificationControlButton("CANCEL") } deleteDownloadedFileOnStorage(downloadFile) @@ -427,8 +384,7 @@ class DownloadTest { waitForPageToLoad() }.clickDownloadLink(downloadFile) { verifyDownloadPrompt(downloadFile) - }.clickDownload { - } + }.clickDownload {} setNetworkEnabled(enabled = false) @@ -438,8 +394,7 @@ class DownloadTest { expandNotificationMessage() swipeDownloadNotification("Left", true) verifySystemNotificationDoesNotExist("Firefox Fenix") - }.closeNotificationTray { - } + }.closeNotificationTray {} downloadRobot { }.closeDownloadPrompt { @@ -449,56 +404,22 @@ class DownloadTest { } @Test - fun notificationCanBeDismissedIfDownloadIsCompletedTest() { - // Clear the "Firefox Fenix default browser notification" - 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) - } + fun warningWhenClosingPrivateTabsWhileDownloadingTest() { + downloadFile = "1GB.zip" - @Test - fun stayInPrivateBrowsingPromptTest() { // Clear the "Firefox Fenix default browser notification" notificationShade { cancelAllShownNotifications() } - downloadFile = "1GB.zip" - homeScreen { }.togglePrivateBrowsingMode() - navigationToolbar { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { waitForPageToLoad() }.clickDownloadLink(downloadFile) { verifyDownloadPrompt(downloadFile) - }.clickDownload { - } + }.clickDownload {} browserScreen { }.openTabDrawer { closeTab() @@ -512,15 +433,16 @@ class DownloadTest { deleteDownloadedFileOnStorage(downloadFile) } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2302663 @Test - fun cancelActiveDownloadsFromPrivateBrowsingPromptTest() { + fun cancelActivePrivateBrowsingDownloadsTest() { + downloadFile = "1GB.zip" + // Clear the "Firefox Fenix default browser notification" notificationShade { cancelAllShownNotifications() } - downloadFile = "1GB.zip" - homeScreen { }.togglePrivateBrowsingMode() @@ -529,8 +451,7 @@ class DownloadTest { waitForPageToLoad() }.clickDownloadLink(downloadFile) { verifyDownloadPrompt(downloadFile) - }.clickDownload { - } + }.clickDownload {} browserScreen { }.openTabDrawer { closeTab() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt index fc16704d2..2f3963caf 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt @@ -63,6 +63,7 @@ class EnhancedTrackingProtectionTest { mockWebServer.shutdown() } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416046 @Test fun testETPSettingsItemsAndSubMenus() { homeScreen { @@ -97,30 +98,9 @@ class EnhancedTrackingProtectionTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1514599 @Test - fun testETPSettingsSummaryChange() { - 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() { + fun verifyETPStateIsReflectedInTPSheetTest() { val genericPage = getGenericAsset(mockWebServer, 1) homeScreen { @@ -129,6 +109,8 @@ class EnhancedTrackingProtectionTest { }.openEnhancedTrackingProtectionSubMenu { switchEnhancedTrackingProtectionToggle() verifyEnhancedTrackingProtectionOptionsEnabled(false) + }.goBack { + verifySettingsOptionSummary("Enhanced Tracking Protection", "Off") 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 @SmokeTest @Test - fun testDisableETPExceptionToggle() { + fun disablingETPOnAWebsiteAddsItToExceptionListTest() { val firstPage = getGenericAsset(mockWebServer, 1) val secondPage = "example.com" @@ -182,8 +165,9 @@ class EnhancedTrackingProtectionTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/339714 @Test - fun trackingProtectionSwitchEnabledRemovesExceptionTest() { + fun enablingETPOnAWebsiteRemovesItFromTheExceptionListTest() { val trackingPage = getEnhancedTrackingProtectionAsset(mockWebServer) 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 @Test - fun clearTrackingProtectionExceptionsTest() { + fun clearWebsitesFromTPExceptionListTest() { val firstPage = getGenericAsset(mockWebServer, 1) val secondPage = "example.com" @@ -249,11 +234,20 @@ class EnhancedTrackingProtectionTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/417444 @Test - fun testStandardETPVisitSheetDetails() { + fun verifyTrackersBlockedWithStandardTPTest() { val genericPage = getGenericAsset(mockWebServer, 1) 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 navigationToolbar { }.enterURLAndEnterToBrowser(genericPage.url) { @@ -280,12 +274,21 @@ class EnhancedTrackingProtectionTest { }.closeEnhancedTrackingProtectionSheet {} } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/417441 @Test - fun testStrictVisitSheetDetails() { + fun verifyTrackersBlockedWithStrictTPTest() { appContext.settings().setStrictETP() val genericPage = getGenericAsset(mockWebServer, 1) 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 navigationToolbar { }.enterURLAndEnterToBrowser(genericPage.url) { @@ -316,9 +319,10 @@ class EnhancedTrackingProtectionTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/561637 @SmokeTest @Test - fun defaultCustomTrackingProtectionSettingsTest() { + fun verifyTrackersBlockedWithCustomTPTest() { val genericWebPage = getGenericAsset(mockWebServer, 1) val trackingPage = getEnhancedTrackingProtectionAsset(mockWebServer) @@ -328,9 +332,12 @@ class EnhancedTrackingProtectionTest { }.openEnhancedTrackingProtectionSubMenu { selectTrackingProtectionOption("Custom") verifyCustomTrackingProtectionSettings() - }.goBackToHomeScreen { - }.openNavigationToolbar { - // browsing a basic page to allow GV to load on a fresh run + }.goBack { + verifySettingsOptionSummary("Enhanced Tracking Protection", "Custom") + exitMenu() + } + + navigationToolbar { }.enterURLAndEnterToBrowser(genericWebPage.url) { }.openNavigationToolbar { }.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: // - Cookies set to "All cookies" // - Tracking content option OFF @@ -398,8 +406,9 @@ class EnhancedTrackingProtectionTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/562709 @Test - fun disableCustomTrackingProtectionOptionsTest() { + fun verifyTrackersBlockedWithCustomTPOptionsDisabledTest() { val genericWebPage = getGenericAsset(mockWebServer, 1) val trackingPage = getEnhancedTrackingProtectionAsset(mockWebServer) @@ -430,8 +439,9 @@ class EnhancedTrackingProtectionTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2106997 @Test - fun testTrackingContentBlockedOnlyInPrivateTabs() { + fun verifyTrackingContentBlockedOnlyInPrivateTabsTest() { val genericWebPage = getGenericAsset(mockWebServer, 1) val trackingPage = getEnhancedTrackingProtectionAsset(mockWebServer) @@ -480,6 +490,7 @@ class EnhancedTrackingProtectionTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2285368 @SmokeTest @Test fun blockCookiesStorageAccessTest() { @@ -502,6 +513,7 @@ class EnhancedTrackingProtectionTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2285369 @SmokeTest @Test fun allowCookiesStorageAccessTest() { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/HistoryTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/HistoryTest.kt index e63cf953e..8526f3186 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/HistoryTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/HistoryTest.kt @@ -73,8 +73,9 @@ class HistoryTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243285 @Test - fun noHistoryItemsInCacheTest() { + fun verifyEmptyHistoryMenuTest() { homeScreen { }.openThreeDotMenu { 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: // caution when making changes to it, so they don't block the builds + @SmokeTest @Test - fun visitedUrlHistoryTest() { + fun verifyHistoryMenuWithHistoryItemsTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -103,34 +106,16 @@ class HistoryTest { verifyVisitedTimeTitle() verifyFirstTestPageTitle("Test_Page_1") verifyTestPageUrl(firstWebPage.url) + verifyDeleteHistoryItemButton("Test_Page_1") } } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243288 @Test fun deleteHistoryItemTest() { 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 { }.enterURLAndEnterToBrowser(firstWebPage.url) { mDevice.waitForIdle() @@ -145,12 +130,16 @@ class HistoryTest { verifyUndoDeleteSnackBarButton() clickUndoDeleteButton() 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 @Test - fun cancelDeleteAllHistoryTest() { + fun deleteAllHistoryTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -168,25 +157,7 @@ class HistoryTest { selectEverythingOption() cancelDeleteHistory() verifyHistoryItemExists(true, firstWebPage.url.toString()) - } - } - - @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() - } + clickDeleteAllHistoryButton() verifyDeleteConfirmationMessage() selectEverythingOption() confirmDeleteAllHistory() @@ -195,7 +166,7 @@ class HistoryTest { } } - @SmokeTest + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/339690 @Test fun historyMultiSelectionToolbarItemsTest() { 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") @Test - fun openHistoryInNewTabTest() { + fun openMultipleSelectedHistoryItemsInANewTabTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -253,8 +225,9 @@ class HistoryTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/346098 @Test - fun openHistoryInPrivateTabTest() { + fun openMultipleSelectedHistoryItemsInPrivateTabTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -278,8 +251,9 @@ class HistoryTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/346099 @Test - fun deleteMultipleSelectionTest() { + fun deleteMultipleSelectedHistoryItemsTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) 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 - fun shareButtonTest() { + fun shareMultipleSelectedHistoryItemsTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -338,6 +313,7 @@ class HistoryTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715627 @Test fun verifySearchHistoryViewTest() { 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 fun verifyVoiceSearchInHistoryTest() { homeScreen { @@ -392,6 +369,7 @@ class HistoryTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715632 @Test fun verifySearchForHistoryItemsTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) @@ -407,13 +385,13 @@ class HistoryTest { // Search for a valid term typeSearch("generic") verifySearchEngineSuggestionResults(activityTestRule, firstWebPage.url.toString(), searchTerm = "generic") - verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString()) }.dismissSearchBar {} historyMenu { }.clickSearchButton { // Search for invalid term typeSearch("Android") - verifyNoSuggestionsAreDisplayed( + verifySuggestionsAreNotDisplayed( activityTestRule, firstWebPage.url.toString(), secondWebPage.url.toString(), @@ -421,6 +399,7 @@ class HistoryTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1715634 @Test fun verifyDeletedHistoryItemsCanNotBeSearchedTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) @@ -448,8 +427,8 @@ class HistoryTest { }.clickSearchButton { // Search for a valid term typeSearch("generic") - verifyNoSuggestionsAreDisplayed(activityTestRule, firstWebPage.url.toString()) - verifyNoSuggestionsAreDisplayed(activityTestRule, secondWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString()) verifySearchEngineSuggestionResults( activityTestRule, thirdWebPage.url.toString(), @@ -463,7 +442,7 @@ class HistoryTest { }.clickSearchButton { // Search for a valid term typeSearch("generic") - verifyNoSuggestionsAreDisplayed(activityTestRule, thirdWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(activityTestRule, thirdWebPage.url.toString()) } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt index 603572df6..9b1417f47 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt @@ -57,8 +57,11 @@ class HomeScreenTest { // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/235396 @Test fun homeScreenItemsTest() { - homeScreen {}.dismissOnboarding() + // Workaround to make sure the Pocket articles are populated before starting the test. homeScreen { + }.openThreeDotMenu { + }.openSettings { + }.goBack { verifyHomeWordmark() verifyHomePrivateBrowsingButton() verifyExistingTopSitesTabs("Wikipedia") @@ -80,7 +83,6 @@ class HomeScreenTest { // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/244199 @Test fun privateBrowsingHomeScreenItemsTest() { - homeScreen { }.dismissOnboarding() homeScreen { }.togglePrivateBrowsingMode() homeScreen { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt index 442e1776c..a2ec7ef4f 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt @@ -67,6 +67,7 @@ class LoginsTest { mockWebServer.shutdown() } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2092713 // Tests the Logins and passwords menu items and default values @Test 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. // For tests after signing in, see SyncIntegration test suite @Test - fun savedLoginsMenuItemsTest() { + fun verifySavedLoginsListTest() { homeScreen { }.openThreeDotMenu { }.openSettings { @@ -101,8 +103,9 @@ class LoginsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2092925 @Test - fun syncLoginsMenuItemsTest() { + fun verifySyncLoginsOptionsTest() { homeScreen { }.openThreeDotMenu { }.openSettings { @@ -115,8 +118,12 @@ class LoginsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/523839 @Test - fun saveLoginsAndPasswordsOptionsItemsTest() { + fun saveLoginFromPromptTest() { + val saveLoginTest = + TestAssetHelper.getSaveLoginAsset(mockWebServer) + homeScreen { }.openThreeDotMenu { }.openSettings { @@ -124,12 +131,8 @@ class LoginsTest { }.openSaveLoginsAndPasswordsOptions { verifySaveLoginsOptionsView() } - } - @Test - fun saveLoginFromPromptTest() { - val saveLoginTest = - TestAssetHelper.getSaveLoginAsset(mockWebServer) + exitMenu() navigationToolbar { }.enterURLAndEnterToBrowser(saveLoginTest.url) { @@ -152,8 +155,9 @@ class LoginsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/960412 @Test - fun openWebsiteForSavedLoginTest() { + fun openLoginWebsiteInBrowserTest() { val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" val originWebsite = "mozilla-mobile.github.io" val userName = "test" @@ -179,6 +183,7 @@ class LoginsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/517817 @Test fun neverSaveLoginFromPromptTest() { val saveLoginTest = TestAssetHelper.getSaveLoginAsset(mockWebServer) @@ -206,9 +211,10 @@ class LoginsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1508171 @SmokeTest @Test - fun updateSavedLoginTest() { + fun verifyUpdatedLoginIsSavedTest() { val saveLoginTest = TestAssetHelper.getSaveLoginAsset(mockWebServer) @@ -241,6 +247,7 @@ class LoginsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1049971 @SmokeTest @Test fun verifyMultipleLoginsSelectionsTest() { @@ -277,6 +284,7 @@ class LoginsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/875849 @Test fun verifyEditLoginsViewTest() { 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 fun verifyEditedLoginsAreSavedTest() { 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 fun verifyLoginWithNoUserNameCanNotBeSavedTest() { 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 fun verifyLoginWithoutPasswordCanNotBeSavedTest() { 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 fun verifyEditModeDismissalDoesNotSaveLoginCredentialsTest() { 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 fun verifyDeleteLoginButtonTest() { val loginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer) @@ -461,6 +474,7 @@ class LoginsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/517818 @SmokeTest @Test fun verifyNeverSaveLoginOptionTest() { @@ -484,6 +498,7 @@ class LoginsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/517819 @Test fun verifyAutofillToggleTest() { 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") @Test - fun verifyLoginIsNotUpdatedTest() { + fun doNotSaveOptionWillNotUpdateALoginTest() { val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html" 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 fun searchLoginsByUsernameTest() { val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer) @@ -618,6 +635,7 @@ class LoginsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/608834 @Test fun searchLoginsByUrlTest() { val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer) @@ -664,6 +682,7 @@ class LoginsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2266441 @Test fun verifyLastUsedLoginSortingOptionTest() { val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer) @@ -710,6 +729,7 @@ class LoginsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2266442 @Test fun verifyAlphabeticalLoginSortingOptionTest() { val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer) @@ -754,6 +774,7 @@ class LoginsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1518435 @Test fun verifyAddLoginManuallyTest() { 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 - fun verifyCopyUsernameTest() { + fun verifyCopyLoginCredentialsToClipboardTest() { val firstLoginPage = TestAssetHelper.getSaveLoginAsset(mockWebServer) navigationToolbar { @@ -809,24 +831,6 @@ class LoginsTest { viewSavedLoginDetails("test@example.com") clickCopyUserNameButton() 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() verifySnackBarText("Password copied to clipboard") } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/MainMenuTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/MainMenuTest.kt index b2d5faf61..17c589e73 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/MainMenuTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/MainMenuTest.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.ui +import androidx.core.net.toUri import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import mozilla.components.concept.engine.utils.EngineReleaseChannel @@ -12,15 +13,20 @@ 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.ext.components import org.mozilla.fenix.helpers.AndroidAssetDispatcher -import org.mozilla.fenix.helpers.HomeActivityTestRule -import org.mozilla.fenix.helpers.RecyclerViewIdlingResource +import org.mozilla.fenix.helpers.HomeActivityIntentTestRule +import org.mozilla.fenix.helpers.MatcherHelper import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper +import org.mozilla.fenix.helpers.TestHelper.assertYoutubeAppOpens 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 class MainMenuTest { @@ -28,7 +34,7 @@ class MainMenuTest { private lateinit var mockWebServer: MockWebServer @get:Rule - val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides() + val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() @Before fun setUp() { @@ -44,9 +50,9 @@ class MainMenuTest { mockWebServer.shutdown() } - @SmokeTest + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/233849 @Test - fun verifyPageMainMenuItemsTest() { + fun verifyTabMainMenuItemsTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) 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 @Test - fun openMainMenuNewTabItemTest() { - val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { + fun homeMainMenuItemsTest() { + homeScreen { }.openThreeDotMenu { - }.clickNewTabButton { - verifySearchView() + verifyHomeThreeDotMainMenuItems(isRequestDesktopSiteEnabled = false) + }.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 - fun openMainMenuBookmarksItemTest() { + fun openNewTabTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.openBookmarks { - verifyBookmarksMenuView() + }.clickNewTabButton { + 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 @Test - fun openMainMenuHistoryItemTest() { - val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) + fun openInAppFunctionalityTest() { + val youtubeURL = "vnd.youtube://".toUri() navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { + }.enterURLAndEnterToBrowser(youtubeURL) { + verifyNotificationDotOnMainMenu() }.openThreeDotMenu { - }.openHistory { - verifyHistoryListExists() + }.clickOpenInApp { + assertYoutubeAppOpens() } } - @SmokeTest + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2284323 @Test - fun openMainMenuAddonsTest() { + fun openSyncAndSaveDataTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { + mDevice.waitForIdle() }.openThreeDotMenu { - }.openAddonsManagerMenu { - TestHelper.registerAndCleanupIdlingResources( - RecyclerViewIdlingResource( - activityTestRule.activity.findViewById(R.id.add_ons_list), - 1, - ), - ) { - verifyAddonsItems() - } + }.openSyncSignIn { + verifyTurnOnSyncMenu() } } - @SmokeTest + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243840 @Test - fun openMainMenuSyncItemTest() { - val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) + fun findInPageTest() { + val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 3) navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { mDevice.waitForIdle() }.openThreeDotMenu { - }.openSyncSignIn { - verifyTurnOnSyncMenu() + 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) } } - @SmokeTest + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2283303 @Test - fun openMainMenuFindInPageTest() { + fun switchDesktopSiteModeOnOffTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.openFindInPage { - verifyFindInPageSearchBarItems() + }.switchDesktopSiteMode { + }.openThreeDotMenu { + verifyDesktopSiteModeEnabled(true) + }.switchDesktopSiteMode { + }.openThreeDotMenu { + verifyDesktopSiteModeEnabled(false) } } - @SmokeTest + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1314137 @Test - fun mainMenuDesktopSiteTest() { - val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) + fun setDesktopSiteBeforePageLoadTest() { + val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 4) - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { + homeScreen { }.openThreeDotMenu { + verifyDesktopSiteModeEnabled(false) }.switchDesktopSiteMode { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(webPage.url) { + }.openThreeDotMenu { + verifyDesktopSiteModeEnabled(true) + }.closeBrowserMenuToBrowser { + clickPageObject(MatcherHelper.itemContainingText("Link 1")) }.openThreeDotMenu { 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 - fun mainMenuReportSiteIssueTest() { + fun reportSiteIssueTest() { runWithCondition( // 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, @@ -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 @Test - fun openMainMenuAddToCollectionTest() { - val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) + fun addPageShortcutToHomeScreenTest() { + val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) + val shortcutTitle = TestHelper.generateRandomString(5) - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { + homeScreen { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(website.url) { + }.openThreeDotMenu { + expandMenu() + }.openAddToHomeScreen { + clickCancelShortcutButton() + } + + browserScreen { }.openThreeDotMenu { - }.openSaveToCollection { - verifyCollectionNameTextField() + expandMenu() + }.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: - // caution when making changes to it, so they don't block the builds + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/329893 @SmokeTest @Test - fun openMainMenuSettingsItemTest() { + fun mainMenuShareButtonTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.openSettings { - verifySettingsView() + }.clickShareButton { + verifyShareTabLayout() } } - @SmokeTest + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/233604 @Test - fun mainMenuShareButtonTest() { + fun navigateBackAndForwardTest() { 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 { - }.clickShareButton { - verifyShareTabLayout() + }.goToPreviousPage { + 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 @Test - fun mainMenuRefreshButtonTest() { + fun refreshPageButtonTest() { val refreshWebPage = TestAssetHelper.getRefreshAsset(mockWebServer) navigationToolbar { @@ -231,9 +337,9 @@ class MainMenuTest { } } - @SmokeTest + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2265657 @Test - fun mainMenuForceRefreshTest() { + fun forceRefreshPageTest() { val refreshWebPage = TestAssetHelper.getRefreshAsset(mockWebServer) navigationToolbar { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt index 15c259c01..2f842939f 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt @@ -15,10 +15,8 @@ import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityTestRule -import org.mozilla.fenix.helpers.MatcherHelper.itemWithText import org.mozilla.fenix.helpers.TestAssetHelper 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 java.util.Locale @@ -54,51 +52,7 @@ class NavigationToolbarTest { 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()) - } - } - + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/987326 // Swipes the nav bar left/right to switch between tabs @SmokeTest @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 @Test fun swipeToSwitchTabInRTLTest() { @@ -139,85 +94,7 @@ class NavigationToolbarTest { } } - // 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) - } - } - + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2265279 @SmokeTest @Test fun verifySecurePageSecuritySubMenuTest() { @@ -233,6 +110,7 @@ class NavigationToolbarTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2265280 @SmokeTest @Test fun verifyInsecurePageSecuritySubMenuTest() { @@ -248,6 +126,8 @@ class NavigationToolbarTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1661318 + @SmokeTest @Test fun verifyClearCookiesFromQuickSettingsTest() { val helpPageUrl = "mozilla.org" @@ -260,4 +140,36 @@ class NavigationToolbarTest { 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() + } + } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusEventTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusEventTest.kt index 55b45aee6..0d63197d9 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusEventTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusEventTest.kt @@ -22,7 +22,6 @@ import org.mozilla.fenix.helpers.Experimentation import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestHelper.appContext -import org.mozilla.fenix.ui.robots.homeScreen class NimbusEventTest { private lateinit var mDevice: UiDevice @@ -56,8 +55,6 @@ class NimbusEventTest { @Test fun homeScreenNimbusEventsTest() { - homeScreen { }.dismissOnboarding() - Experimentation.withHelper { assertTrue(evalJexl("'app_opened'|eventSum('Days', 28, 0) > 0")) } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/NoNetworkAccessStartupTests.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/NoNetworkAccessStartupTests.kt index 9f9c9c680..e86254832 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/NoNetworkAccessStartupTests.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/NoNetworkAccessStartupTests.kt @@ -43,8 +43,6 @@ class NoNetworkAccessStartupTests { activityTestRule.launchActivity(null) - homeScreen { - }.dismissOnboarding() homeScreen { verifyHomeScreen() } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/PDFViewerTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/PDFViewerTest.kt index 9b50e27f3..841785d1c 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/PDFViewerTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/PDFViewerTest.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.ui +import androidx.core.net.toUri import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import okhttp3.mockwebserver.MockWebServer @@ -15,10 +16,10 @@ import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_DOCS 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.itemWithResIdAndText 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.TestHelper.assertExternalAppOpens import org.mozilla.fenix.helpers.TestHelper.deleteDownloadedFileOnStorage @@ -28,6 +29,11 @@ import org.mozilla.fenix.ui.robots.navigationToolbar class PDFViewerTest { 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 val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() @@ -50,7 +56,7 @@ class PDFViewerTest { @Test fun openPDFInBrowserTest() { val genericURL = - TestAssetHelper.getGenericAsset(mockWebServer, 3) + getGenericAsset(mockWebServer, 3) navigationToolbar { }.enterURLAndEnterToBrowser(genericURL.url) { @@ -88,4 +94,55 @@ class PDFViewerTest { } 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) + } + } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt index 757ec2941..885fa80c0 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt @@ -30,6 +30,12 @@ class PocketTest { @Before fun setUp() { 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 @@ -40,9 +46,6 @@ class PocketTest { it.isRecentlyVisitedFeatureEnabled = false } - homeScreen { - }.dismissOnboarding() - homeScreen { verifyThoughtProvokingStories(true) scrollToPocketProvokingStories() @@ -70,9 +73,6 @@ class PocketTest { it.isRecentlyVisitedFeatureEnabled = false } - homeScreen { - }.dismissOnboarding() - homeScreen { verifyThoughtProvokingStories(true) scrollToPocketProvokingStories() @@ -90,9 +90,6 @@ class PocketTest { it.isRecentlyVisitedFeatureEnabled = false } - homeScreen { - }.dismissOnboarding() - homeScreen { scrollToPocketProvokingStories() verifyDiscoverMoreStoriesButton() @@ -109,9 +106,6 @@ class PocketTest { it.isRecentlyVisitedFeatureEnabled = false } - homeScreen { - }.dismissOnboarding() - homeScreen { verifyStoriesByTopicItemState(activityTestRule, false, 1) clickStoriesByTopicItem(activityTestRule, 1) @@ -127,9 +121,6 @@ class PocketTest { it.isRecentlyVisitedFeatureEnabled = false } - homeScreen { - }.dismissOnboarding() - homeScreen { verifyPoweredByPocket() }.clickPocketLearnMoreLink(activityTestRule) { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt index 932c3ca8f..0b8cb35af 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt @@ -16,6 +16,7 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText import org.mozilla.fenix.helpers.MatcherHelper.itemWithText import org.mozilla.fenix.helpers.TestHelper +import org.mozilla.fenix.helpers.TestHelper.assertExternalAppOpens import org.mozilla.fenix.helpers.TestHelper.assertNativeAppOpens import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.ui.robots.addToHomeScreen @@ -58,7 +59,6 @@ class PwaTest { } } - @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1807275") @Test fun emailLinkPWATest() { navigationToolbar { @@ -71,7 +71,7 @@ class PwaTest { }.openHomeScreenShortcut(shortcutTitle) { clickPageObject(itemContainingText("Email link")) clickPageObject(itemWithResIdAndText("android:id/button1", "OPEN")) - assertNativeAppOpens(GMAIL_APP, emailLink) + assertExternalAppOpens(GMAIL_APP) } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt index d759f4298..7d13909b0 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt @@ -20,11 +20,13 @@ import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest 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.searchEngineCodes 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.MockBrowserDataHelper.createBookmarkItem import org.mozilla.fenix.helpers.MockBrowserDataHelper.createHistoryItem import org.mozilla.fenix.helpers.MockBrowserDataHelper.createTabItem import org.mozilla.fenix.helpers.MockBrowserDataHelper.setCustomSearchEngine @@ -647,7 +649,7 @@ class SearchTest { clickSearchSelectorButton() selectTemporarySearchMethod(searchEngineName = "History") typeSearch(searchTerm = "Mozilla") - verifyNoSuggestionsAreDisplayed(rule = activityTestRule, "Mozilla") + verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla") clickClearButton() typeSearch(searchTerm = "generic") verifyTypedToolbarText("generic") @@ -684,7 +686,7 @@ class SearchTest { clickSearchSelectorButton() selectTemporarySearchMethod(searchEngineName = "Tabs") typeSearch(searchTerm = "Mozilla") - verifyNoSuggestionsAreDisplayed(rule = activityTestRule, "Mozilla") + verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla") clickClearButton() typeSearch(searchTerm = "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", + ), + ) + } + } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt index 8f3236701..bd2debace 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt @@ -49,23 +49,22 @@ class SettingsAboutTest { 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 - fun settingsAboutItemsTest() { - // ABOUT + fun verifyAboutSettingsItemsTest() { homeScreen { }.openThreeDotMenu { }.openSettings { - // ABOUT verifyAboutHeading() verifyRateOnGooglePlay() verifyAboutFirefoxPreview() } } - // ABOUT + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/246966 @Test - fun verifyRateOnGooglePlayRedirect() { + fun verifyRateOnGooglePlayButton() { activityIntentTestRule.applySettingsExceptions { it.isTCPCFREnabled = false } @@ -81,8 +80,9 @@ class SettingsAboutTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/246961 @Test - fun verifyAboutFirefoxPreview() { + fun verifyAboutFirefoxMenuItems() { activityIntentTestRule.applySettingsExceptions { it.isJumpBackInCFREnabled = false it.isTCPCFREnabled = false @@ -91,7 +91,7 @@ class SettingsAboutTest { }.openThreeDotMenu { }.openSettings { }.openAboutFirefoxPreview { - verifyAboutFirefoxPreview() + verifyAboutFirefoxPreviewInfo() } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt index ddf3ff9ad..a030cde3b 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt @@ -47,9 +47,10 @@ class SettingsAddonsTest { 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 @Test - fun settingsAddonsItemsTest() { + fun verifyAddonsListItemsTest() { homeScreen { }.openThreeDotMenu { }.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 @Test - fun installAddonTest() { + fun installAddonFromMainMenuTest() { val addonName = "uBlock Origin" 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 @Test - fun verifyAddonsCanBeUninstalled() { + fun verifyAddonsCanBeUninstalledTest() { val addonName = "uBlock Origin" 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 @SmokeTest @Test @@ -133,9 +137,10 @@ class SettingsAddonsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/561594 @SmokeTest @Test - fun useAddonsInPrivateModeTest() { + fun verifyUBlockWorksInPrivateModeTest() { val addonName = "uBlock Origin" val genericPage = getGenericAsset(mockWebServer, 1) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAdvancedTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAdvancedTest.kt index 4c18d5c38..acc0c3aa2 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAdvancedTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAdvancedTest.kt @@ -32,6 +32,11 @@ import org.mozilla.fenix.ui.robots.navigationToolbar class SettingsAdvancedTest { private lateinit var mDevice: UiDevice 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 val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() @@ -50,9 +55,10 @@ class SettingsAdvancedTest { 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 @Test - fun settingsAdvancedItemsTest() { + fun verifyAdvancedSettingsSectionItemsTest() { // ADVANCED homeScreen { }.openThreeDotMenu { @@ -71,24 +77,12 @@ class SettingsAdvancedTest { } } - @SmokeTest - @Test - fun verifyOpenLinkInAppViewTest() { - homeScreen { - }.openThreeDotMenu { - }.openSettings { - verifyOpenLinksInAppsButton() - verifySettingsOptionSummary("Open links in apps", "Never") - }.openOpenLinksInAppsMenu { - verifyOpenLinksInAppsView("Never") - } - } - + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2121046 // Assumes Youtube is installed and enabled @SmokeTest @Test fun neverOpenLinkInAppTest() { - val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) + val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) homeScreen { }.openThreeDotMenu { @@ -102,17 +96,18 @@ class SettingsAdvancedTest { exitMenu() navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - clickPageObject(itemContainingText("Youtube link")) + }.enterURLAndEnterToBrowser(externalLinksPage.url) { + clickPageObject(playStoreLink) waitForPageToLoad() - verifyUrl("youtube.com") + verifyUrl(playStoreUrl) } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2121052 // Assumes Youtube is installed and enabled @Test fun privateBrowsingNeverOpenLinkInAppTest() { - val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) + val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) homeScreen { }.togglePrivateBrowsingMode() @@ -129,18 +124,19 @@ class SettingsAdvancedTest { exitMenu() navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - clickPageObject(itemContainingText("Youtube link")) + }.enterURLAndEnterToBrowser(externalLinksPage.url) { + clickPageObject(playStoreLink) waitForPageToLoad() - verifyUrl("youtube.com") + verifyUrl(playStoreUrl) } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2121045 // Assumes Youtube is installed and enabled @SmokeTest @Test fun askBeforeOpeningLinkInAppCancelTest() { - val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) + val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) homeScreen { }.openThreeDotMenu { @@ -158,20 +154,21 @@ class SettingsAdvancedTest { exitMenu() navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - clickPageObject(itemContainingText("Youtube link")) + }.enterURLAndEnterToBrowser(externalLinksPage.url) { + clickPageObject(youTubeFullLink) verifyOpenLinkInAnotherAppPrompt() clickPageObject(itemWithResIdAndText("android:id/button2", "CANCEL")) waitForPageToLoad() - verifyUrl("youtube.com") + verifyUrl("youtube") } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2288347 // Assumes Youtube is installed and enabled @SmokeTest @Test fun askBeforeOpeningLinkInAppOpenTest() { - val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) + val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) homeScreen { }.openThreeDotMenu { @@ -189,8 +186,8 @@ class SettingsAdvancedTest { exitMenu() navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - clickPageObject(itemContainingText("Youtube link")) + }.enterURLAndEnterToBrowser(externalLinksPage.url) { + clickPageObject(youTubeSchemaLink) verifyOpenLinkInAnotherAppPrompt() clickPageObject(itemWithResIdAndText("android:id/button1", "OPEN")) 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 @Test fun privateBrowsingAskBeforeOpeningLinkInAppCancelTest() { - val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) + val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) homeScreen { }.togglePrivateBrowsingMode() @@ -222,19 +220,20 @@ class SettingsAdvancedTest { exitMenu() navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - clickPageObject(itemContainingText("Youtube link")) - verifyPrivateBrowsingOpenLinkInAnotherAppPrompt("youtube.com") + }.enterURLAndEnterToBrowser(externalLinksPage.url) { + clickPageObject(youTubeFullLink) + verifyPrivateBrowsingOpenLinkInAnotherAppPrompt("youtube") clickPageObject(itemWithResIdAndText("android:id/button2", "CANCEL")) waitForPageToLoad() - verifyUrl("youtube.com") + verifyUrl("youtube") } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2288350 // Assumes Youtube is installed and enabled @Test fun privateBrowsingAskBeforeOpeningLinkInAppOpenTest() { - val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) + val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) homeScreen { }.togglePrivateBrowsingMode() @@ -255,19 +254,20 @@ class SettingsAdvancedTest { exitMenu() navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - clickPageObject(itemContainingText("Youtube link")) - verifyPrivateBrowsingOpenLinkInAnotherAppPrompt("youtube.com") + }.enterURLAndEnterToBrowser(externalLinksPage.url) { + clickPageObject(youTubeSchemaLink) + verifyPrivateBrowsingOpenLinkInAnotherAppPrompt("youtube") clickPageObject(itemWithResIdAndText("android:id/button1", "OPEN")) mDevice.waitForIdle() assertYoutubeAppOpens() } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1058618 // Assumes Youtube is installed and enabled @Test fun alwaysOpenLinkInAppTest() { - val defaultWebPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) + val externalLinksPage = TestAssetHelper.getExternalLinksAsset(mockWebServer) homeScreen { }.openThreeDotMenu { @@ -285,22 +285,22 @@ class SettingsAdvancedTest { exitMenu() navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - clickPageObject(itemContainingText("Youtube link")) + }.enterURLAndEnterToBrowser(externalLinksPage.url) { + clickPageObject(youTubeSchemaLink) mDevice.waitForIdle() assertYoutubeAppOpens() } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1058617 @Test fun dismissOpenLinksInAppCFRTest() { activityIntentTestRule.applySettingsExceptions { it.isOpenInAppBannerEnabled = true } - val defaultWebPage = "https://m.youtube.com/" navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.toUri()) { + }.enterURLAndEnterToBrowser(youTubePage) { waitForPageToLoad() verifyOpenLinksInAppsCFRExists(true) clickOpenLinksInAppsDismissCFRButton() @@ -308,15 +308,15 @@ class SettingsAdvancedTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2288331 @Test fun goToSettingsFromOpenLinksInAppCFRTest() { activityIntentTestRule.applySettingsExceptions { it.isOpenInAppBannerEnabled = true } - val defaultWebPage = "https://m.youtube.com/" navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.toUri()) { + }.enterURLAndEnterToBrowser(youTubePage) { waitForPageToLoad() verifyOpenLinksInAppsCFRExists(true) }.clickOpenLinksInAppsGoToSettingsCFRButton { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt index 72619bea9..78b0b4af8 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt @@ -49,8 +49,9 @@ class SettingsCustomizeTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/344212 @Test - fun changeThemeSettingTest() { + fun changeThemeOfTheAppTest() { // Goes through the settings and changes the default search engine, then verifies it changes. homeScreen { }.openThreeDotMenu { @@ -64,6 +65,7 @@ class SettingsCustomizeTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/466571 @Test fun setToolbarPositionTest() { homeScreen { @@ -88,8 +90,9 @@ class SettingsCustomizeTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1058682 @Test - fun swipeToolbarGesturePreferenceOffTest() { + fun turnOffSwipeToSwitchTabsPreferenceTest() { val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) 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 fun pullToRefreshPreferenceTest() { homeScreen { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataOnQuitTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataOnQuitTest.kt index 99d31bf07..d161098dd 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataOnQuitTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataOnQuitTest.kt @@ -60,8 +60,9 @@ class SettingsDeleteBrowsingDataOnQuitTest { mockWebServer.shutdown() } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416048 @Test - fun deleteBrowsingDataOnQuitSettingsItemsTest() { + fun deleteBrowsingDataOnQuitSettingTest() { homeScreen { }.openThreeDotMenu { }.openSettings { @@ -88,6 +89,7 @@ class SettingsDeleteBrowsingDataOnQuitTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416049 @Test fun deleteOpenTabsOnQuitTest() { 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 - fun deleteHistoryOnQuitTest() { + fun deleteBrowsingHistoryOnQuitTest() { val genericPage = getStorageTestAsset(mockWebServer, "generic1.html") @@ -140,6 +143,7 @@ class SettingsDeleteBrowsingDataOnQuitTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416051 @Test fun deleteCookiesAndSiteDataOnQuitTest() { val storageWritePage = @@ -174,6 +178,7 @@ class SettingsDeleteBrowsingDataOnQuitTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1243096 @SmokeTest @Test fun deleteDownloadsOnQuitTest() { @@ -191,7 +196,7 @@ class SettingsDeleteBrowsingDataOnQuitTest { }.clickDownloadLink("smallZip.zip") { verifyDownloadPrompt("smallZip.zip") }.clickDownload { - verifyDownloadNotificationPopup() + verifyDownloadCompleteNotificationPopup() }.closeCompletedDownloadPrompt { }.goToHomescreen { }.openThreeDotMenu { @@ -207,6 +212,7 @@ class SettingsDeleteBrowsingDataOnQuitTest { deleteDownloadedFileOnStorage("smallZip.zip") } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416053 @SmokeTest @Test fun deleteSitePermissionsOnQuitTest() { @@ -242,6 +248,7 @@ class SettingsDeleteBrowsingDataOnQuitTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416052 @Test fun deleteCachedFilesOnQuitTest() { val pocketTopArticles = TestHelper.getStringResource(R.string.pocket_pinned_top_articles) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataTest.kt index e36c7ecd6..0b89b8461 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataTest.kt @@ -7,6 +7,7 @@ package org.mozilla.fenix.ui import okhttp3.mockwebserver.MockWebServer import org.junit.After import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R @@ -51,6 +52,7 @@ class SettingsDeleteBrowsingDataTest { mockWebServer.shutdown() } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/937561 @Test fun deleteBrowsingDataOptionStatesTest() { homeScreen { @@ -109,8 +111,9 @@ class SettingsDeleteBrowsingDataTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/517811 @Test - fun deleteTabsDataWithNoOpenTabsTest() { + fun deleteOpenTabsBrowsingDataWithNoOpenTabsTest() { homeScreen { }.openThreeDotMenu { }.openSettings { @@ -126,9 +129,10 @@ class SettingsDeleteBrowsingDataTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/353531 @SmokeTest @Test - fun deleteTabsDataTest() { + fun deleteOpenTabsBrowsingDataTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -158,6 +162,7 @@ class SettingsDeleteBrowsingDataTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/378864 @SmokeTest @Test fun deleteBrowsingHistoryTest() { @@ -188,6 +193,7 @@ class SettingsDeleteBrowsingDataTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416041 @SmokeTest @Test 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 @Test fun deleteCachedFilesTest() { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsGeneralTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsGeneralTest.kt index 3fb4a0be9..8e4c16577 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsGeneralTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsGeneralTest.kt @@ -53,8 +53,9 @@ class SettingsGeneralTest { mockWebServer.shutdown() } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2092697 @Test - fun settingsGeneralItemsTests() { + fun verifyGeneralSettingsItemsTest() { homeScreen { }.openThreeDotMenu { }.openSettings { @@ -76,9 +77,10 @@ class SettingsGeneralTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/344213 @SmokeTest @Test - fun changeAccessibiltySettings() { + fun verifyFontSizingChangeTest() { // 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 webpage = getLoremIpsumAsset(mockWebServer).url @@ -107,9 +109,10 @@ class SettingsGeneralTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/516079 @SmokeTest @Test - fun switchLanguageTest() { + fun setAppLanguageDifferentThanSystemLanguageTest() { val enLanguageHeaderText = getStringResource(R.string.preferences_language) homeScreen { @@ -132,6 +135,7 @@ class SettingsGeneralTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/516080 @Test fun searchInLanguagesListTest() { 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 @Ignore("Failing due to app translation bug, see: https://github.com/mozilla-mobile/fenix/issues/26729") @Test - fun frenchSystemLocaleTest() { + fun verifyFollowDeviceLanguageTest() { val frenchLocale = Locale("fr", "FR") runWithSystemLocaleChanged(frenchLocale, activityIntentTestRule) { @@ -172,47 +177,18 @@ class SettingsGeneralTest { } } - @SmokeTest - @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") - } - } - + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1360557 @Test fun tabsSettingsMenuItemsTest() { homeScreen { }.openThreeDotMenu { }.openSettings { + verifyTabsButton() + verifySettingsOptionSummary("Tabs", "Close manually") }.openTabsSubMenu { verifyTabViewOptions() verifyCloseTabsOptions() verifyMoveOldTabsToInactiveOptions() - } - } - - @Test - fun verifyTabsOptionSummaryUpdatesTest() { - homeScreen { - }.openThreeDotMenu { - }.openSettings { - verifyTabsButton() - verifySettingsOptionSummary("Tabs", "Close manually") - }.openTabsSubMenu { verifySelectedCloseTabsOption("Never") clickClosedTabsOption("After one day") verifySelectedCloseTabsOption("After one day") @@ -230,4 +206,21 @@ class SettingsGeneralTest { 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() + } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHTTPSOnlyModeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHTTPSOnlyModeTest.kt index 4280aa24f..05d754c4f 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHTTPSOnlyModeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHTTPSOnlyModeTest.kt @@ -32,6 +32,7 @@ class SettingsHTTPSOnlyModeTest { @get:Rule val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true) + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1724825 @Test fun httpsOnlyModeMenuItemsTest() { homeScreen { @@ -58,6 +59,7 @@ class SettingsHTTPSOnlyModeTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1724827 @SmokeTest @Test fun httpsOnlyModeEnabledInNormalBrowsingTest() { @@ -93,8 +95,9 @@ class SettingsHTTPSOnlyModeTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2091057 @Test - fun httpsOnlyModeExceptionPersistsForCurrentSession() { + fun httpsOnlyModeExceptionPersistsForCurrentSessionTest() { homeScreen { }.openThreeDotMenu { }.openSettings { @@ -120,6 +123,7 @@ class SettingsHTTPSOnlyModeTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1724828 @Test fun httpsOnlyModeEnabledOnlyInPrivateBrowsingTest() { homeScreen { @@ -159,6 +163,7 @@ class SettingsHTTPSOnlyModeTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2091058 @Test fun turnOffHttpsOnlyModeTest() { homeScreen { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt index 4f0fa2247..769add7bf 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt @@ -49,6 +49,7 @@ class SettingsHomepageTest { mockWebServer.shutdown() } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1564843 @Test fun verifyHomepageSettingsTest() { homeScreen { @@ -59,6 +60,7 @@ class SettingsHomepageTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1564859 @Test fun verifyShortcutOptionTest() { // en-US defaults @@ -90,6 +92,7 @@ class SettingsHomepageTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1565003 @Test fun verifyRecentlyVisitedOptionTest() { activityIntentTestRule.applySettingsExceptions { @@ -109,26 +112,7 @@ class SettingsHomepageTest { } } - @Test - fun verifyPocketOptionTest() { - activityIntentTestRule.applySettingsExceptions { - it.isRecentTabsFeatureEnabled = false - it.isRecentlyVisitedFeatureEnabled = false - } - val genericURL = getGenericAsset(mockWebServer, 1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(genericURL.url) { - }.goToHomescreen { - verifyPocketSectionIsDisplayed() - }.openThreeDotMenu { - }.openCustomizeHome { - clickPocketButton() - }.goBackToHomeScreen { - verifyPocketSectionIsNotDisplayed() - } - } - + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1564999 @SmokeTest @Test fun jumpBackInOptionTest() { @@ -146,6 +130,7 @@ class SettingsHomepageTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1565000 @SmokeTest @Test fun recentBookmarksOptionTest() { @@ -165,48 +150,47 @@ class SettingsHomepageTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1569831 @SmokeTest @Test - fun startOnHomepageTest() { + fun verifyOpeningScreenOptionsTest() { val genericURL = getGenericAsset(mockWebServer, 1) navigationToolbar { }.enterURLAndEnterToBrowser(genericURL.url) { }.openThreeDotMenu { }.openSettings { + verifySettingsOptionSummary("Homepage", "Open on homepage after four hours") }.openHomepageSubMenu { + verifySelectedOpeningScreenOption("Homepage after four hours of inactivity") clickOpeningScreenOption("Homepage") + verifySelectedOpeningScreenOption("Homepage") } restartApp(activityIntentTestRule) homeScreen { verifyHomeScreen() - } - } - - @SmokeTest - @Test - fun startOnLastTabTest() { - val firstWebPage = getGenericAsset(mockWebServer, 1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(firstWebPage.url) { - }.goToHomescreen { }.openThreeDotMenu { - }.openCustomizeHome { + }.openSettings { + verifySettingsOptionSummary("Homepage", "Open on homepage") + }.openHomepageSubMenu { clickOpeningScreenOption("Last tab") + verifySelectedOpeningScreenOption("Last tab") + }.goBack { + verifySettingsOptionSummary("Homepage", "Open on last tab") } restartApp(activityIntentTestRule) browserScreen { - verifyUrl(firstWebPage.url.toString()) + verifyUrl(genericURL.url.toString()) } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1569843 @Test - fun ignoreStartOnHomeWhenLaunchedByExternalLinkTest() { + fun verifyOpeningScreenAfterLaunchingExternalLinkTest() { val genericPage = getGenericAsset(mockWebServer, 1) 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") @Test - fun setWallpaperTest() { + fun verifyWallpaperChangeTest() { val wallpapers = listOf( "Wallpaper Item: amethyst", "Wallpaper Item: cerulean", diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt index e182fd593..c70c75df6 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt @@ -44,6 +44,7 @@ class SettingsPrivacyTest { mockWebServer.shutdown() } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2092698 @Test fun settingsPrivacyItemsTest() { homeScreen { @@ -68,8 +69,9 @@ class SettingsPrivacyTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243362 @Test - fun verifyDataCollectionTest() { + fun verifyDataCollectionSettingsTest() { homeScreen { }.openThreeDotMenu { }.openSettings { @@ -79,44 +81,14 @@ class SettingsPrivacyTest { true, "On", ) - } - } - - @Test - fun verifyUsageAndTechnicalDataToggleTest() { - homeScreen { - }.openThreeDotMenu { - }.openSettings { - }.openSettingsSubMenuDataCollection { - verifyUsageAndTechnicalDataToggle(true) clickUsageAndTechnicalDataToggle() verifyUsageAndTechnicalDataToggle(false) - } - } - - @Test - fun verifyMarketingDataToggleTest() { - homeScreen { - }.openThreeDotMenu { - }.openSettings { - }.openSettingsSubMenuDataCollection { - verifyMarketingDataToggle(true) + clickUsageAndTechnicalDataToggle() + verifyUsageAndTechnicalDataToggle(true) clickMarketingDataToggle() verifyMarketingDataToggle(false) - } - } - - @Test - fun verifyStudiesToggleTest() { - homeScreen { - }.openThreeDotMenu { - }.openSettings { - }.openSettingsSubMenuDataCollection { - verifyDataCollectionView( - true, - true, - "On", - ) + clickMarketingDataToggle() + verifyMarketingDataToggle(true) clickStudiesOption() verifyStudiesToggle(true) clickStudiesToggle() @@ -126,26 +98,7 @@ class SettingsPrivacyTest { } } - @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/1024594 @Test fun verifyNotificationsSettingsTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivateBrowsingTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivateBrowsingTest.kt index 429de0091..6b2102e93 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivateBrowsingTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivateBrowsingTest.kt @@ -39,6 +39,7 @@ class SettingsPrivateBrowsingTest { mockWebServer.shutdown() } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/555822 @Test fun verifyPrivateBrowsingMenuItemsTest() { homeScreen { @@ -145,8 +146,9 @@ class SettingsPrivateBrowsingTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/414583 @Test - fun addPrivateBrowsingShortcut() { + fun addPrivateBrowsingShortcutFromSettingsTest() { homeScreen { }.openThreeDotMenu { }.openSettings { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt index c1df13e1f..600b77aca 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt @@ -160,7 +160,7 @@ class SettingsSearchTest { homeScreen { }.openSearch { typeSearch("test") - verifyNoSuggestionsAreDisplayed( + verifySuggestionsAreNotDisplayed( activityTestRule, "Firefox Suggest", websiteURL, @@ -188,7 +188,7 @@ class SettingsSearchTest { homeScreen { }.openSearch { typeSearch("test") - verifyNoSuggestionsAreDisplayed( + verifySuggestionsAreNotDisplayed( activityTestRule, "Firefox Suggest", website.title, @@ -426,7 +426,7 @@ class SettingsSearchTest { }.goBack { }.openSearch { typeSearch("mozilla") - verifyNoSuggestionsAreDisplayed(activityTestRule, "mozilla firefox") + verifySuggestionsAreNotDisplayed(activityTestRule, "mozilla firefox") } } @@ -439,7 +439,7 @@ class SettingsSearchTest { typeSearch("mozilla") verifyAllowSuggestionsInPrivateModeDialog() denySuggestionsInPrivateMode() - verifyNoSuggestionsAreDisplayed(activityTestRule, "mozilla firefox") + verifySuggestionsAreNotDisplayed(activityTestRule, "mozilla firefox") } } @@ -466,7 +466,7 @@ class SettingsSearchTest { }.goBack { }.openSearch { typeSearch("mozilla") - verifyNoSuggestionsAreDisplayed(activityTestRule, "mozilla firefox") + verifySuggestionsAreNotDisplayed(activityTestRule, "mozilla firefox") } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt index d73d92b6d..42dd55e85 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt @@ -69,11 +69,33 @@ class SettingsSitePermissionsTest { 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 @SmokeTest @Test @SdkSuppress(minSdkVersion = 29) - fun redirectToAppPermissionsSystemSettingsTest() { + fun systemBlockedPermissionsRedirectToSystemAppSettingsTest() { homeScreen { }.openThreeDotMenu { }.openSettings { @@ -108,9 +130,10 @@ class SettingsSitePermissionsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2095125 @SmokeTest @Test - fun verifyAutoplayBlockAudioOnlySettingTest() { + fun verifyAutoplayBlockAudioOnlySettingOnNotMutedVideoTest() { val genericPage = getGenericAsset(mockWebServer, 1) 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") @SmokeTest @Test @@ -173,8 +197,9 @@ class SettingsSitePermissionsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2095124 @Test - fun verifyAutoplayAllowAudioVideoSettingTest() { + fun verifyAutoplayAllowAudioVideoSettingOnNotMutedVideoTestTest() { val genericPage = getGenericAsset(mockWebServer, 1) 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") @Test fun verifyAutoplayAllowAudioVideoSettingOnMutedVideoTest() { @@ -235,8 +261,9 @@ class SettingsSitePermissionsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2095126 @Test - fun verifyAutoplayBlockAudioAndVideoSettingTest() { + fun verifyAutoplayBlockAudioAndVideoSettingOnNotMutedVideoTest() { val videoTestPage = getVideoPageAsset(mockWebServer) homeScreen { @@ -265,6 +292,7 @@ class SettingsSitePermissionsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2286808 @Test fun verifyAutoplayBlockAudioAndVideoSettingOnMutedVideoTest() { val mutedVideoTestPage = getMutedVideoPageAsset(mockWebServer) @@ -294,6 +322,7 @@ class SettingsSitePermissionsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/247362 @Test fun verifyCameraPermissionSettingsTest() { navigationToolbar { @@ -319,6 +348,7 @@ class SettingsSitePermissionsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/247364 @Test fun verifyMicrophonePermissionSettingsTest() { navigationToolbar { @@ -344,6 +374,7 @@ class SettingsSitePermissionsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/247363 @Test fun verifyLocationPermissionSettingsTest() { navigationToolbar { @@ -368,6 +399,7 @@ class SettingsSitePermissionsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/247365 @Test fun verifyNotificationsPermissionSettingsTest() { navigationToolbar { @@ -392,6 +424,7 @@ class SettingsSitePermissionsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1923415 @Test fun verifyPersistentStoragePermissionSettingsTest() { 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") @Test fun verifyDRMControlledContentPermissionSettingsTest() { @@ -454,6 +488,7 @@ class SettingsSitePermissionsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/246976 @SmokeTest @Test fun clearAllSitePermissionsExceptionsTest() { @@ -476,8 +511,9 @@ class SettingsSitePermissionsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/247007 @Test - fun clearOneSiteAllPermissionsExceptionsTest() { + fun addAndClearOneWebPagePermission() { navigationToolbar { }.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) { }.clickOpenNotificationButton { @@ -498,8 +534,9 @@ class SettingsSitePermissionsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/326477 @Test - fun clearOneSiteOnePermissionExceptionTest() { + fun clearIndividuallyAWebPagePermission() { navigationToolbar { }.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) { }.clickOpenNotificationButton { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index 485918e56..c73980860 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -1,380 +1,236 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -@file:Suppress("DEPRECATION") - -package org.mozilla.fenix.ui - -import android.view.View -import androidx.compose.ui.test.junit4.AndroidComposeTestRule -import androidx.core.net.toUri -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.rule.ActivityTestRule -import androidx.test.uiautomator.UiDevice -import mozilla.components.browser.state.store.BrowserStore -import mozilla.components.concept.engine.mediasession.MediaSession -import okhttp3.mockwebserver.MockWebServer -import org.junit.After -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.mozilla.fenix.IntentReceiverActivity -import org.mozilla.fenix.R -import org.mozilla.fenix.customannotations.SmokeTest -import org.mozilla.fenix.ext.components -import org.mozilla.fenix.helpers.AndroidAssetDispatcher -import org.mozilla.fenix.helpers.HomeActivityIntentTestRule -import org.mozilla.fenix.helpers.MatcherHelper.itemWithText -import org.mozilla.fenix.helpers.RetryTestRule -import org.mozilla.fenix.helpers.TestAssetHelper -import org.mozilla.fenix.helpers.TestHelper.assertYoutubeAppOpens -import org.mozilla.fenix.helpers.TestHelper.registerAndCleanupIdlingResources -import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource -import org.mozilla.fenix.ui.robots.browserScreen -import org.mozilla.fenix.ui.robots.clickPageObject -import org.mozilla.fenix.ui.robots.homeScreen -import org.mozilla.fenix.ui.robots.navigationToolbar - -/** - * Test Suite that contains a part of the Smoke and Sanity tests defined in TestRail: - * https://testrail.stage.mozaws.net/index.php?/suites/view/3192 - * Other smoke tests have been marked with the @SmokeTest annotation throughout the ui package in order to limit this class expansion. - * These tests will verify different functionalities of the app as a way to quickly detect regressions in main areas - */ -@Suppress("ForbiddenComment") -@SmokeTest -class SmokeTest { - private lateinit var mDevice: UiDevice - private lateinit var mockWebServer: MockWebServer - private lateinit var browserStore: BrowserStore - - @get:Rule(order = 0) - val activityTestRule = AndroidComposeTestRule( - HomeActivityIntentTestRule.withDefaultSettingsOverrides(), - { it.activity }, - ) - - @get: Rule(order = 1) - val intentReceiverActivityTestRule = ActivityTestRule( - IntentReceiverActivity::class.java, - true, - false, - ) - - @Rule(order = 2) - @JvmField - val retryTestRule = RetryTestRule(3) - - @Before - fun setUp() { - // Initializing this as part of class construction, below the rule would throw a NPE - // So we are initializing this here instead of in all related tests. - browserStore = activityTestRule.activity.components.core.store - - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - } - - // Device or AVD requires a Google Services Android OS installation with Play Store installed - // Verifies the Open in app button when an app is installed - @Test - fun mainMenuOpenInAppTest() { - val youtubeURL = "vnd.youtube://".toUri() - - navigationToolbar { - }.enterURLAndEnterToBrowser(youtubeURL) { - verifyNotificationDotOnMainMenu() - }.openThreeDotMenu { - }.clickOpenInApp { - assertYoutubeAppOpens() - } - } - - // Verifies that deleting a Bookmarks folder also removes the item from inside it. - @Test - fun deleteNonEmptyBookmarkFolderTest() { - 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() - verifyBookmarkIsDeleted("My Folder") - verifyBookmarkIsDeleted("My Folder 2") - verifyBookmarkIsDeleted("Test_Page_1") - navigateUp() - } - - browserScreen { - }.openThreeDotMenu { - verifyAddBookmarkButton() - } - } - - @Test - fun shareTabsFromTabsTrayTest() { - val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1) - val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2) - val firstWebsiteTitle = firstWebsite.title - val secondWebsiteTitle = secondWebsite.title - val sharingApp = "Gmail" - val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}" - - homeScreen { - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(firstWebsite.url) { - verifyPageContent(firstWebsite.content) - }.openTabDrawer { - }.openNewTab { - }.submitQuery(secondWebsite.url.toString()) { - verifyPageContent(secondWebsite.content) - }.openTabDrawer { - verifyExistingOpenTabs("Test_Page_1") - verifyExistingOpenTabs("Test_Page_2") - }.openTabsListThreeDotMenu { - verifyShareAllTabsButton() - }.clickShareAllTabsButton { - verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle) - verifySharingWithSelectedApp( - sharingApp, - sharedUrlsString, - "$firstWebsiteTitle, $secondWebsiteTitle", - ) - } - } - - @Test - fun privateTabsTrayWithOpenedTabTest() { - val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) - - homeScreen { - }.togglePrivateBrowsingMode() - - homeScreen { - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(website.url) { - }.openTabDrawer { - verifyNormalBrowsingButtonIsSelected(false) - verifyPrivateBrowsingButtonIsSelected(true) - verifySyncedTabsButtonIsSelected(false) - verifyTabTrayOverflowMenu(true) - verifyTabsTrayCounter() - verifyExistingTabList() - verifyExistingOpenTabs(website.title) - verifyCloseTabsButton(website.title) - verifyOpenedTabThumbnail() - verifyPrivateBrowsingNewTabButton() - } - } - - // Test running on beta/release builds in CI: - // caution when making changes to it, so they don't block the builds - @Test - fun noHistoryInPrivateBrowsingTest() { - val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) - - homeScreen { - }.togglePrivateBrowsingMode() - - homeScreen { - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(website.url) { - mDevice.waitForIdle() - }.openThreeDotMenu { - }.openHistory { - verifyEmptyHistoryView() - } - } - - @Test - fun mainMenuInstallPWATest() { - val pwaPage = "https://mozilla-mobile.github.io/testapp/" - - navigationToolbar { - }.enterURLAndEnterToBrowser(pwaPage.toUri()) { - verifyNotificationDotOnMainMenu() - }.openThreeDotMenu { - }.clickInstall { - clickAddAutomaticallyButton() - }.openHomeScreenShortcut("TEST_APP") { - mDevice.waitForIdle() - verifyNavURLBarHidden() - } - } - - // Verifies that reader mode is detected and the custom appearance controls are displayed - @Test - fun verifyReaderViewAppearanceUI() { - val readerViewPage = - TestAssetHelper.getLoremIpsumAsset(mockWebServer) - val estimatedReadingTime = "1 - 2 minutes" - - navigationToolbar { - }.enterURLAndEnterToBrowser(readerViewPage.url) { - mDevice.waitForIdle() - } - - registerAndCleanupIdlingResources( - ViewVisibilityIdlingResource( - activityTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions), - View.VISIBLE, - ), - ) {} - - navigationToolbar { - verifyReaderViewDetected(true) - toggleReaderView() - } - - browserScreen { - waitForPageToLoad() - verifyPageContent(estimatedReadingTime) - }.openThreeDotMenu { - verifyReaderViewAppearance(true) - }.openReaderViewAppearance { - verifyAppearanceFontGroup(true) - verifyAppearanceFontSansSerif(true) - verifyAppearanceFontSerif(true) - verifyAppearanceFontIncrease(true) - verifyAppearanceFontDecrease(true) - verifyAppearanceColorGroup(true) - verifyAppearanceColorDark(true) - verifyAppearanceColorLight(true) - verifyAppearanceColorSepia(true) - } - } - - @Test - fun tabMediaControlButtonTest() { - val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer) - - navigationToolbar { - }.enterURLAndEnterToBrowser(audioTestPage.url) { - mDevice.waitForIdle() - clickPageObject(itemWithText("Play")) - assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) - }.openTabDrawer { - verifyTabMediaControlButtonState("Pause") - clickTabMediaControlButton("Pause") - verifyTabMediaControlButtonState("Play") - }.openTab(audioTestPage.title) { - assertPlaybackState(browserStore, MediaSession.PlaybackState.PAUSED) - } - } - - // 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() - } - } -} +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +@file:Suppress("DEPRECATION") + +package org.mozilla.fenix.ui + +import android.view.View +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.core.net.toUri +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.rule.ActivityTestRule +import androidx.test.uiautomator.UiDevice +import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.concept.engine.mediasession.MediaSession +import okhttp3.mockwebserver.MockWebServer +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mozilla.fenix.IntentReceiverActivity +import org.mozilla.fenix.R +import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.ext.components +import org.mozilla.fenix.helpers.AndroidAssetDispatcher +import org.mozilla.fenix.helpers.HomeActivityIntentTestRule +import org.mozilla.fenix.helpers.MatcherHelper.itemWithText +import org.mozilla.fenix.helpers.RetryTestRule +import org.mozilla.fenix.helpers.TestAssetHelper +import org.mozilla.fenix.helpers.TestHelper.registerAndCleanupIdlingResources +import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource +import org.mozilla.fenix.ui.robots.browserScreen +import org.mozilla.fenix.ui.robots.clickPageObject +import org.mozilla.fenix.ui.robots.homeScreen +import org.mozilla.fenix.ui.robots.navigationToolbar + +/** + * Test Suite that contains a part of the Smoke and Sanity tests defined in TestRail: + * https://testrail.stage.mozaws.net/index.php?/suites/view/3192 + * Other smoke tests have been marked with the @SmokeTest annotation throughout the ui package in order to limit this class expansion. + * These tests will verify different functionalities of the app as a way to quickly detect regressions in main areas + */ +@Suppress("ForbiddenComment") +@SmokeTest +class SmokeTest { + private lateinit var mDevice: UiDevice + private lateinit var mockWebServer: MockWebServer + private lateinit var browserStore: BrowserStore + + @get:Rule(order = 0) + val activityTestRule = AndroidComposeTestRule( + HomeActivityIntentTestRule.withDefaultSettingsOverrides(), + { it.activity }, + ) + + @get: Rule(order = 1) + val intentReceiverActivityTestRule = ActivityTestRule( + IntentReceiverActivity::class.java, + true, + false, + ) + + @Rule(order = 2) + @JvmField + val retryTestRule = RetryTestRule(3) + + @Before + fun setUp() { + // Initializing this as part of class construction, below the rule would throw a NPE + // So we are initializing this here instead of in all related tests. + browserStore = activityTestRule.activity.components.core.store + + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + start() + } + } + + @After + fun tearDown() { + mockWebServer.shutdown() + } + + @Test + fun shareTabsFromTabsTrayTest() { + val firstWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 1) + val secondWebsite = TestAssetHelper.getGenericAsset(mockWebServer, 2) + val firstWebsiteTitle = firstWebsite.title + val secondWebsiteTitle = secondWebsite.title + val sharingApp = "Gmail" + val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}" + + homeScreen { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(firstWebsite.url) { + verifyPageContent(firstWebsite.content) + }.openTabDrawer { + }.openNewTab { + }.submitQuery(secondWebsite.url.toString()) { + verifyPageContent(secondWebsite.content) + }.openTabDrawer { + verifyExistingOpenTabs("Test_Page_1") + verifyExistingOpenTabs("Test_Page_2") + }.openTabsListThreeDotMenu { + verifyShareAllTabsButton() + }.clickShareAllTabsButton { + verifyShareTabsOverlay(firstWebsiteTitle, secondWebsiteTitle) + verifySharingWithSelectedApp( + sharingApp, + sharedUrlsString, + "$firstWebsiteTitle, $secondWebsiteTitle", + ) + } + } + + @Test + fun privateTabsTrayWithOpenedTabTest() { + val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) + + homeScreen { + }.togglePrivateBrowsingMode() + + homeScreen { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(website.url) { + }.openTabDrawer { + verifyNormalBrowsingButtonIsSelected(false) + verifyPrivateBrowsingButtonIsSelected(true) + verifySyncedTabsButtonIsSelected(false) + verifyTabTrayOverflowMenu(true) + verifyTabsTrayCounter() + verifyExistingTabList() + verifyExistingOpenTabs(website.title) + verifyCloseTabsButton(website.title) + verifyOpenedTabThumbnail() + verifyPrivateBrowsingNewTabButton() + } + } + + // Test running on beta/release builds in CI: + // caution when making changes to it, so they don't block the builds + @Test + fun noHistoryInPrivateBrowsingTest() { + val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) + + homeScreen { + }.togglePrivateBrowsingMode() + + homeScreen { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(website.url) { + mDevice.waitForIdle() + }.openThreeDotMenu { + }.openHistory { + verifyEmptyHistoryView() + } + } + + @Test + fun mainMenuInstallPWATest() { + val pwaPage = "https://mozilla-mobile.github.io/testapp/" + + navigationToolbar { + }.enterURLAndEnterToBrowser(pwaPage.toUri()) { + verifyNotificationDotOnMainMenu() + }.openThreeDotMenu { + }.clickInstall { + clickAddAutomaticallyButton() + }.openHomeScreenShortcut("TEST_APP") { + mDevice.waitForIdle() + verifyNavURLBarHidden() + } + } + + // Verifies that reader mode is detected and the custom appearance controls are displayed + @Test + fun verifyReaderViewAppearanceUI() { + val readerViewPage = + TestAssetHelper.getLoremIpsumAsset(mockWebServer) + val estimatedReadingTime = "1 - 2 minutes" + + navigationToolbar { + }.enterURLAndEnterToBrowser(readerViewPage.url) { + mDevice.waitForIdle() + } + + registerAndCleanupIdlingResources( + ViewVisibilityIdlingResource( + activityTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions), + View.VISIBLE, + ), + ) {} + + navigationToolbar { + verifyReaderViewDetected(true) + toggleReaderView() + } + + browserScreen { + waitForPageToLoad() + verifyPageContent(estimatedReadingTime) + }.openThreeDotMenu { + verifyReaderViewAppearance(true) + }.openReaderViewAppearance { + verifyAppearanceFontGroup(true) + verifyAppearanceFontSansSerif(true) + verifyAppearanceFontSerif(true) + verifyAppearanceFontIncrease(true) + verifyAppearanceFontDecrease(true) + verifyAppearanceColorGroup(true) + verifyAppearanceColorDark(true) + verifyAppearanceColorLight(true) + verifyAppearanceColorSepia(true) + } + } + + @Test + fun tabMediaControlButtonTest() { + val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer) + + navigationToolbar { + }.enterURLAndEnterToBrowser(audioTestPage.url) { + mDevice.waitForIdle() + clickPageObject(itemWithText("Play")) + assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) + }.openTabDrawer { + verifyTabMediaControlButtonState("Pause") + clickTabMediaControlButton("Pause") + verifyTabMediaControlButtonState("Play") + }.openTab(audioTestPage.title) { + assertPlaybackState(browserStore, MediaSession.PlaybackState.PAUSED) + } + } +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SponsoredShortcutsTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SponsoredShortcutsTest.kt index 0f6e0522a..28a747d86 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SponsoredShortcutsTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SponsoredShortcutsTest.kt @@ -49,6 +49,7 @@ class SponsoredShortcutsTest { mockWebServer.shutdown() } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1729331 // Expected for en-us defaults @SmokeTest @Test @@ -67,6 +68,7 @@ class SponsoredShortcutsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1729338 @Test fun openSponsoredShortcutTest() { homeScreen { @@ -76,8 +78,9 @@ class SponsoredShortcutsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1729334 @Test - fun openSponsoredShortcutInPrivateBrowsingTest() { + fun openSponsoredShortcutInPrivateTabTest() { homeScreen { sponsoredShortcutTitle = getSponsoredShortcutTitle(2) }.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") @Test - fun verifySponsorsAndPrivacyLinkTest() { + fun openSponsorsAndYourPrivacyOptionTest() { homeScreen { sponsoredShortcutTitle = getSponsoredShortcutTitle(2) }.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") @Test - fun verifySponsoredShortcutsSettingsOptionTest() { + fun openSponsoredShortcutsSettingsOptionTest() { homeScreen { sponsoredShortcutTitle = getSponsoredShortcutTitle(2) }.openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle) { @@ -108,6 +113,7 @@ class SponsoredShortcutsTest { } } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1729337 @Test fun verifySponsoredShortcutsDetailsTest() { 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 @Test 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 @Test fun verifySponsoredShortcutsListWithEightPinnedSitesTest() { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt deleted file mode 100644 index afa02ef05..000000000 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt +++ /dev/null @@ -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) - } - } -} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt index d1ceacf79..5712d4ebd 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt @@ -16,7 +16,6 @@ import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.Constants.defaultTopSitesList import org.mozilla.fenix.helpers.HomeActivityIntentTestRule -import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.generateRandomString @@ -42,9 +41,6 @@ class TopSitesTest { @get:Rule val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true) - @get:Rule - val retryTestRule = RetryTestRule(3) - @Before fun setUp() { mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) @@ -218,8 +214,6 @@ class TopSitesTest { // Expected for en-us defaults @Test fun verifyDefaultTopSitesList() { - homeScreen { }.dismissOnboarding() - homeScreen { verifyExistingTopSitesList() defaultTopSitesList.values.forEach { value -> diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ContextualHintsTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/TotalCookieProtectionTest.kt similarity index 56% rename from app/src/androidTest/java/org/mozilla/fenix/ui/ContextualHintsTest.kt rename to app/src/androidTest/java/org/mozilla/fenix/ui/TotalCookieProtectionTest.kt index f43eacb5f..c2bd3acf2 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ContextualHintsTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/TotalCookieProtectionTest.kt @@ -4,19 +4,16 @@ package org.mozilla.fenix.ui +import androidx.compose.ui.test.junit4.AndroidComposeTestRule 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.ext.settings 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.itemWithDescription 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 /** @@ -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. * */ -class ContextualHintsTest { +class TotalCookieProtectionTest { private lateinit var mockWebServer: MockWebServer @get:Rule - val activityTestRule = HomeActivityTestRule( - isJumpBackInCFREnabled = true, - isTCPCFREnabled = true, - isPocketEnabled = false, - isRecentlyVisitedFeatureEnabled = false, - isCookieBannerReductionDialogEnabled = false, - ) + val composeTestRule = AndroidComposeTestRule( + HomeActivityTestRule( + isTCPCFREnabled = true, + isCookieBannerReductionDialogEnabled = false, + ), + ) { it.activity } @Before fun setUp() { @@ -49,27 +45,33 @@ class ContextualHintsTest { mockWebServer.shutdown() } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2260552 @Test fun openTotalCookieProtectionLearnMoreLinkTest() { val genericPage = getGenericAsset(mockWebServer, 1) navigationToolbar { - }.enterURLAndEnterToBrowser(genericPage.url) { - verifyCookiesProtectionHintIsDisplayed(true) - clickPageObject(itemContainingText(getStringResource(R.string.tcp_cfr_learn_more))) + }.enterURLAndEnterToBrowserForTCPCFR(genericPage.url) { + waitForPageToLoad() + verifyCookiesProtectionHintIsDisplayed(composeTestRule, true) + clickTCPCFRLearnMore(composeTestRule) 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 fun dismissTotalCookieProtectionHintTest() { val genericPage = getGenericAsset(mockWebServer, 1) navigationToolbar { - }.enterURLAndEnterToBrowser(genericPage.url) { - verifyCookiesProtectionHintIsDisplayed(true) - clickPageObject(itemWithDescription(getStringResource(R.string.mozac_cfr_dismiss_button_content_description))) - verifyCookiesProtectionHintIsDisplayed(false) + }.enterURLAndEnterToBrowserForTCPCFR(genericPage.url) { + waitForPageToLoad() + verifyCookiesProtectionHintIsDisplayed(composeTestRule, true) + dismissTCPCFRPopup(composeTestRule) + verifyCookiesProtectionHintIsDisplayed(composeTestRule, false) + verifyShouldShowCFRTCP(false, composeTestRule.activity.settings()) } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt index 7f98007af..13bd3f9af 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt @@ -5,23 +5,21 @@ package org.mozilla.fenix.ui.robots import android.os.Build -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.matcher.ViewMatchers -import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.junit4.ComposeTestRule +import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.test.performClick import androidx.test.uiautomator.By import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import org.junit.Assert.assertTrue -import org.mozilla.fenix.R import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName -import org.mozilla.fenix.helpers.click import java.util.regex.Pattern /** @@ -29,11 +27,14 @@ import java.util.regex.Pattern */ 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) @@ -104,16 +105,6 @@ fun addToHomeScreen(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenR private fun addAutomaticallyButton() = 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 = itemWithResId("$packageName:id/cancel_button") private val confirmAddToHomeScreenButton = diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt index 9d3e78074..f82de65c0 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt @@ -188,6 +188,13 @@ class BookmarksRobot { addFolderButton().click() } + fun clickAddNewFolderButtonFromSelectFolderView() = + itemWithResId("$packageName:id/add_folder_button") + .also { + it.waitForExists(waitingTime) + it.click() + } + fun addNewFolderName(name: String) { addFolderTitleField() .click() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt index c9e1d4ebf..ebd651562 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt @@ -11,7 +11,9 @@ import android.net.Uri import android.os.SystemClock import android.util.Log import android.widget.TimePicker +import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.test.performClick import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions.click 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.HomeActivityComposeTestRule 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.assertItemWithResIdExists 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.ext.waitNotNull import org.mozilla.fenix.tabstray.TabsTrayTestTag +import org.mozilla.fenix.utils.Settings import java.time.LocalDate 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 not directing to another local asset the "Download link" option is not available assertItemContainingTextExists( - contextMenuLinkUrl(containsURL.toString()), + contextMenuLinkUrl(containsURL), contextMenuOpenLinkInNewTab, contextMenuOpenLinkInPrivateTab, contextMenuCopyLink, @@ -249,15 +251,6 @@ class BrowserRobot { fun verifyMenuButton() = threeDotButton().check(matches(isDisplayed())) - fun verifyNavURLBarItems() { - navURLBar().waitForExists(waitingTime) - verifyMenuButton() - verifyTabCounter("1") - verifySearchBar() - verifySecureConnectionLockIcon() - verifyHomeScreenButton() - } - fun verifyNoLinkImageContextMenuItems(containsURL: Uri) { mDevice.waitNotNull(Until.findObject(By.textContains(containsURL.toString()))) mDevice.waitNotNull( @@ -590,16 +583,32 @@ class BrowserRobot { } } - fun verifyCookiesProtectionHintIsDisplayed(isDisplayed: Boolean) { - assertItemContainingTextExists( - totalCookieProtectionHintMessage, - totalCookieProtectionHintLearnMoreLink, - exists = isDisplayed, - ) - assertItemWithDescriptionExists( - totalCookieProtectionHintCloseButton, - exists = isDisplayed, - ) + fun verifyCookiesProtectionHintIsDisplayed(composeTestRule: HomeActivityComposeTestRule, isDisplayed: Boolean) { + if (isDisplayed) { + composeTestRule.onNodeWithTag("tcp_cfr.message").assertIsDisplayed() + composeTestRule.onNodeWithTag("tcp_cfr.action").assertIsDisplayed() + composeTestRule.onNodeWithTag("cfr.dismiss").assertIsDisplayed() + } else { + composeTestRule.onNodeWithTag("tcp_cfr.message").assertDoesNotExist() + composeTestRule.onNodeWithTag("tcp_cfr.action").assertDoesNotExist() + 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) = @@ -873,6 +882,17 @@ class BrowserRobot { 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() = itemWithResIdContainingText( "$packageName:id/dismiss", @@ -891,6 +911,18 @@ class BrowserRobot { 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 verifyDownloadPromptIsDismissed() = @@ -1066,6 +1098,21 @@ class BrowserRobot { 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 { mDevice.pressBack() @@ -1211,6 +1258,14 @@ class BrowserRobot { BrowserRobot().interact() 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 currentYear = currentDate.year 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 // Link URL @@ -1369,3 +1418,6 @@ private val contextMenuOpenInExternalApp = private val surveyButton = itemContainingText(getStringResource(R.string.preferences_take_survey)) + +private val surveyNoThanksButton = + itemContainingText(getStringResource(R.string.preferences_not_take_survey)) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt index 4193c06a8..e163d8f74 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.test.assertIsNotSelected import androidx.compose.ui.test.assertIsSelected import androidx.compose.ui.test.filter import androidx.compose.ui.test.hasAnyChild +import androidx.compose.ui.test.hasContentDescription import androidx.compose.ui.test.hasParent import androidx.compose.ui.test.hasTestTag 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. */ + @OptIn(ExperimentalTestApi::class) fun verifyTabMediaControlButtonState(action: String) { + composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(action), waitingTime) composeTestRule.tabMediaControlButton(action) .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. */ + @OptIn(ExperimentalTestApi::class) fun clickTabMediaControlButton(action: String) { + composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(action), waitingTime) composeTestRule.tabMediaControlButton(action) .performClick() } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTopSitesRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTopSitesRobot.kt new file mode 100644 index 000000000..93a13b7d8 --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTopSitesRobot.kt @@ -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() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt index 31cc5ae6f..c7a303937 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt @@ -167,13 +167,6 @@ class CustomTabRobot { ShareOverlayRobot().interact() return ShareOverlayRobot.Transition() } - - fun goBackToOnboardingScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { - mDevice.pressBack() - - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() - } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt index 6bca13907..085723b6f 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt @@ -29,6 +29,7 @@ import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_APPS_PHOTOS import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription 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.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong @@ -48,7 +49,58 @@ class DownloadRobot { 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) @@ -126,13 +178,6 @@ class DownloadRobot { return BrowserRobot.Transition() } - fun closePrompt(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - closePromptButton().click() - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - fun closeDownloadPrompt(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { 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() = onView(withId(R.id.download_dialog_close_button)) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt index dcf4a8c88..0cd61c723 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt @@ -82,6 +82,9 @@ class HistoryRobot { deleteButton(item).click() } + fun verifyDeleteHistoryItemButton(historyItemTitle: String) = + deleteButton(historyItemTitle).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + fun clickDeleteAllHistoryButton() = deleteButton().click() fun selectEverythingOption() = deleteHistoryEverythingOption().click() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt index 15dda4234..0622a0592 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt @@ -494,10 +494,6 @@ class HomeScreenRobot { return SearchRobot.Transition() } - fun dismissOnboarding() { - openThreeDotMenu { }.openSettings { }.goBack { } - } - fun clickUpgradingUserOnboardingSignInButton( testRule: ComposeTestRule, interact: SyncSignInRobot.() -> Unit, @@ -785,6 +781,11 @@ fun homeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition return HomeScreenRobot.Transition() } +fun homeScreenWithComposeTopSites(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTopSitesRobot.() -> Unit): ComposeTopSitesRobot.Transition { + ComposeTopSitesRobot(composeTestRule).interact() + return ComposeTopSitesRobot.Transition(composeTestRule) +} + private fun homeScreenList() = UiScrollable( UiSelector() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt index 0fac81254..a9d9cb127 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt @@ -191,6 +191,19 @@ class NavigationToolbarRobot { 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 { val crashUrl = "about:crashcontent" diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt index 6d7c5de1c..06ad6c1d2 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt @@ -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 { fun clickClosePrivateTabsNotification(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt index 1f4e977a1..ecffa0e59 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt @@ -6,7 +6,11 @@ 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.assertCountEquals +import androidx.compose.ui.test.hasTestTag import androidx.compose.ui.test.hasText import androidx.compose.ui.test.junit4.ComposeTestRule 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() for (searchSuggestion in searchSuggestions) { 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() { assertTrue( mDevice.findObject( diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAboutRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAboutRobot.kt index 5203940d7..3b25a269d 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAboutRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAboutRobot.kt @@ -35,7 +35,6 @@ import org.mozilla.fenix.helpers.TestHelper import org.mozilla.fenix.helpers.TestHelper.appName import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName -import org.mozilla.fenix.helpers.click import org.mozilla.fenix.settings.SupportUtils import java.text.SimpleDateFormat import java.time.LocalDateTime @@ -48,8 +47,12 @@ import java.util.Date * Implementation of Robot Pattern for the settings search sub menu. */ class SettingsSubMenuAboutRobot { - - fun verifyAboutFirefoxPreview() = assertFirefoxPreviewPage() + fun verifyAboutFirefoxPreviewInfo() { + assertVersionNumber() + assertProductCompany() + assertCurrentTimestamp() + verifyTheLinksList() + } class 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) { navigationToolbar { }.openThreeDotMenu { @@ -77,7 +73,7 @@ private fun navigateBackToAboutPage(itemToInteract: () -> Unit) { } } -private fun verifyListElements() { +private fun verifyTheLinksList() { assertAboutToolbar() assertWhatIsNewInFirefoxPreview() navigateBackToAboutPage(::assertSupport) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt index 0c0cf2ebc..86d01b8b1 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt @@ -41,6 +41,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort import org.mozilla.fenix.helpers.TestHelper.appName 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.scrollToElementByText import org.mozilla.fenix.helpers.click @@ -51,6 +52,22 @@ import org.mozilla.fenix.helpers.ext.waitNotNull */ 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) { mDevice.waitNotNull(Until.findObject(By.text("Add $addonName?")), waitingTime) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt index f6f93472c..277f58e7e 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt @@ -40,7 +40,6 @@ import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION import org.mozilla.fenix.helpers.Constants.RETRY_COUNT 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.assertItemWithResIdExists 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.sync_sign_in)), ) - assertItemWithResIdAndDescriptionExists( - itemWithResIdAndDescription( - "$packageName:id/new_tab_button", - getStringResource(R.string.resync_button_content_description), - ), - ) } class Transition { diff --git a/app/src/beta/res/drawable-hdpi/ic_logo_wordmark_normal.png b/app/src/beta/res/drawable-hdpi/ic_logo_wordmark_normal.png index 4cb02fda4..ad040413c 100644 Binary files a/app/src/beta/res/drawable-hdpi/ic_logo_wordmark_normal.png and b/app/src/beta/res/drawable-hdpi/ic_logo_wordmark_normal.png differ diff --git a/app/src/beta/res/drawable-hdpi/ic_logo_wordmark_private.png b/app/src/beta/res/drawable-hdpi/ic_logo_wordmark_private.png index 037e08be6..af4196b6e 100644 Binary files a/app/src/beta/res/drawable-hdpi/ic_logo_wordmark_private.png and b/app/src/beta/res/drawable-hdpi/ic_logo_wordmark_private.png differ diff --git a/app/src/beta/res/drawable-mdpi/ic_logo_wordmark_normal.png b/app/src/beta/res/drawable-mdpi/ic_logo_wordmark_normal.png index 193efde2d..d378e855c 100644 Binary files a/app/src/beta/res/drawable-mdpi/ic_logo_wordmark_normal.png and b/app/src/beta/res/drawable-mdpi/ic_logo_wordmark_normal.png differ diff --git a/app/src/beta/res/drawable-mdpi/ic_logo_wordmark_private.png b/app/src/beta/res/drawable-mdpi/ic_logo_wordmark_private.png index c0f356d16..791d76835 100644 Binary files a/app/src/beta/res/drawable-mdpi/ic_logo_wordmark_private.png and b/app/src/beta/res/drawable-mdpi/ic_logo_wordmark_private.png differ diff --git a/app/src/beta/res/drawable-xhdpi/ic_logo_wordmark_normal.png b/app/src/beta/res/drawable-xhdpi/ic_logo_wordmark_normal.png index 7badabff9..c89456aca 100644 Binary files a/app/src/beta/res/drawable-xhdpi/ic_logo_wordmark_normal.png and b/app/src/beta/res/drawable-xhdpi/ic_logo_wordmark_normal.png differ diff --git a/app/src/beta/res/drawable-xhdpi/ic_logo_wordmark_private.png b/app/src/beta/res/drawable-xhdpi/ic_logo_wordmark_private.png index 2573901b9..b4594f712 100644 Binary files a/app/src/beta/res/drawable-xhdpi/ic_logo_wordmark_private.png and b/app/src/beta/res/drawable-xhdpi/ic_logo_wordmark_private.png differ diff --git a/app/src/beta/res/drawable-xxhdpi/ic_logo_wordmark_normal.png b/app/src/beta/res/drawable-xxhdpi/ic_logo_wordmark_normal.png index 6a99dc263..f5a7c9be1 100644 Binary files a/app/src/beta/res/drawable-xxhdpi/ic_logo_wordmark_normal.png and b/app/src/beta/res/drawable-xxhdpi/ic_logo_wordmark_normal.png differ diff --git a/app/src/beta/res/drawable-xxhdpi/ic_logo_wordmark_private.png b/app/src/beta/res/drawable-xxhdpi/ic_logo_wordmark_private.png index f3e888316..89f49c3d9 100644 Binary files a/app/src/beta/res/drawable-xxhdpi/ic_logo_wordmark_private.png and b/app/src/beta/res/drawable-xxhdpi/ic_logo_wordmark_private.png differ diff --git a/app/src/beta/res/drawable-xxxhdpi/ic_logo_wordmark_normal.png b/app/src/beta/res/drawable-xxxhdpi/ic_logo_wordmark_normal.png index 64afec5d2..c5592328d 100644 Binary files a/app/src/beta/res/drawable-xxxhdpi/ic_logo_wordmark_normal.png and b/app/src/beta/res/drawable-xxxhdpi/ic_logo_wordmark_normal.png differ diff --git a/app/src/beta/res/drawable-xxxhdpi/ic_logo_wordmark_private.png b/app/src/beta/res/drawable-xxxhdpi/ic_logo_wordmark_private.png index bb842f128..ab9368256 100644 Binary files a/app/src/beta/res/drawable-xxxhdpi/ic_logo_wordmark_private.png and b/app/src/beta/res/drawable-xxxhdpi/ic_logo_wordmark_private.png differ diff --git a/app/src/beta/res/drawable/animated_splash_screen.xml b/app/src/beta/res/drawable/animated_splash_screen.xml index 5d0d00b8e..02b55b57a 100644 --- a/app/src/beta/res/drawable/animated_splash_screen.xml +++ b/app/src/beta/res/drawable/animated_splash_screen.xml @@ -1,3 +1,6 @@ + diff --git a/app/src/beta/res/drawable/ic_wordmark_text_normal.png b/app/src/beta/res/drawable/ic_wordmark_text_normal.png index 16ef53a53..c46dca395 100644 Binary files a/app/src/beta/res/drawable/ic_wordmark_text_normal.png and b/app/src/beta/res/drawable/ic_wordmark_text_normal.png differ diff --git a/app/src/beta/res/drawable/ic_wordmark_text_private.png b/app/src/beta/res/drawable/ic_wordmark_text_private.png index 21e67c44a..78539347d 100644 Binary files a/app/src/beta/res/drawable/ic_wordmark_text_private.png and b/app/src/beta/res/drawable/ic_wordmark_text_private.png differ diff --git a/app/src/debug/res/drawable/animated_splash_screen.xml b/app/src/debug/res/drawable/animated_splash_screen.xml index 4e96325db..e2b7ead51 100644 --- a/app/src/debug/res/drawable/animated_splash_screen.xml +++ b/app/src/debug/res/drawable/animated_splash_screen.xml @@ -1,3 +1,6 @@ + diff --git a/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt b/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt index d7a120a6e..f33b8e107 100644 --- a/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt +++ b/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt @@ -41,4 +41,5 @@ enum class BrowserDirection(@IdRes val fragmentId: Int) { FromLoginDetailFragment(R.id.loginDetailFragment), FromTabsTray(R.id.tabsTrayFragment), FromRecentlyClosed(R.id.recentlyClosedFragment), + FromReviewQualityCheck(R.id.reviewQualityCheckFragment), } diff --git a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt index 96f831323..d33a92aa2 100644 --- a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt +++ b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt @@ -67,4 +67,15 @@ object FeatureFlags { * Enables the lib-state HistoryFragment refactor */ val historyFragmentLibStateRefactor = Config.channel.isNightlyOrDebug + + /** + * Allows users to enable translations. + * Preference to fully enable translations is pref_key_enable_translations. + */ + val translations = Config.channel.isDebug + + /** + * Allows users to enable Firefox Suggest. + */ + val fxSuggest = Config.channel.isDebug } diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index 01fa39b33..29bd08b44 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -43,6 +43,7 @@ import mozilla.components.concept.storage.FrecencyThresholdOption import mozilla.components.feature.addons.migration.DefaultSupportedAddonsChecker import mozilla.components.feature.addons.update.GlobalAddonDependencyProvider import mozilla.components.feature.autofill.AutofillUseCases +import mozilla.components.feature.fxsuggest.GlobalFxSuggestDependencyProvider import mozilla.components.feature.search.ext.buildSearchUrl import mozilla.components.feature.search.ext.waitForSelectedOrDefaultSearchEngine import mozilla.components.feature.top.sites.TopSitesFrecencyConfig @@ -282,6 +283,8 @@ open class FenixApplication : LocaleAwareApplication(), Provider { startMetricsIfEnabled() setupPush() + GlobalFxSuggestDependencyProvider.initialize(components.fxSuggest.storage) + visibilityLifecycleCallback = VisibilityLifecycleCallback(getSystemService()) registerActivityLifecycleCallbacks(visibilityLifecycleCallback) registerActivityLifecycleCallbacks(MarkersActivityLifecycleCallbacks(components.core.engine)) @@ -365,6 +368,14 @@ open class FenixApplication : LocaleAwareApplication(), Provider { components.core.historyMetadataService.cleanup( System.currentTimeMillis() - Core.HISTORY_METADATA_MAX_AGE_IN_MS, ) + + // If Firefox Suggest is enabled, register a worker to periodically ingest + // new search suggestions. The worker requires us to have called + // `GlobalFxSuggestDependencyProvider.initialize`, which we did before + // scheduling these tasks. + if (settings().enableFxSuggest) { + components.fxSuggest.ingestionScheduler.startPeriodicIngestion() + } } } // Account manager initialization needs to happen on the main thread. @@ -749,6 +760,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider { adjustCreative.set(settings.adjustCreative) adjustNetwork.set(settings.adjustNetwork) + settings.migrateSearchWidgetInstalledPrefIfNeeded() searchWidgetInstalled.set(settings.searchWidgetInstalled) val openTabsCount = settings.openTabsCount @@ -815,6 +827,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider { ) ramMoreThanThreshold.set(isDeviceRamAboveThreshold) + deviceTotalRam.set(getDeviceTotalRAM()) } with(AndroidAutofill) { @@ -863,12 +876,27 @@ open class FenixApplication : LocaleAwareApplication(), Provider { } } - private fun deviceRamApproxMegabytes(): Long { + @VisibleForTesting + internal fun getDeviceTotalRAM(): Long { + val memoryInfo = getMemoryInfo() + return if (SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + memoryInfo.advertisedMem + } else { + memoryInfo.totalMem + } + } + + @VisibleForTesting + internal fun getMemoryInfo(): ActivityManager.MemoryInfo { val memoryInfo = ActivityManager.MemoryInfo() val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager activityManager.getMemoryInfo(memoryInfo) - val deviceRamBytes = memoryInfo.totalMem + return memoryInfo + } + + private fun deviceRamApproxMegabytes(): Long { + val deviceRamBytes = getMemoryInfo().totalMem return deviceRamBytes.toRoundedMegabytes() } diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index a56ff7b48..65c8cae5d 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -80,7 +80,7 @@ import mozilla.components.support.utils.BrowsersCache import mozilla.components.support.utils.ManufacturerCodes import mozilla.components.support.utils.SafeIntent import mozilla.components.support.utils.toSafeIntent -import mozilla.components.support.webextensions.WebExtensionPopupFeature +import mozilla.components.support.webextensions.WebExtensionPopupObserver import mozilla.telemetry.glean.private.NoExtras import org.mozilla.experiments.nimbus.initializeTooling import org.mozilla.fenix.GleanMetrics.AppIcon @@ -153,6 +153,7 @@ import org.mozilla.fenix.settings.search.SaveSearchEngineFragmentDirections import org.mozilla.fenix.settings.studies.StudiesFragmentDirections import org.mozilla.fenix.settings.wallpaper.WallpaperSettingsFragmentDirections import org.mozilla.fenix.share.AddNewDeviceFragmentDirections +import org.mozilla.fenix.shopping.ReviewQualityCheckFragmentDirections import org.mozilla.fenix.shortcut.NewTabShortcutIntentProcessor.Companion.ACTION_OPEN_PRIVATE_TAB import org.mozilla.fenix.tabhistory.TabHistoryDialogFragment import org.mozilla.fenix.tabstray.TabsTrayFragment @@ -189,8 +190,12 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { private var isToolbarInflated = false - private val webExtensionPopupFeature by lazy { - WebExtensionPopupFeature(components.core.store, ::openPopup) + private val webExtensionPopupObserver by lazy { + WebExtensionPopupObserver(components.core.store, ::openPopup) + } + + private val extensionProcessDisabledPopupObserver by lazy { + ExtensionProcessDisabledController(this@HomeActivity, components.core.store) } private val extensionProcessDisabledPopupFeature by lazy { @@ -307,6 +312,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { if (savedInstanceState == null) { navigateToHome() } + if (!shouldStartOnHome() && shouldNavigateToBrowserOnColdStart(savedInstanceState)) { navigateToBrowserOnColdStart() } else { @@ -316,6 +322,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { if (settings().showHomeOnboardingDialog && components.fenixOnboarding.userHasBeenOnboarded()) { navHost.navController.navigate(NavGraphDirections.actionGlobalHomeOnboardingDialog()) } + showNotificationPermissionPromptIfRequired() } @@ -345,7 +352,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { } supportActionBar?.hide() - lifecycle.addObservers(webExtensionPopupFeature, extensionProcessDisabledPopupFeature, serviceWorkerSupport) + lifecycle.addObservers(webExtensionPopupObserver, extensionProcessDisabledPopupObserver, serviceWorkerSupport) if (shouldAddToRecentsScreen(intent)) { intent.removeExtra(START_IN_RECENTS_SCREEN) @@ -412,10 +419,6 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { * Show the pre permission dialog to the user once if the notification are not enabled. */ private fun showNotificationPermissionPromptIfRequired() { - if (settings().junoOnboardingEnabled) { - return - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && !NotificationManagerCompat.from(applicationContext).areNotificationsEnabledSafe() && settings().numberOfAppLaunches <= 1 @@ -1045,6 +1048,9 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { BrowserDirection.FromStudiesFragment -> StudiesFragmentDirections.actionGlobalBrowser( customTabSessionId, ) + BrowserDirection.FromReviewQualityCheck -> ReviewQualityCheckFragmentDirections.actionGlobalBrowser( + customTabSessionId, + ) } /** diff --git a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt index bc493f4ea..4cccac237 100644 --- a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt @@ -32,7 +32,6 @@ import io.github.forkmaintainers.iceraven.components.PagedAddonsManagerAdapter import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch -import mozilla.components.concept.engine.webextension.WebExtensionInstallException import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.AddonManager import mozilla.components.feature.addons.AddonManagerException @@ -40,20 +39,22 @@ import mozilla.components.feature.addons.ui.translateName import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.ktx.android.view.hideKeyboard +import mozilla.components.feature.addons.ui.AddonsManagerAdapter +import mozilla.components.support.base.feature.ViewBoundFeatureWrapper +import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.Config +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.databinding.FragmentAddOnsManagementBinding import org.mozilla.fenix.ext.components -import org.mozilla.fenix.ext.getRootView import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.runIfFragmentIsAttached import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.extension.WebExtensionPromptFeature import org.mozilla.fenix.theme.ThemeManager -import java.util.concurrent.CancellationException import java.util.Locale /** @@ -70,11 +71,6 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) private val webExtensionPromptFeature = ViewBoundFeatureWrapper() - /** - * Whether or not an add-on installation is in progress. - */ - private var isInstallationInProgress = false - private var installExternalAddonComplete: Boolean set(value) { arguments?.putBoolean(BUNDLE_KEY_INSTALL_EXTERNAL_ADDON_COMPLETE, value) @@ -98,10 +94,8 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) webExtensionPromptFeature.set( feature = WebExtensionPromptFeature( store = requireComponents.core.store, - provideAddons = { addons!! }, context = requireContext(), fragmentManager = parentFragmentManager, - snackBarParentView = view, onAddonChanged = { runIfFragmentIsAttached { adapter?.updateAddon(it) @@ -239,6 +233,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) val managementView = AddonsManagementView( navController = findNavController(), onInstallButtonClicked = ::installAddon, + onMoreAddonsButtonClicked = ::openAMO, ) val recyclerView = binding?.addOnsList @@ -265,7 +260,6 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) style = createAddonStyle(requireContext()), ) } - isInstallationInProgress = false binding?.addOnsProgressBar?.isVisible = false binding?.addOnsEmptyMessage?.isVisible = false @@ -290,7 +284,6 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) getString(R.string.mozac_feature_addons_failed_to_query_add_ons), ) } - isInstallationInProgress = false binding?.addOnsProgressBar?.isVisible = false binding?.addOnsEmptyMessage?.isVisible = true } @@ -357,30 +350,12 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) addon, onSuccess = { runIfFragmentIsAttached { - isInstallationInProgress = false adapter?.updateAddon(it) binding?.addonProgressOverlay?.overlayCardView?.visibility = View.GONE } }, - onError = { _, e -> - this@AddonsManagementFragment.view?.let { view -> - // No need to display an error message if installation was cancelled by the user. - if (e !is CancellationException && e !is WebExtensionInstallException.UserCancelled) { - val rootView = activity?.getRootView() ?: view - var messageId = R.string.mozac_feature_addons_failed_to_install - if (e is WebExtensionInstallException.Blocklisted) { - messageId = R.string.mozac_feature_addons_blocklisted - } - context?.let { - showErrorSnackBar( - text = getString(messageId, addon.translateName(it)), - anchorView = rootView, - ) - } - } - binding?.addonProgressOverlay?.overlayCardView?.visibility = View.GONE - isInstallationInProgress = false - } + onError = { _, _ -> + binding?.addonProgressOverlay?.overlayCardView?.visibility = View.GONE }, ) binding?.addonProgressOverlay?.cancelButton?.setOnClickListener { @@ -413,7 +388,20 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) } } + private fun openAMO() { + (activity as HomeActivity).openToBrowserAndLoad( + searchTermOrURL = AMO_HOMEPAGE_FOR_ANDROID, + newTab = true, + from = BrowserDirection.FromGlobal, + ) + } + companion object { private const val BUNDLE_KEY_INSTALL_EXTERNAL_ADDON_COMPLETE = "INSTALL_EXTERNAL_ADDON_COMPLETE" + + // This is locale-less on purpose so that the content negotiation happens on the AMO side because the current + // user language might not be supported by AMO and/or the language might not be exactly what AMO is expecting + // (e.g. `en` instead of `en-US`). + private const val AMO_HOMEPAGE_FOR_ANDROID = "https://addons.mozilla.org/android/" } } diff --git a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementView.kt b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementView.kt index a58fa9596..117c3f8e5 100644 --- a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementView.kt +++ b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementView.kt @@ -7,6 +7,7 @@ package org.mozilla.fenix.addons import androidx.navigation.NavController import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.ui.AddonsManagerAdapterDelegate +import org.mozilla.fenix.Config import org.mozilla.fenix.R import org.mozilla.fenix.ext.navigateSafe @@ -16,6 +17,7 @@ import org.mozilla.fenix.ext.navigateSafe class AddonsManagementView( private val navController: NavController, private val onInstallButtonClicked: (Addon) -> Unit, + private val onMoreAddonsButtonClicked: () -> Unit, ) : AddonsManagerAdapterDelegate { override fun onAddonItemClicked(addon: Addon) { @@ -34,6 +36,14 @@ class AddonsManagementView( showNotYetSupportedAddonFragment(unsupportedAddons) } + override fun shouldShowFindMoreAddonsButton(): Boolean { + return !Config.channel.isRelease + } + + override fun onFindMoreAddonsButtonClicked() { + onMoreAddonsButtonClicked() + } + private fun showInstalledAddonDetailsFragment(addon: Addon) { val directions = AddonsManagementFragmentDirections.actionAddonsManagementFragmentToInstalledAddonDetails( diff --git a/app/src/main/java/org/mozilla/fenix/addons/ExtensionProcessDisabledController.kt b/app/src/main/java/org/mozilla/fenix/addons/ExtensionProcessDisabledController.kt index 0148de27a..4d85768c2 100644 --- a/app/src/main/java/org/mozilla/fenix/addons/ExtensionProcessDisabledController.kt +++ b/app/src/main/java/org/mozilla/fenix/addons/ExtensionProcessDisabledController.kt @@ -10,62 +10,17 @@ import android.widget.Button import android.widget.TextView import androidx.annotation.UiContext import androidx.appcompat.app.AlertDialog +import androidx.lifecycle.LifecycleOwner import mozilla.components.browser.state.action.ExtensionProcessDisabledPopupAction import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.Engine import mozilla.components.support.ktx.android.content.appName -import mozilla.components.support.webextensions.ExtensionProcessDisabledPopupFeature +import mozilla.components.support.webextensions.ExtensionProcessDisabledPopupObserver import org.mozilla.fenix.GleanMetrics.Addons import org.mozilla.fenix.R import org.mozilla.fenix.ext.components import org.mozilla.geckoview.WebExtensionController -/** - * Present a dialog to the user notifying of extension process spawning disabled and also asking - * whether they would like to continue trying or disable extensions. If the user chooses to retry, - * enable the extension process spawning with [WebExtensionController.enableExtensionProcessSpawning]. - * - * @param context to show the AlertDialog - * @param store The [BrowserStore] which holds the state for showing the dialog - * @param webExtensionController to call when a user enables the process spawning - * @param builder to use for creating the dialog which can be styled as needed - * @param appName to be added to the message. Necessary to be added as a param for testing - */ -private fun presentDialog( - @UiContext context: Context, - store: BrowserStore, - engine: Engine, - builder: AlertDialog.Builder, - appName: String, -) { - val message = context.getString(R.string.addon_process_crash_dialog_message, appName) - var onDismissDialog: (() -> Unit)? = null - val layout = LayoutInflater.from(context) - .inflate(R.layout.crash_extension_dialog, null, false) - layout?.apply { - findViewById(R.id.message)?.text = message - findViewById