From 63b923d7a5c45fca3d4d9c0e707f7d0c34a31156 Mon Sep 17 00:00:00 2001 From: Roger Yang Date: Mon, 29 Jan 2024 17:23:02 -0500 Subject: [PATCH 001/586] Revert "Bug 1876419 - Update ktlint-baseline for all projects" This reverts commit 1c653a5f9703565ef03e1d5beb0d43ff575228f3. --- android-components/ktlint-baseline.xml | 4602 +----------------------- fenix/ktlint-baseline.xml | 2623 +------------- focus-android/build.gradle | 4 +- focus-android/ktlint-baseline.xml | 184 - 4 files changed, 6 insertions(+), 7407 deletions(-) delete mode 100644 focus-android/ktlint-baseline.xml diff --git a/android-components/ktlint-baseline.xml b/android-components/ktlint-baseline.xml index 02ee05593080..55cb1f65701a 100644 --- a/android-components/ktlint-baseline.xml +++ b/android-components/ktlint-baseline.xml @@ -2,4624 +2,24 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/fenix/ktlint-baseline.xml b/fenix/ktlint-baseline.xml index 2905d3cc80d8..b033ff3cc01b 100644 --- a/fenix/ktlint-baseline.xml +++ b/fenix/ktlint-baseline.xml @@ -2,2626 +2,9 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/focus-android/build.gradle b/focus-android/build.gradle index be9ed4526835..ee4d63d40b67 100644 --- a/focus-android/build.gradle +++ b/focus-android/build.gradle @@ -140,7 +140,7 @@ tasks.register('ktlint', JavaExec) { description = "Check Kotlin code style." classpath = configurations.ktlint mainClass.set("com.pinterest.ktlint.Main") - args "app/**/*.kt", "!**/build/**/*.kt", "buildSrc/**/*.kt", "--baseline=ktlint-baseline.xml" + args "app/**/*.kt", "!**/build/**/*.kt", "buildSrc/**/*.kt" } @@ -148,7 +148,7 @@ tasks.register('ktlintFormat', JavaExec) { description = "Fix Kotlin code style deviations." classpath = configurations.ktlint mainClass.set("com.pinterest.ktlint.Main") - args "-F", "app/**/*.kt", "!**/build/**/*.kt", "buildSrc/**/*.kt", "--baseline=ktlint-baseline.xml" + args "-F", "app/**/*.kt", "!**/build/**/*.kt", "buildSrc/**/*.kt" jvmArgs("--add-opens", "java.base/java.lang=ALL-UNNAMED") } diff --git a/focus-android/ktlint-baseline.xml b/focus-android/ktlint-baseline.xml deleted file mode 100644 index ead7512d7fd0..000000000000 --- a/focus-android/ktlint-baseline.xml +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 12ae716f4c00ec2bc0b169a5a9f11f61ddc2534b Mon Sep 17 00:00:00 2001 From: Roger Yang Date: Mon, 29 Jan 2024 17:23:02 -0500 Subject: [PATCH 002/586] Revert "Bug 1876419 - Move comment from editorconfig files" This reverts commit f293b810969921ac6468f75a7915375c0c1cab4f. --- android-components/.editorconfig | 4 +--- fenix/.editorconfig | 4 +--- focus-android/.editorconfig | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/android-components/.editorconfig b/android-components/.editorconfig index 2e3da5d4b2e7..f5a93d57bef3 100644 --- a/android-components/.editorconfig +++ b/android-components/.editorconfig @@ -9,9 +9,7 @@ root = True [*.kt] indent_size = 4 indent_style = space - -# Matches maxLineLength in detekt.yml -max_line_length = 120 +max_line_length = 120 # Matches maxLineLength in detekt.yml ij_kotlin_allow_trailing_comma_on_call_site=true ij_kotlin_allow_trailing_comma=true diff --git a/fenix/.editorconfig b/fenix/.editorconfig index fe4b8e6b70ef..35408b9312de 100644 --- a/fenix/.editorconfig +++ b/fenix/.editorconfig @@ -1,9 +1,7 @@ [*.{kt,kts}] ij_kotlin_allow_trailing_comma_on_call_site=true ij_kotlin_allow_trailing_comma=true - -# Matches maxLineLength in detekt.yml -max_line_length = 120 +max_line_length = 120 # Matches maxLineLength in detekt.yml [*] insert_final_newline = true diff --git a/focus-android/.editorconfig b/focus-android/.editorconfig index 449aee5ee2c6..bc45217f6eae 100644 --- a/focus-android/.editorconfig +++ b/focus-android/.editorconfig @@ -1,8 +1,6 @@ [*.{kt,kts}] ij_kotlin_allow_trailing_comma_on_call_site=true ij_kotlin_allow_trailing_comma=true - -# Matches maxLineLength in detekt.yml -max_line_length = 120 +max_line_length = 120 # Matches maxLineLength in detekt.yml ktlint_standard_filename = disabled \ No newline at end of file From 904518801d8dbbdd871a2c05fb1212887f8c7af4 Mon Sep 17 00:00:00 2001 From: Harrison Oglesby Date: Thu, 25 Jan 2024 15:17:45 -0800 Subject: [PATCH 003/586] Bug 1864760 - Added actions to Toolbar and MenuButton to hide and show the menu button --- .../browser/toolbar/BrowserToolbar.kt | 14 +++++++++++ .../browser/toolbar/display/DisplayToolbar.kt | 14 +++++++++++ .../browser/toolbar/display/MenuButton.kt | 9 +++++++ .../browser/toolbar/BrowserToolbarTest.kt | 24 +++++++++++++++++++ .../components/concept/toolbar/Toolbar.kt | 10 ++++++++ .../CustomTabSessionTitleObserverTest.kt | 2 ++ .../toolbar/ToolbarAutocompleteFeatureTest.kt | 8 +++++++ .../feature/toolbar/ToolbarInteractorTest.kt | 8 +++++++ docs/changelog.md | 4 ++++ 9 files changed, 93 insertions(+) diff --git a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/BrowserToolbar.kt b/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/BrowserToolbar.kt index 404c6f00e11b..488fdf628854 100644 --- a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/BrowserToolbar.kt +++ b/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/BrowserToolbar.kt @@ -335,6 +335,20 @@ class BrowserToolbar @JvmOverloads constructor( edit.removeEditActionEnd(action) } + /** + * Hides the menu button in display mode. + */ + override fun hideMenuButton() { + display.hideMenuButton() + } + + /** + * Shows the menu button in display mode. + */ + override fun showMenuButton() { + display.showMenuButton() + } + /** * Switches to URL editing mode. * diff --git a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/display/DisplayToolbar.kt b/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/display/DisplayToolbar.kt index 19a83d862666..a4f206fe4318 100644 --- a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/display/DisplayToolbar.kt +++ b/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/display/DisplayToolbar.kt @@ -648,6 +648,20 @@ class DisplayToolbar internal constructor( internal fun removeNavigationAction(action: Toolbar.Action) { views.navigationActions.removeAction(action) } + + /** + * Hides the menu button in display mode. + */ + internal fun hideMenuButton() { + views.menu.setShouldBeHidden(true) + } + + /** + * Shows the menu button in display mode. + */ + internal fun showMenuButton() { + views.menu.setShouldBeHidden(false) + } } /** diff --git a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/display/MenuButton.kt b/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/display/MenuButton.kt index 2a0990830962..621e20032b33 100644 --- a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/display/MenuButton.kt +++ b/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/display/MenuButton.kt @@ -92,6 +92,15 @@ internal class MenuButton( fun setColorFilter(@ColorInt color: Int) = impl.setColorFilter(color) + /** + * Hides the menu button. + * + * @param shouldBeHidden A [Boolean] that determines the visibility of the menu button. + */ + fun setShouldBeHidden(shouldBeHidden: Boolean) { + impl.isVisible = !shouldBeHidden && shouldBeVisible() + } + @VisibleForTesting internal fun shouldBeVisible() = impl.menuBuilder != null || impl.menuController != null } diff --git a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/BrowserToolbarTest.kt b/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/BrowserToolbarTest.kt index 735e1cc66f9b..33b7352a1728 100644 --- a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/BrowserToolbarTest.kt +++ b/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/BrowserToolbarTest.kt @@ -542,6 +542,30 @@ class BrowserToolbarTest { verify(edit).removeEditActionEnd(action) } + @Test + fun `WHEN hideMenuButton is sent to BrowserToolbar THEN it will be forwarded to the DisplayToolbar`() { + val toolbar = BrowserToolbar(testContext) + + val display: DisplayToolbar = mock() + toolbar.display = display + + toolbar.hideMenuButton() + + verify(display).hideMenuButton() + } + + @Test + fun `WHEN showMenuButton is sent to BrowserToolbar THEN it will be forwarded to the DisplayToolbar`() { + val toolbar = BrowserToolbar(testContext) + + val display: DisplayToolbar = mock() + toolbar.display = display + + toolbar.showMenuButton() + + verify(display).showMenuButton() + } + @Test fun `cast to view`() { // Given diff --git a/android-components/components/concept/toolbar/src/main/java/mozilla/components/concept/toolbar/Toolbar.kt b/android-components/components/concept/toolbar/src/main/java/mozilla/components/concept/toolbar/Toolbar.kt index 740d71c84031..16c0e7c6655f 100644 --- a/android-components/components/concept/toolbar/src/main/java/mozilla/components/concept/toolbar/Toolbar.kt +++ b/android-components/components/concept/toolbar/src/main/java/mozilla/components/concept/toolbar/Toolbar.kt @@ -173,6 +173,16 @@ interface Toolbar { */ fun removeEditActionEnd(action: Action) + /** + * Hides the menu button in display mode. + */ + fun hideMenuButton() + + /** + * Shows the menu button in display mode. + */ + fun showMenuButton() + /** * Casts this toolbar to an Android View object. */ diff --git a/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/feature/CustomTabSessionTitleObserverTest.kt b/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/feature/CustomTabSessionTitleObserverTest.kt index 6551d181c64c..de293b5a7de9 100644 --- a/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/feature/CustomTabSessionTitleObserverTest.kt +++ b/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/feature/CustomTabSessionTitleObserverTest.kt @@ -88,6 +88,8 @@ class CustomTabSessionTitleObserverTest { override fun addEditActionStart(action: Toolbar.Action) = Unit override fun addEditActionEnd(action: Toolbar.Action) = Unit override fun removeEditActionEnd(action: Toolbar.Action) = Unit + override fun hideMenuButton() = Unit + override fun showMenuButton() = Unit override fun setOnEditListener(listener: Toolbar.OnEditListener) = Unit override fun displayMode() = Unit override fun editMode(cursorPlacement: Toolbar.CursorPlacement) = Unit diff --git a/android-components/components/feature/toolbar/src/test/java/mozilla/components/feature/toolbar/ToolbarAutocompleteFeatureTest.kt b/android-components/components/feature/toolbar/src/test/java/mozilla/components/feature/toolbar/ToolbarAutocompleteFeatureTest.kt index dda24d1fb5ab..6f493c232a45 100644 --- a/android-components/components/feature/toolbar/src/test/java/mozilla/components/feature/toolbar/ToolbarAutocompleteFeatureTest.kt +++ b/android-components/components/feature/toolbar/src/test/java/mozilla/components/feature/toolbar/ToolbarAutocompleteFeatureTest.kt @@ -115,6 +115,14 @@ class ToolbarAutocompleteFeatureTest { fail() } + override fun hideMenuButton() { + fail() + } + + override fun showMenuButton() { + fail() + } + override fun invalidateActions() { fail() } diff --git a/android-components/components/feature/toolbar/src/test/java/mozilla/components/feature/toolbar/ToolbarInteractorTest.kt b/android-components/components/feature/toolbar/src/test/java/mozilla/components/feature/toolbar/ToolbarInteractorTest.kt index d726015a825f..e84c9ad32b66 100644 --- a/android-components/components/feature/toolbar/src/test/java/mozilla/components/feature/toolbar/ToolbarInteractorTest.kt +++ b/android-components/components/feature/toolbar/src/test/java/mozilla/components/feature/toolbar/ToolbarInteractorTest.kt @@ -98,6 +98,14 @@ class ToolbarInteractorTest { fail() } + override fun hideMenuButton() { + fail() + } + + override fun showMenuButton() { + fail() + } + override fun invalidateActions() { fail() } diff --git a/docs/changelog.md b/docs/changelog.md index c165b4c1be8f..0f52b2882f33 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -16,6 +16,10 @@ permalink: /changelog/ * **all components** * All new usages of the `concept-fetch` component to make fetch requests now have conservative-mode off by default. Current features will continue to use conservative mode until individually updated. + +* **browser-toolbar** + * Add `showMenuButton` and `hideMenuButton` API to `BrowserToolbar` and `DisplayToolbar` to allow hiding and showing of the menu button in + the `BrowserToolbar` [Bug 1864760](https://bugzilla.mozilla.org/show_bug.cgi?id=1864760) # 123.0 * [Commits](https://github.com/mozilla-mobile/firefox-android/compare/releases_v122..releases_v123) From 0b4e9c39820257b43e4c27317bdbae7b68cd5fa1 Mon Sep 17 00:00:00 2001 From: Roger Yang Date: Mon, 29 Jan 2024 18:09:38 -0500 Subject: [PATCH 004/586] Revert "Bug 1875923 - Update max_line_length in editorconfig to match detekt" --- android-components/.editorconfig | 1 - fenix/.editorconfig | 1 - focus-android/.editorconfig | 1 - 3 files changed, 3 deletions(-) diff --git a/android-components/.editorconfig b/android-components/.editorconfig index f5a93d57bef3..fa63180a86a4 100644 --- a/android-components/.editorconfig +++ b/android-components/.editorconfig @@ -9,7 +9,6 @@ root = True [*.kt] indent_size = 4 indent_style = space -max_line_length = 120 # Matches maxLineLength in detekt.yml ij_kotlin_allow_trailing_comma_on_call_site=true ij_kotlin_allow_trailing_comma=true diff --git a/fenix/.editorconfig b/fenix/.editorconfig index 35408b9312de..7ea380af1c2c 100644 --- a/fenix/.editorconfig +++ b/fenix/.editorconfig @@ -1,7 +1,6 @@ [*.{kt,kts}] ij_kotlin_allow_trailing_comma_on_call_site=true ij_kotlin_allow_trailing_comma=true -max_line_length = 120 # Matches maxLineLength in detekt.yml [*] insert_final_newline = true diff --git a/focus-android/.editorconfig b/focus-android/.editorconfig index bc45217f6eae..3232ddd4a3b7 100644 --- a/focus-android/.editorconfig +++ b/focus-android/.editorconfig @@ -1,6 +1,5 @@ [*.{kt,kts}] ij_kotlin_allow_trailing_comma_on_call_site=true ij_kotlin_allow_trailing_comma=true -max_line_length = 120 # Matches maxLineLength in detekt.yml ktlint_standard_filename = disabled \ No newline at end of file From c347b704cbffd8cc6b00f3cf33786b677159d10a Mon Sep 17 00:00:00 2001 From: Roger Yang Date: Mon, 29 Jan 2024 15:47:28 -0500 Subject: [PATCH 005/586] Bug 1877039 - Do not attempt to trigger external app if new request was too soon --- .../feature/app/links/AppLinksInterceptor.kt | 13 ++++++++++ .../app/links/AppLinksInterceptorTest.kt | 24 +++++++++++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/android-components/components/feature/app-links/src/main/java/mozilla/components/feature/app/links/AppLinksInterceptor.kt b/android-components/components/feature/app-links/src/main/java/mozilla/components/feature/app/links/AppLinksInterceptor.kt index 729e659b5ae7..0b7a6b3383ce 100644 --- a/android-components/components/feature/app-links/src/main/java/mozilla/components/feature/app/links/AppLinksInterceptor.kt +++ b/android-components/components/feature/app-links/src/main/java/mozilla/components/feature/app/links/AppLinksInterceptor.kt @@ -102,6 +102,8 @@ class AppLinksInterceptor( (!interceptLinkClicks || !launchInApp()) && engineSupportsScheme -> true // Never go to an external app when scheme is in blocklist alwaysDeniedSchemes.contains(uriScheme) -> true + // always check this last + lastHasExternalAppTimestamp + APP_LINKS_DO_NOT_INTERCEPT_INTERVAL > SystemClock.elapsedRealtime() -> true else -> false } @@ -112,6 +114,10 @@ class AppLinksInterceptor( val redirect = useCases.interceptedAppLinkRedirect(uri) val result = handleRedirect(redirect, uri, engineSupportedSchemes.contains(uriScheme)) + if (redirect.hasExternalApp()) { + lastHasExternalAppTimestamp = SystemClock.elapsedRealtime() + } + if (redirect.isRedirect()) { if (launchFromInterceptor && result is RequestInterceptor.InterceptionResponse.AppIntent) { result.appIntent.flags = result.appIntent.flags or Intent.FLAG_ACTIVITY_NEW_TASK @@ -184,6 +190,10 @@ class AppLinksInterceptor( @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal var userDoNotInterceptCache: MutableMap = mutableMapOf() + // This should be improved. See https://bugzilla.mozilla.org/show_bug.cgi?id=1877323 + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + internal var lastHasExternalAppTimestamp: Long = 0L + @VisibleForTesting internal fun getCacheKey(url: String, appIntent: Intent?): Int? { return Uri.parse(url)?.let { uri -> @@ -214,5 +224,8 @@ class AppLinksInterceptor( @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal const val APP_LINKS_DO_NOT_OPEN_CACHE_INTERVAL = 60 * 60 * 1000L // 1 hour + + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + internal const val APP_LINKS_DO_NOT_INTERCEPT_INTERVAL = 500L // 1/2 second } } diff --git a/android-components/components/feature/app-links/src/test/java/mozilla/components/feature/app/links/AppLinksInterceptorTest.kt b/android-components/components/feature/app-links/src/test/java/mozilla/components/feature/app/links/AppLinksInterceptorTest.kt index 02bf62628e85..46416fb5ebb5 100644 --- a/android-components/components/feature/app-links/src/test/java/mozilla/components/feature/app/links/AppLinksInterceptorTest.kt +++ b/android-components/components/feature/app-links/src/test/java/mozilla/components/feature/app/links/AppLinksInterceptorTest.kt @@ -10,9 +10,11 @@ import android.content.Intent import androidx.test.ext.junit.runners.AndroidJUnit4 import mozilla.components.concept.engine.EngineSession import mozilla.components.concept.engine.request.RequestInterceptor +import mozilla.components.feature.app.links.AppLinksInterceptor.Companion.APP_LINKS_DO_NOT_INTERCEPT_INTERVAL import mozilla.components.feature.app.links.AppLinksInterceptor.Companion.APP_LINKS_DO_NOT_OPEN_CACHE_INTERVAL import mozilla.components.feature.app.links.AppLinksInterceptor.Companion.addUserDoNotIntercept import mozilla.components.feature.app.links.AppLinksInterceptor.Companion.inUserDoNotIntercept +import mozilla.components.feature.app.links.AppLinksInterceptor.Companion.lastHasExternalAppTimestamp import mozilla.components.feature.app.links.AppLinksInterceptor.Companion.userDoNotInterceptCache import mozilla.components.support.test.any import mozilla.components.support.test.mock @@ -54,6 +56,7 @@ class AppLinksInterceptorTest { whenever(mockUseCases.interceptedAppLinkRedirect).thenReturn(mockGetRedirect) whenever(mockUseCases.openAppLink).thenReturn(mockOpenRedirect) userDoNotInterceptCache.clear() + lastHasExternalAppTimestamp = -APP_LINKS_DO_NOT_INTERCEPT_INTERVAL val webRedirect = AppLinkRedirect(null, webUrl, null) val appRedirect = AppLinkRedirect(Intent.parseUri(intentUrl, 0), null, null) @@ -557,12 +560,9 @@ class AppLinksInterceptorTest { useCases = mockUseCases, ) - var response = appLinksInterceptor.onLoadRequest(mockEngineSession, webUrlWithAppLink, null, true, false, false, false, false) - assert(response is RequestInterceptor.InterceptionResponse.AppIntent) - addUserDoNotIntercept("https://soundcloud.com", null) - response = appLinksInterceptor.onLoadRequest(mockEngineSession, webUrlWithAppLink, null, true, false, false, false, false) + val response = appLinksInterceptor.onLoadRequest(mockEngineSession, webUrlWithAppLink, null, true, false, false, false, false) assertNull(response) } @@ -644,4 +644,20 @@ class AppLinksInterceptorTest { assertFalse(inUserDoNotIntercept("https://example.com", testIntent)) assertFalse(inUserDoNotIntercept("https://test.com", testIntent)) } + + @Test + fun `WHEN request is redirecting to external app quickly THEN request is not intercepted`() { + appLinksInterceptor = AppLinksInterceptor( + context = mockContext, + interceptLinkClicks = true, + launchInApp = { true }, + useCases = mockUseCases, + ) + + var response = appLinksInterceptor.onLoadRequest(mockEngineSession, webUrlWithAppLink, null, true, false, false, false, false) + assertTrue(response is RequestInterceptor.InterceptionResponse.AppIntent) + + response = appLinksInterceptor.onLoadRequest(mockEngineSession, webUrlWithAppLink, null, true, false, false, false, false) + assertNull(response) + } } From e3f3092298577117d77753ea8cb5551cddae107f Mon Sep 17 00:00:00 2001 From: t-p-white Date: Thu, 25 Jan 2024 14:38:51 +0000 Subject: [PATCH 006/586] Bug 1852224 - Prevent background media from being stopped when existing application from an external link. --- .../src/main/java/org/mozilla/fenix/HomeActivity.kt | 3 ++- .../org/mozilla/fenix/perf/StartupPathProvider.kt | 1 - .../mozilla/fenix/perf/StartupPathProviderTest.kt | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index eaa4d725a0b3..8ea4a4d8efc2 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -612,7 +612,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { privateNotificationObserver?.stop() components.notificationsDelegate.unBindActivity(this) - if (this !is ExternalAppBrowserActivity) { + val activityStartedWithLink = startupPathProvider.startupPathForActivity == StartupPathProvider.StartupPath.VIEW + if (this !is ExternalAppBrowserActivity && !activityStartedWithLink) { stopMediaSession() } } diff --git a/fenix/app/src/main/java/org/mozilla/fenix/perf/StartupPathProvider.kt b/fenix/app/src/main/java/org/mozilla/fenix/perf/StartupPathProvider.kt index 1cd626306786..d6b0abe1ca86 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/perf/StartupPathProvider.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/perf/StartupPathProvider.kt @@ -100,7 +100,6 @@ class StartupPathProvider { override fun onStop(owner: LifecycleOwner) { // Clear existing state. - startupPathForActivity = StartupPath.NOT_SET wasResumedSinceStartedState = false } } diff --git a/fenix/app/src/test/java/org/mozilla/fenix/perf/StartupPathProviderTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/perf/StartupPathProviderTest.kt index 8d22d86d3ee6..ad14ebc0c13f 100644 --- a/fenix/app/src/test/java/org/mozilla/fenix/perf/StartupPathProviderTest.kt +++ b/fenix/app/src/test/java/org/mozilla/fenix/perf/StartupPathProviderTest.kt @@ -108,12 +108,12 @@ class StartupPathProviderTest { } @Test - fun `GIVEN the app is launched to the homescreen and stopped WHEN getting the start up path THEN it is not set`() { + fun `GIVEN the app is launched to the homescreen with MAIN and stopped WHEN getting the start up path THEN it set to MAIN`() { every { intent.action } returns Intent.ACTION_MAIN launchApp(intent) stopLaunchedApp() - assertEquals(StartupPath.NOT_SET, provider.startupPathForActivity) + assertEquals(StartupPath.MAIN, provider.startupPathForActivity) } @Test @@ -129,13 +129,13 @@ class StartupPathProviderTest { } @Test - fun `GIVEN the app is launched to the homescreen, stopped, and relaunched warm from the app switcher WHEN getting the start up path THEN it is not set`() { + fun `GIVEN the app is launched to the homescreen with MAIN, stopped, and relaunched warm from the app switcher WHEN getting the start up path THEN it set to MAIN'`() { every { intent.action } returns Intent.ACTION_MAIN launchApp(intent) stopLaunchedApp() startStoppedAppFromAppSwitcher() - assertEquals(StartupPath.NOT_SET, provider.startupPathForActivity) + assertEquals(StartupPath.MAIN, provider.startupPathForActivity) } @Test @@ -159,7 +159,7 @@ class StartupPathProviderTest { } @Test - fun `GIVEN the app is launched, stopped, started from the app switcher and receives an intent in the foreground WHEN getting the start up path THEN it returns not set`() { + fun `GIVEN the app is launched with MAIN, stopped, started from the app switcher and receives an intent in the foreground WHEN getting the start up path THEN it returns MAIN`() { every { intent.action } returns Intent.ACTION_MAIN launchApp(intent) stopLaunchedApp() @@ -167,7 +167,7 @@ class StartupPathProviderTest { every { intent.action } returns Intent.ACTION_VIEW receiveIntentInForeground(intent) - assertEquals(StartupPath.NOT_SET, provider.startupPathForActivity) + assertEquals(StartupPath.MAIN, provider.startupPathForActivity) } private fun launchApp(intent: Intent) { From 357df2e8e391e6c7d3727220d4e112095164982d Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 30 Jan 2024 00:03:16 +0000 Subject: [PATCH 007/586] Import translations from android-l10n --- .../addons/src/main/res/values-su/strings.xml | 6 ++- .../media/src/main/res/values-su/strings.xml | 15 ++++++ .../src/main/res/values-su/strings.xml | 7 +++ .../src/main/res/values-fy-rNL/strings.xml | 47 +++++++++++++++++++ fenix/app/src/main/res/values-th/strings.xml | 36 ++++++++++++++ .../app/src/main/res/values-su/strings.xml | 8 ++-- 6 files changed, 112 insertions(+), 7 deletions(-) diff --git a/android-components/components/feature/addons/src/main/res/values-su/strings.xml b/android-components/components/feature/addons/src/main/res/values-su/strings.xml index 88e89a655bdc..b312b768886e 100644 --- a/android-components/components/feature/addons/src/main/res/values-su/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-su/strings.xml @@ -75,7 +75,7 @@ Pamilik - Pamilik + Pamilik Panungtung diropéa @@ -114,8 +114,10 @@ Rincian Idin - + Piceun + + Laporan Tambahkeun %1$s? diff --git a/android-components/components/feature/media/src/main/res/values-su/strings.xml b/android-components/components/feature/media/src/main/res/values-su/strings.xml index 49f737665690..5308a13f4487 100644 --- a/android-components/components/feature/media/src/main/res/values-su/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-su/strings.xml @@ -11,6 +11,21 @@ Kaméra jeung mikropon hurung + + Toél pikeun muka tab anu maké kaméra anjeun. + + Toél pikeun muka tab anu maké mikropon anjeun. + + Toél pikeun muka tab anu maké mikropon jeung kaméra anjeun. + + + + Panginget: %1$s maké kénéh kaméra anjeun. Toél pikeun muka tabna. + + Panginget: %1$s maké kénéh mikropon anjeun. Toél pikeun muka tabna + + Panginget: %1$s maké kénéh mikropon jeung kaméra anjeun. Toél pikeun muka tabna + Ulinkeun diff --git a/android-components/components/feature/prompts/src/main/res/values-su/strings.xml b/android-components/components/feature/prompts/src/main/res/values-su/strings.xml index 42b13a6540ad..8069cf1b6669 100644 --- a/android-components/components/feature/prompts/src/main/res/values-su/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-su/strings.xml @@ -92,6 +92,13 @@ Saran login + + Usulkeun kecap sandi anu wedel + + Usulkeun kecap sandi anu wedel + + Paké kecap sandi anu wedel: %1$s + Kirimkeun deui data ka ieu loka? Nyegerkeun ieu kaca bisa ngaduplikasi peta panganyarna, contona mayar atawa ngirim koméntar dua kali. diff --git a/fenix/app/src/main/res/values-fy-rNL/strings.xml b/fenix/app/src/main/res/values-fy-rNL/strings.xml index fec73513ae31..cd565c898a1d 100644 --- a/fenix/app/src/main/res/values-fy-rNL/strings.xml +++ b/fenix/app/src/main/res/values-fy-rNL/strings.xml @@ -1694,6 +1694,9 @@ Bewarre wachtwurden De oanmeldingen dy’t jo bewarje of syngronisearje mei %s wurde hjir toand. + + De wachtwurden dy’t jo bewarje of syngronisearje mei %s sille hjir fermeld wurde. Alle wachtwurden dy’t jo bewarje binne fersifere. + Mear ynfo oer Sync. @@ -1702,12 +1705,18 @@ Utsûnderingen Net-bewarre oanmeldingen en wachtwurden wurde hjir werjûn. + + %s sil gjin wachtwurden foar de hjir fermelde websites bewarje. Oanmeldingen en wachtwurden wurde foar dizze websites net bewarre. + + %s sil gjin wachtwurden foar dizze websites bewarje. Alle útsûnderingen fuortsmite Oanmeldingen sykje + + Wachtwurden sykje Website @@ -1736,10 +1745,16 @@ Wachtwurd ferstopje Untskoattelje om jo bewarre oanmeldingen te besjen + + Untskoattelje om jo bewarre wachtwurden te besjen Befeiligje jo oanmeldingen en wachtwurden + + Befeiligje jo bewarre wachtwurden Stel in beskoattelingspatroan, pinkoade of wachtwurd foar jo apparaat yn om jo bewarre oanmeldingen en wachtwurden te beskermjen tsjin tagong as in oar jo apparaat hat. + + Stel in beskoattelingspatroan, pinkoade of wachtwurd foar jo apparaat yn om jo bewarre wachtwurden te beskermjen tsjin tagong as in oar jo apparaat hat. Letter @@ -1776,6 +1791,8 @@ Betellingsmetoaden bewarje en ynfolje Gegevens binne fersifere + + %s fersiferet alle betellingsmetoaden dy’t jo bewarje Kaarten syngronisearje tusken apparaten @@ -1856,6 +1873,8 @@ Stel in beskoattelingspatroan, pinkoade of wachtwurd foar jo apparaat yn om jo bewarre creditcards te beskermjen tsjin tagong as in oar jo apparaat hat. + + Stel in beskoattelingspatroan, pinkoade of wachtwurd foar jo apparaat yn om jo bewarre kaarten te beskermjen tsjin tagong as in oar jo apparaat hat. No ynstelle @@ -1866,6 +1885,8 @@ Untskoattelje om bewarre creditkaartynformaasje te brûken + + Untskoattelje om bewarre betellingsmetoaden te brûken Adres tafoegje @@ -2003,30 +2024,52 @@ Bewurkje Binne jo wis dat jo dizze oanmelding fuortsmite wolle? + + Binne jo wis dat jo dit wachtwurd fuortsmite wolle? Fuortsmite Annulearje Oanmeldopsjes + + Wachtwurdopsjes It bewurkbere tekstfjild foar it webadres fan de oanmelding. + + It bewurkbere tekstfjild foar it websiteadres fan it wachtwurd. It bewurkbere tekstfjild foar de brûkersnamme fan de oanmelding. + + It bewurkbere tekstfjild foar de brûkersnamme fan it wachtwurd. It bewurkbere tekstfjild foar it wachtwurd fan de oanmelding. + + It bewurkbere tekstfjild foar it wachtwurd. Wizigingen oan oanmelding bewarje. + + Wizigingen bewarje. Bewurkje + + Wachtwurd bewurkje Nije oanmelding tafoegje + + Wachtwurd tafoegje Wachtwurd fereaske + + Folje in wachtwurd yn Brûkersnamme fereaske + + Folje in brûkersnamme yn Hostnamme fereaske + + Fier in websiteadres yn Sprutsen sykopdracht @@ -2403,6 +2446,10 @@ Dizze analyze sil jo allinnich helpe om de beoardielingskwaliteit te beoardielen %1$s nea oersette Dizze website nea oersette + + Oerskriuwt alle oare ynstellingen + + Negearret oersetoanbiedingen Oersetynstellingen diff --git a/fenix/app/src/main/res/values-th/strings.xml b/fenix/app/src/main/res/values-th/strings.xml index 481dcdaca3b3..5dbb20346c32 100644 --- a/fenix/app/src/main/res/values-th/strings.xml +++ b/fenix/app/src/main/res/values-th/strings.xml @@ -2345,6 +2345,8 @@ เปิดลิงก์เพื่อเรียนรู้เพิ่มเติม + + %s หัวเรื่อง ลิงก์ @@ -2376,6 +2378,22 @@ เกิดปัญหาในการแปล โปรดลองอีกครั้ง + + + ตัวเลือกการแปล + + เสนอให้แปลอยู่เสมอ + + แปล %1$s เสมอ + + ไม่ต้องแปล %1$s เลย + + ไม่ต้องแปลไซต์นี้เลย + + การตั้งค่าการแปล + + เกี่ยวกับการแปลใน %1$s + การแปล @@ -2396,17 +2414,29 @@ การแปลอัตโนมัติ + + เลือกภาษาที่จะจัดการการกำหนดลักษณะ ”แปลเสมอ“ และ ”ไม่แปลเสมอ“ + เสนอให้แปล (ค่าเริ่มต้น) + + %1$s จะเสนอให้แปลไซต์เป็นภาษานี้ แปลเสมอ + + %1$s จะแปลภาษานี้โดยอัตโนมัติเมื่อโหลดหน้าเว็บ ไม่ต้องแปล + + %1$s จะไม่เสนอให้แปลไซต์เป็นภาษานี้เลย + ไม่ต้องแปลไซต์เหล่านี้ + + หากต้องการเพิ่มไซต์ใหม่: ให้ไปที่ไซต์นั้นแล้วเลือก “ไม่ต้องแปลไซต์นี้เลย” จากเมนูการแปล เอา %1$s ออก @@ -2421,12 +2451,18 @@ ดาวน์โหลดภาษา + + ดาวน์โหลดภาษาแบบสมบูรณ์เพื่อให้แปลได้เร็วขึ้นและแปลแบบออฟไลน์ได้ %1$s เรียนรู้เพิ่ม ภาษาที่มี จำเป็น + + %1$s (%2$s) ดาวน์โหลดภาษา diff --git a/focus-android/app/src/main/res/values-su/strings.xml b/focus-android/app/src/main/res/values-su/strings.xml index b127c3a4f9b3..74dc7d5ee90d 100644 --- a/focus-android/app/src/main/res/values-su/strings.xml +++ b/focus-android/app/src/main/res/values-su/strings.xml @@ -53,7 +53,6 @@ Piceun tina Takulan - Anu Anyar Setélan Ngeunaan Pitulung @@ -84,10 +83,9 @@ sharing an URL. --> Bagikeun kana - + Pupus jujutan langlangan? + Toél atawa beresihan iber ieu pikeun mupus jujutan langlangan anjeun kalayan aman. + Pupus jujutan langlangan From 0e28805f53fc1f55606a97b04870721975a78cfe Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 30 Jan 2024 01:25:02 +0000 Subject: [PATCH 008/586] Update GeckoView (Nightly) to 124.0.20240129214018. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 0142bcfebd82..795370878a72 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240129090053" + const val version = "124.0.20240129214018" /** * GeckoView channel From 4ec3fd1776ee4750ebe87e44ac3fe2ec954402cf Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Fri, 26 Jan 2024 12:12:36 +0200 Subject: [PATCH 009/586] Bug 1876700 - Add more test logs to CollectionRobot --- .../org/mozilla/fenix/helpers/TestHelper.kt | 2 + .../fenix/ui/robots/CollectionRobot.kt | 73 +++++++++++-------- 2 files changed, 46 insertions(+), 29 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt index 06bc94ee6fd9..dedb39b2c2eb 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt @@ -49,8 +49,10 @@ object TestHelper { fun scrollToElementByText(text: String): UiScrollable { val appView = UiScrollable(UiSelector().scrollable(true)) + Log.i(TAG, "scrollToElementByText: Waiting for app view") appView.waitForExists(waitingTime) appView.scrollTextIntoView(text) + Log.i(TAG, "scrollToElementByText: Scrolled to element with text: $text") return appView } diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt index 1cbac1730eea..029e5485d983 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.ui.robots +import android.util.Log import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.hasContentDescription import androidx.compose.ui.test.hasText @@ -17,10 +18,10 @@ import androidx.test.espresso.action.ViewActions.pressImeActionButton import androidx.test.espresso.matcher.RootMatchers import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.uiautomator.By -import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextEquals import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists @@ -46,18 +47,24 @@ class CollectionRobot { itemWithResId("$packageName:id/collections_list"), ) - fun clickAddNewCollection() = addNewCollectionButton().click() + fun clickAddNewCollection() { + addNewCollectionButton().click() + Log.i(TAG, "clickAddNewCollection: Clicked the add new collection button") + } fun verifyCollectionNameTextField() = assertUIObjectExists(mainMenuEditCollectionNameField()) // names a collection saved from tab drawer fun typeCollectionNameAndSave(collectionName: String) { collectionNameTextField().text = collectionName - addCollectionButtonPanel.waitForExists(waitingTime) - addCollectionOkButton.click() + Log.i(TAG, "typeCollectionNameAndSave: Collection name text field set to: $collectionName") + addCollectionButtonPanel().waitForExists(waitingTime) + addCollectionOkButton().click() + Log.i(TAG, "typeCollectionNameAndSave: Clicked \"OK\" panel button") } fun verifyTabsSelectedCounterText(numOfTabs: Int) { + Log.i(TAG, "verifyTabsSelectedCounterText: Waiting for \"Select tabs to save\" prompt to be gone") itemWithText("Select tabs to save").waitUntilGone(waitingTime) val tabsCounter = mDevice.findObject(UiSelector().resourceId("$packageName:id/bottom_bar_text")) @@ -68,7 +75,8 @@ class CollectionRobot { } fun saveTabsSelectedForCollection() { - mDevice.findObject(UiSelector().resourceId("$packageName:id/save_button")).click() + itemWithResId("$packageName:id/save_button").click() + Log.i(TAG, "saveTabsSelectedForCollection: Clicked \"Save\" button") } fun verifyTabSavedInCollection(title: String, visible: Boolean = true) { @@ -91,9 +99,11 @@ class CollectionRobot { collectionThreeDotButton(rule) .assertExists() .assertIsDisplayed() + Log.i(TAG, "verifyCollectionMenuIsVisible: Verified collection three dot button exists") } else { collectionThreeDotButton(rule) .assertDoesNotExist() + Log.i(TAG, "verifyCollectionMenuIsVisible: Verified collection three dot button does not exist") } } @@ -101,18 +111,21 @@ class CollectionRobot { collectionThreeDotButton(rule) .assertIsDisplayed() .performClick() + Log.i(TAG, "clickCollectionThreeDotButton: Clicked three dot button") } fun selectOpenTabs(rule: ComposeTestRule) { rule.onNode(hasText("Open tabs")) .assertIsDisplayed() .performClick() + Log.i(TAG, "selectOpenTabs: Clicked \"Open tabs\" menu option") } fun selectRenameCollection(rule: ComposeTestRule) { rule.onNode(hasText("Rename collection")) .assertIsDisplayed() .performClick() + Log.i(TAG, "selectRenameCollection: Clicked \"Rename collection\" menu option") mainMenuEditCollectionNameField().waitForExists(waitingTime) } @@ -120,6 +133,7 @@ class CollectionRobot { rule.onNode(hasText("Add tab")) .assertIsDisplayed() .performClick() + Log.i(TAG, "selectAddTabToCollection: Clicked \"Add tab\" menu option") mDevice.waitNotNull(Until.findObject(By.text("Select Tabs"))) } @@ -128,35 +142,40 @@ class CollectionRobot { rule.onNode(hasText("Delete collection")) .assertIsDisplayed() .performClick() + Log.i(TAG, "selectDeleteCollection: Clicked \"Delete collection\" menu option") } fun verifyCollectionItemRemoveButtonIsVisible(title: String, visible: Boolean) = assertUIObjectExists(removeTabFromCollectionButton(title), exists = visible) - fun removeTabFromCollection(title: String) = removeTabFromCollectionButton(title).click() + fun removeTabFromCollection(title: String) { + removeTabFromCollectionButton(title).click() + Log.i(TAG, "removeTabFromCollection: Clicked remove button for tab: $title") + } fun swipeTabLeft(title: String, rule: ComposeTestRule) { rule.onNode(hasText(title), useUnmergedTree = true) .performTouchInput { swipeLeft() } + Log.i(TAG, "swipeTabLeft: Removed tab: $title using swipe left action") rule.waitForIdle() + Log.i(TAG, "swipeTabLeft: Waited for rule to be idle") } fun swipeTabRight(title: String, rule: ComposeTestRule) { rule.onNode(hasText(title), useUnmergedTree = true) .performTouchInput { swipeRight() } + Log.i(TAG, "swipeTabRight: Removed tab: $title using swipe right action") rule.waitForIdle() + Log.i(TAG, "swipeTabRight: Waited for rule to be idle") } - fun verifySnackBarText(expectedText: String) { - mDevice.findObject(UiSelector().text(expectedText)).waitForExists(waitingTime) - } - - fun goBackInCollectionFlow() = backButton().click() + fun verifySnackBarText(expectedText: String) = + itemContainingText(expectedText).waitForExists(waitingTime) - fun swipeToBottom() = - UiScrollable( - UiSelector().resourceId("$packageName:id/sessionControlRecyclerView"), - ).scrollToEnd(3) + fun goBackInCollectionFlow() { + backButton().click() + Log.i(TAG, "goBackInCollectionFlow: Clicked collection creation flow back button") + } class Transition { fun collapseCollection( @@ -165,6 +184,7 @@ class CollectionRobot { ): HomeScreenRobot.Transition { assertUIObjectExists(itemContainingText(title)) itemContainingText(title).clickAndWaitForNewWindow(waitingTimeShort) + Log.i(TAG, "collapseCollection: Clicked collection $title") assertUIObjectExists(itemWithDescription(getStringResource(R.string.remove_tab_from_collection)), exists = false) HomeScreenRobot().interact() @@ -178,7 +198,9 @@ class CollectionRobot { ): BrowserRobot.Transition { mainMenuEditCollectionNameField().waitForExists(waitingTime) mainMenuEditCollectionNameField().text = name + Log.i(TAG, "typeCollectionNameAndSave: Collection name text field set to: $name") onView(withId(R.id.name_collection_edittext)).perform(pressImeActionButton()) + Log.i(TAG, "typeCollectionNameAndSave: Pressed done action button") // wait for the collection creation wrapper to be dismissed mDevice.waitNotNull(Until.gone(By.res("$packageName:id/createCollectionWrapper"))) @@ -193,6 +215,7 @@ class CollectionRobot { ): BrowserRobot.Transition { collectionTitle(title).waitForExists(waitingTime) collectionTitle(title).click() + Log.i(TAG, "selectExistingCollection: Clicked collection with title: $title") BrowserRobot().interact() return BrowserRobot.Transition() @@ -201,6 +224,7 @@ class CollectionRobot { fun clickShareCollectionButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { shareCollectionButton().waitForExists(waitingTime) shareCollectionButton().click() + Log.i(TAG, "clickShareCollectionButton: Clicked share collection button") ShareOverlayRobot().interact() return ShareOverlayRobot.Transition() @@ -213,21 +237,14 @@ fun collectionRobot(interact: CollectionRobot.() -> Unit): CollectionRobot.Trans return CollectionRobot.Transition() } -private fun collectionTitle(title: String) = - mDevice.findObject( - UiSelector() - .text(title), - ) +private fun collectionTitle(title: String) = itemWithText(title) private fun collectionThreeDotButton(rule: ComposeTestRule) = rule.onNode(hasContentDescription("Collection menu")) private fun collectionListItem(title: String) = mDevice.findObject(UiSelector().text(title)) -private fun shareCollectionButton() = - mDevice.findObject( - UiSelector().description("Share"), - ) +private fun shareCollectionButton() = itemWithDescription("Share") private fun removeTabFromCollectionButton(title: String) = mDevice.findObject( @@ -245,9 +262,7 @@ private fun collectionNameTextField() = // collection name text field, when saving from the main menu option private fun mainMenuEditCollectionNameField() = - mDevice.findObject( - UiSelector().resourceId("$packageName:id/name_collection_edittext"), - ) + itemWithResId("$packageName:id/name_collection_edittext") private fun addNewCollectionButton() = mDevice.findObject(UiSelector().text("Add new collection")) @@ -256,7 +271,7 @@ private fun backButton() = mDevice.findObject( UiSelector().resourceId("$packageName:id/back_button"), ) -private val addCollectionButtonPanel = +private fun addCollectionButtonPanel() = itemWithResId("$packageName:id/buttonPanel") -private val addCollectionOkButton = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog()) +private fun addCollectionOkButton() = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog()) From 197dadfd4a08bea035df80e7b4c95836dc242225 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Fri, 26 Jan 2024 14:17:27 +0200 Subject: [PATCH 010/586] Bug 1876720 - Add more test logs to ComposeTabDrawerRobot --- .../fenix/ui/robots/ComposeTabDrawerRobot.kt | 64 ++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt index baa7271b07c5..df12b8ff2f0e 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt @@ -6,6 +6,7 @@ package org.mozilla.fenix.ui.robots +import android.util.Log import android.view.View import androidx.compose.ui.semantics.SemanticsActions import androidx.compose.ui.test.ExperimentalTestApi @@ -42,6 +43,7 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior import org.hamcrest.Matcher import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants +import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.HomeActivityComposeTestRule import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists @@ -63,24 +65,30 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest fun verifyNormalBrowsingButtonIsSelected(isSelected: Boolean = true) { if (isSelected) { composeTestRule.normalBrowsingButton().assertIsSelected() + Log.i(TAG, "verifyNormalBrowsingButtonIsSelected: Verified normal browsing button is selected") } else { composeTestRule.normalBrowsingButton().assertIsNotSelected() + Log.i(TAG, "verifyNormalBrowsingButtonIsSelected: Verified normal browsing button is not selected") } } fun verifyPrivateBrowsingButtonIsSelected(isSelected: Boolean = true) { if (isSelected) { composeTestRule.privateBrowsingButton().assertIsSelected() + Log.i(TAG, "verifyPrivateBrowsingButtonIsSelected: Verified private browsing button is selected") } else { composeTestRule.privateBrowsingButton().assertIsNotSelected() + Log.i(TAG, "verifyPrivateBrowsingButtonIsSelected: Verified private browsing button is not selected") } } fun verifySyncedTabsButtonIsSelected(isSelected: Boolean = true) { if (isSelected) { composeTestRule.syncedTabsButton().assertIsSelected() + Log.i(TAG, "verifySyncedTabsButtonIsSelected: Verified synced tabs button is selected") } else { composeTestRule.syncedTabsButton().assertIsNotSelected() + Log.i(TAG, "verifySyncedTabsButtonIsSelected: Verified synced tabs button is not selected") } } @@ -97,14 +105,17 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest titles.forEach { title -> itemContainingText(title).waitForExists(waitingTime) composeTestRule.tabItem(title).assertExists() + Log.i(TAG, "verifyExistingOpenTabs: Verified open tab with title: $title exists") } } - fun verifyOpenTabsOrder(title: String, position: Int) = + fun verifyOpenTabsOrder(title: String, position: Int) { composeTestRule.normalTabsList() .onChildAt(position - 1) .assert(hasTestTag(TabsTrayTestTag.tabItemRoot)) .assert(hasAnyChild(hasText(title))) + Log.i(TAG, "verifyOpenTabsOrder: Verified open tab at position: $position has title: $title") + } fun verifyNoExistingOpenTabs(vararg titles: String) { titles.forEach { title -> @@ -117,58 +128,72 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest fun verifyNormalTabsList() { composeTestRule.normalTabsList().assertExists() + Log.i(TAG, "verifyNormalTabsList: Verified normal tabs list exists") } fun verifyPrivateTabsList() { composeTestRule.privateTabsList().assertExists() + Log.i(TAG, "verifyPrivateTabsList: Verified private tabs list exists") } fun verifySyncedTabsList() { composeTestRule.syncedTabsList().assertExists() + Log.i(TAG, "verifySyncedTabsList: Verified synced tabs list exists") } fun verifyNoOpenTabsInNormalBrowsing() { composeTestRule.emptyNormalTabsList().assertExists() + Log.i(TAG, "verifyNoOpenTabsInNormalBrowsing: Verified empty normal tabs list exists") } fun verifyNoOpenTabsInPrivateBrowsing() { composeTestRule.emptyPrivateTabsList().assertExists() + Log.i(TAG, "verifyNoOpenTabsInPrivateBrowsing: Verified empty private tabs list exists") } fun verifyAccountSettingsButton() { composeTestRule.dropdownMenuItemAccountSettings().assertExists() + Log.i(TAG, "verifyAccountSettingsButton: Verified \"Account settings\" menu button exists") } fun verifyCloseAllTabsButton() { composeTestRule.dropdownMenuItemCloseAllTabs().assertExists() + Log.i(TAG, "verifyCloseAllTabsButton: Verified \"Close all tabs\" menu button exists") } fun verifySelectTabsButton() { composeTestRule.dropdownMenuItemSelectTabs().assertExists() + Log.i(TAG, "verifySelectTabsButton: Verified \"Select tabs\" menu button exists") } fun verifyShareAllTabsButton() { composeTestRule.dropdownMenuItemShareAllTabs().assertExists() + Log.i(TAG, "verifyShareAllTabsButton: Verified \"Share all tabs\" menu button exists") } fun verifyRecentlyClosedTabsButton() { composeTestRule.dropdownMenuItemRecentlyClosedTabs().assertExists() + Log.i(TAG, "verifyRecentlyClosedTabsButton: Verified \"Recently closed tabs\" menu button exists") } fun verifyTabSettingsButton() { composeTestRule.dropdownMenuItemTabSettings().assertExists() + Log.i(TAG, "verifyTabSettingsButton: Verified \"Tab settings\" menu button exists") } fun verifyThreeDotButton() { composeTestRule.threeDotButton().assertExists() + Log.i(TAG, "verifyThreeDotButton: Verified three dot button exists") } fun verifyFab() { composeTestRule.tabsTrayFab().assertExists() + Log.i(TAG, "verifyFab: Verified new tab FAB button exists") } fun verifyNormalTabCounter() { composeTestRule.normalTabsCounter().assertExists() + Log.i(TAG, "verifyNormalTabCounter: Verified normal tabs list counter exists") } /** @@ -176,6 +201,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest */ fun verifyTabThumbnail() { composeTestRule.tabThumbnail().assertExists() + Log.i(TAG, "verifyTabThumbnail: Verified tab thumbnail exists") } /** @@ -183,22 +209,27 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest */ fun verifyTabCloseButton() { composeTestRule.closeTabButton().assertExists() + Log.i(TAG, "verifyTabCloseButton: Verified close tab button exists") } fun verifyTabsTrayBehaviorState(expectedState: Int) { tabsTrayView().check(ViewAssertions.matches(BottomSheetBehaviorStateMatcher(expectedState))) + Log.i(TAG, "verifyTabsTrayBehaviorState: Verified that the tabs tray state matches: $expectedState") } fun verifyMinusculeHalfExpandedRatio() { tabsTrayView().check(ViewAssertions.matches(BottomSheetBehaviorHalfExpandedMaxRatioMatcher(0.001f))) + Log.i(TAG, "verifyMinusculeHalfExpandedRatio: Verified that the tabs tray half expanded ratio") } fun verifyTabTrayIsOpen() { composeTestRule.tabsTray().assertExists() + Log.i(TAG, "verifyTabTrayIsOpen: Verified that the open tabs tray exists") } fun verifyTabTrayIsClosed() { composeTestRule.tabsTray().assertDoesNotExist() + Log.i(TAG, "verifyTabTrayIsClosed: Verified that the tabs tray is closed") } /** @@ -206,6 +237,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest */ fun closeTab() { composeTestRule.closeTabButton().performClick() + Log.i(TAG, "closeTab: Clicked close tab button") } /** @@ -213,6 +245,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest */ fun swipeTabLeft(title: String) { composeTestRule.tabItem(title).performTouchInput { swipeLeft() } + Log.i(TAG, "swipeTabLeft: Performed swipe left action on tab: $title") } /** @@ -220,6 +253,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest */ fun swipeTabRight(title: String) { composeTestRule.tabItem(title).performTouchInput { swipeRight() } + Log.i(TAG, "swipeTabRight: Performed swipe right action on tab: $title") } /** @@ -231,7 +265,9 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest firstCollection: Boolean = true, ) { composeTestRule.threeDotButton().performClick() + Log.i(TAG, "createCollection: Clicked 3 dot button") composeTestRule.dropdownMenuItemSelectTabs().performClick() + Log.i(TAG, "createCollection: Clicked \"Select tabs\" menu button") for (tab in tabTitles) { selectTab(tab) @@ -250,8 +286,10 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest */ @OptIn(ExperimentalTestApi::class) fun selectTab(title: String) { - composeTestRule.waitUntilExactlyOneExists(hasText(title), TestAssetHelper.waitingTime) + Log.i(TAG, "selectTab: Waiting for tab with title: $title to exist") + composeTestRule.waitUntilExactlyOneExists(hasText(title), waitingTime) composeTestRule.tabItem(title).performClick() + Log.i(TAG, "selectTab: Clicked tab with title: $title") } /** @@ -260,6 +298,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest fun longClickTab(title: String) { composeTestRule.tabItem(title) .performTouchInput { longClick(durationMillis = Constants.LONG_CLICK_DURATION) } + Log.i(TAG, "longClickTab: Long clicked tab with title: $title") } /** @@ -268,6 +307,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest fun verifyTabsMultiSelectionCounter(numOfTabs: Int) { composeTestRule.multiSelectionCounter() .assert(hasText("$numOfTabs selected")) + Log.i(TAG, "verifyTabsMultiSelectionCounter: Verified $numOfTabs are selected") } /** @@ -275,9 +315,11 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest */ @OptIn(ExperimentalTestApi::class) fun verifyTabMediaControlButtonState(action: String) { + Log.i(TAG, "verifyTabMediaControlButtonStateTab: Waiting for media tab control button: $action to exist") composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(action), waitingTime) composeTestRule.tabMediaControlButton(action) .assertExists() + Log.i(TAG, "verifyTabMediaControlButtonStateTab: Verified media tab control button: $action exists") } /** @@ -285,9 +327,11 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest */ @OptIn(ExperimentalTestApi::class) fun clickTabMediaControlButton(action: String) { + Log.i(TAG, "clickTabMediaControlButton: Waiting for media tab control button: $action to exist") composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(action), waitingTime) composeTestRule.tabMediaControlButton(action) .performClick() + Log.i(TAG, "clickTabMediaControlButton: Clicked media tab control button: $action") } /** @@ -298,6 +342,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest .filter(hasParent(hasText(title))) .onFirst() .performClick() + Log.i(TAG, "closeTabWithTitle: Closed tab with title: $title") } class Transition(private val composeTestRule: HomeActivityComposeTestRule) { @@ -306,24 +351,28 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest mDevice.waitForIdle() composeTestRule.tabsTrayFab().performClick() + Log.i(TAG, "openNewTab: Clicked new tab FAB button") SearchRobot().interact() return SearchRobot.Transition() } fun toggleToNormalTabs(interact: ComposeTabDrawerRobot.() -> Unit): Transition { composeTestRule.normalBrowsingButton().performClick() + Log.i(TAG, "toggleToNormalTabs: Clicked normal browsing button") ComposeTabDrawerRobot(composeTestRule).interact() return Transition(composeTestRule) } fun toggleToPrivateTabs(interact: ComposeTabDrawerRobot.() -> Unit): Transition { composeTestRule.privateBrowsingButton().performClick() + Log.i(TAG, "toggleToPrivateTabs: Clicked private browsing button") ComposeTabDrawerRobot(composeTestRule).interact() return Transition(composeTestRule) } fun toggleToSyncedTabs(interact: ComposeTabDrawerRobot.() -> Unit): Transition { composeTestRule.syncedTabsButton().performClick() + Log.i(TAG, "toggleToSyncedTabs: Clicked synced tabs button") ComposeTabDrawerRobot(composeTestRule).interact() return Transition(composeTestRule) } @@ -331,18 +380,21 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest fun clickSignInToSyncButton(interact: SyncSignInRobot.() -> Unit): SyncSignInRobot.Transition { itemContainingText(getStringResource(R.string.sync_sign_in)) .clickAndWaitForNewWindow(TestAssetHelper.waitingTimeShort) + Log.i(TAG, "clickSignInToSyncButton: Clicked sign in to sync button") SyncSignInRobot().interact() return SyncSignInRobot.Transition() } fun openThreeDotMenu(interact: ComposeTabDrawerRobot.() -> Unit): Transition { composeTestRule.threeDotButton().performClick() + Log.i(TAG, "openThreeDotMenu: Clicked three dot button") ComposeTabDrawerRobot(composeTestRule).interact() return Transition(composeTestRule) } fun closeAllTabs(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { composeTestRule.dropdownMenuItemCloseAllTabs().performClick() + Log.i(TAG, "closeAllTabs: Clicked \"Close all tabs\" menu button") HomeScreenRobot().interact() return HomeScreenRobot.Transition() } @@ -351,6 +403,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest composeTestRule.tabItem(title) .performScrollTo() .performClick() + Log.i(TAG, "openTab: Scrolled and clicked tab with title: $title") BrowserRobot().interact() return BrowserRobot.Transition() @@ -360,6 +413,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest composeTestRule.privateTabsList() .onChildren()[position] .performClick() + Log.i(TAG, "openPrivateTab: Opened private tab at position: ${position + 1}") BrowserRobot().interact() return BrowserRobot.Transition() @@ -369,6 +423,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest composeTestRule.normalTabsList() .onChildren()[position] .performClick() + Log.i(TAG, "openNormalTab: Opened tab at position: ${position + 1}") BrowserRobot().interact() return BrowserRobot.Transition() @@ -378,6 +433,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest // The topBar contains other views. // Don't do the default click in the middle, rather click in some free space - top right. Espresso.onView(ViewMatchers.withId(R.id.topBar)).clickAtLocationInView(GeneralLocation.TOP_RIGHT) + Log.i(TAG, "clickTopBar: Clicked tabs tray top bar") ComposeTabDrawerRobot(composeTestRule).interact() return Transition(composeTestRule) } @@ -435,6 +491,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest fun closeTabDrawer(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { composeTestRule.bannerHandle().performSemanticsAction(SemanticsActions.OnClick) + Log.i(TAG, "closeTabDrawer: Closed tabs tray clicking the handle") BrowserRobot().interact() return BrowserRobot.Transition() @@ -442,6 +499,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest fun clickSaveCollection(interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { composeTestRule.collectionsButton().performClick() + Log.i(TAG, "clickSaveCollection: Clicked collections button") CollectionRobot().interact() return CollectionRobot.Transition() @@ -449,6 +507,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest fun clickShareAllTabsButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { composeTestRule.dropdownMenuItemShareAllTabs().performClick() + Log.i(TAG, "clickShareAllTabsButton: Clicked \"Share all tabs\" menu button button") ShareOverlayRobot().interact() return ShareOverlayRobot.Transition() @@ -469,6 +528,7 @@ fun composeTabDrawer(composeTestRule: HomeActivityComposeTestRule, interact: Com */ private fun clickCollectionsButton(composeTestRule: HomeActivityComposeTestRule, interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { composeTestRule.collectionsButton().performClick() + Log.i(TAG, "clickCollectionsButton: Clicked collections button") CollectionRobot().interact() return CollectionRobot.Transition() From 494bd98c4e7161bd1be82b98698dda360e4db0a7 Mon Sep 17 00:00:00 2001 From: t-p-white Date: Fri, 26 Jan 2024 16:17:19 +0000 Subject: [PATCH 011/586] Bug 1796209 - If `config.toolbarColor` is null use the `toolbar` 'menu' colour as a fallback --- .../browser/state/state/CustomTabConfig.kt | 1 - .../customtabs/CustomTabsToolbarFeature.kt | 31 +++++----- .../CustomTabsToolbarFeatureTest.kt | 60 +++++++++++++++---- 3 files changed, 67 insertions(+), 25 deletions(-) diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/CustomTabConfig.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/CustomTabConfig.kt index bf7cfe36dc3c..e8e2367ad435 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/CustomTabConfig.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/CustomTabConfig.kt @@ -14,7 +14,6 @@ import androidx.browser.customtabs.CustomTabsSessionToken /** * Holds configuration data for a Custom Tab. * - * @property id a unique ID of this custom tab. * @property toolbarColor Background color for the toolbar. * @property closeButtonIcon Custom icon of the back button on the toolbar. * @property enableUrlbarHiding Enables the toolbar to hide as the user scrolls down on the page. diff --git a/android-components/components/feature/customtabs/src/main/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeature.kt b/android-components/components/feature/customtabs/src/main/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeature.kt index 09e5756259ea..20d685f7259c 100644 --- a/android-components/components/feature/customtabs/src/main/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeature.kt +++ b/android-components/components/feature/customtabs/src/main/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeature.kt @@ -6,7 +6,6 @@ package mozilla.components.feature.customtabs import android.app.PendingIntent import android.graphics.Bitmap -import android.graphics.Color import android.view.Window import androidx.annotation.ColorInt import androidx.annotation.VisibleForTesting @@ -74,7 +73,6 @@ class CustomTabsToolbarFeature( private var initialized: Boolean = false private val titleObserver = CustomTabSessionTitleObserver(toolbar) private val context get() = toolbar.context - internal var readableColor = Color.WHITE private var scope: CoroutineScope? = null /** @@ -114,29 +112,27 @@ class CustomTabsToolbarFeature( internal fun init(config: CustomTabConfig) { // Don't allow clickable toolbar so a custom tab can't switch to edit mode. toolbar.display.onUrlClicked = { false } - - // If it's available, hold on to the readable colour for other assets. - if (updateToolbarBackground && config.toolbarColor != null) { - readableColor = getReadableTextColor(config.toolbarColor!!) - } + val readableColor = + config.toolbarColor?.let { getReadableTextColor(it) } ?: toolbar.display.colors.menu // Change the toolbar colour updateToolbarColor( config.toolbarColor, config.navigationBarColor ?: config.toolbarColor, + readableColor, ) // Add navigation close action if (config.showCloseButton) { - addCloseButton(config.closeButtonIcon) + addCloseButton(readableColor, config.closeButtonIcon) } // Add action button - addActionButton(config.actionButtonConfig) + addActionButton(readableColor, config.actionButtonConfig) // Show share button if (config.showShareMenuItem) { - addShareButton() + addShareButton(readableColor) } // Add menu items @@ -146,7 +142,11 @@ class CustomTabsToolbarFeature( } @VisibleForTesting - internal fun updateToolbarColor(@ColorInt toolbarColor: Int?, @ColorInt navigationBarColor: Int?) { + internal fun updateToolbarColor( + @ColorInt toolbarColor: Int?, + @ColorInt navigationBarColor: Int?, + @ColorInt readableColor: Int, + ) { if (updateToolbarBackground && toolbarColor != null) { toolbar.setBackgroundColor(toolbarColor) @@ -171,7 +171,7 @@ class CustomTabsToolbarFeature( * When clicked, it calls [closeListener]. */ @VisibleForTesting - internal fun addCloseButton(bitmap: Bitmap?) { + internal fun addCloseButton(@ColorInt readableColor: Int, bitmap: Bitmap?) { val drawableIcon = bitmap?.toDrawable(context.resources) ?: getDrawable(context, iconsR.drawable.mozac_ic_cross_24)!!.mutate() @@ -195,7 +195,10 @@ class CustomTabsToolbarFeature( * When clicked, it activates the corresponding [PendingIntent]. */ @VisibleForTesting - internal fun addActionButton(buttonConfig: CustomTabActionButtonConfig?) { + internal fun addActionButton( + @ColorInt readableColor: Int, + buttonConfig: CustomTabActionButtonConfig?, + ) { buttonConfig?.let { config -> val drawableIcon = Bitmap.createScaledBitmap( config.icon, @@ -227,7 +230,7 @@ class CustomTabsToolbarFeature( * When clicked, it activates [shareListener] and defaults to the [share] KTX helper. */ @VisibleForTesting - internal fun addShareButton() { + internal fun addShareButton(@ColorInt readableColor: Int) { val drawableIcon = getDrawable(context, iconsR.drawable.mozac_ic_share_android_24)!! drawableIcon.setTint(readableColor) diff --git a/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeatureTest.kt b/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeatureTest.kt index c3ec57dcadd3..1a849ed51794 100644 --- a/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeatureTest.kt +++ b/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeatureTest.kt @@ -314,7 +314,7 @@ class CustomTabsToolbarFeatureTest { feature.start() - verify(feature, never()).addShareButton() + verify(feature, never()).addShareButton(anyInt()) verify(toolbar, never()).addBrowserAction(any()) } @@ -341,7 +341,7 @@ class CustomTabsToolbarFeatureTest { feature.start() - verify(feature).addShareButton() + verify(feature).addShareButton(anyInt()) verify(toolbar).addBrowserAction(any()) } @@ -400,7 +400,7 @@ class CustomTabsToolbarFeatureTest { feature.start() - verify(feature).addActionButton(any()) + verify(feature).addActionButton(anyInt(), any()) } @Test @@ -433,7 +433,7 @@ class CustomTabsToolbarFeatureTest { feature.start() - verify(feature).addActionButton(any()) + verify(feature).addActionButton(anyInt(), any()) verify(toolbar).addBrowserAction(captor.capture()) val button = captor.value.createView(FrameLayout(testContext)) @@ -480,7 +480,7 @@ class CustomTabsToolbarFeatureTest { ), ).joinBlocking() - verify(feature).addActionButton(any()) + verify(feature).addActionButton(anyInt(), any()) verify(toolbar).addBrowserAction(captor.capture()) doNothing().`when`(pendingIntent).send(any(), anyInt(), any()) @@ -905,7 +905,7 @@ class CustomTabsToolbarFeatureTest { } @Test - fun `readableColor - White on Black`() { + fun `WHEN config toolbar color is dark THEN readableColor is white`() { val tab = createCustomTab( "https://www.mozilla.org", id = "mozilla", @@ -936,12 +936,14 @@ class CustomTabsToolbarFeatureTest { feature.start() - assertEquals(Color.WHITE, feature.readableColor) + verify(feature).updateToolbarColor(tab.config.toolbarColor, tab.config.toolbarColor, Color.WHITE) + verify(feature).addCloseButton(Color.WHITE, tab.config.closeButtonIcon) + verify(feature).addActionButton(Color.WHITE, tab.config.actionButtonConfig) assertEquals(Color.WHITE, toolbar.display.colors.text) } @Test - fun `readableColor - Black on White`() { + fun `WHEN config toolbar color is not dark THEN readableColor is black`() { val tab = createCustomTab( "https://www.mozilla.org", id = "mozilla", @@ -955,6 +957,42 @@ class CustomTabsToolbarFeatureTest { ), ) val toolbar = spy(BrowserToolbar(testContext)) + + val useCases = CustomTabsUseCases( + store = store, + loadUrlUseCase = SessionUseCases(store).loadUrl, + ) + val feature = spy( + CustomTabsToolbarFeature( + store, + toolbar, + sessionId = "mozilla", + useCases = useCases, + menuBuilder = BrowserMenuBuilder(listOf(mock(), mock())), + menuItemIndex = 4, + ) {}, + ) + + feature.start() + + verify(feature).updateToolbarColor(tab.config.toolbarColor, tab.config.toolbarColor, Color.BLACK) + verify(feature).addCloseButton(Color.BLACK, tab.config.closeButtonIcon) + verify(feature).addActionButton(Color.BLACK, tab.config.actionButtonConfig) + } + + @Test + fun `WHEN config toolbar has no colour set THEN readableColor uses the toolbar display menu colour`() { + val tab = createCustomTab( + "https://www.mozilla.org", + id = "mozilla", + config = CustomTabConfig(), + ) + val store = BrowserStore( + BrowserState( + customTabs = listOf(tab), + ), + ) + val toolbar = spy(BrowserToolbar(testContext)) val useCases = CustomTabsUseCases( store = store, loadUrlUseCase = SessionUseCases(store).loadUrl, @@ -972,8 +1010,10 @@ class CustomTabsToolbarFeatureTest { feature.start() - assertEquals(Color.BLACK, feature.readableColor) - assertEquals(Color.BLACK, toolbar.display.colors.text) + verify(feature).updateToolbarColor(tab.config.toolbarColor, tab.config.toolbarColor, toolbar.display.colors.menu) + verify(feature).addCloseButton(toolbar.display.colors.menu, tab.config.closeButtonIcon) + verify(feature).addActionButton(toolbar.display.colors.menu, tab.config.actionButtonConfig) + assertEquals(Color.WHITE, toolbar.display.colors.menu) } @Test From 926bed9c7fc8d3a0b7a32734591c48f325dc912d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 08:13:14 -0500 Subject: [PATCH 012/586] Update GeckoView (Nightly) to 124.0.20240130045011. (#5367) Co-authored-by: MickeyMoz Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 795370878a72..9d98b1f1ef7d 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240129214018" + const val version = "124.0.20240130045011" /** * GeckoView channel From fe1ac741354266480b2e883be3f0ffc77e809153 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 30 Jan 2024 05:48:31 +0000 Subject: [PATCH 013/586] Update A-S to 124.20240130050233. --- .../plugins/dependencies/src/main/java/ApplicationServices.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt index 09439fe56a5e..4552bcabce97 100644 --- a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt +++ b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // These lines are generated by android-components/automation/application-services-nightly-bump.py -val VERSION = "124.20240127050245" +val VERSION = "124.20240130050233" val CHANNEL = ApplicationServicesChannel.NIGHTLY object ApplicationServicesConfig { From 8dec04da85283c267311532003a621c3784a3740 Mon Sep 17 00:00:00 2001 From: ohall-m Date: Fri, 26 Jan 2024 16:30:18 -0500 Subject: [PATCH 014/586] Bug 1876844 - Translations LanguageSetting Helper This patch adds a way to convert between LanguageSetting and Booleans. --- .../state/state/LanguageSettingTest.kt | 85 +++++++++++++++++++ .../engine/translate/LanguageSetting.kt | 80 +++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 android-components/components/browser/state/src/test/java/mozilla/components/browser/state/state/LanguageSettingTest.kt diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/state/LanguageSettingTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/state/LanguageSettingTest.kt new file mode 100644 index 000000000000..f5662cb48969 --- /dev/null +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/state/LanguageSettingTest.kt @@ -0,0 +1,85 @@ +/* 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 mozilla.components.browser.state.state + +import mozilla.components.concept.engine.translate.LanguageSetting.ALWAYS +import mozilla.components.concept.engine.translate.LanguageSetting.NEVER +import mozilla.components.concept.engine.translate.LanguageSetting.OFFER +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Test + +class LanguageSettingTest { + @Test + fun `GIVEN an OFFER LanguageSetting THEN find its Boolean counterpart`() { + val isAlways = OFFER.toBoolean(categoryToSetFor = ALWAYS) + assertFalse(isAlways!!) + + val isOffer = OFFER.toBoolean(categoryToSetFor = OFFER) + assertTrue(isOffer!!) + + val isNever = OFFER.toBoolean(categoryToSetFor = NEVER) + assertFalse(isNever!!) + } + + @Test + fun `GIVEN an ALWAYS LanguageSetting THEN find its Boolean counterpart`() { + val isAlways = ALWAYS.toBoolean(categoryToSetFor = ALWAYS) + assertTrue(isAlways!!) + + val isOffer = ALWAYS.toBoolean(categoryToSetFor = OFFER) + assertNull(isOffer) + + val isNever = ALWAYS.toBoolean(categoryToSetFor = NEVER) + assertFalse(isNever!!) + } + + @Test + fun `GIVEN a NEVER LanguageSetting THEN find its Boolean counterpart`() { + val isAlways = NEVER.toBoolean(categoryToSetFor = ALWAYS) + assertFalse(isAlways!!) + + val isOffer = NEVER.toBoolean(categoryToSetFor = OFFER) + assertNull(isOffer) + + val isNever = NEVER.toBoolean(categoryToSetFor = NEVER) + assertTrue(isNever!!) + } + + @Test + fun `GIVEN a Boolean corresponding to Always THEN find its LanguageSetting counterpart`() { + var isAlways = true + var conversion = ALWAYS.toLanguageSetting(value = isAlways) + assertEquals(conversion, ALWAYS) + + isAlways = false + conversion = ALWAYS.toLanguageSetting(value = isAlways) + assertEquals(conversion, NEVER) + } + + @Test + fun `GIVEN a Boolean corresponding to Never THEN find its LanguageSetting counterpart`() { + var isNever = true + var conversion = NEVER.toLanguageSetting(value = isNever) + assertEquals(conversion, NEVER) + + isNever = false + conversion = NEVER.toLanguageSetting(value = isNever) + assertEquals(conversion, ALWAYS) + } + + @Test + fun `GIVEN a Boolean corresponding to Offer THEN find its LanguageSetting counterpart`() { + var isOffer = true + var conversion = OFFER.toLanguageSetting(value = isOffer) + assertEquals(conversion, OFFER) + + isOffer = false + conversion = OFFER.toLanguageSetting(value = isOffer) + assertNull(conversion) + } +} diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/LanguageSetting.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/LanguageSetting.kt index c8a5ca1f947c..a5a5f6efd0d8 100644 --- a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/LanguageSetting.kt +++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/LanguageSetting.kt @@ -42,4 +42,84 @@ enum class LanguageSetting(private val languageSetting: String) { throw IllegalArgumentException("The language setting $languageSetting is not mapped.") } } + + /** + * Helper function to transform a given [LanguageSetting] setting into its boolean counterpart. + * + * @param categoryToSetFor The [LanguageSetting] type that we would like to determine the + * boolean value for. For example, if trying to calculate a boolean 'isAlways', + * [categoryToSetFor] would be [LanguageSetting.ALWAYS]. + * + * @return A boolean that corresponds to the language setting. Will return null if not enough + * information is present to make a determination. + */ + fun toBoolean( + categoryToSetFor: LanguageSetting, + ): Boolean? { + when (this) { + ALWAYS -> { + return when (categoryToSetFor) { + ALWAYS -> true + // Cannot determine offer without more information + OFFER -> null + NEVER -> false + } + } + + OFFER -> { + return when (categoryToSetFor) { + ALWAYS -> false + OFFER -> true + NEVER -> false + } + } + + NEVER -> { + return when (categoryToSetFor) { + ALWAYS -> false + // Cannot determine offer without more information + OFFER -> null + NEVER -> true + } + } + } + } + + /** + * Helper function to transform a given [LanguageSetting] that represents a category and the given boolean to its + * correct [LanguageSetting]. The calling object should be the object to set for. + * + * For example, if trying to calculate a value for an `isAlways` boolean, then `this` should be [ALWAYS]. + * + * @param value The given [Boolean] to convert to a [LanguageSetting]. + * @return A language setting that corresponds to the boolean. Will return null if not enough information is present + * to make a determination. + */ + fun toLanguageSetting( + value: Boolean, + ): LanguageSetting? { + when (this) { + ALWAYS -> { + return when (value) { + true -> ALWAYS + false -> NEVER + } + } + + OFFER -> { + return when (value) { + true -> OFFER + // Cannot determine if it should be ALWAYS or NEVER without more information + false -> null + } + } + + NEVER -> { + return when (value) { + true -> NEVER + false -> ALWAYS + } + } + } + } } From cb3c255547ec010c5c6007870c047a7f92224a8d Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Mon, 22 Jan 2024 11:35:02 +0200 Subject: [PATCH 015/586] Bug 1874831 - Fix disabled FxSuggest related UI tests --- .../org/mozilla/fenix/ui/FirefoxSuggestTest.kt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/FirefoxSuggestTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/FirefoxSuggestTest.kt index a6b6eb35db78..1f8b929fc522 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/FirefoxSuggestTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/FirefoxSuggestTest.kt @@ -5,7 +5,6 @@ package org.mozilla.fenix.ui import androidx.compose.ui.test.junit4.AndroidComposeTestRule -import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest @@ -48,9 +47,9 @@ class FirefoxSuggestTest { "Nike.com - Official Site", "nike.com/?cp=16423867261_search_318370984us128${getSponsoredFxSuggestPlaceHolder()}&mfadid=adm", ), - "Macy" to listOf( - "macys.com - Official Site", - "macys.com/?cm_mmc=Google_AdMarketPlace-_-Privacy_Instant%20Suggest-_-319101130_Broad-_-kclickid__kenshoo_clickid_&m_sc=sem&m_sb=Admarketplace&m_tp=Search&m_ac=Admarketplace&m_ag=Instant%20Suggest&m_cn=Privacy&m_pi=kclickid__kenshoo_clickid__319101130us1201${getSponsoredFxSuggestPlaceHolder()}&mfadid=adm", + "Houzz" to listOf( + "Houzz.com - Official Site", + "houzz.com/products?m_refid=us-dsp-mpl-admp-219577_15416306_kwd-353208810&adcid=319104989us1287${getSponsoredFxSuggestPlaceHolder()}&mfadid=adm", ), "Spanx" to listOf( "SPANX® - Official Site", @@ -101,7 +100,7 @@ class FirefoxSuggestTest { private val nonSponsoredKeyWord = nonSponsoredKeyWords.keys.random() // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348361 - @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1874831") + // Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587 @SmokeTest @Test fun verifyFirefoxSuggestSponsoredSearchResultsTest() { @@ -123,7 +122,7 @@ class FirefoxSuggestTest { } // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348362 - @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1874831") + // Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587 @Test fun verifyFirefoxSuggestSponsoredSearchResultsWithPartialKeywordTest() { runWithCondition(TestHelper.appContext.settings().enableFxSuggest) { @@ -144,7 +143,7 @@ class FirefoxSuggestTest { } // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348363 - @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1874831") + // Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587 @Test fun openFirefoxSuggestSponsoredSearchResultsTest() { runWithCondition(TestHelper.appContext.settings().enableFxSuggest) { @@ -168,7 +167,7 @@ class FirefoxSuggestTest { } // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348369 - @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1874831") + // Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587 @Test fun verifyFirefoxSuggestSponsoredSearchResultsWithEditedKeywordTest() { runWithCondition(TestHelper.appContext.settings().enableFxSuggest) { @@ -192,6 +191,7 @@ class FirefoxSuggestTest { } // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348374 + // Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587 @SmokeTest @Test fun verifyFirefoxSuggestNonSponsoredSearchResultsTest() { @@ -218,6 +218,7 @@ class FirefoxSuggestTest { } // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348375 + // Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587 @Test fun verifyFirefoxSuggestNonSponsoredSearchResultsWithPartialKeywordTest() { runWithCondition(TestHelper.appContext.settings().enableFxSuggest) { @@ -237,6 +238,7 @@ class FirefoxSuggestTest { } // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348376 + // Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587 @Test fun openFirefoxSuggestNonSponsoredSearchResultsTest() { runWithCondition(TestHelper.appContext.settings().enableFxSuggest) { From 8832039332e80981ae980d4b84c5c3731ea6df94 Mon Sep 17 00:00:00 2001 From: Arturo Mejia Date: Fri, 5 Jan 2024 16:39:28 -0500 Subject: [PATCH 016/586] Bug 1870351 - Improve touch targets Add-ons details screen. --- .../res/layout/fragment_add_on_details.xml | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/fenix/app/src/main/res/layout/fragment_add_on_details.xml b/fenix/app/src/main/res/layout/fragment_add_on_details.xml index 61bff2fcde42..1ab400991322 100644 --- a/fenix/app/src/main/res/layout/fragment_add_on_details.xml +++ b/fenix/app/src/main/res/layout/fragment_add_on_details.xml @@ -32,7 +32,9 @@ style="@style/AboutHeaderContentText" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="20dp" + android:gravity="center" + android:minHeight="48dp" + android:layout_marginTop="10dp" android:text="@string/mozac_feature_addons_author" app:layout_constraintEnd_toStartOf="@+id/author_text" app:layout_constraintHorizontal_chainStyle="spread_inside" @@ -44,8 +46,10 @@ style="@style/AboutHeaderContentText" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:gravity="center" + android:minHeight="48dp" android:layout_alignParentEnd="true" - android:layout_marginTop="20dp" + android:layout_marginTop="10dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/author_label" app:layout_constraintTop_toBottomOf="@+id/details" @@ -56,7 +60,6 @@ android:id="@+id/author_divider" android:layout_width="match_parent" android:layout_height="1dp" - android:layout_marginTop="10dp" android:background="?android:attr/listDivider" android:importantForAccessibility="no" app:layout_constraintTop_toBottomOf="@id/author_text" @@ -67,7 +70,8 @@ style="@style/AboutHeaderContentText" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="10dp" + android:gravity="center" + android:minHeight="48dp" android:text="@string/mozac_feature_addons_version" app:layout_constraintEnd_toStartOf="@+id/version_text" app:layout_constraintHorizontal_chainStyle="spread_inside" @@ -80,7 +84,9 @@ style="@style/AboutHeaderContentText" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="10dp" + android:minWidth="48dp" + android:minHeight="48dp" + android:gravity="center" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/version_label" app:layout_constraintTop_toBottomOf="@+id/author_divider" @@ -91,8 +97,6 @@ android:id="@+id/version_divider" android:layout_width="match_parent" android:layout_height="1dp" - android:layout_marginTop="10dp" - android:layout_marginBottom="10dp" android:background="?android:attr/listDivider" android:importantForAccessibility="no" app:layout_constraintTop_toBottomOf="@+id/version_text" /> @@ -102,7 +106,8 @@ style="@style/AboutHeaderContentText" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="10dp" + android:gravity="center" + android:minHeight="48dp" android:text="@string/mozac_feature_addons_last_updated" app:layout_constraintEnd_toStartOf="@+id/last_updated_text" app:layout_constraintHorizontal_chainStyle="spread_inside" @@ -114,7 +119,8 @@ style="@style/AboutHeaderContentText" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="10dp" + android:gravity="center" + android:minHeight="48dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/last_updated_label" app:layout_constraintTop_toBottomOf="@+id/version_divider" @@ -125,7 +131,6 @@ android:id="@+id/last_updated_divider" android:layout_width="match_parent" android:layout_height="1dp" - android:layout_marginTop="10dp" android:background="?android:attr/listDivider" android:importantForAccessibility="no" app:layout_constraintTop_toBottomOf="@+id/last_updated_text" /> @@ -135,7 +140,10 @@ style="@style/AboutHeaderContentText" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="10dp" + android:gravity="center" + android:minHeight="48dp" + android:clickable="true" + android:focusable="true" android:text="@string/mozac_feature_addons_home_page" android:textColor="?textAccent" app:layout_constraintStart_toStartOf="parent" @@ -145,7 +153,6 @@ android:id="@+id/home_page_divider" android:layout_width="match_parent" android:layout_height="1dp" - android:layout_marginTop="10dp" android:background="?android:attr/listDivider" android:importantForAccessibility="no" app:layout_constraintTop_toBottomOf="@+id/home_page_label" /> @@ -154,7 +161,6 @@ android:id="@+id/rating" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="10dp" app:layout_constraintTop_toBottomOf="@+id/home_page_divider"> @@ -212,7 +222,10 @@ style="@style/AboutHeaderContentText" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="10dp" + android:gravity="center" + android:minHeight="48dp" + android:clickable="true" + android:focusable="true" android:text="@string/mozac_feature_addons_more_info_link" android:textColor="?textAccent" app:layout_constraintStart_toStartOf="parent" From cd5f8f2df4c38ec4e59b41492511bc3cace19bf2 Mon Sep 17 00:00:00 2001 From: Noah Bond Date: Tue, 30 Jan 2024 10:07:26 -0800 Subject: [PATCH 017/586] Bug 1876596 - Add probe for debug drawer secret setting --- fenix/app/metrics.yaml | 16 ++++++++++++++++ .../fenix/settings/SecretSettingsFragment.kt | 2 ++ 2 files changed, 18 insertions(+) diff --git a/fenix/app/metrics.yaml b/fenix/app/metrics.yaml index aba35607b70d..fe36185ed84c 100644 --- a/fenix/app/metrics.yaml +++ b/fenix/app/metrics.yaml @@ -11353,3 +11353,19 @@ fx_suggest: expires: never send_in_pings: - fx-suggest +debug_drawer: + debug_drawer_enabled: + type: boolean + description: | + Whether or not the user has enabled the Debug Drawer feature. + send_in_pings: + - metrics + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1876596 + data_reviews: + - https://github.com/mozilla-mobile/firefox-android/pull/5356 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: never diff --git a/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt index ecffe568a4cb..4f5c99085b91 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt @@ -23,6 +23,7 @@ import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar +import org.mozilla.fenix.GleanMetrics.DebugDrawer as DebugDrawerMetrics class SecretSettingsFragment : PreferenceFragmentCompat() { @@ -114,6 +115,7 @@ class SecretSettingsFragment : PreferenceFragmentCompat() { onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> debugSettingsRepository.setDebugDrawerEnabled(enabled = newValue as Boolean) + DebugDrawerMetrics.debugDrawerEnabled.set(newValue) true } } From 734bb03b6f65469e02f521a9816357267ef0455a Mon Sep 17 00:00:00 2001 From: mike a Date: Mon, 29 Jan 2024 18:58:36 -0800 Subject: [PATCH 018/586] Bug 1877350 - Refactor tabstray composable to extract tab counter into a separate file Preparing to use it for navigation bar composable. --- .../org/mozilla/fenix/compose/TabCounter.kt | 127 ++++++++++++++++++ .../mozilla/fenix/tabstray/TabsTrayBanner.kt | 93 +------------ 2 files changed, 130 insertions(+), 90 deletions(-) create mode 100644 fenix/app/src/main/java/org/mozilla/fenix/compose/TabCounter.kt diff --git a/fenix/app/src/main/java/org/mozilla/fenix/compose/TabCounter.kt b/fenix/app/src/main/java/org/mozilla/fenix/compose/TabCounter.kt new file mode 100644 index 000000000000..a2f2d070973b --- /dev/null +++ b/fenix/app/src/main/java/org/mozilla/fenix/compose/TabCounter.kt @@ -0,0 +1,127 @@ +/* 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.compose + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Icon +import androidx.compose.material.LocalContentAlpha +import androidx.compose.material.LocalContentColor +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.testTag +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import org.mozilla.fenix.R +import org.mozilla.fenix.compose.annotation.LightDarkPreview +import org.mozilla.fenix.tabstray.TabsTrayTestTag +import org.mozilla.fenix.theme.FirefoxTheme + +private const val MAX_VISIBLE_TABS = 99 +private const val SO_MANY_TABS_OPEN = "∞" +private val NORMAL_TABS_BOTTOM_PADDING = 0.5.dp +private const val ONE_DIGIT_SIZE_RATIO = 0.5f +private const val TWO_DIGITS_SIZE_RATIO = 0.4f +private const val MIN_SINGLE_DIGIT = 0 +private const val MAX_SINGLE_DIGIT = 9 +private const val TWO_DIGIT_THRESHOLD = 10 +private const val TAB_TEXT_BOTTOM_PADDING_RATIO = 4 + +/** + * UI for displaying the number of opened tabs. +* +* This composable uses LocalContentColor, provided by CompositionLocalProvider, +* to set the color of its icons and text. +* +* @param tabCount the number to be displayed inside the counter. +*/ + +@Composable +fun TabCounter(tabCount: Int) { + val normalTabCountText: String + val tabCountTextRatio: Float + val needsBottomPaddingForInfiniteTabs: Boolean + + when (tabCount) { + in MIN_SINGLE_DIGIT..MAX_SINGLE_DIGIT -> { + normalTabCountText = tabCount.toString() + tabCountTextRatio = ONE_DIGIT_SIZE_RATIO + needsBottomPaddingForInfiniteTabs = false + } + + in TWO_DIGIT_THRESHOLD..MAX_VISIBLE_TABS -> { + normalTabCountText = tabCount.toString() + tabCountTextRatio = TWO_DIGITS_SIZE_RATIO + needsBottomPaddingForInfiniteTabs = false + } + + else -> { + normalTabCountText = SO_MANY_TABS_OPEN + tabCountTextRatio = ONE_DIGIT_SIZE_RATIO + needsBottomPaddingForInfiniteTabs = true + } + } + + val normalTabsContentDescription = if (tabCount == 1) { + stringResource(id = R.string.mozac_tab_counter_open_tab_tray_single) + } else { + stringResource( + id = R.string.mozac_tab_counter_open_tab_tray_plural, + tabCount.toString(), + ) + } + + val counterBoxWidthDp = + dimensionResource(id = mozilla.components.ui.tabcounter.R.dimen.mozac_tab_counter_box_width_height) + val counterBoxWidthPx = LocalDensity.current.run { counterBoxWidthDp.roundToPx() } + val counterTabsTextSize = (tabCountTextRatio * counterBoxWidthPx).toInt() + + val normalTabsTextModifier = if (needsBottomPaddingForInfiniteTabs) { + val bottomPadding = with(LocalDensity.current) { counterTabsTextSize.toDp() / TAB_TEXT_BOTTOM_PADDING_RATIO } + Modifier.padding(bottom = bottomPadding) + } else { + Modifier.padding(bottom = NORMAL_TABS_BOTTOM_PADDING) + } + + Box( + modifier = Modifier + .semantics(mergeDescendants = true) { + testTag = TabsTrayTestTag.normalTabsCounter + }, + contentAlignment = Alignment.Center, + ) { + Icon( + painter = painterResource( + id = mozilla.components.ui.tabcounter.R.drawable.mozac_ui_tabcounter_box, + ), + contentDescription = normalTabsContentDescription, + ) + + Text( + text = normalTabCountText, + modifier = normalTabsTextModifier, + color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current), + fontSize = with(LocalDensity.current) { counterTabsTextSize.toDp().toSp() }, + fontWeight = FontWeight.W700, + textAlign = TextAlign.Center, + ) + } +} + +@LightDarkPreview +@Composable +private fun TabCounterPreview() { + FirefoxTheme { + TabCounter(tabCount = 55) + } +} diff --git a/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayBanner.kt b/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayBanner.kt index 2779acc4f178..13e9c1d4c019 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayBanner.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayBanner.kt @@ -13,12 +13,9 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.Icon import androidx.compose.material.IconButton -import androidx.compose.material.LocalContentAlpha -import androidx.compose.material.LocalContentColor import androidx.compose.material.Tab import androidx.compose.material.TabRow import androidx.compose.material.Text @@ -35,27 +32,22 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.semantics.testTag -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp import mozilla.components.browser.state.state.ContentState import mozilla.components.browser.state.state.TabSessionState import mozilla.components.lib.state.ext.observeAsComposableState -import mozilla.components.ui.tabcounter.TabCounter import org.mozilla.fenix.R import org.mozilla.fenix.compose.Banner import org.mozilla.fenix.compose.BottomSheetHandle import org.mozilla.fenix.compose.ContextualMenu import org.mozilla.fenix.compose.Divider import org.mozilla.fenix.compose.MenuItem +import org.mozilla.fenix.compose.TabCounter import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.tabstray.ext.getMenuItems import org.mozilla.fenix.theme.FirefoxTheme @@ -232,7 +224,7 @@ private fun SingleSelectBanner( selectedContentColor = selectedColor, unselectedContentColor = inactiveColor, ) { - NormalTabsTabIcon(normalTabCount = normalTabCount) + TabCounter(tabCount = normalTabCount) } Tab( @@ -293,85 +285,6 @@ private fun SingleSelectBanner( } } -private const val MAX_VISIBLE_TABS = 99 -private const val SO_MANY_TABS_OPEN = "∞" -private val NORMAL_TABS_BOTTOM_PADDING = 0.5.dp -private const val ONE_DIGIT_SIZE_RATIO = 0.5f -private const val TWO_DIGITS_SIZE_RATIO = 0.4f - -@Composable -@Suppress("MagicNumber") -private fun NormalTabsTabIcon(normalTabCount: Int) { - val normalTabCountText: String - val tabCountTextRatio: Float - val needsBottomPaddingForInfiniteTabs: Boolean - - when (normalTabCount) { - in 0..9 -> { - normalTabCountText = normalTabCount.toString() - tabCountTextRatio = ONE_DIGIT_SIZE_RATIO - needsBottomPaddingForInfiniteTabs = false - } - - in 10..MAX_VISIBLE_TABS -> { - normalTabCountText = normalTabCount.toString() - tabCountTextRatio = TWO_DIGITS_SIZE_RATIO - needsBottomPaddingForInfiniteTabs = false - } - - else -> { - normalTabCountText = SO_MANY_TABS_OPEN - tabCountTextRatio = ONE_DIGIT_SIZE_RATIO - needsBottomPaddingForInfiniteTabs = true - } - } - - val normalTabsContentDescription = if (normalTabCount == 1) { - stringResource(id = R.string.mozac_tab_counter_open_tab_tray_single) - } else { - stringResource( - id = R.string.mozac_tab_counter_open_tab_tray_plural, - normalTabCount.toString(), - ) - } - - val counterBoxWidthDp = - dimensionResource(id = mozilla.components.ui.tabcounter.R.dimen.mozac_tab_counter_box_width_height) - val counterBoxWidthPx = LocalDensity.current.run { counterBoxWidthDp.roundToPx() } - val counterTabsTextSize = (tabCountTextRatio * counterBoxWidthPx).toInt() - - val normalTabsTextModifier = if (needsBottomPaddingForInfiniteTabs) { - val bottomPadding = with(LocalDensity.current) { counterTabsTextSize.toDp() / 4 } - Modifier.padding(bottom = bottomPadding) - } else { - Modifier.padding(bottom = NORMAL_TABS_BOTTOM_PADDING) - } - - Box( - modifier = Modifier - .semantics(mergeDescendants = true) { - testTag = TabsTrayTestTag.normalTabsCounter - }, - contentAlignment = Alignment.Center, - ) { - Icon( - painter = painterResource( - id = mozilla.components.ui.tabcounter.R.drawable.mozac_ui_tabcounter_box, - ), - contentDescription = normalTabsContentDescription, - ) - - Text( - text = normalTabCountText, - modifier = normalTabsTextModifier, - color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current), - fontSize = with(LocalDensity.current) { counterTabsTextSize.toDp().toSp() }, - fontWeight = FontWeight.W700, - textAlign = TextAlign.Center, - ) - } -} - /** * Banner displayed in multi select mode. * @@ -470,7 +383,7 @@ private fun TabsTrayBannerPreview() { @Composable private fun TabsTrayBannerInfinityPreview() { TabsTrayBannerPreviewRoot( - normalTabCount = TabCounter.MAX_VISIBLE_TABS + 1, + normalTabCount = 200, ) } From 942d3f6451633481a86835ced2290824b025b90d Mon Sep 17 00:00:00 2001 From: sarah541 Date: Thu, 25 Jan 2024 11:12:41 -0500 Subject: [PATCH 019/586] Bug 1876794 - Fixes in A-C and Fenix strings --- .../feature/prompts/src/main/res/values/strings.xml | 10 +++++----- fenix/app/src/main/res/values/strings.xml | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/android-components/components/feature/prompts/src/main/res/values/strings.xml b/android-components/components/feature/prompts/src/main/res/values/strings.xml index 2727e92c6198..57bcb160199f 100644 --- a/android-components/components/feature/prompts/src/main/res/values/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values/strings.xml @@ -39,7 +39,7 @@ Password field must not be empty Enter a password - + Unable to save login Can’t save password @@ -100,19 +100,19 @@ Set time Manage logins - + Manage passwords Expand suggested logins - + Expand saved passwords Collapse suggested logins - + Collapse saved passwords Suggested logins - + Saved passwords diff --git a/fenix/app/src/main/res/values/strings.xml b/fenix/app/src/main/res/values/strings.xml index 081bf9eb9232..ad5d9588a897 100644 --- a/fenix/app/src/main/res/values/strings.xml +++ b/fenix/app/src/main/res/values/strings.xml @@ -1812,7 +1812,7 @@ Set up a device lock pattern, PIN, or password to protect your saved credit cards from being accessed if someone else has your device. - Set up a device lock pattern, PIN, or password to protect your saved cards from being accessed if someone else has your device. + Set up a device lock pattern, PIN, or password to protect your saved payment methods from being accessed if someone else has your device. Set up now @@ -1969,12 +1969,12 @@ Password options The editable text field for the web address of the login. - - The editable text field for the website address of the password. + + The editable text field for the website address. The editable text field for the username of the login. - - The editable text field for the username of the password. + + The editable text field for the username. The editable text field for the password of the login. From 1aa7ea0ae3add6f4617146ee3f94d736cba06ad0 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 31 Jan 2024 00:03:42 +0000 Subject: [PATCH 020/586] Import translations from android-l10n --- .../src/main/res/values-pa-rPK/strings.xml | 7 + .../src/main/res/values-pa-rPK/strings.xml | 158 ++++++++++++++++-- 2 files changed, 151 insertions(+), 14 deletions(-) diff --git a/android-components/components/feature/prompts/src/main/res/values-pa-rPK/strings.xml b/android-components/components/feature/prompts/src/main/res/values-pa-rPK/strings.xml index ec6bd5e21f18..f3e24af90d23 100644 --- a/android-components/components/feature/prompts/src/main/res/values-pa-rPK/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-pa-rPK/strings.xml @@ -94,6 +94,13 @@ تجویز دے ویروے + + مضبوط پاس‌ورڈ لئی تجویز کرو + + مضبوط پاس‌ورڈ لئی تجویز کرو + + مضبوط پاس‌ورڈ نوں ورتوں: %1$s + فیر بھیجیو؟ ایس صفحے نوں مڑ تازہ کرن نال تاشہ کاروائیاں نوں دہرایا جاۓگا؛ جیویں کہ بھگتان بھیجݨ یاں ٹپݨی نوں دو وار پا لایا جاۓگا۔ diff --git a/fenix/app/src/main/res/values-pa-rPK/strings.xml b/fenix/app/src/main/res/values-pa-rPK/strings.xml index a77e24283a38..36245c9b3b84 100644 --- a/fenix/app/src/main/res/values-pa-rPK/strings.xml +++ b/fenix/app/src/main/res/values-pa-rPK/strings.xml @@ -259,8 +259,6 @@ سکین کرو - - کھوج انجݨ کھوج انجݨ دیاں ترجیحاں @@ -312,23 +310,28 @@ - اطلاعواں تہانوں %s نال ہور کرن دی مدد کردے ہن + اطلاعواں تہانوں %s نال ہور کرن دی مدد کردے ہن - ڈوائیساں وچالے آپݨیاں ٹیباں نوں ہم وقت کرو، ڈاؤن‌لوڈ دا انتظام کرو، %s ایپ دی پردہ داری سرکھیا دا پورا فائدہ لیݨ لئی گر لوو تے ہور۔ + ڈوائیساں وچالے آپݨیاں ٹیباں نوں ہم وقت کرو، ڈاؤن‌لوڈ دا انتظام کرو، %s ایپ دی پردہ داری سرکھیا دا پورا فائدہ لیݨ لئی گر لوو تے ہور۔ - جاری رکھو + جاری رکھو - ہݨے نہیں + ہݨے نہیں + + فائرفاکس پردے داری سوچنا + اسیں تہانوں سرکھیت رکھݨا چاہندے آں - ساڈا غیر منافع سمرتھ براؤزر کمپنیاں نوں ویب اُتے چوری بھِپے پِچھا کرن توں روکݨ لئی مدد کردا اے۔ \n\n ساڈے پردے داری نوٹس بارے ہور سکھو۔ + کمپنیاں نوں چوری چوری ویب اُتے تہاڈا پچھا کرن توں ساڈا غیر فائدہ سمرتھ براؤزر آپݨے آپ ہی روکدا اے۔ + + ساڈا غیر منافع سمرتھ براؤزر کمپنیاں نوں ویب اُتے چوری بھِپے پِچھا کرن توں روکݨ لئی مدد کردا اے۔ \n\n ساڈے پردے داری نوٹس بارے ہور سکھو۔ - پردے داری دا بیان + پردے داری دا بیان مول براؤزر تے طور تے بݨاؤ @@ -354,6 +357,22 @@ ہݨے نہیں + + فائرفاکس کھوج وجیٹ ازماؤ + + تہاڈی مکھ سکرین اُتے فائرفاکس نال تسیں پرائیویسی ادھارت براؤزر نوں سوکھی طرح ورت سکدے او، جو کہ انتر سائیٹ ٹریکراں اُتے پابندی لاوندا اے۔ + + + فائرفاکس وجیٹ جوڑو + + ہݨے نہیں + + + + %1$s نال نویں ٹیب کھولھو کھوج @@ -369,34 +388,115 @@ عام بارے + + اک چݨو + + بدلویں کھوج انجݨاں دا انتئام کرو + + کھوج مینو وچ دسݨ والے انجݨاں نوں سودھو + + کھوج مینو وچ دسݨ والے انجݨ مول کھوج والا کھوج + + کھوجݨ والے انجݨ + + کھوجݨ والیاں انجݨاں توں سجھاؤ + + سرناواں پٹی لئی ترجیحاں + + سرناواں پٹی – فائرفاکس سجھاؤ + + فائرفاکس سجھاؤ بارے پور جاݨو ایپ دکان تے درجہ دیو %1$s بارے + + مول براؤزر تے طور تے بݨاؤ اضافی - - بند - - چالو + + پردے داری تے سرکھیا + + سائیٹ دیاں اجازتاں + + نجی براؤز کرن + + لنک نجی ٹیب وچ کھولھو + + نجی براؤز وچ سکرین‌شاٹ منظور کرو + + جے اجازت دتی تاں نجی ٹیباں اودوں وی دکھائی دیݨ‌گیاں، جدوں کئی ایپاں کھلھیاں ہندیاں ہن + + + نجی براؤز کرن شارٹ‌کٹ جوڑو + + سرف HTTPS ڈھنگ + + + کوکی جھنڈا روکو + + نجی براؤز کرن وچ کوکی جھنڈا روکو + + ایس سائیٹ لئی بند اے رد کرو - - اجازت دیو + + بینتی بھیجیں + + ایس سائیٹ لئی سہایتا دی بینتی کرنی اے؟ + + ںینتی بھیجی ہوئی + + ایس سائیٹ لئی چالو + + سہایتا بینتی بھیجی + + سائیٹ ایس ویلے سہایک نہیں اے + + کیہہ %1$s لئی کوکی جھنڈا روکو چالو کرنا اے؟ + + کیہہ %1$s لئی کوکی جھنڈا روکو بند کرنا اے؟ + + %1$s ایس سائیٹ لئی آپݨے آپ کوکی بینتیاں نوں بند نہیں کر سکدا اے۔ تسیں مستقبل وچ ایس سائیٹ واسطے سہایتا لئی بینتی کر سکدے او۔ + + بند کرن نال %1$s ایس سائیٹ لئی کوکیاں مٹا کے ایس نوں مڑ لوڈ کرےگا۔ ایہہ تہانوں لاگ آؤٹ جاں تہاڈی خرید داری کارٹاں نوں خالی کرےگا۔ + + + چاکو کرو تے %1$s ایس سائیٹ واسطے کوکی جھنڈے نوں آپݨے آپ انکار کرن دی کوشش کرےگا۔ + + %1$s نے ہݨے تہاڈے لئی کوکیاں توں انکار کیتا اے + + + ایس سائیٹ لئی تہاڈے لئی گھٹ دھیان بھٹکݨا، گھٹ کوکیاں ٹریک کرن اے۔ + + + وادھا کیتی سرکھیا لئی HTTPS انکرپشن پروٹوکال ورت کے سائیٹاں نال کنیکٹ کرن دی آپݨے آپ کوشش کرو۔ بند + + سبھناں ٹیباں وچ چالو اے + + نجی ٹیباں وچ چالو ہی اے ہور جاݨو + + ساریاں ٹیباں وچ چالو کرو + + صرف نجی ٹیباں وچ چالو کرو + + سرکھیت سائیٹ دستیاب نہیں اے + + رسائیت کھاتہ @@ -416,17 +516,32 @@ ڈیٹا چوݨاں + + اتے پتے دی کھوج + + ہمیشہ + + کدے نہیں + وادھے والے اطلاع نامے + + اجازت دتے + + اجازت نہیں دتے + ٹھیک اے رد کرو + + والپیپر + ویکھو @@ -437,6 +552,18 @@ تریخ + + اتے پتے + + لاگ ان + + پاس‌ورڈ + + ساریاں کھولھو + + لاگ آؤٹ + + ڈوائیس دا ناں پتے @@ -811,6 +938,9 @@ ہور جاݨو + + سیٹنگاں نوں جاؤ + From 76213dc84f49a0400e009ea06e3d09fd3ad68ded Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 31 Jan 2024 02:22:15 +0000 Subject: [PATCH 021/586] Update GeckoView (Nightly) to 124.0.20240130214506. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 9d98b1f1ef7d..90df3e5519e1 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240130045011" + const val version = "124.0.20240130214506" /** * GeckoView channel From ac3a4eaa745a95ee765444e8a42b4463fdfe413a Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 30 Jan 2024 12:48:21 +0200 Subject: [PATCH 022/586] Bug 1877409 - Add more test logs to CustomTabRobot --- .../mozilla/fenix/ui/robots/CustomTabRobot.kt | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt index fd76071c1c81..01959e7b8560 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.fenix.ui.robots +import android.util.Log import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.assertion.ViewAssertions.matches @@ -14,6 +15,7 @@ import androidx.test.uiautomator.By import androidx.test.uiautomator.UiSelector import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION +import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText @@ -43,14 +45,16 @@ class CustomTabRobot { itemWithDescription(getStringResource(R.string.mozac_feature_customtabs_share_link)), ) - fun verifyMainMenuButton() = assertUIObjectExists(mainMenuButton) + fun verifyMainMenuButton() = assertUIObjectExists(mainMenuButton()) fun verifyDesktopSiteButtonExists() { desktopSiteButton().check(matches(isDisplayed())) + Log.i(TAG, "verifyDesktopSiteButtonExists: Verified request desktop site button is displayed") } fun verifyFindInPageButtonExists() { findInPageButton().check(matches(isDisplayed())) + Log.i(TAG, "verifyFindInPageButtonExists: Verified find in page button is displayed") } fun verifyPoweredByTextIsDisplayed() = @@ -58,6 +62,7 @@ class CustomTabRobot { fun verifyOpenInBrowserButtonExists() { openInBrowserButton().check(matches(isDisplayed())) + Log.i(TAG, "verifyOpenInBrowserButtonExists: Verified open in browser button is displayed") } fun verifyBackButtonExists() = assertUIObjectExists(itemWithDescription("Back")) @@ -70,6 +75,7 @@ class CustomTabRobot { fun verifyCustomTabCloseButton() { closeButton().check(matches(isDisplayed())) + Log.i(TAG, "verifyCustomTabCloseButton: Verified close custom tab button is displayed") } fun verifyCustomTabToolbarTitle(title: String) { @@ -104,6 +110,7 @@ class CustomTabRobot { waitingTime, ) customTabToolbar().click(LONG_CLICK_DURATION) + Log.i(TAG, "longCLickAndCopyToolbarUrl: Long clicked custom tab toolbar") clickContextMenuItem("Copy") } @@ -118,9 +125,15 @@ class CustomTabRobot { ) } - fun waitForPageToLoad() = progressBar.waitUntilGone(waitingTime) + fun waitForPageToLoad() { + progressBar().waitUntilGone(waitingTime) + Log.i(TAG, "waitForPageToLoad: Waited $waitingTime ms until progress bar was gone") + } - fun clickCustomTabCloseButton() = closeButton().click() + fun clickCustomTabCloseButton() { + closeButton().click() + Log.i(TAG, "clickCustomTabCloseButton: Clicked close custom tab button") + } fun verifyCustomTabActionButton(customTabActionButtonDescription: String) = assertUIObjectExists(itemWithDescription(customTabActionButtonDescription)) @@ -133,9 +146,11 @@ class CustomTabRobot { class Transition { fun openMainMenu(interact: CustomTabRobot.() -> Unit): Transition { - mainMenuButton.also { + mainMenuButton().also { + Log.i(TAG, "openMainMenu: Looking for main menu button") it.waitForExists(waitingTime) it.click() + Log.i(TAG, "openMainMenu: Clicked main menu button") } CustomTabRobot().interact() @@ -144,6 +159,7 @@ class CustomTabRobot { fun clickOpenInBrowserButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { openInBrowserButton().perform(click()) + Log.i(TAG, "clickOpenInBrowserButton: Clicked \"Open in Firefox\" button") BrowserRobot().interact() return BrowserRobot.Transition() @@ -151,6 +167,7 @@ class CustomTabRobot { fun clickShareButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { itemWithDescription(getStringResource(R.string.mozac_feature_customtabs_share_link)).click() + Log.i(TAG, "clickShareButton: Clicked share button") ShareOverlayRobot().interact() return ShareOverlayRobot.Transition() @@ -163,7 +180,7 @@ fun customTabScreen(interact: CustomTabRobot.() -> Unit): CustomTabRobot.Transit return CustomTabRobot.Transition() } -private val mainMenuButton = itemWithResId("$packageName:id/mozac_browser_toolbar_menu") +private fun mainMenuButton() = itemWithResId("$packageName:id/mozac_browser_toolbar_menu") private fun desktopSiteButton() = onView(withId(R.id.switch_widget)) @@ -175,7 +192,7 @@ private fun closeButton() = onView(withContentDescription("Return to previous ap private fun customTabToolbar() = mDevice.findObject(By.res("$packageName:id/toolbar")) -private val progressBar = +private fun progressBar() = mDevice.findObject( UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_progress"), ) From 1ec06b2b158290e01715b1209cefa893787e5e36 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 30 Jan 2024 14:10:25 +0200 Subject: [PATCH 023/586] Bug 1877435 - Add more test logs to EnhancedTrackingProtectionRobot --- .../robots/EnhancedTrackingProtectionRobot.kt | 51 +++++++++++++++---- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt index 6c7cdeff3af6..29e2a25abcef 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt @@ -6,6 +6,7 @@ package org.mozilla.fenix.ui.robots +import android.util.Log import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.RootMatchers @@ -21,6 +22,7 @@ import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.containsString import org.hamcrest.Matchers.not import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId @@ -43,7 +45,8 @@ class EnhancedTrackingProtectionRobot { fun verifyCrossSiteCookiesBlocked(isBlocked: Boolean) { assertUIObjectExists(itemWithResId("$packageName:id/cross_site_tracking")) - crossSiteCookiesBlockListButton.click() + crossSiteCookiesBlockListButton().click() + Log.i(TAG, "verifyCrossSiteCookiesBlocked: Clicked cross site cookies block list button") // Verifies the trackers block/allow list onView(withId(R.id.details_blocking_header)) .check( @@ -57,11 +60,13 @@ class EnhancedTrackingProtectionRobot { ), ), ) + Log.i(TAG, "verifyCrossSiteCookiesBlocked: Verified cross site cookies are blocked: $isBlocked") } fun verifySocialMediaTrackersBlocked(isBlocked: Boolean) { assertUIObjectExists(itemWithResId("$packageName:id/social_media_trackers")) - socialTrackersBlockListButton.click() + socialTrackersBlockListButton().click() + Log.i(TAG, "verifySocialMediaTrackersBlocked: Clicked social trackers block list button") // Verifies the trackers block/allow list onView(withId(R.id.details_blocking_header)) .check( @@ -75,12 +80,15 @@ class EnhancedTrackingProtectionRobot { ), ), ) + Log.i(TAG, "verifySocialMediaTrackersBlocked: Verified social trackers are blocked: $isBlocked") onView(withId(R.id.blocking_text_list)).check(matches(isDisplayed())) + Log.i(TAG, "verifySocialMediaTrackersBlocked: Verified blocked social trackers list is displayed") } fun verifyFingerprintersBlocked(isBlocked: Boolean) { assertUIObjectExists(itemWithResId("$packageName:id/fingerprinters")) - fingerprintersBlockListButton.click() + fingerprintersBlockListButton().click() + Log.i(TAG, "verifyFingerprintersBlocked: Clicked fingerprinters block list button") // Verifies the trackers block/allow list onView(withId(R.id.details_blocking_header)) .check( @@ -94,12 +102,15 @@ class EnhancedTrackingProtectionRobot { ), ), ) + Log.i(TAG, "verifyFingerprintersBlocked: Verified fingerprinters are blocked: $isBlocked") onView(withId(R.id.blocking_text_list)).check(matches(isDisplayed())) + Log.i(TAG, "verifyFingerprintersBlocked: Verified blocked fingerprinter trackers list is displayed") } fun verifyCryptominersBlocked(isBlocked: Boolean) { assertUIObjectExists(itemWithResId("$packageName:id/cryptominers")) - cryptominersBlockListButton.click() + cryptominersBlockListButton().click() + Log.i(TAG, "verifyCryptominersBlocked: Clicked cryptominers block list button") // Verifies the trackers block/allow list onView(withId(R.id.details_blocking_header)) .check( @@ -113,12 +124,15 @@ class EnhancedTrackingProtectionRobot { ), ), ) + Log.i(TAG, "verifyCryptominersBlocked: Verified cryptominers are blocked: $isBlocked") onView(withId(R.id.blocking_text_list)).check(matches(isDisplayed())) + Log.i(TAG, "verifyCryptominersBlocked: Verified blocked cryptominers trackers list is displayed") } fun verifyTrackingContentBlocked(isBlocked: Boolean) { assertUIObjectExists(itemWithText("Tracking Content")) - trackingContentBlockListButton.click() + trackingContentBlockListButton().click() + Log.i(TAG, "verifyTrackingContentBlocked: Clicked tracking content block list button") // Verifies the trackers block/allow list onView(withId(R.id.details_blocking_header)) .check( @@ -132,7 +146,9 @@ class EnhancedTrackingProtectionRobot { ), ), ) + Log.i(TAG, "verifyTrackingContentBlocked: Verified tracking content is blocked: $isBlocked") onView(withId(R.id.blocking_text_list)).check(matches(isDisplayed())) + Log.i(TAG, "verifyTrackingContentBlocked: Verified blocked tracking content trackers list is displayed") } fun viewTrackingContentBlockList() { @@ -148,6 +164,7 @@ class EnhancedTrackingProtectionRobot { ), ), ) + Log.i(TAG, "viewTrackingContentBlockList: Verified blocked tracking content trackers") } fun verifyETPSectionIsDisplayedInQuickSettingsSheet(isDisplayed: Boolean) = @@ -158,12 +175,15 @@ class EnhancedTrackingProtectionRobot { fun navigateBackToDetails() { onView(withId(R.id.details_back)).click() + Log.i(TAG, "navigateBackToDetails: Clicked details list back button") } class Transition { fun openEnhancedTrackingProtectionSheet(interact: EnhancedTrackingProtectionRobot.() -> Unit): Transition { + Log.i(TAG, "openEnhancedTrackingProtectionSheet: Looking for site security button") pageSecurityIndicator().waitForExists(waitingTime) pageSecurityIndicator().click() + Log.i(TAG, "openEnhancedTrackingProtectionSheet: Clicked site security button") assertSecuritySheetIsCompletelyDisplayed() EnhancedTrackingProtectionRobot().interact() @@ -173,6 +193,7 @@ class EnhancedTrackingProtectionRobot { fun closeEnhancedTrackingProtectionSheet(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { // Back out of the Enhanced Tracking Protection sheet mDevice.pressBack() + Log.i(TAG, "closeEnhancedTrackingProtectionSheet: Clicked device back button") BrowserRobot().interact() return BrowserRobot.Transition() @@ -180,23 +201,29 @@ class EnhancedTrackingProtectionRobot { fun toggleEnhancedTrackingProtectionFromSheet(interact: EnhancedTrackingProtectionRobot.() -> Unit): Transition { enhancedTrackingProtectionSwitch().click() + Log.i(TAG, "toggleEnhancedTrackingProtectionFromSheet: Clicked ETP switch") EnhancedTrackingProtectionRobot().interact() return Transition() } fun openProtectionSettings(interact: SettingsSubMenuEnhancedTrackingProtectionRobot.() -> Unit): SettingsSubMenuEnhancedTrackingProtectionRobot.Transition { + Log.i(TAG, "openProtectionSettings: Looking for ETP sheet \"Details\" button") openEnhancedTrackingProtectionDetails().waitForExists(waitingTime) openEnhancedTrackingProtectionDetails().click() + Log.i(TAG, "openProtectionSettings: Clicked ETP sheet \"Details\" button") trackingProtectionSettingsButton().click() + Log.i(TAG, "openProtectionSettings: Clicked \"Protection Settings\" button") SettingsSubMenuEnhancedTrackingProtectionRobot().interact() return SettingsSubMenuEnhancedTrackingProtectionRobot.Transition() } fun openDetails(interact: EnhancedTrackingProtectionRobot.() -> Unit): Transition { + Log.i(TAG, "openDetails: Looking for ETP sheet \"Details\" button") openEnhancedTrackingProtectionDetails().waitForExists(waitingTime) openEnhancedTrackingProtectionDetails().click() + Log.i(TAG, "openDetails: Clicked ETP sheet \"Details\" button") EnhancedTrackingProtectionRobot().interact() return Transition() @@ -213,9 +240,11 @@ private fun assertETPSwitchVisibility(visible: Boolean) { if (visible) { enhancedTrackingProtectionSwitch() .check(matches(isDisplayed())) + Log.i(TAG, "assertETPSwitchVisibility: Verified ETP toggle is displayed") } else { enhancedTrackingProtectionSwitch() .check(matches(not(isDisplayed()))) + Log.i(TAG, "assertETPSwitchVisibility: Verified ETP toggle is not displayed") } } @@ -228,6 +257,7 @@ private fun assertEnhancedTrackingProtectionSheetStatus(status: String, state: B ), ), ) + Log.i(TAG, "assertEnhancedTrackingProtectionSheetStatus: Verified ETP toggle is checked: $state") } private fun pageSecurityIndicator() = @@ -246,7 +276,7 @@ private fun trackingProtectionSettingsButton() = private fun openEnhancedTrackingProtectionDetails() = mDevice.findObject(UiSelector().resourceId("$packageName:id/trackingProtectionDetails")) -private val trackingContentBlockListButton = +private fun trackingContentBlockListButton() = onView( allOf( withText("Tracking Content"), @@ -254,7 +284,7 @@ private val trackingContentBlockListButton = ), ) -private val socialTrackersBlockListButton = +private fun socialTrackersBlockListButton() = onView( allOf( withId(R.id.social_media_trackers), @@ -262,7 +292,7 @@ private val socialTrackersBlockListButton = ), ) -private val crossSiteCookiesBlockListButton = +private fun crossSiteCookiesBlockListButton() = onView( allOf( withId(R.id.cross_site_tracking), @@ -270,7 +300,7 @@ private val crossSiteCookiesBlockListButton = ), ) -private val cryptominersBlockListButton = +private fun cryptominersBlockListButton() = onView( allOf( withId(R.id.cryptominers), @@ -278,7 +308,7 @@ private val cryptominersBlockListButton = ), ) -private val fingerprintersBlockListButton = +private fun fingerprintersBlockListButton() = onView( allOf( withId(R.id.fingerprinters), @@ -287,6 +317,7 @@ private val fingerprintersBlockListButton = ) private fun assertSecuritySheetIsCompletelyDisplayed() { + Log.i(TAG, "assertSecuritySheetIsCompletelyDisplayed: Looking for quick actions sheet") mDevice.findObject(UiSelector().description(getStringResource(R.string.quick_settings_sheet))) .waitForExists(waitingTime) assertUIObjectExists(itemWithResId("$packageName:id/quick_action_sheet")) From 9f4330214afb6c858b9ec840ce3cd8cd27db4cad Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Fri, 26 Jan 2024 15:16:37 +0200 Subject: [PATCH 024/586] Bug 1876734 - Add more test logs to ComposeTopSitesRobot --- .../mozilla/fenix/ui/ComposeTopSitesTest.kt | 6 +++- .../fenix/ui/robots/ComposeTopSitesRobot.kt | 28 +++++++++++-------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeTopSitesTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeTopSitesTest.kt index a648e4d6da72..50bfadce1205 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeTopSitesTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeTopSitesTest.kt @@ -20,8 +20,10 @@ import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource 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.verifySnackBarText import org.mozilla.fenix.helpers.TestHelper.waitUntilSnackbarGone import org.mozilla.fenix.ui.robots.browserScreen +import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.homeScreenWithComposeTopSites import org.mozilla.fenix.ui.robots.navigationToolbar @@ -259,9 +261,11 @@ class ComposeTopSitesTest { verifyExistingTopSitesList() verifyExistingTopSiteItem(defaultWebPage.title) }.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) { - }.deleteTopSiteFromHistory { + }.removeTopSite { verifySnackBarText(getStringResource(R.string.snackbar_top_site_removed)) waitUntilSnackbarGone() + } + homeScreen { }.openThreeDotMenu { }.openHistory { verifyEmptyHistoryView() diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTopSitesRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTopSitesRobot.kt index 8493d3ee7ca5..1a25a39e6915 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTopSitesRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTopSitesRobot.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.ui.robots +import android.util.Log import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.filter import androidx.compose.ui.test.hasAnyChild @@ -16,6 +17,7 @@ import androidx.compose.ui.test.onFirst import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performScrollTo import androidx.compose.ui.test.performTouchInput +import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.HomeActivityComposeTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId @@ -32,14 +34,17 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR @OptIn(ExperimentalTestApi::class) fun verifyExistingTopSitesList() { + Log.i(TAG, "verifyExistingTopSitesList: Waiting for top sites list to exist") composeTestRule.waitUntilAtLeastOneExists(hasTestTag(TopSitesTestTag.topSites), timeoutMillis = waitingTime) } @OptIn(ExperimentalTestApi::class) fun verifyExistingTopSiteItem(vararg titles: String) { titles.forEach { title -> + Log.i(TAG, "verifyExistingTopSiteItem: Waiting for top site: $title to exist") composeTestRule.waitUntilAtLeastOneExists(hasText(title), timeoutMillis = waitingTime) composeTestRule.topSiteItem(title).assertExists() + Log.i(TAG, "verifyExistingTopSiteItem: Top site with $title exists") } } @@ -47,6 +52,7 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR titles.forEach { title -> itemContainingText(title).waitForExists(waitingTime) composeTestRule.topSiteItem(title).assertDoesNotExist() + Log.i(TAG, "verifyNotExistingTopSiteItem: Top site with $title does not exist") } } @@ -58,14 +64,17 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR fun verifyTopSiteContextMenuOpenInPrivateTabButton() { composeTestRule.contextMenuItemOpenInPrivateTab().assertExists() + Log.i(TAG, "verifyTopSiteContextMenuOpenInPrivateTabButton: Verified \"Open in private tab\" menu button exists") } fun verifyTopSiteContextMenuRenameButton() { composeTestRule.contextMenuItemRename().assertExists() + Log.i(TAG, "verifyTopSiteContextMenuRenameButton: Verified \"Rename\" menu button exists") } fun verifyTopSiteContextMenuRemoveButton() { composeTestRule.contextMenuItemRemove().assertExists() + Log.i(TAG, "verifyTopSiteContextMenuRemoveButton: Verified \"Remove\" menu button exists") } class Transition(private val composeTestRule: HomeActivityComposeTestRule) { @@ -75,6 +84,7 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR interact: BrowserRobot.() -> Unit, ): BrowserRobot.Transition { composeTestRule.topSiteItem(title).performScrollTo().performClick() + Log.i(TAG, "openTopSiteTabWithTitle: Scrolled and clicked top site with title: $title") BrowserRobot().interact() return BrowserRobot.Transition() @@ -84,6 +94,7 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR interact: BrowserRobot.() -> Unit, ): BrowserRobot.Transition { composeTestRule.contextMenuItemOpenInPrivateTab().performClick() + Log.i(TAG, "openTopSiteInPrivate: Clicked \"Open in private tab\" menu button") composeTestRule.waitForIdle() BrowserRobot().interact() @@ -97,6 +108,7 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR composeTestRule.topSiteItem(title).performScrollTo().performTouchInput { longClick() } + Log.i(TAG, "openContextMenuOnTopSitesWithTitle: Long clicked top site with title: $title") ComposeTopSitesRobot(composeTestRule).interact() return Transition(composeTestRule) @@ -107,12 +119,15 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR interact: ComposeTopSitesRobot.() -> Unit, ): Transition { composeTestRule.contextMenuItemRename().performClick() + Log.i(TAG, "renameTopSite: Clicked \"Rename\" menu button") itemWithResId("$packageName:id/top_site_title") .also { it.waitForExists(waitingTimeShort) it.setText(title) } + Log.i(TAG, "renameTopSite: Top site rename text box was set to: $title") itemWithResIdContainingText("android:id/button1", "OK").click() + Log.i(TAG, "renameTopSite: Clicked \"Ok\" dialog button") ComposeTopSitesRobot(composeTestRule).interact() return Transition(composeTestRule) @@ -123,22 +138,13 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR interact: ComposeTopSitesRobot.() -> Unit, ): Transition { composeTestRule.contextMenuItemRemove().performClick() + Log.i(TAG, "removeTopSite: Clicked \"Remove\" menu button") composeTestRule.waitUntilDoesNotExist(hasTestTag(TopSitesTestTag.remove), waitingTime) + Log.i(TAG, "removeTopSite: Waited for \"Remove\" menu button to not exist") 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() - } } } From 52e294d38f596d8bda10a9e3397170c4dde80a79 Mon Sep 17 00:00:00 2001 From: jackyzy823 Date: Fri, 19 Jan 2024 23:04:43 +0800 Subject: [PATCH 025/586] Bug 1812359 - 'suspend' should also be applied to CustomTabs --- .../engine/middleware/SuspendMiddleware.kt | 4 +- .../middleware/SuspendMiddlewareTest.kt | 43 +++++++++++++++---- .../middleware/TrimMemoryMiddlewareTest.kt | 6 +-- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/SuspendMiddleware.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/SuspendMiddleware.kt index 0dc73b0ec1d4..f302d1179aeb 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/SuspendMiddleware.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/SuspendMiddleware.kt @@ -8,7 +8,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import mozilla.components.browser.state.action.BrowserAction import mozilla.components.browser.state.action.EngineAction -import mozilla.components.browser.state.selector.findTab +import mozilla.components.browser.state.selector.findTabOrCustomTab import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.EngineState import mozilla.components.concept.engine.EngineSession @@ -43,7 +43,7 @@ internal class SuspendMiddleware( context: MiddlewareContext, sessionId: String, ) { - val tab = context.state.findTab(sessionId) ?: return + val tab = context.state.findTabOrCustomTab(sessionId) ?: return // First we unlink (which clearsEngineSession and state) context.dispatch( diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/SuspendMiddlewareTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/SuspendMiddlewareTest.kt index f9541544977e..2a14b04607a5 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/SuspendMiddlewareTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/SuspendMiddlewareTest.kt @@ -5,8 +5,9 @@ package mozilla.components.browser.state.engine.middleware import mozilla.components.browser.state.action.EngineAction -import mozilla.components.browser.state.selector.findTab +import mozilla.components.browser.state.selector.findTabOrCustomTab import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.createCustomTab import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.EngineSession @@ -32,7 +33,7 @@ class SuspendMiddlewareTest { private val scope = coroutinesTestRule.scope @Test - fun `suspends engine session`() = runTestOnMain { + fun `suspends engine session for tab`() = runTestOnMain { val middleware = SuspendMiddleware(scope) val tab = createTab("https://www.mozilla.org", id = "1") @@ -52,8 +53,34 @@ class SuspendMiddlewareTest { store.waitUntilIdle() dispatcher.scheduler.advanceUntilIdle() - assertNull(store.state.findTab(tab.id)?.engineState?.engineSession) - assertEquals(state, store.state.findTab(tab.id)?.engineState?.engineSessionState) + assertNull(store.state.findTabOrCustomTab(tab.id)?.engineState?.engineSession) + assertEquals(state, store.state.findTabOrCustomTab(tab.id)?.engineState?.engineSessionState) + verify(engineSession).close() + } + + @Test + fun `suspends engine session for custom tab`() = runTestOnMain { + val middleware = SuspendMiddleware(scope) + + val tab = createCustomTab("https://www.mozilla.org", id = "1") + val store = BrowserStore( + initialState = BrowserState(customTabs = listOf(tab)), + middleware = listOf(middleware), + ) + + val engineSession: EngineSession = mock() + store.dispatch(EngineAction.LinkEngineSessionAction(tab.id, engineSession)).joinBlocking() + + val state: EngineSessionState = mock() + store.dispatch(EngineAction.UpdateEngineSessionStateAction(tab.id, state)).joinBlocking() + + store.dispatch(EngineAction.SuspendEngineSessionAction(tab.id)).joinBlocking() + + store.waitUntilIdle() + dispatcher.scheduler.advanceUntilIdle() + + assertNull(store.state.findTabOrCustomTab(tab.id)?.engineState?.engineSession) + assertEquals(state, store.state.findTabOrCustomTab(tab.id)?.engineState?.engineSessionState) verify(engineSession).close() } @@ -117,11 +144,11 @@ class SuspendMiddlewareTest { killStore.waitUntilIdle() dispatcher.scheduler.advanceUntilIdle() - assertNull(suspendStore.state.findTab(tab.id)?.engineState?.engineSession) - assertEquals(state, suspendStore.state.findTab(tab.id)?.engineState?.engineSessionState) + assertNull(suspendStore.state.findTabOrCustomTab(tab.id)?.engineState?.engineSession) + assertEquals(state, suspendStore.state.findTabOrCustomTab(tab.id)?.engineState?.engineSessionState) - assertNull(killStore.state.findTab(tab.id)?.engineState?.engineSession) - assertEquals(state, killStore.state.findTab(tab.id)?.engineState?.engineSessionState) + assertNull(killStore.state.findTabOrCustomTab(tab.id)?.engineState?.engineSession) + assertEquals(state, killStore.state.findTabOrCustomTab(tab.id)?.engineState?.engineSessionState) assertEquals(suspendStore.state, killStore.state) } diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TrimMemoryMiddlewareTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TrimMemoryMiddlewareTest.kt index 4c2f63b03636..f0ba85d952b5 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TrimMemoryMiddlewareTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TrimMemoryMiddlewareTest.kt @@ -234,8 +234,8 @@ class TrimMemoryMiddlewareTest { } store.state.findCustomTab("twitch")!!.engineState.apply { - assertNotNull(engineSession) - assertNotNull(engineObserver) + assertNull(engineSession) + assertNull(engineObserver) assertNotNull(engineSessionState) } @@ -247,9 +247,9 @@ class TrimMemoryMiddlewareTest { verify(engineSessionTheVerge).close() verify(engineSessionYouTube).close() + verify(engineSessionTwitch).close() verify(engineSessionReddit, never()).close() - verify(engineSessionTwitch, never()).close() verify(engineSessionGoogleNews, never()).close() verify(engineSessionFacebook, never()).close() verify(engineSessionAmazon, never()).close() From 9cb30bc35e0d1006cd8d6272d820452d8f002209 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 31 Jan 2024 05:33:40 +0000 Subject: [PATCH 026/586] Update A-S to 124.20240131050340. --- .../plugins/dependencies/src/main/java/ApplicationServices.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt index 4552bcabce97..eb0c7467df45 100644 --- a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt +++ b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // These lines are generated by android-components/automation/application-services-nightly-bump.py -val VERSION = "124.20240130050233" +val VERSION = "124.20240131050340" val CHANNEL = ApplicationServicesChannel.NIGHTLY object ApplicationServicesConfig { From 6424933e6dc336eb8697afae67391533e2ad79d8 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Wed, 31 Jan 2024 11:06:09 +0200 Subject: [PATCH 027/586] Bug 1877639 - Add more test logs to FindInPageRobot --- .../java/org/mozilla/fenix/ui/MainMenuTest.kt | 12 ++-- .../org/mozilla/fenix/ui/PDFViewerTest.kt | 8 +-- .../fenix/ui/robots/FindInPageRobot.kt | 61 +++++++++++-------- 3 files changed, 44 insertions(+), 37 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MainMenuTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MainMenuTest.kt index fa871f7790e9..24a877737846 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MainMenuTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MainMenuTest.kt @@ -175,21 +175,21 @@ class MainMenuTest { verifyFindInPagePrevButton() verifyFindInPageCloseButton() enterFindInPageQuery("a") - verifyFindNextInPageResult("1/3") + verifyFindInPageResult("1/3") clickFindInPageNextButton() - verifyFindNextInPageResult("2/3") + verifyFindInPageResult("2/3") clickFindInPageNextButton() - verifyFindNextInPageResult("3/3") + verifyFindInPageResult("3/3") clickFindInPagePrevButton() - verifyFindPrevInPageResult("2/3") + verifyFindInPageResult("2/3") clickFindInPagePrevButton() - verifyFindPrevInPageResult("1/3") + verifyFindInPageResult("1/3") }.closeFindInPageWithCloseButton { verifyFindInPageBar(false) }.openThreeDotMenu { }.openFindInPage { enterFindInPageQuery("3") - verifyFindNextInPageResult("1/1") + verifyFindInPageResult("1/1") }.closeFindInPageWithBackButton { verifyFindInPageBar(false) } diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PDFViewerTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PDFViewerTest.kt index 7b07993a2978..340cbd08ef4d 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PDFViewerTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PDFViewerTest.kt @@ -117,17 +117,17 @@ class PDFViewerTest { verifyFindInPagePrevButton() verifyFindInPageCloseButton() enterFindInPageQuery("l") - verifyFindNextInPageResult("1/2") + verifyFindInPageResult("1/2") clickFindInPageNextButton() - verifyFindNextInPageResult("2/2") + verifyFindInPageResult("2/2") clickFindInPagePrevButton() - verifyFindPrevInPageResult("1/2") + verifyFindInPageResult("1/2") }.closeFindInPageWithCloseButton { verifyFindInPageBar(false) }.openThreeDotMenu { }.openFindInPage { enterFindInPageQuery("p") - verifyFindNextInPageResult("1/1") + verifyFindInPageResult("1/1") }.closeFindInPageWithBackButton { verifyFindInPageBar(false) } diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt index 277375597490..ed459189ba81 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt @@ -6,6 +6,7 @@ package org.mozilla.fenix.ui.robots +import android.util.Log import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions.clearText import androidx.test.espresso.action.ViewActions.typeText @@ -16,6 +17,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.uiautomator.By import androidx.test.uiautomator.Until import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.click @@ -25,42 +27,39 @@ import org.mozilla.fenix.helpers.ext.waitNotNull * Implementation of Robot Pattern for the find in page UI. */ class FindInPageRobot { - fun verifyFindInPageQuery() = assertFindInPageQuery()!! - fun verifyFindInPageNextButton() = assertFindInPageNextButton()!! - fun verifyFindInPagePrevButton() = assertFindInPagePrevButton()!! - fun verifyFindInPageCloseButton() = assertFindInPageCloseButton()!! - fun clickFindInPageNextButton() = findInPageNextButton().click() - fun clickFindInPagePrevButton() = findInPagePrevButton().click() - - fun verifyFindInPageSearchBarItems() { - verifyFindInPageQuery() - verifyFindInPageNextButton() - verifyFindInPagePrevButton() - verifyFindInPageCloseButton() + fun verifyFindInPageNextButton() = assertFindInPageNextButton() + fun verifyFindInPagePrevButton() = assertFindInPagePrevButton() + fun verifyFindInPageCloseButton() = assertFindInPageCloseButton() + fun clickFindInPageNextButton() { + findInPageNextButton().click() + Log.i(TAG, "clickFindInPageNextButton: Clicked next result button") + } + fun clickFindInPagePrevButton() { + findInPagePrevButton().click() + Log.i(TAG, "clickFindInPagePrevButton: Clicked previous result button") } fun enterFindInPageQuery(expectedText: String) { mDevice.waitNotNull(Until.findObject(By.res("org.mozilla.fenix.debug:id/find_in_page_query_text")), waitingTime) findInPageQuery().perform(clearText()) + Log.i(TAG, "enterFindInPageQuery: Cleared find in page bar text") mDevice.waitNotNull(Until.gone(By.res("org.mozilla.fenix.debug:id/find_in_page_result_text")), waitingTime) findInPageQuery().perform(typeText(expectedText)) + Log.i(TAG, "enterFindInPageQuery: Typed $expectedText to find in page bar") mDevice.waitNotNull(Until.findObject(By.res("org.mozilla.fenix.debug:id/find_in_page_result_text")), waitingTime) } - fun verifyFindNextInPageResult(ratioCounter: String) { - mDevice.waitNotNull(Until.findObject(By.text(ratioCounter)), waitingTime) - findInPageResult().check(matches(withText((ratioCounter)))) - } - - fun verifyFindPrevInPageResult(ratioCounter: String) { + fun verifyFindInPageResult(ratioCounter: String) { mDevice.waitNotNull(Until.findObject(By.text(ratioCounter)), waitingTime) findInPageResult().check(matches(withText((ratioCounter)))) + Log.i(TAG, "verifyFindInPageResult: Verified $ratioCounter results") } class Transition { fun closeFindInPageWithCloseButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { mDevice.waitForIdle() findInPageCloseButton().click() + Log.i(TAG, "closeFindInPageWithCloseButton: Clicked close find in page button") BrowserRobot().interact() return BrowserRobot.Transition() } @@ -70,7 +69,9 @@ class FindInPageRobot { // Will need to press back 2x, the first will only dismiss the keyboard mDevice.pressBack() + Log.i(TAG, "closeFindInPageWithBackButton: Pressed 1x the device back button") mDevice.pressBack() + Log.i(TAG, "closeFindInPageWithBackButton: Pressed 2x the device back button") BrowserRobot().interact() return BrowserRobot.Transition() @@ -84,14 +85,20 @@ private fun findInPageNextButton() = onView(withId(R.id.find_in_page_next_btn)) private fun findInPagePrevButton() = onView(withId(R.id.find_in_page_prev_btn)) private fun findInPageCloseButton() = onView(withId(R.id.find_in_page_close_btn)) -private fun assertFindInPageQuery() = findInPageQuery() - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) - -private fun assertFindInPageNextButton() = findInPageNextButton() - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) +private fun assertFindInPageNextButton() { + findInPageNextButton() + .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + Log.i(TAG, "assertFindInPageNextButton: Verified find in page next result button is visible") +} -private fun assertFindInPagePrevButton() = findInPagePrevButton() - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) +private fun assertFindInPagePrevButton() { + findInPagePrevButton() + .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + Log.i(TAG, "assertFindInPagePrevButton: Verified find in page previous result button is visible") +} -private fun assertFindInPageCloseButton() = findInPageCloseButton() - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) +private fun assertFindInPageCloseButton() { + findInPageCloseButton() + .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + Log.i(TAG, "assertFindInPageCloseButton: Verified find in page close button is visible") +} From ff169ea9cfa505dcdf6c9191ac4e4bd079b20b4e Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Wed, 31 Jan 2024 11:32:26 +0200 Subject: [PATCH 028/586] Bug 1865316 - Fix askBeforeOpeningLinkInAppCancelTest UI test --- .../org/mozilla/fenix/ui/SettingsAdvancedTest.kt | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAdvancedTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAdvancedTest.kt index 61244f8a6561..86b0b1752314 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAdvancedTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAdvancedTest.kt @@ -158,11 +158,10 @@ class SettingsAdvancedTest { navigationToolbar { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(youTubeFullLink) + clickPageObject(youTubeSchemaLink) verifyOpenLinkInAnotherAppPrompt() clickPageObject(itemWithResIdAndText("android:id/button2", "CANCEL")) - waitForPageToLoad() - verifyUrl("youtube") + verifyUrl(externalLinksPage.url.toString()) } } @@ -225,14 +224,13 @@ class SettingsAdvancedTest { navigationToolbar { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(youTubeFullLink) + clickPageObject(youTubeSchemaLink) verifyPrivateBrowsingOpenLinkInAnotherAppPrompt( url = "youtube", - pageObject = youTubeFullLink, + pageObject = youTubeSchemaLink, ) clickPageObject(itemWithResIdAndText("android:id/button2", "CANCEL")) - waitForPageToLoad() - verifyUrl("youtube") + verifyUrl(externalLinksPage.url.toString()) } } From ef7daac03bef25b6d8805bf8108a18a43d1336f8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 12:15:54 -0500 Subject: [PATCH 029/586] Update GeckoView (Nightly) to 124.0.20240131095100. (#5385) Co-authored-by: MickeyMoz Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 90df3e5519e1..703853914d63 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240130214506" + const val version = "124.0.20240131095100" /** * GeckoView channel From 9edfde0a1382b4d5fb4342792d98d4c1d4d41bef Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Wed, 31 Jan 2024 11:43:18 +0200 Subject: [PATCH 030/586] Bug 1844252 - Fix verifyVideoPlaybackSystemNotificationTest UI test --- .../java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt index df12b8ff2f0e..ffe888fbff34 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt @@ -235,7 +235,10 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest /** * Closes a tab when there is only one tab open. */ + @OptIn(ExperimentalTestApi::class) fun closeTab() { + composeTestRule.waitUntilAtLeastOneExists(hasTestTag(TabsTrayTestTag.tabItemClose)) + composeTestRule.closeTabButton().assertExists() composeTestRule.closeTabButton().performClick() Log.i(TAG, "closeTab: Clicked close tab button") } From e6521aab671eb42865bba817d9fd08d72ad6cda7 Mon Sep 17 00:00:00 2001 From: ohall-m Date: Tue, 30 Jan 2024 16:12:44 -0500 Subject: [PATCH 031/586] Bug 1875093 - Bug 1875093 - AC Action to Fetch and Set Page Preferences for Translations This patch adds two new Actions: * `OperationRequestedAction` - for requesting to fetch data * `SetSettingsAction` - for setting that data on the browser store `TranslationsMiddleware` reacts to these Actions by fetching and setting the appropriate data. The patch to update data will be bug 1877203. --- .../browser/state/action/BrowserAction.kt | 23 ++++ .../middleware/TranslationsMiddleware.kt | 117 ++++++++++++++++ .../state/reducer/TranslationsStateReducer.kt | 39 +++++- .../browser/state/state/TranslationsState.kt | 5 + .../state/action/TranslationsActionTest.kt | 58 ++++++++ .../middleware/TranslationsMiddlewareTest.kt | 128 +++++++++++++++--- .../engine/translate/TranslationError.kt | 8 ++ .../engine/translate/TranslationOperation.kt | 5 + .../translate/TranslationPageSettings.kt | 26 ++++ 9 files changed, 385 insertions(+), 24 deletions(-) create mode 100644 android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationPageSettings.kt diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt index 32ee2c2d2210..1074c65a2b42 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt @@ -49,6 +49,7 @@ import mozilla.components.concept.engine.translate.TranslationEngineState import mozilla.components.concept.engine.translate.TranslationError import mozilla.components.concept.engine.translate.TranslationOperation import mozilla.components.concept.engine.translate.TranslationOptions +import mozilla.components.concept.engine.translate.TranslationPageSettings import mozilla.components.concept.engine.translate.TranslationSupport import mozilla.components.concept.engine.webextension.WebExtensionBrowserAction import mozilla.components.concept.engine.webextension.WebExtensionPageAction @@ -936,6 +937,17 @@ sealed class TranslationsAction : BrowserAction() { val translationError: TranslationError, ) : TranslationsAction(), ActionWithTab + /** + * Indicates that the given [operation] data should be fetched for the given [tabId]. + * + * @property tabId The ID of the tab the [EngineSession] should be linked to. + * @property operation The translation operation that failed. + */ + data class OperationRequestedAction( + override val tabId: String, + val operation: TranslationOperation, + ) : TranslationsAction(), ActionWithTab + /** * Sets the languages that are supported by the translations engine. * @@ -946,6 +958,17 @@ sealed class TranslationsAction : BrowserAction() { override val tabId: String, val supportedLanguages: TranslationSupport?, ) : TranslationsAction(), ActionWithTab + + /** + * Sets the given page settings on the page on the given [tabId]'s store. + * + * @property tabId The ID of the tab the [EngineSession] should be linked to. + * @property pageSettings The new page settings. + */ + data class SetPageSettingsAction( + override val tabId: String, + val pageSettings: TranslationPageSettings?, + ) : TranslationsAction(), ActionWithTab } /** diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt index e60aed71dba7..5062a870f566 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt @@ -11,13 +11,19 @@ import kotlinx.coroutines.withContext import mozilla.components.browser.state.action.BrowserAction import mozilla.components.browser.state.action.TranslationsAction import mozilla.components.browser.state.action.TranslationsAction.TranslateExpectedAction +import mozilla.components.browser.state.selector.findTab import mozilla.components.browser.state.state.BrowserState import mozilla.components.concept.engine.Engine +import mozilla.components.concept.engine.EngineSession +import mozilla.components.concept.engine.translate.LanguageSetting import mozilla.components.concept.engine.translate.TranslationError import mozilla.components.concept.engine.translate.TranslationOperation +import mozilla.components.concept.engine.translate.TranslationPageSettings import mozilla.components.lib.state.Middleware import mozilla.components.lib.state.MiddlewareContext import mozilla.components.support.base.log.logger.Logger +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine /** * This middleware is for use with managing any states or resources required for translating a @@ -41,6 +47,22 @@ class TranslationsMiddleware( requestSupportedLanguages(context, action.tabId) } } + + is TranslationsAction.OperationRequestedAction -> { + when (action.operation) { + TranslationOperation.FETCH_LANGUAGES -> { + // Bug 1877205 + } + TranslationOperation.FETCH_PAGE_SETTINGS -> { + scope.launch { + requestTranslationPageSettings(context, action.tabId) + } + } + TranslationOperation.TRANSLATE, + TranslationOperation.RESTORE, + -> Unit + } + } else -> { // no-op } @@ -88,4 +110,99 @@ class TranslationsMiddleware( ) } } + + /** + * Retrieves the page settings using [scope] and dispatches the result to the + * store via [TranslationsAction.SetPageSettingsAction] or else dispatches the failure + * [TranslationsAction.TranslateExceptionAction]. + * + * @param context Context to use to dispatch to the store. + * @param tabId Tab ID associated with the request. + */ + private suspend fun requestTranslationPageSettings( + context: MiddlewareContext, + tabId: String, + ) = withContext(Dispatchers.IO) { + // Always offer setting + val alwaysOfferPopup: Boolean = engine.getTranslationsOfferPopup() + + // Page language settings + val pageLanguage = context.store.state.findTab(tabId) + ?.translationsState?.translationEngineState?.detectedLanguages?.documentLangTag + val setting = pageLanguage?.let { getLanguageSetting(it) } + val alwaysTranslateLanguage = setting?.toBoolean(LanguageSetting.ALWAYS) + val neverTranslateLanguage = setting?.toBoolean(LanguageSetting.NEVER) + + // Never translate site + val engineSession = context.store.state.findTab(tabId) + ?.engineState?.engineSession + val neverTranslateSite = engineSession?.let { getNeverTranslateSiteSetting(it) } + + if ( + alwaysTranslateLanguage != null && + neverTranslateLanguage != null && + neverTranslateSite != null + ) { + TranslationsAction.SetPageSettingsAction( + tabId = tabId, + pageSettings = + TranslationPageSettings( + alwaysOfferPopup = alwaysOfferPopup, + alwaysTranslateLanguage = alwaysTranslateLanguage, + neverTranslateLanguage = neverTranslateLanguage, + neverTranslateSite = neverTranslateSite, + ), + ) + } else { + // Any null values indicate something went wrong, alert an error occurred + TranslationsAction.TranslateExceptionAction( + tabId = tabId, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + translationError = TranslationError.CouldNotLoadPageSettingsError(null), + ) + } + } + + /** + * Fetches the always or never language setting synchronously from the engine. Will + * return null if an error occurs. + * + * @param pageLanguage Page language to check the translation preferences for. + * @return The page translate language setting or null. + */ + private suspend fun getLanguageSetting(pageLanguage: String): LanguageSetting? { + return suspendCoroutine { continuation -> + engine.getLanguageSetting( + languageCode = pageLanguage, + + onSuccess = { setting -> + continuation.resume(setting) + }, + + onError = { + continuation.resume(null) + }, + ) + } + } + + /** + * Fetches the never translate site setting synchronously from the [EngineSession]. Will + * return null if an error occurs. + * + * @param engineSession With page context on how to complete this operation. + * @return The never translate site setting from the [EngineSession] or null. + */ + private suspend fun getNeverTranslateSiteSetting(engineSession: EngineSession): Boolean? { + return suspendCoroutine { continuation -> + engineSession.getNeverTranslateSiteSetting( + onResult = { setting -> + continuation.resume(setting) + }, + onException = { + continuation.resume(null) + }, + ) + } + } } diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt index 70f89f8da69b..cedc93f756dc 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt @@ -77,14 +77,26 @@ internal object TranslationsStateReducer { } TranslationOperation.FETCH_LANGUAGES -> { - // Generally expect [TranslationsAction.TranslateSetLanguagesAction] to be used - // as the success condition since the updated value is needed. + // Reset the error state, and then generally expect + // [TranslationsAction.TranslateSetLanguagesAction] to update state in the + // success case. state.copyWithTranslationsState(action.tabId) { it.copy( translationError = null, ) } } + + TranslationOperation.FETCH_PAGE_SETTINGS -> { + // Reset the error state, and then generally expect + // [TranslationsAction.SetPageSettingsAction] to update state in the + // success case. + state.copyWithTranslationsState(action.tabId) { + it.copy( + settingsError = null, + ) + } + } } } @@ -116,6 +128,15 @@ internal object TranslationsStateReducer { ) } } + + TranslationOperation.FETCH_PAGE_SETTINGS -> { + state.copyWithTranslationsState(action.tabId) { + it.copy( + pageSettings = null, + settingsError = action.translationError, + ) + } + } } } @@ -126,6 +147,20 @@ internal object TranslationsStateReducer { translationError = null, ) } + + is TranslationsAction.SetPageSettingsAction -> + state.copyWithTranslationsState(action.tabId) { + it.copy( + pageSettings = action.pageSettings, + ) + } + + is TranslationsAction.OperationRequestedAction -> + state.copyWithTranslationsState(action.tabId) { + it.copy( + pageSettings = null, + ) + } } private inline fun BrowserState.copyWithTranslationsState( diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/TranslationsState.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/TranslationsState.kt index a5886b3990ed..2f99cdd084b1 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/TranslationsState.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/TranslationsState.kt @@ -6,6 +6,7 @@ package mozilla.components.browser.state.state import mozilla.components.concept.engine.translate.TranslationEngineState import mozilla.components.concept.engine.translate.TranslationError +import mozilla.components.concept.engine.translate.TranslationPageSettings import mozilla.components.concept.engine.translate.TranslationSupport /** @@ -18,9 +19,11 @@ import mozilla.components.concept.engine.translate.TranslationSupport * @property isTranslated The page is currently translated. * @property isTranslateProcessing The page is currently attempting a translation. * @property isRestoreProcessing The page is currently attempting a restoration. + * @property pageSettings The translation engine settings that relate to the current page. * @property supportedLanguages Set of languages the translation engine supports. * @property translationError Type of error that occurred when acquiring resources, translating, or * restoring a translation. + * @property settingsError Type of error that occurred when acquiring resources or setting preferences. */ data class TranslationsState( val isExpectedTranslate: Boolean = false, @@ -30,5 +33,7 @@ data class TranslationsState( val isTranslateProcessing: Boolean = false, val isRestoreProcessing: Boolean = false, val supportedLanguages: TranslationSupport? = null, + val pageSettings: TranslationPageSettings? = null, val translationError: TranslationError? = null, + val settingsError: TranslationError? = null, ) diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt index 5db8ce3e486b..5b94d28fc243 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt @@ -12,10 +12,12 @@ import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.translate.Language import mozilla.components.concept.engine.translate.TranslationError import mozilla.components.concept.engine.translate.TranslationOperation +import mozilla.components.concept.engine.translate.TranslationPageSettings import mozilla.components.concept.engine.translate.TranslationSupport import mozilla.components.support.test.ext.joinBlocking import mozilla.components.support.test.mock import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull import org.junit.Before import org.junit.Test import java.lang.Exception @@ -240,4 +242,60 @@ class TranslationsActionTest { assertEquals(null, tabState().translationsState.translationError) assertEquals(false, tabState().translationsState.isTranslated) } + + @Test + fun `WHEN a SetPageSettingsAction is dispatched THEN set pageSettings`() { + // Initial + assertNull(tabState().translationsState.pageSettings) + + // Action started + val pageSettings = TranslationPageSettings( + alwaysOfferPopup = true, + alwaysTranslateLanguage = true, + neverTranslateLanguage = true, + neverTranslateSite = true, + ) + store.dispatch( + TranslationsAction.SetPageSettingsAction( + tabId = tab.id, + pageSettings = pageSettings, + ), + ).joinBlocking() + + // Action success + assertEquals(pageSettings, tabState().translationsState.pageSettings) + } + + @Test + fun `WHEN a OperationRequestedAction is dispatched THEN clear pageSettings`() { + // Setting first to have a more robust initial state + assertNull(tabState().translationsState.pageSettings) + + val pageSettings = TranslationPageSettings( + alwaysOfferPopup = true, + alwaysTranslateLanguage = true, + neverTranslateLanguage = true, + neverTranslateSite = true, + ) + + store.dispatch( + TranslationsAction.SetPageSettingsAction( + tabId = tab.id, + pageSettings = pageSettings, + ), + ).joinBlocking() + + assertEquals(pageSettings, tabState().translationsState.pageSettings) + + // Action started + store.dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + ), + ).joinBlocking() + + // Action success + assertNull(tabState().translationsState.pageSettings) + } } diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt index 9cd9dbb58a29..0b4721b660cc 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt @@ -5,14 +5,20 @@ package mozilla.components.browser.state.engine.middleware import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runTest import mozilla.components.browser.state.action.BrowserAction import mozilla.components.browser.state.action.TranslationsAction +import mozilla.components.browser.state.selector.findTab import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.TabSessionState +import mozilla.components.browser.state.state.TranslationsState import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.Engine import mozilla.components.concept.engine.EngineSession +import mozilla.components.concept.engine.translate.DetectedLanguages +import mozilla.components.concept.engine.translate.LanguageSetting +import mozilla.components.concept.engine.translate.TranslationEngineState import mozilla.components.concept.engine.translate.TranslationError import mozilla.components.concept.engine.translate.TranslationOperation import mozilla.components.concept.engine.translate.TranslationSupport @@ -24,7 +30,6 @@ import mozilla.components.support.test.libstate.ext.waitUntilIdle import mozilla.components.support.test.mock import mozilla.components.support.test.rule.MainCoroutineRule import mozilla.components.support.test.whenever -import org.junit.Before import org.junit.Rule import org.junit.Test import org.mockito.Mockito.spy @@ -35,29 +40,23 @@ class TranslationsMiddlewareTest { @get:Rule val coroutinesTestRule = MainCoroutineRule() private val scope = coroutinesTestRule.scope - private lateinit var engine: Engine - private lateinit var engineSession: EngineSession - private lateinit var tab: TabSessionState - private lateinit var store: BrowserStore - private lateinit var translationsMiddleware: TranslationsMiddleware - - @Before - fun setUp() { - engine = mock() - engineSession = mock() - tab = createTab("https://www.mozilla.org", id = "test-tab", engineSession = engineSession) - translationsMiddleware = TranslationsMiddleware(engine = engine, scope = scope) - store = spy( - BrowserStore( - middleware = listOf(translationsMiddleware), - initialState = BrowserState( - tabs = listOf(tab), - ), - ), - ) - } + private val engine: Engine = mock() + private val engineSession: EngineSession = mock() + private val tab: TabSessionState = spy( + createTab( + url = "https://www.firefox.com", + title = "Firefox", + id = "1", + engineSession = engineSession, + ), + ) + private val translationsMiddleware = TranslationsMiddleware(engine = engine, scope = scope) + private val tabs = spy(listOf(tab)) + private val state = spy(BrowserState(tabs = tabs)) + private val store = spy(BrowserStore(middleware = listOf(translationsMiddleware), initialState = state)) private fun waitForIdle() { + scope.testScheduler.runCurrent() scope.testScheduler.advanceUntilIdle() coroutinesTestRule.testDispatcher.scheduler.advanceUntilIdle() store.waitUntilIdle() @@ -107,4 +106,89 @@ class TranslationsMiddlewareTest { waitForIdle() } + + @Test + fun `WHEN OperationRequestedAction is dispatched WITH FETCH_PAGE_SETTINGS AND fetching languages is successful THEN TranslationPageSettings is dispatched`() = runTest { + // Mock detected languages are required to pull the language settings + val mockFrom = "es" + val mockTo = "en" + val mockDetectedLanguages = DetectedLanguages( + documentLangTag = mockFrom, + supportedDocumentLang = true, + userPreferredLangTag = mockTo, + ) + val mockState = TranslationsState( + translationEngineState = TranslationEngineState(mockDetectedLanguages), + ) + // Had mock issues when mocking anything more granular + whenever(store.state.findTab(tab.id)?.translationsState).thenReturn(mockState) + + // Always offer behavior + val offerResponse = true + whenever(engine.getTranslationsOfferPopup()).thenAnswer { offerResponse } + + // Page language + val languageSettingCallback = argumentCaptor<((LanguageSetting) -> Unit)>() + val languageResponse = LanguageSetting.ALWAYS + whenever( + engine.getLanguageSetting( + languageCode = any(), + onSuccess = languageSettingCallback.capture(), + onError = any(), + ), + ) + .thenAnswer { + languageSettingCallback.value.invoke(languageResponse) + } + + // Never translate site behavior + val neverTranslateSiteCallback = argumentCaptor<((Boolean) -> Unit)>() + val neverSiteResponse = true + whenever( + engineSession.getNeverTranslateSiteSetting( + onResult = neverTranslateSiteCallback.capture(), + onException = any(), + ), + ) + .thenAnswer { + neverTranslateSiteCallback.value.invoke(neverSiteResponse) + } + + store.dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + ), + ).joinBlocking() + + waitForIdle() + + verify(store).dispatch( + TranslationsAction.SetPageSettingsAction( + tabId = tab.id, + pageSettings = any(), + ), + ) + } + + @Test + fun `WHEN OperationRequestedAction AND fetching data fails THEN TranslateExceptionAction is dispatched`() { + store.dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + ), + ).joinBlocking() + waitForIdle() + + verify(store).dispatch( + TranslationsAction.TranslateExceptionAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + translationError = TranslationError.CouldNotLoadPageSettingsError(any()), + ), + ) + + waitForIdle() + } } diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationError.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationError.kt index bbb64aa503a9..313744478668 100644 --- a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationError.kt +++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationError.kt @@ -72,6 +72,14 @@ sealed class TranslationError( class CouldNotLoadLanguagesError(override val cause: Throwable?) : TranslationError(errorName = "could-not-load-languages", displayError = true, cause = cause) + /** + * Could not load page settings error. + * + * @param cause The original throwable before it was converted into this error state. + */ + class CouldNotLoadPageSettingsError(override val cause: Throwable?) : + TranslationError(errorName = "could-not-load-settings", displayError = false, cause = cause) + /** * The language is not supported for translation. * diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationOperation.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationOperation.kt index 369def415b36..711aef827d22 100644 --- a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationOperation.kt +++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationOperation.kt @@ -24,4 +24,9 @@ enum class TranslationOperation { * and localized name. */ FETCH_LANGUAGES, + + /** + * The page related settings the translation engine should fetch. + */ + FETCH_PAGE_SETTINGS, } diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationPageSettings.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationPageSettings.kt new file mode 100644 index 000000000000..7c253d6af2cc --- /dev/null +++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationPageSettings.kt @@ -0,0 +1,26 @@ +/* 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 mozilla.components.concept.engine.translate + +/** + * Translation settings that relate to the page + * + * @property alwaysOfferPopup The setting for whether translations should automatically be offered. + * When true, the engine will offer to translate the page if the detected translatable page language + * is different from the user's preferred languages. + * @property alwaysTranslateLanguage The setting for whether the current page language should be + * automatically translated or not. When true, the page will automatically be translated by the + * translations engine. + * @property neverTranslateLanguage The setting for whether the current page language should offer a + * translation or not. When true, the engine will not offer a translation. + * @property neverTranslateSite The setting for whether the current site should be translated or not. + * When true, the engine will not offer a translation on the current host site. + */ +data class TranslationPageSettings( + val alwaysOfferPopup: Boolean? = null, + val alwaysTranslateLanguage: Boolean? = null, + val neverTranslateLanguage: Boolean? = null, + val neverTranslateSite: Boolean? = null, +) From 60b022dbe3020fe1f79a61847c2cbab9627ee82b Mon Sep 17 00:00:00 2001 From: mike a Date: Fri, 5 Jan 2024 10:52:04 -0800 Subject: [PATCH 032/586] Bug 1873260 - Move Behavior classes to ui-widget component --- android-components/.buildconfig.yml | 14 + .../components/browser/toolbar/build.gradle | 1 + .../browser/toolbar/BrowserToolbar.kt | 10 +- .../BrowserToolbarYTranslationStrategy.kt | 189 ----- .../behavior/BrowserToolbarYTranslator.kt | 81 -- .../browser/toolbar/BrowserToolbarTest.kt | 12 +- .../BrowserToolbarYTranslationStrategyTest.kt | 712 ------------------ .../behavior/BrowserToolbarYTranslatorTest.kt | 113 --- .../concept/toolbar/ScrollableToolbar.kt | 34 + .../components/concept/toolbar/Toolbar.kt | 25 +- .../toolbar/ToolbarBehaviorController.kt | 6 +- .../components/ui/widgets/build.gradle | 4 + .../behavior/BrowserGestureDetector.kt | 2 +- .../behavior/EngineViewClippingBehavior.kt} | 6 +- .../behavior/EngineViewScrollingBehavior.kt} | 87 ++- .../behavior/ViewYTranslationStrategy.kt | 189 +++++ .../ui/widgets/behavior/ViewYTranslator.kt | 81 ++ .../behavior/BrowserGestureDetectorTest.kt | 2 +- .../EngineViewClippingBehaviorTest.kt} | 26 +- .../EngineViewScrollingBehaviorTest.kt} | 188 ++--- .../ui/widgets}/behavior/TestUtils.kt | 4 +- .../behavior/ViewYTranslationStrategyTest.kt | 712 ++++++++++++++++++ .../widgets/behavior/ViewYTranslatorTest.kt | 113 +++ .../fenix/browser/BaseBrowserFragment.kt | 6 +- .../components/toolbar/BrowserToolbarView.kt | 13 +- .../fenix/browser/BaseBrowserFragmentTest.kt | 8 +- .../toolbar/BrowserToolbarViewTest.kt | 12 +- .../org/mozilla/focus/ext/BrowserToolbar.kt | 12 +- .../mozilla/focus/ext/BrowserToolbarTest.kt | 8 +- 29 files changed, 1349 insertions(+), 1321 deletions(-) delete mode 100644 android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslationStrategy.kt delete mode 100644 android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslator.kt delete mode 100644 android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslationStrategyTest.kt delete mode 100644 android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslatorTest.kt create mode 100644 android-components/components/concept/toolbar/src/main/java/mozilla/components/concept/toolbar/ScrollableToolbar.kt rename android-components/components/{browser/toolbar/src/main/java/mozilla/components/browser/toolbar => ui/widgets/src/main/java/mozilla/components/ui/widgets}/behavior/BrowserGestureDetector.kt (99%) rename android-components/components/{feature/session/src/main/java/mozilla/components/feature/session/behavior/EngineViewBrowserToolbarBehavior.kt => ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehavior.kt} (96%) rename android-components/components/{browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarBehavior.kt => ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehavior.kt} (70%) create mode 100644 android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategy.kt create mode 100644 android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslator.kt rename android-components/components/{browser/toolbar/src/test/java/mozilla/components/browser/toolbar => ui/widgets/src/test/java/mozilla/components/ui/widgets}/behavior/BrowserGestureDetectorTest.kt (99%) rename android-components/components/{feature/session/src/test/java/mozilla/components/feature/session/behavior/EngineViewBrowserToolbarBehaviorTest.kt => ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehaviorTest.kt} (89%) rename android-components/components/{browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarBehaviorTest.kt => ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehaviorTest.kt} (74%) rename android-components/components/{browser/toolbar/src/test/java/mozilla/components/browser/toolbar => ui/widgets/src/test/java/mozilla/components/ui/widgets}/behavior/TestUtils.kt (93%) create mode 100644 android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategyTest.kt create mode 100644 android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslatorTest.kt diff --git a/android-components/.buildconfig.yml b/android-components/.buildconfig.yml index 4544ac581217..c8a03c3ab507 100644 --- a/android-components/.buildconfig.yml +++ b/android-components/.buildconfig.yml @@ -269,6 +269,7 @@ projects: - ui-autocomplete - ui-colors - ui-icons + - ui-widgets compose-awesomebar: description: An awesomebar component showing search results matching text entered into the toolbar. @@ -601,7 +602,9 @@ projects: path: components/feature/autofill publish: true upstream_dependencies: + - browser-errorpages - concept-base + - concept-engine - concept-fetch - concept-storage - lib-fetch-okhttp @@ -756,6 +759,7 @@ projects: - ui-colors - ui-icons - ui-tabcounter + - ui-widgets feature-downloads: description: Feature implementation for apps that want to use Android downloads manager. @@ -1029,6 +1033,7 @@ projects: - ui-colors - ui-icons - ui-tabcounter + - ui-widgets feature-qr: description: A feature that provides functionality for scanning QR codes. path: components/feature/qr @@ -1863,6 +1868,7 @@ projects: - ui-colors - ui-icons - ui-tabcounter + - ui-widgets service-contile: description: A library to communicate with the Contile services API path: components/service/contile @@ -2261,9 +2267,17 @@ projects: path: components/ui/widgets publish: true upstream_dependencies: + - browser-errorpages - concept-base + - concept-engine + - concept-fetch + - concept-storage + - lib-publicsuffixlist - support-base + - support-ktx - support-test + - support-test-fakes + - support-utils - tooling-lint - ui-colors - ui-icons diff --git a/android-components/components/browser/toolbar/build.gradle b/android-components/components/browser/toolbar/build.gradle index 449317e20bfa..d18b1ebd4895 100644 --- a/android-components/components/browser/toolbar/build.gradle +++ b/android-components/components/browser/toolbar/build.gradle @@ -33,6 +33,7 @@ dependencies { implementation project(':browser-menu2') implementation project(':ui-icons') implementation project(':ui-colors') + implementation project(':ui-widgets') implementation project(':support-ktx') implementation ComponentsDependencies.androidx_appcompat diff --git a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/BrowserToolbar.kt b/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/BrowserToolbar.kt index 488fdf628854..a993014590b6 100644 --- a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/BrowserToolbar.kt +++ b/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/BrowserToolbar.kt @@ -25,7 +25,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.isActive import kotlinx.coroutines.launch -import mozilla.components.browser.toolbar.behavior.BrowserToolbarBehavior import mozilla.components.browser.toolbar.display.DisplayToolbar import mozilla.components.browser.toolbar.edit.EditToolbar import mozilla.components.concept.toolbar.AutocompleteDelegate @@ -38,6 +37,7 @@ import mozilla.components.support.ktx.kotlin.trimmed import mozilla.components.ui.autocomplete.AutocompleteView import mozilla.components.ui.autocomplete.InlineAutocompleteEditText import mozilla.components.ui.autocomplete.OnFilterListener +import mozilla.components.ui.widgets.behavior.EngineViewScrollingBehavior import kotlin.coroutines.CoroutineContext internal fun ImageView.setTintResource(@ColorRes tintColorResource: Int) { @@ -387,26 +387,26 @@ class BrowserToolbar @JvmOverloads constructor( override fun enableScrolling() { // Behavior can be changed without us knowing. Not safe to use a memoized value. (layoutParams as? CoordinatorLayout.LayoutParams)?.apply { - (behavior as? BrowserToolbarBehavior)?.enableScrolling() + (behavior as? EngineViewScrollingBehavior)?.enableScrolling() } } override fun disableScrolling() { // Behavior can be changed without us knowing. Not safe to use a memoized value. (layoutParams as? CoordinatorLayout.LayoutParams)?.apply { - (behavior as? BrowserToolbarBehavior)?.disableScrolling() + (behavior as? EngineViewScrollingBehavior)?.disableScrolling() } } override fun expand() { (layoutParams as? CoordinatorLayout.LayoutParams)?.apply { - (behavior as? BrowserToolbarBehavior)?.forceExpand(this@BrowserToolbar) + (behavior as? EngineViewScrollingBehavior)?.forceExpand(this@BrowserToolbar) } } override fun collapse() { (layoutParams as? CoordinatorLayout.LayoutParams)?.apply { - (behavior as? BrowserToolbarBehavior)?.forceCollapse(this@BrowserToolbar) + (behavior as? EngineViewScrollingBehavior)?.forceCollapse(this@BrowserToolbar) } } diff --git a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslationStrategy.kt b/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslationStrategy.kt deleted file mode 100644 index adea7a54d2a2..000000000000 --- a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslationStrategy.kt +++ /dev/null @@ -1,189 +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 mozilla.components.browser.toolbar.behavior - -import android.animation.ValueAnimator -import android.view.animation.DecelerateInterpolator -import androidx.annotation.VisibleForTesting -import mozilla.components.browser.toolbar.BrowserToolbar -import kotlin.math.max -import kotlin.math.min - -@VisibleForTesting -internal const val SNAP_ANIMATION_DURATION = 150L - -/** - * Helper class with methods for different behaviors for when translating a [BottomToolbar] on the Y axis. - */ -internal abstract class BrowserToolbarYTranslationStrategy { - @VisibleForTesting - var animator = ValueAnimator().apply { - interpolator = DecelerateInterpolator() - duration = SNAP_ANIMATION_DURATION - } - - /** - * Snap the [BrowserToolbar] to be collapsed or expanded, depending on whatever state is closer - * over a short amount of time. - */ - abstract fun snapWithAnimation(toolbar: BrowserToolbar) - - /** - * Snap the [BrowserToolbar] to be collapsed or expanded, depending on whatever state is closer immediately. - */ - abstract fun snapImmediately(toolbar: BrowserToolbar?) - - /** - * Translate the [BrowserToolbar] to it's full visible height. - */ - abstract fun expandWithAnimation(toolbar: BrowserToolbar) - - /** - * Force expanding the [BrowserToolbar] depending on the [distance] value that should be translated - * cancelling any other translation already in progress. - */ - abstract fun forceExpandWithAnimation(toolbar: BrowserToolbar, distance: Float) - - /** - * Translate the [BrowserToolbar] to it's full 0 visible height. - */ - abstract fun collapseWithAnimation(toolbar: BrowserToolbar) - - /** - * Translate [toolbar] immediately to the specified [distance] amount (positive or negative). - */ - abstract fun translate(toolbar: BrowserToolbar, distance: Float) - - /** - * Translate [toolbar] to the indicated [targetTranslationY] vaue over a short amount of time. - */ - open fun animateToTranslationY(toolbar: BrowserToolbar, targetTranslationY: Float) = with(animator) { - addUpdateListener { toolbar.translationY = it.animatedValue as Float } - setFloatValues(toolbar.translationY, targetTranslationY) - start() - } - - /** - * Cancel any translation animations currently in progress. - */ - fun cancelInProgressTranslation() = animator.cancel() -} - -/** - * Helper class containing methods for translating a [BrowserToolbar] on the Y axis - * between 0 and [BrowserToolbar.getHeight] - */ -internal class BottomToolbarBehaviorStrategy : BrowserToolbarYTranslationStrategy() { - @VisibleForTesting - internal var wasLastExpanding = false - - override fun snapWithAnimation(toolbar: BrowserToolbar) { - if (toolbar.translationY >= (toolbar.height / 2f)) { - collapseWithAnimation(toolbar) - } else { - expandWithAnimation(toolbar) - } - } - - override fun snapImmediately(toolbar: BrowserToolbar?) { - if (animator.isStarted) { - animator.end() - } else { - toolbar?.apply { - translationY = if (translationY >= height / 2) { - height.toFloat() - } else { - 0f - } - } - } - } - - override fun expandWithAnimation(toolbar: BrowserToolbar) { - animateToTranslationY(toolbar, 0f) - } - - override fun forceExpandWithAnimation(toolbar: BrowserToolbar, distance: Float) { - val shouldExpandToolbar = distance < 0 - val isToolbarExpanded = toolbar.translationY == 0f - if (shouldExpandToolbar && !isToolbarExpanded && !wasLastExpanding) { - animator.cancel() - expandWithAnimation(toolbar) - } - } - - override fun collapseWithAnimation(toolbar: BrowserToolbar) { - animateToTranslationY(toolbar, toolbar.height.toFloat()) - } - - override fun translate(toolbar: BrowserToolbar, distance: Float) { - toolbar.translationY = - max(0f, min(toolbar.height.toFloat(), toolbar.translationY + distance)) - } - - override fun animateToTranslationY(toolbar: BrowserToolbar, targetTranslationY: Float) { - wasLastExpanding = targetTranslationY <= toolbar.translationY - super.animateToTranslationY(toolbar, targetTranslationY) - } -} - -/** - * Helper class containing methods for translating a [BrowserToolbar] on the Y axis - * between -[BrowserToolbar.getHeight] and 0. - */ -internal class TopToolbarBehaviorStrategy : BrowserToolbarYTranslationStrategy() { - @VisibleForTesting - internal var wasLastExpanding = false - - override fun snapWithAnimation(toolbar: BrowserToolbar) { - if (toolbar.translationY >= -(toolbar.height / 2f)) { - expandWithAnimation(toolbar) - } else { - collapseWithAnimation(toolbar) - } - } - - override fun snapImmediately(toolbar: BrowserToolbar?) { - if (animator.isStarted) { - animator.end() - } else { - toolbar?.apply { - translationY = if (translationY >= -height / 2) { - 0f - } else { - -height.toFloat() - } - } - } - } - - override fun expandWithAnimation(toolbar: BrowserToolbar) { - animateToTranslationY(toolbar, 0f) - } - - override fun forceExpandWithAnimation(toolbar: BrowserToolbar, distance: Float) { - val isExpandingInProgress = animator.isStarted && wasLastExpanding - val shouldExpandToolbar = distance < 0 - val isToolbarExpanded = toolbar.translationY == 0f - if (shouldExpandToolbar && !isToolbarExpanded && !isExpandingInProgress) { - animator.cancel() - expandWithAnimation(toolbar) - } - } - - override fun collapseWithAnimation(toolbar: BrowserToolbar) { - animateToTranslationY(toolbar, -toolbar.height.toFloat()) - } - - override fun translate(toolbar: BrowserToolbar, distance: Float) { - toolbar.translationY = - min(0f, max(-toolbar.height.toFloat(), toolbar.translationY - distance)) - } - - override fun animateToTranslationY(toolbar: BrowserToolbar, targetTranslationY: Float) { - wasLastExpanding = targetTranslationY >= toolbar.translationY - super.animateToTranslationY(toolbar, targetTranslationY) - } -} diff --git a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslator.kt b/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslator.kt deleted file mode 100644 index 70db1d93cf4e..000000000000 --- a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslator.kt +++ /dev/null @@ -1,81 +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 mozilla.components.browser.toolbar.behavior - -import androidx.annotation.VisibleForTesting -import mozilla.components.browser.toolbar.BrowserToolbar - -/** - * Helper class with methods for translating on the Y axis a top / bottom [BottomToolbar]. - * - * @param toolbarPosition whether the toolbar is displayed immediately at the top of the screen or - * immediately at the bottom. This affects how it will be translated: - * - if place at the bottom it will be Y translated between 0 and [BrowserToolbar.getHeight] - * - if place at the top it will be Y translated between -[BrowserToolbar.getHeight] and 0 - */ -class BrowserToolbarYTranslator(toolbarPosition: ToolbarPosition) { - @VisibleForTesting - internal var strategy = getTranslationStrategy(toolbarPosition) - - /** - * Snap the [BrowserToolbar] to be collapsed or expanded, depending on whatever state is closer - * over a short amount of time. - */ - internal fun snapWithAnimation(toolbar: BrowserToolbar) { - strategy.snapWithAnimation(toolbar) - } - - /** - * Snap the [BrowserToolbar] to be collapsed or expanded, depending on whatever state is closer immediately. - */ - fun snapImmediately(toolbar: BrowserToolbar?) { - strategy.snapImmediately(toolbar) - } - - /** - * Translate the [BrowserToolbar] to it's full visible height over a short amount of time. - */ - internal fun expandWithAnimation(toolbar: BrowserToolbar) { - strategy.expandWithAnimation(toolbar) - } - - /** - * Translate the [BrowserToolbar] to be hidden from view over a short amount of time. - */ - internal fun collapseWithAnimation(toolbar: BrowserToolbar) { - strategy.collapseWithAnimation(toolbar) - } - - /** - * Force expanding the [BrowserToolbar] depending on the [distance] value that should be translated - * cancelling any other translation already in progress. - */ - fun forceExpandIfNotAlready(toolbar: BrowserToolbar, distance: Float) { - strategy.forceExpandWithAnimation(toolbar, distance) - } - - /** - * Translate [toolbar] immediately to the specified [distance] amount (positive or negative). - */ - fun translate(toolbar: BrowserToolbar, distance: Float) { - strategy.translate(toolbar, distance) - } - - /** - * Cancel any translation animations currently in progress. - */ - fun cancelInProgressTranslation() { - strategy.cancelInProgressTranslation() - } - - @VisibleForTesting - internal fun getTranslationStrategy(toolbarPosition: ToolbarPosition): BrowserToolbarYTranslationStrategy { - return if (toolbarPosition == ToolbarPosition.TOP) { - TopToolbarBehaviorStrategy() - } else { - BottomToolbarBehaviorStrategy() - } - } -} diff --git a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/BrowserToolbarTest.kt b/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/BrowserToolbarTest.kt index 33b7352a1728..9f69e5b40237 100644 --- a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/BrowserToolbarTest.kt +++ b/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/BrowserToolbarTest.kt @@ -17,8 +17,6 @@ import androidx.core.view.inputmethod.EditorInfoCompat import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.test.ext.junit.runners.AndroidJUnit4 -import mozilla.components.browser.toolbar.behavior.BrowserToolbarBehavior -import mozilla.components.browser.toolbar.behavior.ToolbarPosition import mozilla.components.browser.toolbar.display.DisplayToolbar import mozilla.components.browser.toolbar.display.DisplayToolbarViews import mozilla.components.browser.toolbar.display.MenuButton @@ -32,6 +30,8 @@ import mozilla.components.support.test.argumentCaptor import mozilla.components.support.test.mock import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.test.whenever +import mozilla.components.ui.widgets.behavior.EngineViewScrollingBehavior +import mozilla.components.ui.widgets.behavior.ViewPosition import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNotEquals @@ -911,7 +911,7 @@ class BrowserToolbarTest { fun `enable scrolling is forwarded to the toolbar behavior`() { // Seems like real instances are needed for things to be set properly val toolbar = BrowserToolbar(testContext) - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) val params = CoordinatorLayout.LayoutParams(10, 10).apply { this.behavior = behavior } @@ -926,7 +926,7 @@ class BrowserToolbarTest { fun `disable scrolling is forwarded to the toolbar behavior`() { // Seems like real instances are needed for things to be set properly val toolbar = BrowserToolbar(testContext) - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) val params = CoordinatorLayout.LayoutParams(10, 10).apply { this.behavior = behavior } @@ -941,7 +941,7 @@ class BrowserToolbarTest { fun `expand is forwarded to the toolbar behavior`() { // Seems like real instances are needed for things to be set properly val toolbar = BrowserToolbar(testContext) - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) val params = CoordinatorLayout.LayoutParams(10, 10).apply { this.behavior = behavior } @@ -956,7 +956,7 @@ class BrowserToolbarTest { fun `collapse is forwarded to the toolbar behavior`() { // Seems like real instances are needed for things to be set properly val toolbar = BrowserToolbar(testContext) - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) val params = CoordinatorLayout.LayoutParams(10, 10).apply { this.behavior = behavior } diff --git a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslationStrategyTest.kt b/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslationStrategyTest.kt deleted file mode 100644 index fa6cc43c1cec..000000000000 --- a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslationStrategyTest.kt +++ /dev/null @@ -1,712 +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 mozilla.components.browser.toolbar.behavior - -import android.animation.ValueAnimator -import android.view.animation.DecelerateInterpolator -import androidx.test.ext.junit.runners.AndroidJUnit4 -import mozilla.components.browser.toolbar.BrowserToolbar -import mozilla.components.support.test.any -import mozilla.components.support.test.mock -import mozilla.components.support.test.robolectric.testContext -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mockito.doReturn -import org.mockito.Mockito.never -import org.mockito.Mockito.spy -import org.mockito.Mockito.times -import org.mockito.Mockito.verify - -@RunWith(AndroidJUnit4::class) -class BrowserToolbarYTranslationStrategyTest { - @Test - fun `snapAnimator should use a DecelerateInterpolator with SNAP_ANIMATION_DURATION for bottom toolbar translations`() { - val strategy = BottomToolbarBehaviorStrategy() - - assertTrue(strategy.animator.interpolator is DecelerateInterpolator) - assertEquals(SNAP_ANIMATION_DURATION, strategy.animator.duration) - } - - @Test - fun `snapAnimator should use a DecelerateInterpolator with SNAP_ANIMATION_DURATION for top toolbar translations`() { - val strategy = TopToolbarBehaviorStrategy() - - assertTrue(strategy.animator.interpolator is DecelerateInterpolator) - assertEquals(SNAP_ANIMATION_DURATION, strategy.animator.duration) - } - - @Test - fun `BottomToolbarBehaviorStrategy should start with isToolbarExpanding = false`() { - val strategy = BottomToolbarBehaviorStrategy() - - assertFalse(strategy.wasLastExpanding) - } - - @Test - fun `TopToolbarBehaviorStrategy should start with isToolbarExpanding = false`() { - val strategy = TopToolbarBehaviorStrategy() - - assertFalse(strategy.wasLastExpanding) - } - - @Test - fun `BottomToolbarBehaviorStrategy - snapWithAnimation should collapse toolbar if more than half hidden`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(50f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - doReturn(51f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - doReturn(100f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - doReturn(333f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - verify(strategy, times(4)).collapseWithAnimation(toolbar) - verify(strategy, never()).expandWithAnimation(toolbar) - } - - @Test - fun `BottomToolbarBehaviorStrategy - snapWithAnimation should expand toolbar if more than half visible`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(49f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - doReturn(0f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - doReturn(-50f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - verify(strategy, times(3)).expandWithAnimation(toolbar) - verify(strategy, never()).collapseWithAnimation(toolbar) - } - - @Test - fun `TopToolbarBehaviorStrategy - snapWithAnimation should collapse toolbar if more than half hidden`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(-51f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - doReturn(-100f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - doReturn(-333f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - verify(strategy, times(3)).collapseWithAnimation(toolbar) - verify(strategy, never()).expandWithAnimation(toolbar) - } - - @Test - fun `TopToolbarBehaviorStrategy - snapWithAnimation should expand toolbar if more than half visible`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(-50f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - doReturn(-49f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - doReturn(0f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - doReturn(50f).`when`(toolbar).translationY - strategy.snapWithAnimation(toolbar) - - verify(strategy, times(4)).expandWithAnimation(toolbar) - verify(strategy, never()).collapseWithAnimation(toolbar) - } - - @Test - fun `BottomToolbarBehaviorStrategy - snapImmediately should end translations animations if in progress`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(true).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - - strategy.snapImmediately(toolbar) - - verify(animator).end() - verify(toolbar, never()).translationY - } - - @Test - fun `BottomToolbarBehaviorStrategy - snapImmediately should translate away the toolbar if half translated`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(50f).`when`(toolbar).translationY - strategy.snapImmediately(toolbar) - verify(toolbar).translationY = 100f - } - - @Test - fun `BottomToolbarBehaviorStrategy - snapImmediately should translate away the toolbar if more than half`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(55f).`when`(toolbar).translationY - strategy.snapImmediately(toolbar) - verify(toolbar).translationY = 100f - } - - @Test - fun `BottomToolbarBehaviorStrategy - snapImmediately should translate away the toolbar if translated off screen`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(555f).`when`(toolbar).translationY - strategy.snapImmediately(toolbar) - verify(toolbar).translationY = 100f - } - - @Test - fun `BottomToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated less than half`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(49f).`when`(toolbar).translationY - strategy.snapImmediately(toolbar) - verify(toolbar).translationY = 0f - } - - @Test - fun `BottomToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated 0`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(0f).`when`(toolbar).translationY - strategy.snapImmediately(toolbar) - verify(toolbar).translationY = 0f - } - - @Test - fun `BottomToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated inside the screen`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(-1f).`when`(toolbar).translationY - strategy.snapImmediately(toolbar) - verify(toolbar).translationY = 0f - } - - @Test - fun `TopToolbarBehaviorStrategy - snapImmediately should end translations animations if in progress`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(true).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - - strategy.snapImmediately(toolbar) - - verify(animator).end() - verify(toolbar, never()).translationY - } - - @Test - fun `TopToolbarBehaviorStrategy - snapImmediately should translate translate to 0 the toolbar if translated less than half`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(-49f).`when`(toolbar).translationY - strategy.snapImmediately(toolbar) - verify(toolbar).translationY = 0f - } - - @Test - fun `TopToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated 0`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(0f).`when`(toolbar).translationY - strategy.snapImmediately(toolbar) - verify(toolbar).translationY = 0f - } - - @Test - fun `TopToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated inside the screen`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(1f).`when`(toolbar).translationY - strategy.snapImmediately(toolbar) - verify(toolbar).translationY = 0f - } - - @Test - fun `TopToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if half translated`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(-50f).`when`(toolbar).translationY - strategy.snapImmediately(toolbar) - verify(toolbar).translationY = 0f - } - - @Test - fun `TopToolbarBehaviorStrategy - snapImmediately should translate away the toolbar if more than half translated`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(-55f).`when`(toolbar).translationY - strategy.snapImmediately(toolbar) - verify(toolbar).translationY = -100f - } - - @Test - fun `TopToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated offscreen`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - doReturn(-111f).`when`(toolbar).translationY - strategy.snapImmediately(toolbar) - verify(toolbar).translationY = -100f - } - - @Test - fun `BottomToolbarBehaviorStrategy - expandWithAnimation should translate the toolbar to to y 0`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - val toolbar: BrowserToolbar = mock() - - strategy.expandWithAnimation(toolbar) - - verify(strategy).animateToTranslationY(toolbar, 0f) - } - - @Test - fun `TopToolbarBehaviorStrategy - expandWithAnimation should translate the toolbar to to y 0`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - val toolbar: BrowserToolbar = mock() - - strategy.expandWithAnimation(toolbar) - - verify(strategy).animateToTranslationY(toolbar, 0f) - } - - @Test - fun `BottomToolbarBehaviorStrategy - forceExpandWithAnimation should expand toolbar`() { - // Setting the scenario in which forceExpandWithAnimation will actually do what the name says. - // Below this test we can change each variable one at a time to test them in isolation. - - val strategy = spy(BottomToolbarBehaviorStrategy()) - strategy.wasLastExpanding = false - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100f).`when`(toolbar).translationY - - strategy.forceExpandWithAnimation(toolbar, -100f) - - verify(strategy.animator).cancel() - verify(strategy).expandWithAnimation(any()) - } - - @Test - fun `BottomToolbarBehaviorStrategy - forceExpandWithAnimation should not force expand the toolbar if not currently collapsing`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - strategy.wasLastExpanding = true - val animator: ValueAnimator = mock() - doReturn(true).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100f).`when`(toolbar).translationY - - strategy.forceExpandWithAnimation(toolbar, -100f) - - verify(strategy.animator, never()).cancel() - verify(strategy, never()).expandWithAnimation(any()) - } - - @Test - fun `BottomToolbarBehaviorStrategy - forceExpandWithAnimation should not expand if user swipes down`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - strategy.wasLastExpanding = false - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(100f).`when`(toolbar).translationY - - strategy.forceExpandWithAnimation(toolbar, 100f) - - verify(strategy.animator, never()).cancel() - verify(strategy, never()).expandWithAnimation(any()) - } - - @Test - fun `BottomToolbarBehaviorStrategy - forceExpandWithAnimation should not expand the toolbar if it is already expanded`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - strategy.wasLastExpanding = false - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(0f).`when`(toolbar).translationY - - strategy.forceExpandWithAnimation(toolbar, -100f) - - verify(strategy.animator, never()).cancel() - verify(strategy, never()).expandWithAnimation(any()) - } - - @Test - fun `TopToolbarBehaviorStrategy - forceExpandWithAnimation should expand toolbar`() { - // Setting the scenario in which forceExpandWithAnimation will actually do what the name says. - // Below this test we can change each variable one at a time to test them in isolation. - - val strategy = spy(TopToolbarBehaviorStrategy()) - strategy.wasLastExpanding = false - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(-100f).`when`(toolbar).translationY - - strategy.forceExpandWithAnimation(toolbar, -100f) - - verify(strategy.animator).cancel() - verify(strategy).expandWithAnimation(any()) - } - - @Test - fun `TopToolbarBehaviorStrategy - forceExpandWithAnimation should not force expand the toolbar if not currently collapsing`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - strategy.wasLastExpanding = true - val animator: ValueAnimator = mock() - doReturn(true).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(-100f).`when`(toolbar).translationY - - strategy.forceExpandWithAnimation(toolbar, -100f) - - verify(strategy.animator, never()).cancel() - verify(strategy, never()).expandWithAnimation(any()) - } - - @Test - fun `TopToolbarBehaviorStrategy - forceExpandWithAnimation should not expand if user swipes up`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - strategy.wasLastExpanding = false - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(-100f).`when`(toolbar).translationY - - strategy.forceExpandWithAnimation(toolbar, 10f) - - verify(strategy.animator, never()).cancel() - verify(strategy, never()).expandWithAnimation(any()) - } - - @Test - fun `TopToolbarBehaviorStrategy - forceExpandWithAnimation should not expand the toolbar if it is already expanded`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - strategy.wasLastExpanding = false - val animator: ValueAnimator = mock() - doReturn(false).`when`(animator).isStarted - strategy.animator = animator - val toolbar: BrowserToolbar = mock() - doReturn(0f).`when`(toolbar).translationY - - strategy.forceExpandWithAnimation(toolbar, -100f) - - verify(strategy.animator, never()).cancel() - verify(strategy, never()).expandWithAnimation(any()) - } - - @Test - fun `BottomToolbarBehaviorStrategy - collapseWithAnimation should animate translating the toolbar down, off-screen`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - strategy.collapseWithAnimation(toolbar) - - verify(strategy).animateToTranslationY(toolbar, 100f) - } - - @Test - fun `TopToolbarBehaviorStrategy - collapseWithAnimation should animate translating the toolbar up, off-screen`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - - strategy.collapseWithAnimation(toolbar) - - verify(strategy).animateToTranslationY(toolbar, -100f) - } - - @Test - fun `BottomToolbarBehaviorStrategy - translate should translate up the toolbar with the distance parameter`() { - val strategy = BottomToolbarBehaviorStrategy() - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - doReturn(50f).`when`(toolbar).translationY - - strategy.translate(toolbar, -25f) - - verify(toolbar).translationY = 25f - } - - @Test - fun `BottomToolbarBehaviorStrategy - translate should translate down the toolbar with the distance parameter`() { - val strategy = BottomToolbarBehaviorStrategy() - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - doReturn(50f).`when`(toolbar).translationY - - strategy.translate(toolbar, 25f) - - verify(toolbar).translationY = 75f - } - - @Test - fun `BottomToolbarBehaviorStrategy - translate should not translate up the toolbar if already expanded`() { - val strategy = BottomToolbarBehaviorStrategy() - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - doReturn(0f).`when`(toolbar).translationY - - strategy.translate(toolbar, -1f) - - verify(toolbar).translationY = 0f - } - - @Test - fun `BottomToolbarBehaviorStrategy - translate should not translate up the toolbar more than to 0`() { - val strategy = BottomToolbarBehaviorStrategy() - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - doReturn(50f).`when`(toolbar).translationY - - strategy.translate(toolbar, -51f) - - verify(toolbar).translationY = 0f - } - - @Test - fun `BottomToolbarBehaviorStrategy - translate should not translate down the toolbar if already collapsed`() { - val strategy = BottomToolbarBehaviorStrategy() - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - doReturn(100f).`when`(toolbar).translationY - - strategy.translate(toolbar, 1f) - - verify(toolbar).translationY = 100f - } - - @Test - fun `BottomToolbarBehaviorStrategy - translate should not translate down the toolbar more than it's height`() { - val strategy = BottomToolbarBehaviorStrategy() - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - doReturn(50f).`when`(toolbar).translationY - - strategy.translate(toolbar, 51f) - - verify(toolbar).translationY = 100f - } - - @Test - fun `TopToolbarBehaviorStrategy - translate should translate down the toolbar with the distance parameter`() { - val strategy = TopToolbarBehaviorStrategy() - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - doReturn(-50f).`when`(toolbar).translationY - - strategy.translate(toolbar, 25f) - - verify(toolbar).translationY = -75f - } - - @Test - fun `TopToolbarBehaviorStrategy - translate should translate up the toolbar with the distance parameter`() { - val strategy = TopToolbarBehaviorStrategy() - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - doReturn(-50f).`when`(toolbar).translationY - - strategy.translate(toolbar, 25f) - - verify(toolbar).translationY = -75f - } - - @Test - fun `TopToolbarBehaviorStrategy - translate should not translate down the toolbar if already expanded`() { - val strategy = TopToolbarBehaviorStrategy() - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - doReturn(0f).`when`(toolbar).translationY - - strategy.translate(toolbar, -1f) - - verify(toolbar).translationY = 0f - } - - @Test - fun `TopToolbarBehaviorStrategy - translate should not translate down the toolbar more than to 0`() { - val strategy = TopToolbarBehaviorStrategy() - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - doReturn(-50f).`when`(toolbar).translationY - - strategy.translate(toolbar, -51f) - - verify(toolbar).translationY = 0f - } - - @Test - fun `TopToolbarBehaviorStrategy - translate should not translate up the toolbar if already collapsed`() { - val strategy = TopToolbarBehaviorStrategy() - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - doReturn(-100f).`when`(toolbar).translationY - - strategy.translate(toolbar, 1f) - - verify(toolbar).translationY = -100f - } - - @Test - fun `TopToolbarBehaviorStrategy - translate should not translate up the toolbar more than it's height`() { - val strategy = TopToolbarBehaviorStrategy() - val toolbar: BrowserToolbar = mock() - doReturn(100).`when`(toolbar).height - doReturn(-50f).`when`(toolbar).translationY - - strategy.translate(toolbar, 51f) - - verify(toolbar).translationY = -100f - } - - @Test - fun `BottomToolbarBehaviorStrategy - animateToTranslationY should set wasLastExpanding if expanding`() { - val strategy = BottomToolbarBehaviorStrategy() - strategy.wasLastExpanding = false - val toolbar: BrowserToolbar = mock() - doReturn(50f).`when`(toolbar).translationY - - strategy.animateToTranslationY(toolbar, 10f) - assertTrue(strategy.wasLastExpanding) - - strategy.animateToTranslationY(toolbar, 60f) - assertFalse(strategy.wasLastExpanding) - } - - @Test - fun `BottomToolbarBehaviorStrategy - animateToTranslationY should animate to the indicated y translation`() { - val strategy = spy(BottomToolbarBehaviorStrategy()) - strategy.wasLastExpanding = false - val toolbar: BrowserToolbar = BrowserToolbar(testContext) - val animator: ValueAnimator = spy(strategy.animator) - strategy.animator = animator - - strategy.animateToTranslationY(toolbar, 10f) - - verify(animator).start() - animator.end() - assertEquals(10f, toolbar.translationY) - } - - @Test - fun `TopToolbarBehaviorStrategy - animateToTranslationY should set wasLastExpanding if expanding`() { - val strategy = TopToolbarBehaviorStrategy() - strategy.wasLastExpanding = false - val toolbar: BrowserToolbar = mock() - doReturn(-50f).`when`(toolbar).translationY - - strategy.animateToTranslationY(toolbar, -10f) - assertTrue(strategy.wasLastExpanding) - - strategy.animateToTranslationY(toolbar, -60f) - assertFalse(strategy.wasLastExpanding) - } - - @Test - fun `TopToolbarBehaviorStrategy - animateToTranslationY should animate to the indicated y translation`() { - val strategy = spy(TopToolbarBehaviorStrategy()) - strategy.wasLastExpanding = false - val toolbar: BrowserToolbar = BrowserToolbar(testContext) - val animator: ValueAnimator = spy(strategy.animator) - strategy.animator = animator - - strategy.animateToTranslationY(toolbar, -10f) - - verify(animator).start() - animator.end() - assertEquals(-10f, toolbar.translationY) - } -} diff --git a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslatorTest.kt b/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslatorTest.kt deleted file mode 100644 index eeca64c7e73a..000000000000 --- a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarYTranslatorTest.kt +++ /dev/null @@ -1,113 +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 mozilla.components.browser.toolbar.behavior - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import mozilla.components.browser.toolbar.BrowserToolbar -import mozilla.components.support.test.mock -import org.junit.Assert.assertTrue -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mockito.verify - -@RunWith(AndroidJUnit4::class) -class BrowserToolbarYTranslatorTest { - @Test - fun `yTranslator should use BottomToolbarBehaviorStrategy for bottom placed toolbars`() { - val yTranslator = BrowserToolbarYTranslator(ToolbarPosition.BOTTOM) - - assertTrue(yTranslator.strategy is BottomToolbarBehaviorStrategy) - } - - @Test - fun `yTranslator should use TopToolbarBehaviorStrategy for top placed toolbars`() { - val yTranslator = BrowserToolbarYTranslator(ToolbarPosition.TOP) - - assertTrue(yTranslator.strategy is TopToolbarBehaviorStrategy) - } - - @Test - fun `yTranslator should delegate it's strategy for snapWithAnimation`() { - val yTranslator = BrowserToolbarYTranslator(ToolbarPosition.BOTTOM) - val strategy: BrowserToolbarYTranslationStrategy = mock() - yTranslator.strategy = strategy - val toolbar: BrowserToolbar = mock() - - yTranslator.snapWithAnimation(toolbar) - - verify(strategy).snapWithAnimation(toolbar) - } - - @Test - fun `yTranslator should delegate it's strategy for expandWithAnimation`() { - val yTranslator = BrowserToolbarYTranslator(ToolbarPosition.BOTTOM) - val strategy: BrowserToolbarYTranslationStrategy = mock() - yTranslator.strategy = strategy - val toolbar: BrowserToolbar = mock() - - yTranslator.expandWithAnimation(toolbar) - - verify(strategy).expandWithAnimation(toolbar) - } - - @Test - fun `yTranslator should delegate it's strategy for collapseWithAnimation`() { - val yTranslator = BrowserToolbarYTranslator(ToolbarPosition.BOTTOM) - val strategy: BrowserToolbarYTranslationStrategy = mock() - yTranslator.strategy = strategy - val toolbar: BrowserToolbar = mock() - - yTranslator.collapseWithAnimation(toolbar) - - verify(strategy).collapseWithAnimation(toolbar) - } - - @Test - fun `yTranslator should delegate it's strategy for forceExpandIfNotAlready`() { - val yTranslator = BrowserToolbarYTranslator(ToolbarPosition.BOTTOM) - val strategy: BrowserToolbarYTranslationStrategy = mock() - yTranslator.strategy = strategy - val toolbar: BrowserToolbar = mock() - - yTranslator.forceExpandIfNotAlready(toolbar, 14f) - - verify(strategy).forceExpandWithAnimation(toolbar, 14f) - } - - @Test - fun `yTranslator should delegate it's strategy for translate`() { - val yTranslator = BrowserToolbarYTranslator(ToolbarPosition.BOTTOM) - val strategy: BrowserToolbarYTranslationStrategy = mock() - yTranslator.strategy = strategy - val toolbar: BrowserToolbar = mock() - - yTranslator.translate(toolbar, 23f) - - verify(strategy).translate(toolbar, 23f) - } - - @Test - fun `yTranslator should delegate it's strategy for cancelInProgressTranslation`() { - val yTranslator = BrowserToolbarYTranslator(ToolbarPosition.BOTTOM) - val strategy: BrowserToolbarYTranslationStrategy = mock() - yTranslator.strategy = strategy - - yTranslator.cancelInProgressTranslation() - - verify(strategy).cancelInProgressTranslation() - } - - @Test - fun `yTranslator should delegate it's strategy for snapImmediately`() { - val yTranslator = BrowserToolbarYTranslator(ToolbarPosition.BOTTOM) - val strategy: BrowserToolbarYTranslationStrategy = mock() - yTranslator.strategy = strategy - val toolbar: BrowserToolbar = mock() - - yTranslator.snapImmediately(toolbar) - - verify(strategy).snapImmediately(toolbar) - } -} diff --git a/android-components/components/concept/toolbar/src/main/java/mozilla/components/concept/toolbar/ScrollableToolbar.kt b/android-components/components/concept/toolbar/src/main/java/mozilla/components/concept/toolbar/ScrollableToolbar.kt new file mode 100644 index 000000000000..86af351c26e2 --- /dev/null +++ b/android-components/components/concept/toolbar/src/main/java/mozilla/components/concept/toolbar/ScrollableToolbar.kt @@ -0,0 +1,34 @@ +/* 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 mozilla.components.concept.toolbar + +/** + * Interface to be implemented by components that provide hiding-on-scroll toolbar functionality. + */ +interface ScrollableToolbar { + + /** + * Enable scrolling of the dynamic toolbar. Restore this functionality after [disableScrolling] stopped it. + * + * The toolbar may have other intrinsic checks depending on which the toolbar will be animated or not. + */ + fun enableScrolling() + + /** + * Completely disable scrolling of the dynamic toolbar. + * Use [enableScrolling] to restore the functionality. + */ + fun disableScrolling() + + /** + * Force the toolbar to expand. + */ + fun expand() + + /** + * Force the toolbar to collapse. Only if dynamic. + */ + fun collapse() +} diff --git a/android-components/components/concept/toolbar/src/main/java/mozilla/components/concept/toolbar/Toolbar.kt b/android-components/components/concept/toolbar/src/main/java/mozilla/components/concept/toolbar/Toolbar.kt index 16c0e7c6655f..398acca62d72 100644 --- a/android-components/components/concept/toolbar/src/main/java/mozilla/components/concept/toolbar/Toolbar.kt +++ b/android-components/components/concept/toolbar/src/main/java/mozilla/components/concept/toolbar/Toolbar.kt @@ -26,7 +26,7 @@ import java.lang.ref.WeakReference * Interface to be implemented by components that provide browser toolbar functionality. */ @Suppress("TooManyFunctions") -interface Toolbar { +interface Toolbar : ScrollableToolbar { /** * Sets/Gets the title to be displayed on the toolbar. */ @@ -211,29 +211,6 @@ interface Toolbar { */ fun dismissMenu() - /** - * Enable scrolling of the dynamic toolbar. Restore this functionality after [disableScrolling] stopped it. - * - * The toolbar may have other intrinsic checks depending on which the toolbar will be animated or not. - */ - fun enableScrolling() - - /** - * Completely disable scrolling of the dynamic toolbar. - * Use [enableScrolling] to restore the functionality. - */ - fun disableScrolling() - - /** - * Force the toolbar to expand. - */ - fun expand() - - /** - * Force the toolbar to collapse. Only if dynamic. - */ - fun collapse() - /** * Listener to be invoked when the user edits the URL. */ diff --git a/android-components/components/feature/toolbar/src/main/java/mozilla/components/feature/toolbar/ToolbarBehaviorController.kt b/android-components/components/feature/toolbar/src/main/java/mozilla/components/feature/toolbar/ToolbarBehaviorController.kt index 4fbc4333547c..7928f1ac64ce 100644 --- a/android-components/components/feature/toolbar/src/main/java/mozilla/components/feature/toolbar/ToolbarBehaviorController.kt +++ b/android-components/components/feature/toolbar/src/main/java/mozilla/components/feature/toolbar/ToolbarBehaviorController.kt @@ -12,17 +12,17 @@ import kotlinx.coroutines.flow.mapNotNull import mozilla.components.browser.state.action.ContentAction import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab import mozilla.components.browser.state.store.BrowserStore -import mozilla.components.concept.toolbar.Toolbar +import mozilla.components.concept.toolbar.ScrollableToolbar import mozilla.components.lib.state.ext.flowScoped /** - * Controls how the dynamic toolbar should behave based on the current tab state. + * Controls how a dynamic toolbar should behave based on the current tab state. * * Responsible to enforce the following: * - toolbar should not be scrollable if the page has not finished loading */ class ToolbarBehaviorController( - private val toolbar: Toolbar, + private val toolbar: ScrollableToolbar, private val store: BrowserStore, private val customTabId: String? = null, ) { diff --git a/android-components/components/ui/widgets/build.gradle b/android-components/components/ui/widgets/build.gradle index 4a16d26c758c..bc0d98e0e975 100644 --- a/android-components/components/ui/widgets/build.gradle +++ b/android-components/components/ui/widgets/build.gradle @@ -25,8 +25,11 @@ android { } dependencies { + implementation project(':concept-base') + implementation project(':concept-engine') implementation project(':ui-colors') implementation project(':ui-icons') + implementation project(':support-ktx') implementation ComponentsDependencies.androidx_appcompat implementation ComponentsDependencies.androidx_constraintlayout @@ -35,6 +38,7 @@ dependencies { implementation ComponentsDependencies.androidx_swiperefreshlayout testImplementation project(":support-test") + testImplementation project(':support-test-fakes') testImplementation ComponentsDependencies.androidx_test_junit testImplementation ComponentsDependencies.testing_robolectric diff --git a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserGestureDetector.kt b/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetector.kt similarity index 99% rename from android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserGestureDetector.kt rename to android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetector.kt index 038e5ed6e5f3..b15df650780a 100644 --- a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserGestureDetector.kt +++ b/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetector.kt @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package mozilla.components.browser.toolbar.behavior +package mozilla.components.ui.widgets.behavior import android.content.Context import android.view.GestureDetector diff --git a/android-components/components/feature/session/src/main/java/mozilla/components/feature/session/behavior/EngineViewBrowserToolbarBehavior.kt b/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehavior.kt similarity index 96% rename from android-components/components/feature/session/src/main/java/mozilla/components/feature/session/behavior/EngineViewBrowserToolbarBehavior.kt rename to android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehavior.kt index d50b65589bd6..7ffe1166c555 100644 --- a/android-components/components/feature/session/src/main/java/mozilla/components/feature/session/behavior/EngineViewBrowserToolbarBehavior.kt +++ b/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehavior.kt @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package mozilla.components.feature.session.behavior +package mozilla.components.ui.widgets.behavior import android.annotation.SuppressLint import android.content.Context @@ -27,7 +27,7 @@ import kotlin.math.roundToInt * @param toolbarHeight size of [BrowserToolbar] when it is placed above the [EngineView] * @param whether the [BrowserToolbar] is placed above or below the [EngineView] */ -class EngineViewBrowserToolbarBehavior( +class EngineViewClippingBehavior( context: Context?, attrs: AttributeSet?, engineViewParent: View, @@ -76,7 +76,7 @@ class EngineViewBrowserToolbarBehavior( } /** - * Apply vertical clipping to [EngineView]. This requires [EngineViewBrowserToolbarBehavior] to be set + * Apply vertical clipping to [EngineView]. This requires [EngineViewClippingBehavior] to be set * in/on the [EngineView] or its parent. Must be a direct descending child of [CoordinatorLayout]. */ override fun onDependentViewChanged(parent: CoordinatorLayout, child: View, dependency: View): Boolean { diff --git a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarBehavior.kt b/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehavior.kt similarity index 70% rename from android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarBehavior.kt rename to android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehavior.kt index b79c448eeffa..08da7e5064c0 100644 --- a/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarBehavior.kt +++ b/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehavior.kt @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package mozilla.components.browser.toolbar.behavior +package mozilla.components.ui.widgets.behavior import android.content.Context import android.util.AttributeSet @@ -11,35 +11,34 @@ import android.view.View import androidx.annotation.VisibleForTesting import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.ViewCompat -import mozilla.components.browser.toolbar.BrowserToolbar import mozilla.components.concept.base.crash.CrashReporting import mozilla.components.concept.engine.EngineView import mozilla.components.support.ktx.android.view.findViewInHierarchy /** - * Where the toolbar is placed on the screen. + * Where the view is placed on the screen. */ -enum class ToolbarPosition { +enum class ViewPosition { TOP, BOTTOM, } /** - * A [CoordinatorLayout.Behavior] implementation to be used when placing [BrowserToolbar] at the bottom of the screen. + * A [CoordinatorLayout.Behavior] implementation to be used when placing [View] at the bottom of the screen. * - * This is safe to use even if the [BrowserToolbar] may be added / removed from a parent layout later + * This is safe to use even if the [View] may be added / removed from a parent layout later * or if it could have Visibility.GONE set. * * This implementation will: - * - Show/Hide the [BrowserToolbar] automatically when scrolling vertically. - * - Snap the [BrowserToolbar] to be hidden or visible when the user stops scrolling. + * - Show/Hide the [View] automatically when scrolling vertically. + * - Snap the [View] to be hidden or visible when the user stops scrolling. */ -class BrowserToolbarBehavior( +class EngineViewScrollingBehavior( val context: Context?, attrs: AttributeSet?, - private val toolbarPosition: ToolbarPosition, + private val viewPosition: ViewPosition, private val crashReporting: CrashReporting? = null, -) : CoordinatorLayout.Behavior(context, attrs) { +) : CoordinatorLayout.Behavior(context, attrs) { // This implementation is heavily based on this blog article: // https://android.jlelse.eu/scroll-your-bottom-navigation-view-away-with-10-lines-of-code-346f1ed40e9e @@ -59,10 +58,10 @@ class BrowserToolbarBehavior( internal var engineView: EngineView? = null /** - * Reference to the actual [BrowserToolbar] that we'll animate. + * Reference to the actual [View] that we'll animate. */ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) - internal var browserToolbar: BrowserToolbar? = null + internal var dynamicScrollView: View? = null /** * Depending on how user's touch was consumed by EngineView / current website, @@ -84,19 +83,19 @@ class BrowserToolbarBehavior( internal var gesturesDetector: BrowserGestureDetector = createGestureDetector() @VisibleForTesting - internal var yTranslator: BrowserToolbarYTranslator = createYTranslationStragy() + internal var yTranslator: ViewYTranslator = createYTranslationStrategy() - private fun createYTranslationStragy() = BrowserToolbarYTranslator(toolbarPosition) + private fun createYTranslationStrategy() = ViewYTranslator(viewPosition) override fun onStartNestedScroll( coordinatorLayout: CoordinatorLayout, - child: BrowserToolbar, + child: View, directTargetChild: View, target: View, axes: Int, type: Int, ): Boolean { - return if (browserToolbar != null) { + return if (dynamicScrollView != null) { startNestedScroll(axes, type, child) } else { return false // not interested in subsequent scroll events @@ -105,21 +104,21 @@ class BrowserToolbarBehavior( override fun onStopNestedScroll( coordinatorLayout: CoordinatorLayout, - child: BrowserToolbar, + child: View, target: View, type: Int, ) { - if (browserToolbar != null) { + if (dynamicScrollView != null) { stopNestedScroll(type, child) } } override fun onInterceptTouchEvent( parent: CoordinatorLayout, - child: BrowserToolbar, + child: View, ev: MotionEvent, ): Boolean { - if (browserToolbar != null) { + if (dynamicScrollView != null) { gesturesDetector.handleTouchEvent(ev) } return false // allow events to be passed to below listeners @@ -127,31 +126,31 @@ class BrowserToolbarBehavior( override fun onLayoutChild( parent: CoordinatorLayout, - child: BrowserToolbar, + child: View, layoutDirection: Int, ): Boolean { - browserToolbar = child + dynamicScrollView = child engineView = parent.findViewInHierarchy { it is EngineView } as? EngineView return super.onLayoutChild(parent, child, layoutDirection) } /** - * Used to expand the [BrowserToolbar] + * Used to expand the [View] */ - fun forceExpand(toolbar: BrowserToolbar) { - yTranslator.expandWithAnimation(toolbar) + fun forceExpand(view: View) { + yTranslator.expandWithAnimation(view) } /** - * Used to collapse the [BrowserToolbar] + * Used to collapse the [View] */ - fun forceCollapse(toolbar: BrowserToolbar) { - yTranslator.collapseWithAnimation(toolbar) + fun forceCollapse(view: View) { + yTranslator.collapseWithAnimation(view) } /** - * Allow this toolbar can be animated. + * Allow this view to be animated. * * @see disableScrolling */ @@ -160,7 +159,7 @@ class BrowserToolbarBehavior( } /** - * Disable scrolling this toolbar irrespective of the intrinsic checks. + * Disable scrolling of the view irrespective of the intrinsic checks. * * @see enableScrolling */ @@ -170,15 +169,15 @@ class BrowserToolbarBehavior( @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal fun tryToScrollVertically(distance: Float) { - browserToolbar?.let { toolbar -> + dynamicScrollView?.let { view -> if (shouldScroll && startedScroll) { - yTranslator.translate(toolbar, distance) + yTranslator.translate(view, distance) } else if (engineView?.getInputResultDetail()?.isTouchHandlingUnknown() == false) { - // Force expand the toolbar if the user scrolled up, it is not already expanded and + // Force expand the view if the user scrolled up, it is not already expanded and // an animation to expand it is not already in progress, - // otherwise the user could get stuck in a state where they cannot show the toolbar + // otherwise the user could get stuck in a state where they cannot show the view // See https://github.com/mozilla-mobile/android-components/issues/7101 - yTranslator.forceExpandIfNotAlready(toolbar, distance) + yTranslator.forceExpandIfNotAlready(view, distance) } } } @@ -202,26 +201,26 @@ class BrowserToolbarBehavior( BrowserGestureDetector.GesturesListener( onVerticalScroll = ::tryToScrollVertically, onScaleBegin = { - // Scale shouldn't animate the toolbar but a small y translation is still possible + // Scale shouldn't animate the view but a small y translation is still possible // because of a previous scroll. Try to be swift about such an in progress animation. - yTranslator.snapImmediately(browserToolbar) + yTranslator.snapImmediately(dynamicScrollView) }, ), crashReporting = crashReporting, ) @VisibleForTesting - internal fun startNestedScroll(axes: Int, type: Int, toolbar: BrowserToolbar): Boolean { + internal fun startNestedScroll(axes: Int, type: Int, view: View): Boolean { return if (shouldScroll && axes == ViewCompat.SCROLL_AXIS_VERTICAL) { startedScroll = true shouldSnapAfterScroll = type == ViewCompat.TYPE_TOUCH yTranslator.cancelInProgressTranslation() true } else if (engineView?.getInputResultDetail()?.isTouchUnhandled() == true) { - // Force expand the toolbar if event is unhandled, otherwise user could get stuck in a - // state where they cannot show the toolbar + // Force expand the view if event is unhandled, otherwise user could get stuck in a + // state where they cannot show the view yTranslator.cancelInProgressTranslation() - yTranslator.expandWithAnimation(toolbar) + yTranslator.expandWithAnimation(view) false } else { false @@ -229,10 +228,10 @@ class BrowserToolbarBehavior( } @VisibleForTesting - internal fun stopNestedScroll(type: Int, toolbar: BrowserToolbar) { + internal fun stopNestedScroll(type: Int, view: View) { startedScroll = false if (shouldSnapAfterScroll || type == ViewCompat.TYPE_NON_TOUCH) { - yTranslator.snapWithAnimation(toolbar) + yTranslator.snapWithAnimation(view) } } } diff --git a/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategy.kt b/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategy.kt new file mode 100644 index 000000000000..8311f2d21a0c --- /dev/null +++ b/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategy.kt @@ -0,0 +1,189 @@ +/* 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 mozilla.components.ui.widgets.behavior + +import android.animation.ValueAnimator +import android.view.View +import android.view.animation.DecelerateInterpolator +import androidx.annotation.VisibleForTesting +import kotlin.math.max +import kotlin.math.min + +@VisibleForTesting +internal const val SNAP_ANIMATION_DURATION = 150L + +/** + * Helper class with methods for different behaviors for when translating a [View] on the Y axis. + */ +internal abstract class ViewYTranslationStrategy { + @VisibleForTesting + var animator = ValueAnimator().apply { + interpolator = DecelerateInterpolator() + duration = SNAP_ANIMATION_DURATION + } + + /** + * Snap the [View] to be collapsed or expanded, depending on whatever state is closer + * over a short amount of time. + */ + abstract fun snapWithAnimation(view: View) + + /** + * Snap the [View] to be collapsed or expanded, depending on whatever state is closer immediately. + */ + abstract fun snapImmediately(view: View?) + + /** + * Translate the [View] to it's full visible height. + */ + abstract fun expandWithAnimation(view: View) + + /** + * Force expanding the [View] depending on the [distance] value that should be translated + * cancelling any other translation already in progress. + */ + abstract fun forceExpandWithAnimation(view: View, distance: Float) + + /** + * Translate the [View] to it's full 0 visible height. + */ + abstract fun collapseWithAnimation(view: View) + + /** + * Translate [view] immediately to the specified [distance] amount (positive or negative). + */ + abstract fun translate(view: View, distance: Float) + + /** + * Translate [view] to the indicated [targetTranslationY] vaue over a short amount of time. + */ + open fun animateToTranslationY(view: View, targetTranslationY: Float) = with(animator) { + addUpdateListener { view.translationY = it.animatedValue as Float } + setFloatValues(view.translationY, targetTranslationY) + start() + } + + /** + * Cancel any translation animations currently in progress. + */ + fun cancelInProgressTranslation() = animator.cancel() +} + +/** + * Helper class containing methods for translating a [View] on the Y axis + * between 0 and [View.getHeight] + */ +internal class BottomViewBehaviorStrategy : ViewYTranslationStrategy() { + @VisibleForTesting + internal var wasLastExpanding = false + + override fun snapWithAnimation(view: View) { + if (view.translationY >= (view.height / 2f)) { + collapseWithAnimation(view) + } else { + expandWithAnimation(view) + } + } + + override fun snapImmediately(view: View?) { + if (animator.isStarted) { + animator.end() + } else { + view?.apply { + translationY = if (translationY >= height / 2) { + height.toFloat() + } else { + 0f + } + } + } + } + + override fun expandWithAnimation(view: View) { + animateToTranslationY(view, 0f) + } + + override fun forceExpandWithAnimation(view: View, distance: Float) { + val shouldExpandToolbar = distance < 0 + val isToolbarExpanded = view.translationY == 0f + if (shouldExpandToolbar && !isToolbarExpanded && !wasLastExpanding) { + animator.cancel() + expandWithAnimation(view) + } + } + + override fun collapseWithAnimation(view: View) { + animateToTranslationY(view, view.height.toFloat()) + } + + override fun translate(view: View, distance: Float) { + view.translationY = + max(0f, min(view.height.toFloat(), view.translationY + distance)) + } + + override fun animateToTranslationY(view: View, targetTranslationY: Float) { + wasLastExpanding = targetTranslationY <= view.translationY + super.animateToTranslationY(view, targetTranslationY) + } +} + +/** + * Helper class containing methods for translating a [View] on the Y axis + * between -[View.getHeight] and 0. + */ +internal class TopViewBehaviorStrategy : ViewYTranslationStrategy() { + @VisibleForTesting + internal var wasLastExpanding = false + + override fun snapWithAnimation(view: View) { + if (view.translationY >= -(view.height / 2f)) { + expandWithAnimation(view) + } else { + collapseWithAnimation(view) + } + } + + override fun snapImmediately(view: View?) { + if (animator.isStarted) { + animator.end() + } else { + view?.apply { + translationY = if (translationY >= -height / 2) { + 0f + } else { + -height.toFloat() + } + } + } + } + + override fun expandWithAnimation(view: View) { + animateToTranslationY(view, 0f) + } + + override fun forceExpandWithAnimation(view: View, distance: Float) { + val isExpandingInProgress = animator.isStarted && wasLastExpanding + val shouldExpandToolbar = distance < 0 + val isToolbarExpanded = view.translationY == 0f + if (shouldExpandToolbar && !isToolbarExpanded && !isExpandingInProgress) { + animator.cancel() + expandWithAnimation(view) + } + } + + override fun collapseWithAnimation(view: View) { + animateToTranslationY(view, -view.height.toFloat()) + } + + override fun translate(view: View, distance: Float) { + view.translationY = + min(0f, max(-view.height.toFloat(), view.translationY - distance)) + } + + override fun animateToTranslationY(view: View, targetTranslationY: Float) { + wasLastExpanding = targetTranslationY >= view.translationY + super.animateToTranslationY(view, targetTranslationY) + } +} diff --git a/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslator.kt b/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslator.kt new file mode 100644 index 000000000000..042b810b40ef --- /dev/null +++ b/android-components/components/ui/widgets/src/main/java/mozilla/components/ui/widgets/behavior/ViewYTranslator.kt @@ -0,0 +1,81 @@ +/* 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 mozilla.components.ui.widgets.behavior + +import android.view.View +import androidx.annotation.VisibleForTesting + +/** + * Helper class with methods for translating on the Y axis a top / bottom [View]. + * + * @param viewPosition whether the view is displayed immediately at the top of the screen or + * immediately at the bottom. This affects how it will be translated: + * - if place at the bottom it will be Y translated between 0 and [View.getHeight] + * - if place at the top it will be Y translated between -[View.getHeight] and 0 + */ +class ViewYTranslator(viewPosition: ViewPosition) { + @VisibleForTesting + internal var strategy = getTranslationStrategy(viewPosition) + + /** + * Snap the [View] to be collapsed or expanded, depending on whatever state is closer + * over a short amount of time. + */ + internal fun snapWithAnimation(view: View) { + strategy.snapWithAnimation(view) + } + + /** + * Snap the [View] to be collapsed or expanded, depending on whatever state is closer immediately. + */ + fun snapImmediately(view: View?) { + strategy.snapImmediately(view) + } + + /** + * Translate the [View] to it's full visible height over a short amount of time. + */ + internal fun expandWithAnimation(view: View) { + strategy.expandWithAnimation(view) + } + + /** + * Translate the [View] to be hidden from view over a short amount of time. + */ + internal fun collapseWithAnimation(view: View) { + strategy.collapseWithAnimation(view) + } + + /** + * Force expanding the [View] depending on the [distance] value that should be translated + * cancelling any other translation already in progress. + */ + fun forceExpandIfNotAlready(view: View, distance: Float) { + strategy.forceExpandWithAnimation(view, distance) + } + + /** + * Translate [view] immediately to the specified [distance] amount (positive or negative). + */ + fun translate(view: View, distance: Float) { + strategy.translate(view, distance) + } + + /** + * Cancel any translation animations currently in progress. + */ + fun cancelInProgressTranslation() { + strategy.cancelInProgressTranslation() + } + + @VisibleForTesting + internal fun getTranslationStrategy(viewPosition: ViewPosition): ViewYTranslationStrategy { + return if (viewPosition == ViewPosition.TOP) { + TopViewBehaviorStrategy() + } else { + BottomViewBehaviorStrategy() + } + } +} diff --git a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserGestureDetectorTest.kt b/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetectorTest.kt similarity index 99% rename from android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserGestureDetectorTest.kt rename to android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetectorTest.kt index 56847252da72..66c4b826ff7e 100644 --- a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserGestureDetectorTest.kt +++ b/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/BrowserGestureDetectorTest.kt @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package mozilla.components.browser.toolbar.behavior +package mozilla.components.ui.widgets.behavior import android.view.GestureDetector import android.view.MotionEvent diff --git a/android-components/components/feature/session/src/test/java/mozilla/components/feature/session/behavior/EngineViewBrowserToolbarBehaviorTest.kt b/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehaviorTest.kt similarity index 89% rename from android-components/components/feature/session/src/test/java/mozilla/components/feature/session/behavior/EngineViewBrowserToolbarBehaviorTest.kt rename to android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehaviorTest.kt index 3b8a8aaecb83..a589f90b5bf2 100644 --- a/android-components/components/feature/session/src/test/java/mozilla/components/feature/session/behavior/EngineViewBrowserToolbarBehaviorTest.kt +++ b/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewClippingBehaviorTest.kt @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package mozilla.components.feature.session.behavior +package mozilla.components.ui.widgets.behavior import android.content.Context import android.view.View @@ -24,7 +24,7 @@ import org.mockito.Mockito.spy import org.mockito.Mockito.verify @RunWith(AndroidJUnit4::class) -class EngineViewBrowserToolbarBehaviorTest { +class EngineViewClippingBehaviorTest { @Test fun `EngineView clipping and bottom toolbar offset are kept in sync`() { @@ -33,7 +33,7 @@ class EngineViewBrowserToolbarBehaviorTest { doReturn(100).`when`(toolbar).height doReturn(42f).`when`(toolbar).translationY - val behavior = EngineViewBrowserToolbarBehavior( + val behavior = EngineViewClippingBehavior( mock(), null, engineView.asView(), @@ -54,7 +54,7 @@ class EngineViewBrowserToolbarBehaviorTest { doReturn(100).`when`(toolbar).height doReturn(42f).`when`(toolbar).translationY - val behavior = EngineViewBrowserToolbarBehavior( + val behavior = EngineViewClippingBehavior( mock(), null, engineView.asView(), @@ -70,7 +70,7 @@ class EngineViewBrowserToolbarBehaviorTest { @Test fun `Behavior does not depend on normal views`() { - val behavior = EngineViewBrowserToolbarBehavior( + val behavior = EngineViewClippingBehavior( mock(), null, mock(), @@ -85,7 +85,7 @@ class EngineViewBrowserToolbarBehaviorTest { @Test fun `Behavior depends on BrowserToolbar`() { - val behavior = EngineViewBrowserToolbarBehavior( + val behavior = EngineViewClippingBehavior( mock(), null, mock(), @@ -99,7 +99,7 @@ class EngineViewBrowserToolbarBehaviorTest { @Test fun `GIVEN a bottom toolbar WHEN translation has below a half decimal THEN set vertical clipping with the floor value`() { val engineView: FakeEngineView = mock() - val behavior = EngineViewBrowserToolbarBehavior( + val behavior = EngineViewClippingBehavior( mock(), null, engineView, @@ -115,7 +115,7 @@ class EngineViewBrowserToolbarBehaviorTest { @Test fun `GIVEN a bottom toolbar WHEN translation has exactly half of a decimal THEN set vertical clipping with the ceiling value`() { val engineView: FakeEngineView = mock() - val behavior = EngineViewBrowserToolbarBehavior( + val behavior = EngineViewClippingBehavior( mock(), null, engineView, @@ -131,7 +131,7 @@ class EngineViewBrowserToolbarBehaviorTest { @Test fun `GIVEN a bottom toolbar WHEN translation has more than a half decimal THEN set vertical clipping with the ceiling value`() { val engineView: FakeEngineView = mock() - val behavior = EngineViewBrowserToolbarBehavior( + val behavior = EngineViewClippingBehavior( mock(), null, engineView, @@ -147,7 +147,7 @@ class EngineViewBrowserToolbarBehaviorTest { @Test fun `GIVEN a top toolbar WHEN translation has below a half decimal THEN set vertical clipping with the floor value`() { val engineView: FakeEngineView = mock() - val behavior = EngineViewBrowserToolbarBehavior( + val behavior = EngineViewClippingBehavior( mock(), null, engineView, @@ -163,7 +163,7 @@ class EngineViewBrowserToolbarBehaviorTest { @Test fun `GIVEN a top toolbar WHEN translation has exactly half of a decimal THEN set vertical clipping with the ceiling value`() { val engineView: FakeEngineView = mock() - val behavior = EngineViewBrowserToolbarBehavior( + val behavior = EngineViewClippingBehavior( mock(), null, engineView, @@ -179,7 +179,7 @@ class EngineViewBrowserToolbarBehaviorTest { @Test fun `GIVEN a top toolbar WHEN translation has more than a half decimal THEN set vertical clipping with the ceiling value`() { val engineView: FakeEngineView = mock() - val behavior = EngineViewBrowserToolbarBehavior( + val behavior = EngineViewClippingBehavior( mock(), null, engineView, @@ -199,7 +199,7 @@ class EngineViewBrowserToolbarBehaviorTest { doReturn(100).`when`(toolbar).height doReturn(Float.NaN).`when`(toolbar).translationY - val behavior = EngineViewBrowserToolbarBehavior( + val behavior = EngineViewClippingBehavior( mock(), null, engineView.asView(), diff --git a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarBehaviorTest.kt b/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehaviorTest.kt similarity index 74% rename from android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarBehaviorTest.kt rename to android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehaviorTest.kt index 6f8c427cad36..0f0c10b71ad4 100644 --- a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarBehaviorTest.kt +++ b/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/EngineViewScrollingBehaviorTest.kt @@ -2,17 +2,17 @@ * 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 mozilla.components.browser.toolbar.behavior +package mozilla.components.ui.widgets.behavior import android.content.Context import android.graphics.Bitmap import android.view.MotionEvent.ACTION_DOWN import android.view.MotionEvent.ACTION_MOVE +import android.view.View import android.widget.FrameLayout import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.ViewCompat import androidx.test.ext.junit.runners.AndroidJUnit4 -import mozilla.components.browser.toolbar.BrowserToolbar import mozilla.components.concept.engine.EngineSession import mozilla.components.concept.engine.EngineView import mozilla.components.concept.engine.INPUT_UNHANDLED @@ -35,13 +35,13 @@ import org.mockito.Mockito.verify import org.mockito.Mockito.`when` @RunWith(AndroidJUnit4::class) -class BrowserToolbarBehaviorTest { +class EngineViewScrollingBehaviorTest { @Test fun `onStartNestedScroll should attempt scrolling only if browserToolbar is valid`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) doReturn(true).`when`(behavior).shouldScroll - behavior.browserToolbar = null + behavior.dynamicScrollView = null var acceptsNestedScroll = behavior.onStartNestedScroll( coordinatorLayout = mock(), child = mock(), @@ -53,7 +53,7 @@ class BrowserToolbarBehaviorTest { assertFalse(acceptsNestedScroll) verify(behavior, never()).startNestedScroll(anyInt(), anyInt(), any()) - behavior.browserToolbar = mock() + behavior.dynamicScrollView = mock() acceptsNestedScroll = behavior.onStartNestedScroll( coordinatorLayout = mock(), child = mock(), @@ -68,15 +68,15 @@ class BrowserToolbarBehaviorTest { @Test fun `startNestedScroll should cancel an ongoing snap animation`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) - val yTranslator: BrowserToolbarYTranslator = mock() + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) + val yTranslator: ViewYTranslator = mock() behavior.yTranslator = yTranslator doReturn(true).`when`(behavior).shouldScroll val acceptsNestedScroll = behavior.startNestedScroll( axes = ViewCompat.SCROLL_AXIS_VERTICAL, type = ViewCompat.TYPE_TOUCH, - toolbar = mock(), + view = mock(), ) assertTrue(acceptsNestedScroll) @@ -85,30 +85,30 @@ class BrowserToolbarBehaviorTest { @Test fun `startNestedScroll should not accept nested scrolls on the horizontal axis`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) doReturn(true).`when`(behavior).shouldScroll var acceptsNestedScroll = behavior.startNestedScroll( axes = ViewCompat.SCROLL_AXIS_VERTICAL, type = ViewCompat.TYPE_TOUCH, - toolbar = mock(), + view = mock(), ) assertTrue(acceptsNestedScroll) acceptsNestedScroll = behavior.startNestedScroll( axes = ViewCompat.SCROLL_AXIS_HORIZONTAL, type = ViewCompat.TYPE_TOUCH, - toolbar = mock(), + view = mock(), ) assertFalse(acceptsNestedScroll) } @Test fun `GIVEN a gesture that doesn't scroll the toolbar WHEN startNestedScroll THEN toolbar is expanded and nested scroll not accepted`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) val engineView: EngineView = mock() val inputResultDetail: InputResultDetail = mock() - val yTranslator: BrowserToolbarYTranslator = mock() + val yTranslator: ViewYTranslator = mock() behavior.yTranslator = yTranslator doReturn(false).`when`(behavior).shouldScroll doReturn(true).`when`(inputResultDetail).isTouchUnhandled() @@ -118,7 +118,7 @@ class BrowserToolbarBehaviorTest { val acceptsNestedScroll = behavior.startNestedScroll( axes = ViewCompat.SCROLL_AXIS_VERTICAL, type = ViewCompat.TYPE_TOUCH, - toolbar = mock(), + view = mock(), ) verify(yTranslator).cancelInProgressTranslation() @@ -128,8 +128,8 @@ class BrowserToolbarBehaviorTest { @Test fun `Behavior should not accept nested scrolls on the horizontal axis`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) - behavior.browserToolbar = mock() + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) + behavior.dynamicScrollView = mock() doReturn(true).`when`(behavior).shouldScroll var acceptsNestedScroll = behavior.onStartNestedScroll( @@ -155,29 +155,29 @@ class BrowserToolbarBehaviorTest { @Test fun `Behavior should delegate the onStartNestedScroll logic`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) - val toolbar: BrowserToolbar = mock() - behavior.browserToolbar = toolbar + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) + val view: View = mock() + behavior.dynamicScrollView = view val inputType = ViewCompat.TYPE_TOUCH val axes = ViewCompat.SCROLL_AXIS_VERTICAL behavior.onStartNestedScroll( coordinatorLayout = mock(), - child = toolbar, + child = view, directTargetChild = mock(), target = mock(), axes = axes, type = inputType, ) - verify(behavior).startNestedScroll(axes, inputType, toolbar) + verify(behavior).startNestedScroll(axes, inputType, view) } @Test fun `onStopNestedScroll should attempt stopping nested scrolling only if browserToolbar is valid`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) - behavior.browserToolbar = null + behavior.dynamicScrollView = null behavior.onStopNestedScroll( coordinatorLayout = mock(), child = mock(), @@ -186,7 +186,7 @@ class BrowserToolbarBehaviorTest { ) verify(behavior, never()).stopNestedScroll(anyInt(), any()) - behavior.browserToolbar = mock() + behavior.dynamicScrollView = mock() behavior.onStopNestedScroll( coordinatorLayout = mock(), child = mock(), @@ -198,29 +198,29 @@ class BrowserToolbarBehaviorTest { @Test fun `Behavior should delegate the onStopNestedScroll logic`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) val inputType = ViewCompat.TYPE_TOUCH - val toolbar: BrowserToolbar = mock() + val view: View = mock() - behavior.browserToolbar = null + behavior.dynamicScrollView = null behavior.onStopNestedScroll( coordinatorLayout = mock(), - child = toolbar, + child = view, target = mock(), type = inputType, ) - verify(behavior, never()).stopNestedScroll(inputType, toolbar) + verify(behavior, never()).stopNestedScroll(inputType, view) } @Test fun `stopNestedScroll will snap toolbar up if toolbar is more than 50 percent visible`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) - val yTranslator: BrowserToolbarYTranslator = mock() + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) + val yTranslator: ViewYTranslator = mock() behavior.yTranslator = yTranslator - behavior.browserToolbar = mock() + behavior.dynamicScrollView = mock() doReturn(true).`when`(behavior).shouldScroll - val child = mock() + val child = mock() doReturn(100).`when`(child).height doReturn(10f).`when`(child).translationY @@ -245,13 +245,13 @@ class BrowserToolbarBehaviorTest { @Test fun `stopNestedScroll will snap toolbar down if toolbar is less than 50 percent visible`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) doReturn(true).`when`(behavior).shouldScroll - val yTranslator: BrowserToolbarYTranslator = mock() + val yTranslator: ViewYTranslator = mock() behavior.yTranslator = yTranslator - val child = mock() - behavior.browserToolbar = child + val child = mock() + behavior.dynamicScrollView = child doReturn(100).`when`(child).height doReturn(90f).`when`(child).translationY @@ -276,8 +276,8 @@ class BrowserToolbarBehaviorTest { @Test fun `onStopNestedScroll should snap the toolbar only if browserToolbar is valid`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) - behavior.browserToolbar = null + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) + behavior.dynamicScrollView = null behavior.onStopNestedScroll( coordinatorLayout = mock(), @@ -291,10 +291,10 @@ class BrowserToolbarBehaviorTest { @Test fun `Behavior will intercept MotionEvents and pass them to the custom gesture detector`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) val gestureDetector: BrowserGestureDetector = mock() behavior.initGesturesDetector(gestureDetector) - behavior.browserToolbar = mock() + behavior.dynamicScrollView = mock() val downEvent = TestUtils.getMotionEvent(ACTION_DOWN) behavior.onInterceptTouchEvent(mock(), mock(), downEvent) @@ -304,7 +304,7 @@ class BrowserToolbarBehaviorTest { @Test fun `Behavior should only dispatch MotionEvents to the gesture detector only if browserToolbar is valid`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) val gestureDetector: BrowserGestureDetector = mock() behavior.initGesturesDetector(gestureDetector) val downEvent = TestUtils.getMotionEvent(ACTION_DOWN) @@ -316,10 +316,10 @@ class BrowserToolbarBehaviorTest { @Test fun `Behavior will apply translation to toolbar only for vertical scrolls`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) behavior.initGesturesDetector(behavior.createGestureDetector()) - val child = spy(BrowserToolbar(testContext, null, 0)) - behavior.browserToolbar = child + val child = spy(View(testContext, null, 0)) + behavior.dynamicScrollView = child val downEvent = TestUtils.getMotionEvent(ACTION_DOWN, 0f, 0f) val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, 0f, 100f, downEvent) @@ -331,7 +331,7 @@ class BrowserToolbarBehaviorTest { @Test fun `GIVEN a null InputResultDetail from the EngineView WHEN shouldScroll is called THEN it returns false`() { - val behavior = BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM) + val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM) behavior.engineView = null assertFalse(behavior.shouldScroll) behavior.engineView = mock() @@ -342,7 +342,7 @@ class BrowserToolbarBehaviorTest { @Test fun `GIVEN an InputResultDetail with the right values and scroll enabled WHEN shouldScroll is called THEN it returns true`() { - val behavior = BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM) + val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM) val engineView: EngineView = mock() behavior.engineView = engineView behavior.isScrollEnabled = true @@ -364,7 +364,7 @@ class BrowserToolbarBehaviorTest { @Test fun `GIVEN an InputResultDetail with the right values but with scroll disabled WHEN shouldScroll is called THEN it returns false`() { - val behavior = BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM) + val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM) behavior.engineView = mock() behavior.isScrollEnabled = false val validInputResultDetail: InputResultDetail = mock() @@ -376,7 +376,7 @@ class BrowserToolbarBehaviorTest { @Test fun `GIVEN scroll enabled but EngineView cannot scroll to bottom WHEN shouldScroll is called THEN it returns false`() { - val behavior = BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM) + val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM) behavior.engineView = mock() behavior.isScrollEnabled = true val validInputResultDetail: InputResultDetail = mock() @@ -388,7 +388,7 @@ class BrowserToolbarBehaviorTest { @Test fun `GIVEN scroll enabled but EngineView cannot scroll to top WHEN shouldScroll is called THEN it returns false`() { - val behavior = BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM) + val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM) behavior.engineView = mock() behavior.isScrollEnabled = true val validInputResultDetail: InputResultDetail = mock() @@ -400,12 +400,12 @@ class BrowserToolbarBehaviorTest { @Test fun `Behavior will vertically scroll nested scroll started and EngineView handled the event`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) - val yTranslator: BrowserToolbarYTranslator = mock() + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) + val yTranslator: ViewYTranslator = mock() behavior.yTranslator = yTranslator doReturn(true).`when`(behavior).shouldScroll - val child = spy(BrowserToolbar(testContext, null, 0)) - behavior.browserToolbar = child + val child = spy(View(testContext, null, 0)) + behavior.dynamicScrollView = child doReturn(100).`when`(child).height doReturn(0f).`when`(child).translationY behavior.startedScroll = true @@ -417,12 +417,12 @@ class BrowserToolbarBehaviorTest { @Test fun `Behavior will not scroll vertically if startedScroll is false`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) - val yTranslator: BrowserToolbarYTranslator = mock() + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) + val yTranslator: ViewYTranslator = mock() behavior.yTranslator = yTranslator doReturn(true).`when`(behavior).shouldScroll - val child = spy(BrowserToolbar(testContext, null, 0)) - behavior.browserToolbar = child + val child = spy(View(testContext, null, 0)) + behavior.dynamicScrollView = child doReturn(100).`when`(child).height doReturn(0f).`when`(child).translationY behavior.startedScroll = false @@ -434,12 +434,12 @@ class BrowserToolbarBehaviorTest { @Test fun `Behavior will not scroll vertically if EngineView did not handled the event`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) - val yTranslator: BrowserToolbarYTranslator = mock() + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) + val yTranslator: ViewYTranslator = mock() behavior.yTranslator = yTranslator doReturn(false).`when`(behavior).shouldScroll - val child = spy(BrowserToolbar(testContext, null, 0)) - behavior.browserToolbar = child + val child = spy(View(testContext, null, 0)) + behavior.dynamicScrollView = child doReturn(100).`when`(child).height doReturn(0f).`when`(child).translationY @@ -450,43 +450,43 @@ class BrowserToolbarBehaviorTest { @Test fun `forceExpand should delegate the translator`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) - val yTranslator: BrowserToolbarYTranslator = mock() + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) + val yTranslator: ViewYTranslator = mock() behavior.yTranslator = yTranslator - val toolbar: BrowserToolbar = mock() + val view: View = mock() - behavior.forceExpand(toolbar) + behavior.forceExpand(view) - verify(yTranslator).expandWithAnimation(toolbar) + verify(yTranslator).expandWithAnimation(view) } @Test fun `forceCollapse should delegate the translator`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) - val yTranslator: BrowserToolbarYTranslator = mock() + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) + val yTranslator: ViewYTranslator = mock() behavior.yTranslator = yTranslator - val toolbar: BrowserToolbar = mock() + val view: View = mock() - behavior.forceCollapse(toolbar) + behavior.forceCollapse(view) - verify(yTranslator).collapseWithAnimation(toolbar) + verify(yTranslator).collapseWithAnimation(view) } @Test fun `Behavior will forceExpand when scrolling up and !shouldScroll if the touch was handled in the browser`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) - val yTranslator: BrowserToolbarYTranslator = mock() + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) + val yTranslator: ViewYTranslator = mock() behavior.yTranslator = yTranslator behavior.initGesturesDetector(behavior.createGestureDetector()) - val toolbar: BrowserToolbar = spy(BrowserToolbar(testContext, null, 0)) - behavior.browserToolbar = toolbar + val view: View = spy(View(testContext, null, 0)) + behavior.dynamicScrollView = view val engineView: EngineView = mock() behavior.engineView = engineView val handledTouchInput = InputResultDetail.newInstance().copy(INPUT_UNHANDLED) doReturn(handledTouchInput).`when`(engineView).getInputResultDetail() - doReturn(100).`when`(toolbar).height - doReturn(100f).`when`(toolbar).translationY + doReturn(100).`when`(view).height + doReturn(100f).`when`(view).translationY val downEvent = TestUtils.getMotionEvent(ACTION_DOWN, 0f, 0f) val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, 0f, 30f, downEvent) @@ -495,24 +495,24 @@ class BrowserToolbarBehaviorTest { behavior.onInterceptTouchEvent(mock(), mock(), moveEvent) verify(behavior).tryToScrollVertically(-30f) - verify(yTranslator).forceExpandIfNotAlready(toolbar, -30f) + verify(yTranslator).forceExpandIfNotAlready(view, -30f) } @Test fun `Behavior will not forceExpand when scrolling up and !shouldScroll if the touch was not yet handled in the browser`() { - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) - val yTranslator: BrowserToolbarYTranslator = mock() + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) + val yTranslator: ViewYTranslator = mock() behavior.yTranslator = yTranslator behavior.initGesturesDetector(behavior.createGestureDetector()) - val toolbar: BrowserToolbar = spy(BrowserToolbar(testContext, null, 0)) - behavior.browserToolbar = toolbar + val view: View = spy(View(testContext, null, 0)) + behavior.dynamicScrollView = view val engineView: EngineView = mock() behavior.engineView = engineView val handledTouchInput = InputResultDetail.newInstance() doReturn(handledTouchInput).`when`(engineView).getInputResultDetail() - doReturn(100).`when`(toolbar).height - doReturn(100f).`when`(toolbar).translationY + doReturn(100).`when`(view).height + doReturn(100f).`when`(view).translationY val downEvent = TestUtils.getMotionEvent(ACTION_DOWN, 0f, 0f) val moveEvent = TestUtils.getMotionEvent(ACTION_MOVE, 0f, 30f, downEvent) @@ -521,28 +521,28 @@ class BrowserToolbarBehaviorTest { behavior.onInterceptTouchEvent(mock(), mock(), moveEvent) verify(behavior).tryToScrollVertically(-30f) - verify(yTranslator, never()).forceExpandIfNotAlready(toolbar, -30f) + verify(yTranslator, never()).forceExpandIfNotAlready(view, -30f) } @Test fun `onLayoutChild initializes browserToolbar and engineView`() { - val toolbarView = BrowserToolbar(testContext) + val view = View(testContext) val engineView = createDummyEngineView(testContext).asView() val container = CoordinatorLayout(testContext).apply { - addView(BrowserToolbar(testContext)) + addView(View(testContext)) addView(engineView) } - val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)) + val behavior = spy(EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM)) - behavior.onLayoutChild(container, toolbarView, ViewCompat.LAYOUT_DIRECTION_LTR) + behavior.onLayoutChild(container, view, ViewCompat.LAYOUT_DIRECTION_LTR) - assertEquals(toolbarView, behavior.browserToolbar) + assertEquals(view, behavior.dynamicScrollView) assertEquals(engineView, behavior.engineView) } @Test fun `enableScrolling sets isScrollEnabled to true`() { - val behavior = BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM) + val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM) assertFalse(behavior.isScrollEnabled) behavior.enableScrolling() @@ -552,7 +552,7 @@ class BrowserToolbarBehaviorTest { @Test fun `disableScrolling sets isScrollEnabled to false`() { - val behavior = BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM) + val behavior = EngineViewScrollingBehavior(testContext, null, ViewPosition.BOTTOM) behavior.isScrollEnabled = true assertTrue(behavior.isScrollEnabled) diff --git a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/TestUtils.kt b/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/TestUtils.kt similarity index 93% rename from android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/TestUtils.kt rename to android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/TestUtils.kt index d08b38729c6c..2e5bbaa9dfd4 100644 --- a/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/TestUtils.kt +++ b/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/TestUtils.kt @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package mozilla.components.browser.toolbar.behavior +package mozilla.components.ui.widgets.behavior import android.view.MotionEvent @@ -23,7 +23,7 @@ object TestUtils { pointerCount = 1 } - val properties = Array(pointerCount, ::getPointerProperties) + val properties = Array(pointerCount, TestUtils::getPointerProperties) val pointerCoords = getPointerCoords(x, y, pointerCount) return MotionEvent.obtain( diff --git a/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategyTest.kt b/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategyTest.kt new file mode 100644 index 000000000000..62d152f7f602 --- /dev/null +++ b/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslationStrategyTest.kt @@ -0,0 +1,712 @@ +/* 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 mozilla.components.ui.widgets.behavior + +import android.animation.ValueAnimator +import android.view.View +import android.view.animation.DecelerateInterpolator +import androidx.test.ext.junit.runners.AndroidJUnit4 +import mozilla.components.support.test.any +import mozilla.components.support.test.mock +import mozilla.components.support.test.robolectric.testContext +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.doReturn +import org.mockito.Mockito.never +import org.mockito.Mockito.spy +import org.mockito.Mockito.times +import org.mockito.Mockito.verify + +@RunWith(AndroidJUnit4::class) +class ViewYTranslationStrategyTest { + @Test + fun `snapAnimator should use a DecelerateInterpolator with SNAP_ANIMATION_DURATION for bottom toolbar translations`() { + val strategy = BottomViewBehaviorStrategy() + + assertTrue(strategy.animator.interpolator is DecelerateInterpolator) + assertEquals(SNAP_ANIMATION_DURATION, strategy.animator.duration) + } + + @Test + fun `snapAnimator should use a DecelerateInterpolator with SNAP_ANIMATION_DURATION for top toolbar translations`() { + val strategy = TopViewBehaviorStrategy() + + assertTrue(strategy.animator.interpolator is DecelerateInterpolator) + assertEquals(SNAP_ANIMATION_DURATION, strategy.animator.duration) + } + + @Test + fun `BottomToolbarBehaviorStrategy should start with isToolbarExpanding = false`() { + val strategy = BottomViewBehaviorStrategy() + + assertFalse(strategy.wasLastExpanding) + } + + @Test + fun `TopToolbarBehaviorStrategy should start with isToolbarExpanding = false`() { + val strategy = TopViewBehaviorStrategy() + + assertFalse(strategy.wasLastExpanding) + } + + @Test + fun `BottomToolbarBehaviorStrategy - snapWithAnimation should collapse toolbar if more than half hidden`() { + val strategy = spy(BottomViewBehaviorStrategy()) + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(50f).`when`(view).translationY + strategy.snapWithAnimation(view) + + doReturn(51f).`when`(view).translationY + strategy.snapWithAnimation(view) + + doReturn(100f).`when`(view).translationY + strategy.snapWithAnimation(view) + + doReturn(333f).`when`(view).translationY + strategy.snapWithAnimation(view) + + verify(strategy, times(4)).collapseWithAnimation(view) + verify(strategy, never()).expandWithAnimation(view) + } + + @Test + fun `BottomToolbarBehaviorStrategy - snapWithAnimation should expand toolbar if more than half visible`() { + val strategy = spy(BottomViewBehaviorStrategy()) + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(49f).`when`(view).translationY + strategy.snapWithAnimation(view) + + doReturn(0f).`when`(view).translationY + strategy.snapWithAnimation(view) + + doReturn(-50f).`when`(view).translationY + strategy.snapWithAnimation(view) + + verify(strategy, times(3)).expandWithAnimation(view) + verify(strategy, never()).collapseWithAnimation(view) + } + + @Test + fun `TopToolbarBehaviorStrategy - snapWithAnimation should collapse toolbar if more than half hidden`() { + val strategy = spy(TopViewBehaviorStrategy()) + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(-51f).`when`(view).translationY + strategy.snapWithAnimation(view) + + doReturn(-100f).`when`(view).translationY + strategy.snapWithAnimation(view) + + doReturn(-333f).`when`(view).translationY + strategy.snapWithAnimation(view) + + verify(strategy, times(3)).collapseWithAnimation(view) + verify(strategy, never()).expandWithAnimation(view) + } + + @Test + fun `TopToolbarBehaviorStrategy - snapWithAnimation should expand toolbar if more than half visible`() { + val strategy = spy(TopViewBehaviorStrategy()) + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(-50f).`when`(view).translationY + strategy.snapWithAnimation(view) + + doReturn(-49f).`when`(view).translationY + strategy.snapWithAnimation(view) + + doReturn(0f).`when`(view).translationY + strategy.snapWithAnimation(view) + + doReturn(50f).`when`(view).translationY + strategy.snapWithAnimation(view) + + verify(strategy, times(4)).expandWithAnimation(view) + verify(strategy, never()).collapseWithAnimation(view) + } + + @Test + fun `BottomToolbarBehaviorStrategy - snapImmediately should end translations animations if in progress`() { + val strategy = spy(BottomViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(true).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + + strategy.snapImmediately(view) + + verify(animator).end() + verify(view, never()).translationY + } + + @Test + fun `BottomToolbarBehaviorStrategy - snapImmediately should translate away the toolbar if half translated`() { + val strategy = spy(BottomViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(50f).`when`(view).translationY + strategy.snapImmediately(view) + verify(view).translationY = 100f + } + + @Test + fun `BottomToolbarBehaviorStrategy - snapImmediately should translate away the toolbar if more than half`() { + val strategy = spy(BottomViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(55f).`when`(view).translationY + strategy.snapImmediately(view) + verify(view).translationY = 100f + } + + @Test + fun `BottomToolbarBehaviorStrategy - snapImmediately should translate away the toolbar if translated off screen`() { + val strategy = spy(BottomViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(555f).`when`(view).translationY + strategy.snapImmediately(view) + verify(view).translationY = 100f + } + + @Test + fun `BottomToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated less than half`() { + val strategy = spy(BottomViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(49f).`when`(view).translationY + strategy.snapImmediately(view) + verify(view).translationY = 0f + } + + @Test + fun `BottomToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated 0`() { + val strategy = spy(BottomViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(0f).`when`(view).translationY + strategy.snapImmediately(view) + verify(view).translationY = 0f + } + + @Test + fun `BottomToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated inside the screen`() { + val strategy = spy(BottomViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(-1f).`when`(view).translationY + strategy.snapImmediately(view) + verify(view).translationY = 0f + } + + @Test + fun `TopToolbarBehaviorStrategy - snapImmediately should end translations animations if in progress`() { + val strategy = spy(TopViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(true).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + + strategy.snapImmediately(view) + + verify(animator).end() + verify(view, never()).translationY + } + + @Test + fun `TopToolbarBehaviorStrategy - snapImmediately should translate translate to 0 the toolbar if translated less than half`() { + val strategy = spy(TopViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(-49f).`when`(view).translationY + strategy.snapImmediately(view) + verify(view).translationY = 0f + } + + @Test + fun `TopToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated 0`() { + val strategy = spy(TopViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(0f).`when`(view).translationY + strategy.snapImmediately(view) + verify(view).translationY = 0f + } + + @Test + fun `TopToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated inside the screen`() { + val strategy = spy(TopViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(1f).`when`(view).translationY + strategy.snapImmediately(view) + verify(view).translationY = 0f + } + + @Test + fun `TopToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if half translated`() { + val strategy = spy(TopViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(-50f).`when`(view).translationY + strategy.snapImmediately(view) + verify(view).translationY = 0f + } + + @Test + fun `TopToolbarBehaviorStrategy - snapImmediately should translate away the toolbar if more than half translated`() { + val strategy = spy(TopViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(-55f).`when`(view).translationY + strategy.snapImmediately(view) + verify(view).translationY = -100f + } + + @Test + fun `TopToolbarBehaviorStrategy - snapImmediately should translate to 0 the toolbar if translated offscreen`() { + val strategy = spy(TopViewBehaviorStrategy()) + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100).`when`(view).height + + doReturn(-111f).`when`(view).translationY + strategy.snapImmediately(view) + verify(view).translationY = -100f + } + + @Test + fun `BottomToolbarBehaviorStrategy - expandWithAnimation should translate the toolbar to to y 0`() { + val strategy = spy(BottomViewBehaviorStrategy()) + val view: View = mock() + + strategy.expandWithAnimation(view) + + verify(strategy).animateToTranslationY(view, 0f) + } + + @Test + fun `TopToolbarBehaviorStrategy - expandWithAnimation should translate the toolbar to to y 0`() { + val strategy = spy(TopViewBehaviorStrategy()) + val view: View = mock() + + strategy.expandWithAnimation(view) + + verify(strategy).animateToTranslationY(view, 0f) + } + + @Test + fun `BottomToolbarBehaviorStrategy - forceExpandWithAnimation should expand toolbar`() { + // Setting the scenario in which forceExpandWithAnimation will actually do what the name says. + // Below this test we can change each variable one at a time to test them in isolation. + + val strategy = spy(BottomViewBehaviorStrategy()) + strategy.wasLastExpanding = false + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100f).`when`(view).translationY + + strategy.forceExpandWithAnimation(view, -100f) + + verify(strategy.animator).cancel() + verify(strategy).expandWithAnimation(any()) + } + + @Test + fun `BottomToolbarBehaviorStrategy - forceExpandWithAnimation should not force expand the toolbar if not currently collapsing`() { + val strategy = spy(BottomViewBehaviorStrategy()) + strategy.wasLastExpanding = true + val animator: ValueAnimator = mock() + doReturn(true).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100f).`when`(view).translationY + + strategy.forceExpandWithAnimation(view, -100f) + + verify(strategy.animator, never()).cancel() + verify(strategy, never()).expandWithAnimation(any()) + } + + @Test + fun `BottomToolbarBehaviorStrategy - forceExpandWithAnimation should not expand if user swipes down`() { + val strategy = spy(BottomViewBehaviorStrategy()) + strategy.wasLastExpanding = false + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(100f).`when`(view).translationY + + strategy.forceExpandWithAnimation(view, 100f) + + verify(strategy.animator, never()).cancel() + verify(strategy, never()).expandWithAnimation(any()) + } + + @Test + fun `BottomToolbarBehaviorStrategy - forceExpandWithAnimation should not expand the toolbar if it is already expanded`() { + val strategy = spy(BottomViewBehaviorStrategy()) + strategy.wasLastExpanding = false + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(0f).`when`(view).translationY + + strategy.forceExpandWithAnimation(view, -100f) + + verify(strategy.animator, never()).cancel() + verify(strategy, never()).expandWithAnimation(any()) + } + + @Test + fun `TopToolbarBehaviorStrategy - forceExpandWithAnimation should expand toolbar`() { + // Setting the scenario in which forceExpandWithAnimation will actually do what the name says. + // Below this test we can change each variable one at a time to test them in isolation. + + val strategy = spy(TopViewBehaviorStrategy()) + strategy.wasLastExpanding = false + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(-100f).`when`(view).translationY + + strategy.forceExpandWithAnimation(view, -100f) + + verify(strategy.animator).cancel() + verify(strategy).expandWithAnimation(any()) + } + + @Test + fun `TopToolbarBehaviorStrategy - forceExpandWithAnimation should not force expand the toolbar if not currently collapsing`() { + val strategy = spy(TopViewBehaviorStrategy()) + strategy.wasLastExpanding = true + val animator: ValueAnimator = mock() + doReturn(true).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(-100f).`when`(view).translationY + + strategy.forceExpandWithAnimation(view, -100f) + + verify(strategy.animator, never()).cancel() + verify(strategy, never()).expandWithAnimation(any()) + } + + @Test + fun `TopToolbarBehaviorStrategy - forceExpandWithAnimation should not expand if user swipes up`() { + val strategy = spy(TopViewBehaviorStrategy()) + strategy.wasLastExpanding = false + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(-100f).`when`(view).translationY + + strategy.forceExpandWithAnimation(view, 10f) + + verify(strategy.animator, never()).cancel() + verify(strategy, never()).expandWithAnimation(any()) + } + + @Test + fun `TopToolbarBehaviorStrategy - forceExpandWithAnimation should not expand the toolbar if it is already expanded`() { + val strategy = spy(TopViewBehaviorStrategy()) + strategy.wasLastExpanding = false + val animator: ValueAnimator = mock() + doReturn(false).`when`(animator).isStarted + strategy.animator = animator + val view: View = mock() + doReturn(0f).`when`(view).translationY + + strategy.forceExpandWithAnimation(view, -100f) + + verify(strategy.animator, never()).cancel() + verify(strategy, never()).expandWithAnimation(any()) + } + + @Test + fun `BottomToolbarBehaviorStrategy - collapseWithAnimation should animate translating the toolbar down, off-screen`() { + val strategy = spy(BottomViewBehaviorStrategy()) + val view: View = mock() + doReturn(100).`when`(view).height + + strategy.collapseWithAnimation(view) + + verify(strategy).animateToTranslationY(view, 100f) + } + + @Test + fun `TopToolbarBehaviorStrategy - collapseWithAnimation should animate translating the toolbar up, off-screen`() { + val strategy = spy(TopViewBehaviorStrategy()) + val view: View = mock() + doReturn(100).`when`(view).height + + strategy.collapseWithAnimation(view) + + verify(strategy).animateToTranslationY(view, -100f) + } + + @Test + fun `BottomToolbarBehaviorStrategy - translate should translate up the toolbar with the distance parameter`() { + val strategy = BottomViewBehaviorStrategy() + val view: View = mock() + doReturn(100).`when`(view).height + doReturn(50f).`when`(view).translationY + + strategy.translate(view, -25f) + + verify(view).translationY = 25f + } + + @Test + fun `BottomToolbarBehaviorStrategy - translate should translate down the toolbar with the distance parameter`() { + val strategy = BottomViewBehaviorStrategy() + val view: View = mock() + doReturn(100).`when`(view).height + doReturn(50f).`when`(view).translationY + + strategy.translate(view, 25f) + + verify(view).translationY = 75f + } + + @Test + fun `BottomToolbarBehaviorStrategy - translate should not translate up the toolbar if already expanded`() { + val strategy = BottomViewBehaviorStrategy() + val view: View = mock() + doReturn(100).`when`(view).height + doReturn(0f).`when`(view).translationY + + strategy.translate(view, -1f) + + verify(view).translationY = 0f + } + + @Test + fun `BottomToolbarBehaviorStrategy - translate should not translate up the toolbar more than to 0`() { + val strategy = BottomViewBehaviorStrategy() + val view: View = mock() + doReturn(100).`when`(view).height + doReturn(50f).`when`(view).translationY + + strategy.translate(view, -51f) + + verify(view).translationY = 0f + } + + @Test + fun `BottomToolbarBehaviorStrategy - translate should not translate down the toolbar if already collapsed`() { + val strategy = BottomViewBehaviorStrategy() + val view: View = mock() + doReturn(100).`when`(view).height + doReturn(100f).`when`(view).translationY + + strategy.translate(view, 1f) + + verify(view).translationY = 100f + } + + @Test + fun `BottomToolbarBehaviorStrategy - translate should not translate down the toolbar more than it's height`() { + val strategy = BottomViewBehaviorStrategy() + val view: View = mock() + doReturn(100).`when`(view).height + doReturn(50f).`when`(view).translationY + + strategy.translate(view, 51f) + + verify(view).translationY = 100f + } + + @Test + fun `TopToolbarBehaviorStrategy - translate should translate down the toolbar with the distance parameter`() { + val strategy = TopViewBehaviorStrategy() + val view: View = mock() + doReturn(100).`when`(view).height + doReturn(-50f).`when`(view).translationY + + strategy.translate(view, 25f) + + verify(view).translationY = -75f + } + + @Test + fun `TopToolbarBehaviorStrategy - translate should translate up the toolbar with the distance parameter`() { + val strategy = TopViewBehaviorStrategy() + val view: View = mock() + doReturn(100).`when`(view).height + doReturn(-50f).`when`(view).translationY + + strategy.translate(view, 25f) + + verify(view).translationY = -75f + } + + @Test + fun `TopToolbarBehaviorStrategy - translate should not translate down the toolbar if already expanded`() { + val strategy = TopViewBehaviorStrategy() + val view: View = mock() + doReturn(100).`when`(view).height + doReturn(0f).`when`(view).translationY + + strategy.translate(view, -1f) + + verify(view).translationY = 0f + } + + @Test + fun `TopToolbarBehaviorStrategy - translate should not translate down the toolbar more than to 0`() { + val strategy = TopViewBehaviorStrategy() + val view: View = mock() + doReturn(100).`when`(view).height + doReturn(-50f).`when`(view).translationY + + strategy.translate(view, -51f) + + verify(view).translationY = 0f + } + + @Test + fun `TopToolbarBehaviorStrategy - translate should not translate up the toolbar if already collapsed`() { + val strategy = TopViewBehaviorStrategy() + val view: View = mock() + doReturn(100).`when`(view).height + doReturn(-100f).`when`(view).translationY + + strategy.translate(view, 1f) + + verify(view).translationY = -100f + } + + @Test + fun `TopToolbarBehaviorStrategy - translate should not translate up the toolbar more than it's height`() { + val strategy = TopViewBehaviorStrategy() + val view: View = mock() + doReturn(100).`when`(view).height + doReturn(-50f).`when`(view).translationY + + strategy.translate(view, 51f) + + verify(view).translationY = -100f + } + + @Test + fun `BottomToolbarBehaviorStrategy - animateToTranslationY should set wasLastExpanding if expanding`() { + val strategy = BottomViewBehaviorStrategy() + strategy.wasLastExpanding = false + val view: View = mock() + doReturn(50f).`when`(view).translationY + + strategy.animateToTranslationY(view, 10f) + assertTrue(strategy.wasLastExpanding) + + strategy.animateToTranslationY(view, 60f) + assertFalse(strategy.wasLastExpanding) + } + + @Test + fun `BottomToolbarBehaviorStrategy - animateToTranslationY should animate to the indicated y translation`() { + val strategy = spy(BottomViewBehaviorStrategy()) + strategy.wasLastExpanding = false + val view = View(testContext) + val animator: ValueAnimator = spy(strategy.animator) + strategy.animator = animator + + strategy.animateToTranslationY(view, 10f) + + verify(animator).start() + animator.end() + assertEquals(10f, view.translationY) + } + + @Test + fun `TopToolbarBehaviorStrategy - animateToTranslationY should set wasLastExpanding if expanding`() { + val strategy = TopViewBehaviorStrategy() + strategy.wasLastExpanding = false + val view: View = mock() + doReturn(-50f).`when`(view).translationY + + strategy.animateToTranslationY(view, -10f) + assertTrue(strategy.wasLastExpanding) + + strategy.animateToTranslationY(view, -60f) + assertFalse(strategy.wasLastExpanding) + } + + @Test + fun `TopToolbarBehaviorStrategy - animateToTranslationY should animate to the indicated y translation`() { + val strategy = spy(TopViewBehaviorStrategy()) + strategy.wasLastExpanding = false + val view = View(testContext) + val animator: ValueAnimator = spy(strategy.animator) + strategy.animator = animator + + strategy.animateToTranslationY(view, -10f) + + verify(animator).start() + animator.end() + assertEquals(-10f, view.translationY) + } +} diff --git a/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslatorTest.kt b/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslatorTest.kt new file mode 100644 index 000000000000..6a3a908adc55 --- /dev/null +++ b/android-components/components/ui/widgets/src/test/java/mozilla/components/ui/widgets/behavior/ViewYTranslatorTest.kt @@ -0,0 +1,113 @@ +/* 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 mozilla.components.ui.widgets.behavior + +import android.view.View +import androidx.test.ext.junit.runners.AndroidJUnit4 +import mozilla.components.support.test.mock +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.verify + +@RunWith(AndroidJUnit4::class) +class ViewYTranslatorTest { + @Test + fun `yTranslator should use BottomToolbarBehaviorStrategy for bottom placed toolbars`() { + val yTranslator = ViewYTranslator(ViewPosition.BOTTOM) + + assertTrue(yTranslator.strategy is BottomViewBehaviorStrategy) + } + + @Test + fun `yTranslator should use TopToolbarBehaviorStrategy for top placed toolbars`() { + val yTranslator = ViewYTranslator(ViewPosition.TOP) + + assertTrue(yTranslator.strategy is TopViewBehaviorStrategy) + } + + @Test + fun `yTranslator should delegate it's strategy for snapWithAnimation`() { + val yTranslator = ViewYTranslator(ViewPosition.BOTTOM) + val strategy: ViewYTranslationStrategy = mock() + yTranslator.strategy = strategy + val view: View = mock() + + yTranslator.snapWithAnimation(view) + + verify(strategy).snapWithAnimation(view) + } + + @Test + fun `yTranslator should delegate it's strategy for expandWithAnimation`() { + val yTranslator = ViewYTranslator(ViewPosition.BOTTOM) + val strategy: ViewYTranslationStrategy = mock() + yTranslator.strategy = strategy + val view: View = mock() + + yTranslator.expandWithAnimation(view) + + verify(strategy).expandWithAnimation(view) + } + + @Test + fun `yTranslator should delegate it's strategy for collapseWithAnimation`() { + val yTranslator = ViewYTranslator(ViewPosition.BOTTOM) + val strategy: ViewYTranslationStrategy = mock() + yTranslator.strategy = strategy + val view: View = mock() + + yTranslator.collapseWithAnimation(view) + + verify(strategy).collapseWithAnimation(view) + } + + @Test + fun `yTranslator should delegate it's strategy for forceExpandIfNotAlready`() { + val yTranslator = ViewYTranslator(ViewPosition.BOTTOM) + val strategy: ViewYTranslationStrategy = mock() + yTranslator.strategy = strategy + val view: View = mock() + + yTranslator.forceExpandIfNotAlready(view, 14f) + + verify(strategy).forceExpandWithAnimation(view, 14f) + } + + @Test + fun `yTranslator should delegate it's strategy for translate`() { + val yTranslator = ViewYTranslator(ViewPosition.BOTTOM) + val strategy: ViewYTranslationStrategy = mock() + yTranslator.strategy = strategy + val view: View = mock() + + yTranslator.translate(view, 23f) + + verify(strategy).translate(view, 23f) + } + + @Test + fun `yTranslator should delegate it's strategy for cancelInProgressTranslation`() { + val yTranslator = ViewYTranslator(ViewPosition.BOTTOM) + val strategy: ViewYTranslationStrategy = mock() + yTranslator.strategy = strategy + + yTranslator.cancelInProgressTranslation() + + verify(strategy).cancelInProgressTranslation() + } + + @Test + fun `yTranslator should delegate it's strategy for snapImmediately`() { + val yTranslator = ViewYTranslator(ViewPosition.BOTTOM) + val strategy: ViewYTranslationStrategy = mock() + yTranslator.strategy = strategy + val view: View = mock() + + yTranslator.snapImmediately(view) + + verify(strategy).snapImmediately(view) + } +} diff --git a/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index db23b580b01f..c90ccb91bc0a 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -91,7 +91,6 @@ import mozilla.components.feature.session.PictureInPictureFeature import mozilla.components.feature.session.ScreenOrientationFeature import mozilla.components.feature.session.SessionFeature import mozilla.components.feature.session.SwipeRefreshFeature -import mozilla.components.feature.session.behavior.EngineViewBrowserToolbarBehavior import mozilla.components.feature.sitepermissions.SitePermissionsFeature import mozilla.components.feature.webauthn.WebAuthnFeature import mozilla.components.lib.state.ext.consumeFlow @@ -111,6 +110,7 @@ import mozilla.components.support.ktx.android.view.hideKeyboard import mozilla.components.support.ktx.kotlin.getOrigin import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged import mozilla.components.support.locale.ActivityContextWrapper +import mozilla.components.ui.widgets.behavior.EngineViewClippingBehavior import mozilla.components.ui.widgets.withCenterAlignedButtons import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.FeatureFlags @@ -168,7 +168,7 @@ import org.mozilla.fenix.utils.allowUndo import org.mozilla.fenix.wifi.SitePermissionsWifiIntegration import java.lang.ref.WeakReference import kotlin.coroutines.cancellation.CancellationException -import mozilla.components.feature.session.behavior.ToolbarPosition as MozacToolbarPosition +import mozilla.components.ui.widgets.behavior.ToolbarPosition as MozacToolbarPosition /** * Base fragment extended by [BrowserFragment]. @@ -1154,7 +1154,7 @@ abstract class BaseBrowserFragment : MozacToolbarPosition.TOP } (getSwipeRefreshLayout().layoutParams as CoordinatorLayout.LayoutParams).behavior = - EngineViewBrowserToolbarBehavior( + EngineViewClippingBehavior( context, null, getSwipeRefreshLayout(), diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt index 6668191599d8..1e3fc7a98cb2 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt @@ -19,9 +19,9 @@ import mozilla.components.browser.state.selector.selectedTab import mozilla.components.browser.state.state.CustomTabSessionState import mozilla.components.browser.state.state.ExternalAppType import mozilla.components.browser.toolbar.BrowserToolbar -import mozilla.components.browser.toolbar.behavior.BrowserToolbarBehavior import mozilla.components.browser.toolbar.display.DisplayToolbar import mozilla.components.support.ktx.util.URLStringUtils +import mozilla.components.ui.widgets.behavior.EngineViewScrollingBehavior import org.mozilla.fenix.R import org.mozilla.fenix.components.toolbar.interactor.BrowserToolbarInteractor import org.mozilla.fenix.customtabs.CustomTabToolbarIntegration @@ -32,7 +32,7 @@ import org.mozilla.fenix.theme.ThemeManager import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.utils.ToolbarPopupWindow import java.lang.ref.WeakReference -import mozilla.components.browser.toolbar.behavior.ToolbarPosition as MozacToolbarPosition +import mozilla.components.ui.widgets.behavior.ViewPosition as MozacToolbarPosition @SuppressWarnings("LargeClass") class BrowserToolbarView( @@ -53,8 +53,7 @@ class BrowserToolbarView( private val layout = LayoutInflater.from(context) .inflate(toolbarLayout, container, true) - @VisibleForTesting - internal var view: BrowserToolbar = layout + var view: BrowserToolbar = layout .findViewById(R.id.toolbar) val toolbarIntegration: ToolbarIntegration @@ -191,7 +190,7 @@ class BrowserToolbarView( } (view.layoutParams as? CoordinatorLayout.LayoutParams)?.apply { - (behavior as? BrowserToolbarBehavior)?.forceExpand(view) + (behavior as? EngineViewScrollingBehavior)?.forceExpand(view) } } @@ -202,7 +201,7 @@ class BrowserToolbarView( } (view.layoutParams as? CoordinatorLayout.LayoutParams)?.apply { - (behavior as? BrowserToolbarBehavior)?.forceCollapse(view) + (behavior as? EngineViewScrollingBehavior)?.forceCollapse(view) } } @@ -255,7 +254,7 @@ class BrowserToolbarView( @VisibleForTesting internal fun setDynamicToolbarBehavior(toolbarPosition: MozacToolbarPosition) { (view.layoutParams as? CoordinatorLayout.LayoutParams)?.apply { - behavior = BrowserToolbarBehavior(view.context, null, toolbarPosition) + behavior = EngineViewScrollingBehavior(view.context, null, toolbarPosition) } } diff --git a/fenix/app/src/test/java/org/mozilla/fenix/browser/BaseBrowserFragmentTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/browser/BaseBrowserFragmentTest.kt index 9db600442229..4a7e37e36c10 100644 --- a/fenix/app/src/test/java/org/mozilla/fenix/browser/BaseBrowserFragmentTest.kt +++ b/fenix/app/src/test/java/org/mozilla/fenix/browser/BaseBrowserFragmentTest.kt @@ -16,8 +16,8 @@ import mozilla.components.browser.state.state.SessionState import mozilla.components.concept.engine.EngineView import mozilla.components.concept.engine.permission.SitePermissions import mozilla.components.feature.contextmenu.ContextMenuCandidate -import mozilla.components.feature.session.behavior.EngineViewBrowserToolbarBehavior import mozilla.components.ui.widgets.VerticalSwipeRefreshLayout +import mozilla.components.ui.widgets.behavior.EngineViewClippingBehavior import org.junit.Before import org.junit.Test import org.mozilla.fenix.ext.components @@ -88,17 +88,17 @@ class BaseBrowserFragmentTest { } @Test - fun `initializeEngineView should set EngineViewBrowserToolbarBehavior when dynamic toolbar is enabled`() { + fun `initializeEngineView should set EngineViewClippingBehavior when dynamic toolbar is enabled`() { every { settings.shouldUseFixedTopToolbar } returns false every { settings.isDynamicToolbarEnabled } returns true val params: CoordinatorLayout.LayoutParams = mockk(relaxed = true) every { params.behavior } returns mockk(relaxed = true) every { swipeRefreshLayout.layoutParams } returns params - val behavior = slot() + val behavior = slot() fragment.initializeEngineView(13) - // EngineViewBrowserToolbarBehavior constructor parameters are not properties, we cannot check them. + // EngineViewClippingBehavior constructor parameters are not properties, we cannot check them. // Ensure just that the right behavior is set. verify { params.behavior = capture(behavior) } } diff --git a/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt index 8ad2f685416f..2fad1a270c4c 100644 --- a/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt +++ b/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt @@ -11,9 +11,9 @@ import io.mockk.mockk import io.mockk.spyk import io.mockk.verify import mozilla.components.browser.toolbar.BrowserToolbar -import mozilla.components.browser.toolbar.behavior.BrowserToolbarBehavior import mozilla.components.lib.publicsuffixlist.PublicSuffixList import mozilla.components.support.test.robolectric.testContext +import mozilla.components.ui.widgets.behavior.EngineViewScrollingBehavior import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Before @@ -22,20 +22,20 @@ import org.junit.runner.RunWith import org.mozilla.fenix.ext.components import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.utils.Settings -import mozilla.components.browser.toolbar.behavior.ToolbarPosition as MozacToolbarPosition +import mozilla.components.ui.widgets.behavior.ViewPosition as MozacToolbarPosition @RunWith(FenixRobolectricTestRunner::class) class BrowserToolbarViewTest { private lateinit var toolbarView: BrowserToolbarView private lateinit var toolbar: BrowserToolbar - private lateinit var behavior: BrowserToolbarBehavior + private lateinit var behavior: EngineViewScrollingBehavior private lateinit var settings: Settings @Before fun setup() { toolbar = BrowserToolbar(testContext) toolbar.layoutParams = CoordinatorLayout.LayoutParams(100, 100) - behavior = spyk(BrowserToolbarBehavior(testContext, null, MozacToolbarPosition.BOTTOM)) + behavior = spyk(EngineViewScrollingBehavior(testContext, null, MozacToolbarPosition.BOTTOM)) (toolbar.layoutParams as CoordinatorLayout.LayoutParams).behavior = behavior settings = mockk(relaxed = true) every { testContext.components.useCases } returns mockk(relaxed = true) @@ -217,7 +217,7 @@ class BrowserToolbarViewTest { } @Test - fun `setDynamicToolbarBehavior should set a BrowserToolbarBehavior for the bottom toolbar`() { + fun `setDynamicToolbarBehavior should set a ViewHideOnScrollBehavior for the bottom toolbar`() { val toolbarViewSpy = spyk(toolbarView) (toolbar.layoutParams as CoordinatorLayout.LayoutParams).behavior = null @@ -227,7 +227,7 @@ class BrowserToolbarViewTest { } @Test - fun `setDynamicToolbarBehavior should set a BrowserToolbarBehavior for the top toolbar`() { + fun `setDynamicToolbarBehavior should set a ViewHideOnScrollBehavior for the top toolbar`() { val toolbarViewSpy = spyk(toolbarView) (toolbar.layoutParams as CoordinatorLayout.LayoutParams).behavior = null diff --git a/focus-android/app/src/main/java/org/mozilla/focus/ext/BrowserToolbar.kt b/focus-android/app/src/main/java/org/mozilla/focus/ext/BrowserToolbar.kt index 35a50fa3005c..e719986a9d60 100644 --- a/focus-android/app/src/main/java/org/mozilla/focus/ext/BrowserToolbar.kt +++ b/focus-android/app/src/main/java/org/mozilla/focus/ext/BrowserToolbar.kt @@ -8,12 +8,12 @@ import android.content.Context import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.isVisible import mozilla.components.browser.toolbar.BrowserToolbar -import mozilla.components.browser.toolbar.behavior.BrowserToolbarBehavior import mozilla.components.concept.engine.EngineView -import mozilla.components.feature.session.behavior.EngineViewBrowserToolbarBehavior +import mozilla.components.ui.widgets.behavior.EngineViewClippingBehavior +import mozilla.components.ui.widgets.behavior.EngineViewScrollingBehavior import org.mozilla.focus.R -import mozilla.components.browser.toolbar.behavior.ToolbarPosition as browserToolbarPosition -import mozilla.components.feature.session.behavior.ToolbarPosition as engineToolbarPosition +import mozilla.components.ui.widgets.behavior.ToolbarPosition as engineToolbarPosition +import mozilla.components.ui.widgets.behavior.ViewPosition as browserToolbarPosition /** * Collapse the toolbar and block it from appearing until calling [enableDynamicBehavior]. @@ -38,7 +38,7 @@ fun BrowserToolbar.disableDynamicBehavior(engineView: EngineView) { * @param engineView [EngineView] that should react to toolbar's dynamic behavior. */ fun BrowserToolbar.enableDynamicBehavior(context: Context, engineView: EngineView) { - (layoutParams as? CoordinatorLayout.LayoutParams)?.behavior = BrowserToolbarBehavior( + (layoutParams as? CoordinatorLayout.LayoutParams)?.behavior = EngineViewScrollingBehavior( context, null, browserToolbarPosition.TOP, @@ -48,7 +48,7 @@ fun BrowserToolbar.enableDynamicBehavior(context: Context, engineView: EngineVie engineView.setDynamicToolbarMaxHeight(toolbarHeight) (engineView.asView().layoutParams as? CoordinatorLayout.LayoutParams)?.apply { topMargin = 0 - behavior = EngineViewBrowserToolbarBehavior( + behavior = EngineViewClippingBehavior( context, null, engineView.asView(), diff --git a/focus-android/app/src/test/java/org/mozilla/focus/ext/BrowserToolbarTest.kt b/focus-android/app/src/test/java/org/mozilla/focus/ext/BrowserToolbarTest.kt index 3134a75b03db..4407e03a76b3 100644 --- a/focus-android/app/src/test/java/org/mozilla/focus/ext/BrowserToolbarTest.kt +++ b/focus-android/app/src/test/java/org/mozilla/focus/ext/BrowserToolbarTest.kt @@ -8,9 +8,9 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.isVisible import mozilla.components.browser.engine.gecko.GeckoEngineView import mozilla.components.browser.toolbar.BrowserToolbar -import mozilla.components.browser.toolbar.behavior.BrowserToolbarBehavior -import mozilla.components.feature.session.behavior.EngineViewBrowserToolbarBehavior import mozilla.components.support.test.robolectric.testContext +import mozilla.components.ui.widgets.behavior.EngineViewClippingBehavior +import mozilla.components.ui.widgets.behavior.EngineViewScrollingBehavior import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Assert.assertTrue @@ -42,8 +42,8 @@ internal class BrowserToolbarTest { toolbar.enableDynamicBehavior(testContext, engineView) - assertTrue((toolbar.layoutParams as? CoordinatorLayout.LayoutParams)?.behavior is BrowserToolbarBehavior) - assertTrue((engineView.layoutParams as? CoordinatorLayout.LayoutParams)?.behavior is EngineViewBrowserToolbarBehavior) + assertTrue((toolbar.layoutParams as? CoordinatorLayout.LayoutParams)?.behavior is EngineViewScrollingBehavior) + assertTrue((engineView.layoutParams as? CoordinatorLayout.LayoutParams)?.behavior is EngineViewClippingBehavior) assertEquals(0, (engineView.layoutParams as? CoordinatorLayout.LayoutParams)?.topMargin) verify(engineView).setDynamicToolbarMaxHeight(toolbarHeight) } From 8a7226082f2d3c18092afbcee3a73d294fa26a8d Mon Sep 17 00:00:00 2001 From: Ben Dean-Kawamura Date: Tue, 19 Dec 2023 14:11:44 -0500 Subject: [PATCH 033/586] Bug 1870912 - hook up the `FxaStateMachineChecker` code --- .../components/feature/accounts/build.gradle | 1 + .../FirefoxAccountsAuthFeatureTest.kt | 14 +- .../service/fxa/FxaDeviceConstellation.kt | 15 ++ .../manager/AppServicesStateMachineChecker.kt | 209 ++++++++++++++++++ .../service/fxa/manager/FxaAccountManager.kt | 24 ++ .../service/fxa/FxaAccountManagerTest.kt | 38 ++-- 6 files changed, 278 insertions(+), 23 deletions(-) create mode 100644 android-components/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/manager/AppServicesStateMachineChecker.kt diff --git a/android-components/components/feature/accounts/build.gradle b/android-components/components/feature/accounts/build.gradle index 7dafca4ef9ce..b508fe6697ea 100644 --- a/android-components/components/feature/accounts/build.gradle +++ b/android-components/components/feature/accounts/build.gradle @@ -44,6 +44,7 @@ dependencies { implementation project(':support-webextensions') testImplementation ComponentsDependencies.androidx_test_junit + testImplementation ComponentsDependencies.mozilla_appservices_full_megazord_forUnitTests testImplementation ComponentsDependencies.testing_robolectric testImplementation ComponentsDependencies.testing_coroutines diff --git a/android-components/components/feature/accounts/src/test/java/mozilla/components/feature/accounts/FirefoxAccountsAuthFeatureTest.kt b/android-components/components/feature/accounts/src/test/java/mozilla/components/feature/accounts/FirefoxAccountsAuthFeatureTest.kt index 092fb6509ad7..a32681e8fee1 100644 --- a/android-components/components/feature/accounts/src/test/java/mozilla/components/feature/accounts/FirefoxAccountsAuthFeatureTest.kt +++ b/android-components/components/feature/accounts/src/test/java/mozilla/components/feature/accounts/FirefoxAccountsAuthFeatureTest.kt @@ -16,6 +16,7 @@ import mozilla.components.concept.sync.AuthFlowUrl import mozilla.components.concept.sync.AuthType import mozilla.components.concept.sync.DeviceConfig import mozilla.components.concept.sync.DeviceType +import mozilla.components.concept.sync.FxAEntryPoint import mozilla.components.concept.sync.OAuthAccount import mozilla.components.concept.sync.Profile import mozilla.components.service.fxa.FxaAuthData @@ -26,6 +27,7 @@ import mozilla.components.support.base.observer.ObserverRegistry import mozilla.components.support.test.any import mozilla.components.support.test.mock import mozilla.components.support.test.robolectric.testContext +import mozilla.components.support.test.whenever import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Test @@ -71,6 +73,10 @@ class TestableFxaAccountManager( @RunWith(AndroidJUnit4::class) class FirefoxAccountsAuthFeatureTest { + val mockEntryPoint: FxAEntryPoint = mock().apply { + whenever(entryName).thenReturn("home-menu") + } + // Note that tests that involve secure storage specify API=21, because of issues testing secure storage on // 23+ API levels. See https://github.com/mozilla-mobile/android-components/issues/4956 @@ -88,7 +94,7 @@ class FirefoxAccountsAuthFeatureTest { ) { _, url -> authUrl.complete(url) } - feature.beginAuthentication(testContext, mock()) + feature.beginAuthentication(testContext, mockEntryPoint) authUrl.await() assertEquals("auth://url", authUrl.getCompleted()) } @@ -107,7 +113,7 @@ class FirefoxAccountsAuthFeatureTest { ) { _, url -> authUrl.complete(url) } - feature.beginPairingAuthentication(testContext, "auth://pair", mock()) + feature.beginPairingAuthentication(testContext, "auth://pair", mockEntryPoint) authUrl.await() assertEquals("auth://url", authUrl.getCompleted()) } @@ -127,7 +133,7 @@ class FirefoxAccountsAuthFeatureTest { ) { _, url -> authUrl.complete(url) } - feature.beginAuthentication(testContext, mock()) + feature.beginAuthentication(testContext, mockEntryPoint) authUrl.await() // Fallback url is invoked. assertEquals("https://accounts.firefox.com/signin", authUrl.getCompleted()) @@ -148,7 +154,7 @@ class FirefoxAccountsAuthFeatureTest { ) { _, url -> authUrl.complete(url) } - feature.beginPairingAuthentication(testContext, "auth://pair", mock()) + feature.beginPairingAuthentication(testContext, "auth://pair", mockEntryPoint) authUrl.await() // Fallback url is invoked. assertEquals("https://accounts.firefox.com/signin", authUrl.getCompleted()) diff --git a/android-components/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/FxaDeviceConstellation.kt b/android-components/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/FxaDeviceConstellation.kt index a2c2bf754ecb..dadafcbd698e 100644 --- a/android-components/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/FxaDeviceConstellation.kt +++ b/android-components/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/FxaDeviceConstellation.kt @@ -12,6 +12,8 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.withContext import mozilla.appservices.fxaclient.FxaClient import mozilla.appservices.fxaclient.FxaException +import mozilla.appservices.fxaclient.FxaStateCheckerEvent +import mozilla.appservices.fxaclient.FxaStateCheckerState import mozilla.appservices.syncmanager.SyncTelemetry import mozilla.components.concept.base.crash.CrashReporting import mozilla.components.concept.sync.AccountEvent @@ -25,6 +27,7 @@ import mozilla.components.concept.sync.DeviceConstellation import mozilla.components.concept.sync.DeviceConstellationObserver import mozilla.components.concept.sync.DevicePushSubscription import mozilla.components.concept.sync.ServiceResult +import mozilla.components.service.fxa.manager.AppServicesStateMachineChecker import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.base.observer.Observable import mozilla.components.support.base.observer.ObserverRegistry @@ -86,22 +89,33 @@ class FxaDeviceConstellation( val capabilities = config.capabilities.map { it.into() }.toSet() if (finalizeAction == DeviceFinalizeAction.Initialize) { try { + AppServicesStateMachineChecker.checkInternalState(FxaStateCheckerState.InitializeDevice) account.initializeDevice(config.name, config.type.into(), capabilities) + AppServicesStateMachineChecker.handleInternalEvent(FxaStateCheckerEvent.InitializeDeviceSuccess) ServiceResult.Ok } catch (e: FxaPanicException) { + AppServicesStateMachineChecker.handleInternalEvent(FxaStateCheckerEvent.CallError) throw e } catch (e: FxaUnauthorizedException) { + AppServicesStateMachineChecker.handleInternalEvent(FxaStateCheckerEvent.CallError) ServiceResult.AuthError } catch (e: FxaException) { + AppServicesStateMachineChecker.handleInternalEvent(FxaStateCheckerEvent.CallError) ServiceResult.OtherError } } else { try { + AppServicesStateMachineChecker.checkInternalState(FxaStateCheckerState.EnsureDeviceCapabilities) account.ensureCapabilities(capabilities) + AppServicesStateMachineChecker.handleInternalEvent( + FxaStateCheckerEvent.EnsureDeviceCapabilitiesSuccess, + ) ServiceResult.Ok } catch (e: FxaPanicException) { + AppServicesStateMachineChecker.handleInternalEvent(FxaStateCheckerEvent.CallError) throw e } catch (e: FxaUnauthorizedException) { + AppServicesStateMachineChecker.handleInternalEvent(FxaStateCheckerEvent.CallError) // Unless we've added a new capability, in practice 'ensureCapabilities' isn't // actually expected to do any work: everything should have been done by initializeDevice. // So if it did, and failed, let's report this so that we're aware of this! @@ -111,6 +125,7 @@ class FxaDeviceConstellation( ) ServiceResult.AuthError } catch (e: FxaException) { + AppServicesStateMachineChecker.handleInternalEvent(FxaStateCheckerEvent.CallError) ServiceResult.OtherError } } diff --git a/android-components/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/manager/AppServicesStateMachineChecker.kt b/android-components/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/manager/AppServicesStateMachineChecker.kt new file mode 100644 index 000000000000..3b18aab823de --- /dev/null +++ b/android-components/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/manager/AppServicesStateMachineChecker.kt @@ -0,0 +1,209 @@ +/* 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 mozilla.components.service.fxa.manager + +import mozilla.appservices.fxaclient.FxaEvent +import mozilla.appservices.fxaclient.FxaRustAuthState +import mozilla.appservices.fxaclient.FxaState +import mozilla.appservices.fxaclient.FxaStateCheckerEvent +import mozilla.appservices.fxaclient.FxaStateCheckerState +import mozilla.appservices.fxaclient.FxaStateMachineChecker +import mozilla.components.concept.sync.DeviceConfig +import mozilla.components.service.fxa.into +import mozilla.appservices.fxaclient.DeviceConfig as ASDeviceConfig + +/** + * Checks the new app-services state machine logic against the current android-components code + * + * This is a temporary measure to prep for migrating the android-components code to using the new + * app-services state machine. It performs a "dry-run" test of the code where we check the new logic + * against the current logic, without performing any side-effects. + * + * If one of the checks fails, then we report an error to Sentry. After that the calls become + * no-ops to avoid spamming sentry with errors from a single client. By checking the Sentry errors, + * we can find places where the application-services logic doesn't match the current + * android-components logic and fix the issue. + * + * Once we determine that the new application-services code is correct, let's switch the + * android-components code to using it (https://bugzilla.mozilla.org/show_bug.cgi?id=1867793) and + * delete all this code. + */ +object AppServicesStateMachineChecker { + /** + * The Rust state machine checker. This handles the actual checks and sentry reporting. + */ + private val rustChecker = FxaStateMachineChecker() + + /** + * Handle an event about to be processed + * + * Call this when processing an android-components event, after checking that it's valid. + */ + internal fun handleEvent(event: Event, deviceConfig: DeviceConfig, scopes: Set) { + val convertedEvent = when (event) { + Event.Account.Start -> FxaEvent.Initialize( + ASDeviceConfig( + name = deviceConfig.name, + deviceType = deviceConfig.type.into(), + capabilities = ArrayList(deviceConfig.capabilities.map { it.into() }), + ), + ) + is Event.Account.BeginEmailFlow -> FxaEvent.BeginOAuthFlow(ArrayList(scopes), event.entrypoint.entryName) + is Event.Account.BeginPairingFlow -> { + // pairingUrl should always be non-null, if it is somehow null let's use a + // placeholder value that can be identified when checking in sentry + val pairingUrl = event.pairingUrl ?: "" + FxaEvent.BeginPairingFlow(pairingUrl, ArrayList(scopes), event.entrypoint.entryName) + } + is Event.Account.AuthenticationError -> FxaEvent.CheckAuthorizationStatus + Event.Account.AccessTokenKeyError -> FxaEvent.CheckAuthorizationStatus + Event.Account.Logout -> FxaEvent.Disconnect + // This is the one ProgressEvent that's considered a "public event" in app-services + is Event.Progress.AuthData -> FxaEvent.CompleteOAuthFlow(event.authData.code, event.authData.state) + else -> return + } + rustChecker.handlePublicEvent(convertedEvent) + } + + /** + * Check a new account state + * + * Call this after transitioning to an android-components account state. + */ + internal fun checkAccountState(state: AccountState) { + val convertedState = when (state) { + AccountState.NotAuthenticated -> FxaState.Disconnected + is AccountState.Authenticating -> FxaState.Authenticating(state.oAuthUrl) + AccountState.Authenticated -> FxaState.Connected + AccountState.AuthenticationProblem -> FxaState.AuthIssues + } + rustChecker.checkPublicState(convertedState) + } + + /** + * General validation for new progress state being processed by the AC state machine. + * + * This handles all validation for most state transitions in a simple manner. The one transition + * it can't handle is completing oauth, which entails multiple FxA calls and can fail in multiple + * different ways. For that, the lower-level `checkInternalState` and `handleInternalEvent` are + * used. + */ + @Suppress("LongMethod") + internal fun validateProgressEvent(progressEvent: Event.Progress, via: Event, scopes: Set) { + when (progressEvent) { + Event.Progress.AccountRestored -> { + AppServicesStateMachineChecker.checkInternalState(FxaStateCheckerState.GetAuthState) + AppServicesStateMachineChecker.handleInternalEvent( + FxaStateCheckerEvent.GetAuthStateSuccess(FxaRustAuthState.CONNECTED), + ) + } + Event.Progress.AccountNotFound -> { + AppServicesStateMachineChecker.checkInternalState(FxaStateCheckerState.GetAuthState) + AppServicesStateMachineChecker.handleInternalEvent( + FxaStateCheckerEvent.GetAuthStateSuccess(FxaRustAuthState.DISCONNECTED), + ) + } + is Event.Progress.StartedOAuthFlow -> { + when (via) { + is Event.Account.BeginEmailFlow -> { + AppServicesStateMachineChecker.checkInternalState( + FxaStateCheckerState.BeginOAuthFlow(ArrayList(scopes), via.entrypoint.entryName), + ) + AppServicesStateMachineChecker.handleInternalEvent( + FxaStateCheckerEvent.BeginOAuthFlowSuccess(progressEvent.oAuthUrl), + ) + } + is Event.Account.BeginPairingFlow -> { + AppServicesStateMachineChecker.checkInternalState( + FxaStateCheckerState.BeginPairingFlow( + via.pairingUrl!!, + ArrayList(scopes), + via.entrypoint.entryName, + ), + ) + AppServicesStateMachineChecker.handleInternalEvent( + FxaStateCheckerEvent.BeginPairingFlowSuccess(progressEvent.oAuthUrl), + ) + } + // This branch should never be taken, if it does we'll probably see a state + // check error down the line. + else -> Unit + } + } + Event.Progress.FailedToBeginAuth -> { + when (via) { + is Event.Account.BeginEmailFlow -> { + AppServicesStateMachineChecker.checkInternalState( + FxaStateCheckerState.BeginOAuthFlow(ArrayList(scopes), via.entrypoint.entryName), + ) + } + is Event.Account.BeginPairingFlow -> { + AppServicesStateMachineChecker.checkInternalState( + FxaStateCheckerState.BeginPairingFlow( + via.pairingUrl!!, + ArrayList(scopes), + via.entrypoint.entryName, + ), + ) + } + // This branch should never be taken, if it does we'll probably see a state + // check error down the line. + else -> Unit + } + AppServicesStateMachineChecker.handleInternalEvent(FxaStateCheckerEvent.CallError) + } + Event.Progress.LoggedOut -> { + AppServicesStateMachineChecker.checkInternalState( + FxaStateCheckerState.Disconnect, + ) + AppServicesStateMachineChecker.handleInternalEvent( + FxaStateCheckerEvent.DisconnectSuccess, + ) + } + Event.Progress.RecoveredFromAuthenticationProblem -> { + AppServicesStateMachineChecker.checkInternalState(FxaStateCheckerState.CheckAuthorizationStatus) + AppServicesStateMachineChecker.handleInternalEvent( + FxaStateCheckerEvent.CheckAuthorizationStatusSuccess(true), + ) + } + Event.Progress.FailedToRecoverFromAuthenticationProblem -> { + // `via` should always be `AuthenticationError` if not, we'll probably see a state + // check error down the line. + if (via is Event.Account.AuthenticationError) { + if (via.errorCountWithinTheTimeWindow >= AUTH_CHECK_CIRCUIT_BREAKER_COUNT) { + // In this case, the state machine fails early and doesn't actualy make any + // calls + return + } + AppServicesStateMachineChecker.checkInternalState(FxaStateCheckerState.CheckAuthorizationStatus) + AppServicesStateMachineChecker.handleInternalEvent( + FxaStateCheckerEvent.CheckAuthorizationStatusSuccess(false), + ) + } + } + else -> Unit + } + } + + /** + * Check an app-services internal state + * + * The app-services internal states correspond to internal firefox account method calls. Call + * this before making one of those calls. + */ + internal fun checkInternalState(state: FxaStateCheckerState) { + rustChecker.checkInternalState(state) + } + + /** + * Handle an app-services internal event + * + * The app-services internal states correspond the results of internal firefox account method + * calls. Call this before after making a call. + */ + internal fun handleInternalEvent(event: FxaStateCheckerEvent) { + rustChecker.handleInternalEvent(event) + } +} diff --git a/android-components/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/manager/FxaAccountManager.kt b/android-components/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/manager/FxaAccountManager.kt index f3400ba79e87..925f96e2acf1 100644 --- a/android-components/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/manager/FxaAccountManager.kt +++ b/android-components/components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/manager/FxaAccountManager.kt @@ -12,6 +12,8 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.cancel import kotlinx.coroutines.withContext +import mozilla.appservices.fxaclient.FxaStateCheckerEvent +import mozilla.appservices.fxaclient.FxaStateCheckerState import mozilla.appservices.syncmanager.DeviceSettings import mozilla.components.concept.base.crash.Breadcrumb import mozilla.components.concept.base.crash.CrashReporting @@ -461,12 +463,22 @@ open class FxaAccountManager( continue } + AppServicesStateMachineChecker.handleEvent(toProcess, deviceConfig, scopes) + if (transitionInto is State.Idle) { + AppServicesStateMachineChecker.checkAccountState(transitionInto.accountState) + } + logger.info("Processing event '$toProcess' for state $state. Next state is $transitionInto") state = transitionInto stateActions(state, toProcess)?.let { successiveEvent -> logger.info("Ran '$toProcess' side-effects for state $state, got successive event $successiveEvent") + if (successiveEvent is Event.Progress) { + // Note: stateActions should only return progress events, so this captures all + // possibilities. + AppServicesStateMachineChecker.validateProgressEvent(successiveEvent, toProcess, scopes) + } eventQueue.add(successiveEvent) } } while (!eventQueue.isEmpty()) @@ -611,11 +623,23 @@ open class FxaAccountManager( } is Event.Progress.AuthData -> { val completeAuth = suspend { + AppServicesStateMachineChecker.checkInternalState( + FxaStateCheckerState.CompleteOAuthFlow(via.authData.code, via.authData.state), + ) withRetries(logger, MAX_NETWORK_RETRIES) { account.completeOAuthFlow(via.authData.code, via.authData.state) + }.also { + if (it is Result.Failure) { + AppServicesStateMachineChecker.handleInternalEvent(FxaStateCheckerEvent.CallError) + } else { + AppServicesStateMachineChecker.handleInternalEvent( + FxaStateCheckerEvent.CompleteOAuthFlowSuccess, + ) + } } } val finalize = suspend { + // Note: finalizeDevice state checking happens in the DeviceConstellation.kt withServiceRetries(logger, MAX_NETWORK_RETRIES) { finalizeDevice(via.authData.authType) } } // If we can't 'complete', we won't run 'finalize' due to short-circuiting. diff --git a/android-components/components/service/firefox-accounts/src/test/java/mozilla/components/service/fxa/FxaAccountManagerTest.kt b/android-components/components/service/firefox-accounts/src/test/java/mozilla/components/service/fxa/FxaAccountManagerTest.kt index f90eb2435f93..4b3d99d6e0b8 100644 --- a/android-components/components/service/firefox-accounts/src/test/java/mozilla/components/service/fxa/FxaAccountManagerTest.kt +++ b/android-components/components/service/firefox-accounts/src/test/java/mozilla/components/service/fxa/FxaAccountManagerTest.kt @@ -681,7 +681,7 @@ class FxaAccountManagerTest { verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(entrypoint = mock())) + assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(entrypoint = entryPoint)) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -726,7 +726,7 @@ class FxaAccountManagerTest { verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(entrypoint = mock())) + assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(entrypoint = entryPoint)) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -764,7 +764,7 @@ class FxaAccountManagerTest { } manager.start() - manager.beginAuthentication("http://pairing.com", mock()) + manager.beginAuthentication("http://pairing.com", entryPoint) fail() } @@ -783,7 +783,7 @@ class FxaAccountManagerTest { verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(pairingUrl = "auth://pairing", mock())) + assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(pairingUrl = "auth://pairing", entryPoint)) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -825,7 +825,7 @@ class FxaAccountManagerTest { testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication( pairingUrl = "auth://pairing", - entrypoint = mock(), + entrypoint = entryPoint, ), ) assertNull(manager.authenticatedAccount()) @@ -836,7 +836,7 @@ class FxaAccountManagerTest { testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication( pairingUrl = "auth://pairing", - entrypoint = mock(), + entrypoint = entryPoint, ), ) assertNull(manager.authenticatedAccount()) @@ -879,7 +879,7 @@ class FxaAccountManagerTest { reset(accountObserver) - assertNull(manager.beginAuthentication(entrypoint = mock())) + assertNull(manager.beginAuthentication(entrypoint = entryPoint)) // Confirm that account state observable doesn't receive authentication errors. assertNull(manager.authenticatedAccount()) @@ -889,7 +889,7 @@ class FxaAccountManagerTest { `when`(mockAccount.beginOAuthFlow(any(), any())).thenReturn(testAuthFlowUrl()) `when`(constellation.finalizeDevice(any(), any())).thenReturn(ServiceResult.Ok) - assertEquals(testAuthFlowUrl().url, manager.beginAuthentication(entrypoint = mock())) + assertEquals(testAuthFlowUrl().url, manager.beginAuthentication(entrypoint = entryPoint)) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -927,7 +927,7 @@ class FxaAccountManagerTest { reset(accountObserver) - assertNull(manager.beginAuthentication(pairingUrl = "auth://pairing", entrypoint = mock())) + assertNull(manager.beginAuthentication(pairingUrl = "auth://pairing", entrypoint = entryPoint)) // Confirm that account state observable doesn't receive authentication errors. assertNull(manager.authenticatedAccount()) @@ -947,7 +947,7 @@ class FxaAccountManagerTest { testAuthFlowUrl().url, manager.beginAuthentication( pairingUrl = "auth://pairing", - entrypoint = mock(), + entrypoint = entryPoint, ), ) @@ -984,7 +984,7 @@ class FxaAccountManagerTest { verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(entrypoint = mock())) + assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(entrypoint = entryPoint)) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1013,7 +1013,7 @@ class FxaAccountManagerTest { // Able to re-authenticate. reset(accountObserver) - assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(entrypoint = mock())) + assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(entrypoint = entryPoint)) manager.finishAuthentication(FxaAuthData(AuthType.Pairing, "dummyCode", EXPECTED_AUTH_STATE)) assertTrue(manager.authenticatedAccount() != null) @@ -1048,7 +1048,7 @@ class FxaAccountManagerTest { verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(entrypoint = mock())) + assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(entrypoint = entryPoint)) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1096,7 +1096,7 @@ class FxaAccountManagerTest { verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(entrypoint = mock())) + assertEquals(testAuthFlowUrl(entrypoint = "home-menu").url, manager.beginAuthentication(entrypoint = entryPoint)) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1195,7 +1195,7 @@ class FxaAccountManagerTest { verify(accountObserver, never()).onAuthenticated(any(), any()) reset(accountObserver) - assertEquals(testAuthFlowUrl().url, manager.beginAuthentication(entrypoint = mock())) + assertEquals(testAuthFlowUrl().url, manager.beginAuthentication(entrypoint = entryPoint)) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1277,7 +1277,7 @@ class FxaAccountManagerTest { assertFalse(manager.accountNeedsReauth()) reset(accountObserver) - assertEquals(testAuthFlowUrl().url, manager.beginAuthentication(entrypoint = mock())) + assertEquals(testAuthFlowUrl().url, manager.beginAuthentication(entrypoint = entryPoint)) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1337,7 +1337,7 @@ class FxaAccountManagerTest { assertFalse(manager.accountNeedsReauth()) reset(accountObserver) - assertEquals(testAuthFlowUrl().url, manager.beginAuthentication(entrypoint = mock())) + assertEquals(testAuthFlowUrl().url, manager.beginAuthentication(entrypoint = entryPoint)) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1415,7 +1415,7 @@ class FxaAccountManagerTest { assertFalse(manager.accountNeedsReauth()) reset(accountObserver) - assertEquals(testAuthFlowUrl().url, manager.beginAuthentication(entrypoint = mock())) + assertEquals(testAuthFlowUrl().url, manager.beginAuthentication(entrypoint = entryPoint)) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) @@ -1473,7 +1473,7 @@ class FxaAccountManagerTest { assertFalse(manager.accountNeedsReauth()) reset(accountObserver) - assertEquals(testAuthFlowUrl().url, manager.beginAuthentication(entrypoint = mock())) + assertEquals(testAuthFlowUrl().url, manager.beginAuthentication(entrypoint = entryPoint)) assertNull(manager.authenticatedAccount()) assertNull(manager.accountProfile()) From dafd789a588498b69d34d872bd36d078d747dc68 Mon Sep 17 00:00:00 2001 From: Arturo Mejia Date: Wed, 31 Jan 2024 14:13:30 -0500 Subject: [PATCH 034/586] Bug 1870347 - Update the comment for the content description of the addon permission item. --- .../components/feature/addons/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/components/feature/addons/src/main/res/values/strings.xml b/android-components/components/feature/addons/src/main/res/values/strings.xml index 9e523223652a..2091d64276a9 100644 --- a/android-components/components/feature/addons/src/main/res/values/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values/strings.xml @@ -25,7 +25,7 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Access your data on %1$d other domains - + %1$s, %2$d of %3$d Access browser tabs From 651f22b87e9da611ccaa866b3f127926c3607023 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 1 Feb 2024 00:03:43 +0000 Subject: [PATCH 035/586] Import translations from android-l10n --- .../src/main/res/values-azb/strings.xml | 6 + .../src/main/res/values-kab/strings.xml | 7 +- fenix/app/src/main/res/values-am/strings.xml | 14 ++- fenix/app/src/main/res/values-bg/strings.xml | 58 +++------ fenix/app/src/main/res/values-cy/strings.xml | 16 ++- fenix/app/src/main/res/values-da/strings.xml | 54 ++------ fenix/app/src/main/res/values-de/strings.xml | 61 +++------ fenix/app/src/main/res/values-dsb/strings.xml | 59 +++------ .../src/main/res/values-es-rAR/strings.xml | 16 ++- fenix/app/src/main/res/values-fi/strings.xml | 12 +- fenix/app/src/main/res/values-fr/strings.xml | 61 +++------ .../src/main/res/values-fy-rNL/strings.xml | 16 ++- fenix/app/src/main/res/values-hsb/strings.xml | 62 +++------ fenix/app/src/main/res/values-hu/strings.xml | 61 +++------ fenix/app/src/main/res/values-ia/strings.xml | 61 +++------ fenix/app/src/main/res/values-is/strings.xml | 61 +++------ fenix/app/src/main/res/values-it/strings.xml | 61 +++------ fenix/app/src/main/res/values-iw/strings.xml | 58 +++------ fenix/app/src/main/res/values-kab/strings.xml | 118 ++++++++++++------ fenix/app/src/main/res/values-kk/strings.xml | 62 +++------ fenix/app/src/main/res/values-ko/strings.xml | 64 +++------- fenix/app/src/main/res/values-nl/strings.xml | 61 +++------ .../src/main/res/values-pt-rBR/strings.xml | 16 ++- .../src/main/res/values-pt-rPT/strings.xml | 16 ++- fenix/app/src/main/res/values-ru/strings.xml | 62 +++------ fenix/app/src/main/res/values-si/strings.xml | 7 ++ .../src/main/res/values-sv-rSE/strings.xml | 16 ++- fenix/app/src/main/res/values-tr/strings.xml | 16 ++- fenix/app/src/main/res/values-ug/strings.xml | 16 ++- .../src/main/res/values-zh-rCN/strings.xml | 53 ++------ .../src/main/res/values-zh-rTW/strings.xml | 62 +++------ .../app/src/main/res/values-ia/strings.xml | 2 + 32 files changed, 462 insertions(+), 853 deletions(-) diff --git a/android-components/components/feature/addons/src/main/res/values-azb/strings.xml b/android-components/components/feature/addons/src/main/res/values-azb/strings.xml index db78fcc56268..1e3e38101288 100644 --- a/android-components/components/feature/addons/src/main/res/values-azb/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-azb/strings.xml @@ -172,10 +172,16 @@ یئنی تاخیلان‌لار الده وار باشاریلی قورولدو %1$s + + %1$s قورماسی قیریلدی + + بو تاخیلانین قورماسی قیریلدی %1$s باشاریلی گوجلندی. %1$s باشاریلی گوجدن سالیندی. + + %1$s گوجدن سالماسی قیریلدی %1$s باشاریلی قالدیریلدی diff --git a/android-components/components/feature/prompts/src/main/res/values-kab/strings.xml b/android-components/components/feature/prompts/src/main/res/values-kab/strings.xml index 7df3a9d1a8e2..114f4be40826 100644 --- a/android-components/components/feature/prompts/src/main/res/values-kab/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-kab/strings.xml @@ -92,6 +92,11 @@ Inekcam yettwasumren + + SuƔer awal uffir iǧehden + + Sumer awal uffir iǧehden + Ales tuzna n yisefka ɣer usmel-a? Asmiren n usebter-a yezmer ad d-yerr tigawin n melmi kan, am tuzna n lexlaṣ neɣ asuffeɣ n uwennit snat tikkal. @@ -131,8 +136,6 @@ Tugna n umiḍan Fren asaǧǧăw n unekcum - - Fren amiḍan Qqen s umidan %1$s diff --git a/fenix/app/src/main/res/values-am/strings.xml b/fenix/app/src/main/res/values-am/strings.xml index 536812bbd505..82c9874c7538 100644 --- a/fenix/app/src/main/res/values-am/strings.xml +++ b/fenix/app/src/main/res/values-am/strings.xml @@ -238,6 +238,7 @@ አርትዕ መነሻ ገጽ አብጅ + የመነሻ ማያ ገጽ @@ -245,6 +246,9 @@ የአሰሳ ታሪክን አጥፋ + + ገጽ ተርጉም + የተመረጠ ቋንቋ @@ -1992,12 +1996,12 @@ የይለፍ ቃል አማራጮች ለመግቢያው የድር አድራሻ ሊስተካከል የሚችል የጽሑፍ መስክ። - - የይለፍ ቃል የድርጣቢያ አድራሻ ሊስተካከል የሚችል የጽሑፍ መስክ። + + ለድር ጣቢያው አድራሻ ሊስተካከል የሚችል የጽሑፍ መስክ። ለመግቢያው የተጠቃሚ ስም ሊስተካከል የሚችል የጽሑፍ መስክ። - - የይለፍ ቃል የተጠቃሚ ስም ሊስተካከል የሚችል የጽሑፍ መስክ። + + ለተጠቃሚ ስም ሊስተካከል የሚችል የጽሑፍ መስክ። ለመግቢያው የይለፍ ቃል ሊስተካከል የሚችል የጽሑፍ መስክ። @@ -2374,6 +2378,8 @@ በመተርጎም ሂደት ላይ + + ቋንቋ ይምረጡ የመተርጎም ችግር ነበር። እባክዎ እንደገና ይሞክሩ። diff --git a/fenix/app/src/main/res/values-bg/strings.xml b/fenix/app/src/main/res/values-bg/strings.xml index cc35bf1dae26..36085508a123 100644 --- a/fenix/app/src/main/res/values-bg/strings.xml +++ b/fenix/app/src/main/res/values-bg/strings.xml @@ -246,6 +246,7 @@ Персонализиране на началната страница + Начален екран @@ -253,6 +254,9 @@ Изчистване историята на разглеждане + + Превеждане на страницатa + Избран език @@ -265,8 +269,6 @@ Сканиране - - Търсеща машина Настройки на търсачките @@ -320,14 +322,14 @@ - Известията ви помагат да правите повече с %s + Известията ви помагат да правите повече с %s - Синхронизирайте вашите раздели между устройствата, управлявайте изтеглянията, получавайте съвети как да се възползвате максимално от защитата на поверителността на %s и много други. + Синхронизирайте вашите раздели между устройствата, управлявайте изтеглянията, получавайте съвети как да се възползвате максимално от защитата на поверителността на %s и много други. - Продължаване + Продължаване - Не сега + Не сега @@ -445,20 +447,10 @@ Режим „само HTTPS“ - - Намаляване на банерите за бисквитки Блокиране на банери за бисквитки Блокиране на банери за бисквитки при поверително сърфиране - - Намаляване на банерите за бисквитки - - Изключено - - Включено - - %1$s автоматично се опитва да отхвърли заявки за бисквитки от банери за бисквитки. Изключено за страницата @@ -476,34 +468,16 @@ Страницата не се поддържа - Включване на намаляването на банерите за бисквитки за %1$s? - Включване на скриването на банери за бисквитки за %1$s? - - Изключване на намаляването на банерите за бисквитки за %1$s? Изключване на скриването на банери за бисквитки за %1$s? %1$s не може автоматично да отхвърля заявките за бисквитки на този сайт. Можете да изпратите заявка за поддръжка на този сайт в бъдеще. - %1$s ще изчисти бисквитките на този сайт и ще презареди страницата. Изчистването на всички бисквитки може да ви отпише от системата или да изпразни количките ви за пазаруване. - Изключете и %1$s ще изчисти бисквитките и ще презареди този сайт. Това може да доведе до излизане от профила или изпразване на количките. - %1$s се опитва автоматично да отхвърли всички заявки за бисквитки на поддържаните сайтове. - Включете и %1$s ще се опита автоматично да откаже всички банери за бисквитки на този сайт. - - Да се разреши ли на %1$s да отхвърля банери за бисквитки? - - %1$s може автоматично да отхвърли много заявки за банери за бисквитки. - - Не сега - - Ще виждате по-малко заявки за бисквитки - - Разрешаване %1$s току-що отказа бисквитки вместо вас @@ -1292,8 +1266,6 @@ Прекратяване - Грешка при отпечатване - Страницата не може да бъде отпечатана Отпечатване @@ -1919,7 +1891,7 @@ Настройте фигура, PIN или парола за отключване на устройството, за да защитите запазените банкови карти, в случай че някой друг има достъп до него. - Настройте фигура, PIN или парола за отключване на устройството, за да защитите запазените карти от достъп, ако някой друг има вашето устройство. + Настройте фигура, PIN или парола за отключване на устройството, за да защитите запазените методи на плащане от достъп, ако някой друг има вашето устройство. Настройване @@ -2084,12 +2056,12 @@ Опции за парола Текстовото поле за редактиране на адреса на регистрация. - - Текстовото поле за редактиране на адреса на уебсайта на паролата. + + Текстовото поле за редактиране на адреса на уебсайта. Текстовото поле за редактиране на потребителското име на регистрация. - - Текстовото поле за редактиране на потребителското име на паролата. + + Текстовото поле за редактиране на потребителското име. Текстовото поле за редактиране на паролата на регистрация. @@ -2284,8 +2256,6 @@ Акцентите са от %s отзиви през последните 80 дни, които смятаме за надеждни.]]> Научете повече за %s. - - как %s от Mozilla определя качеството на рецензията как %s определя качеството на рецензията @@ -2469,6 +2439,8 @@ Превеждането е в процес на изпълнение + + Избор на език Възникна проблем при превода. Моля, опитайте отново. diff --git a/fenix/app/src/main/res/values-cy/strings.xml b/fenix/app/src/main/res/values-cy/strings.xml index 9bac5c4fc5c6..4f1c27f9cead 100644 --- a/fenix/app/src/main/res/values-cy/strings.xml +++ b/fenix/app/src/main/res/values-cy/strings.xml @@ -242,6 +242,7 @@ Cyfaddasu’r dudalen cartref + Sgrin cartref @@ -249,6 +250,9 @@ Dileu hanes pori + + Cyfieithu\'r dudalen + Dewi iaith @@ -1874,7 +1878,7 @@ Gosodwch batrwm cloi dyfais, PIN, neu gyfrinair i ddiogelu eich mewngofnodion a’ch cyfrineiriau sydd wedi’u cadw rhag i rhywun arall sydd â mynediad i’ch dyfais. - Gosodwch batrwm clo dyfais, PIN neu gyfrinair i ddiogelu eich cyfrineiriau sydd wedi\'u cadw rhag i rywun arall sydd â\'ch dyfais gael mynediad iddyn nhw. + Sefydlwch batrwm clo dyfais, PIN, neu gyfrinair i amddiffyn eich dulliau talu a arbedwyd rhag cael mynediad iddynt os oes gan rywun arall eich dyfais. Gosod nawr @@ -2036,12 +2040,12 @@ Dewisiadau cyfrineiriau Maes testun golygadwy cyfeiriad gwe’r mewngofnodi. - - Maes testun golygadwy ar gyfer cyfeiriad gwefan y cyfrinair. + + Y maes testun y gellir ei olygu ar gyfer cyfeiriad y wefan. Maes testun golygadwy enw defnyddiwr y mewngofnodi. - - Maes testun golygadwy ar gyfer enw defnyddiwr y cyfrinair. + + Y maes testun y gellir ei olygu ar gyfer yr enw defnyddiwr. Maes testun golygadwy cyfrinair y mewngofnodi. @@ -2422,6 +2426,8 @@ Wrthi\'n Cyfieithu + + Dewiswch iaith Bu anhawster wrth gyfieithu. Ceisiwch eto. diff --git a/fenix/app/src/main/res/values-da/strings.xml b/fenix/app/src/main/res/values-da/strings.xml index e1ff65330886..7e983ecc98c1 100644 --- a/fenix/app/src/main/res/values-da/strings.xml +++ b/fenix/app/src/main/res/values-da/strings.xml @@ -243,6 +243,7 @@ Tilpas startside + Startskærm @@ -250,6 +251,7 @@ Slet browser-historik + Valgt sprog @@ -261,8 +263,6 @@ Skan - - Søgetjeneste Indstillinger for søgetjenester @@ -316,23 +316,23 @@ - Meddelelser hjælper dig med at gøre mere med %s + Meddelelser hjælper dig med at gøre mere med %s - Synkroniser dine faneblade mellem enheder, håndter filhentninger, få tips til at få mest muligt ud af privatlivsbeskyttelse i %s og meget mere. + Synkroniser dine faneblade mellem enheder, håndter filhentninger, få tips til at få mest muligt ud af privatlivsbeskyttelse i %s og meget mere. - Fortsæt + Fortsæt - Ikke nu + Ikke nu - + Vi elsker at holde dig sikker - Vores non-profit-støttede browser hjælper med at forhindre virksomheder i at følge dig rundt på nettet i hemmelighed.\n\nLæs mere i vores privatlivserklæring. + Vores non-profit-støttede browser hjælper med at forhindre virksomheder i at følge dig rundt på nettet i hemmelighed.\n\nLæs mere i vores privatlivserklæring. - privatlivserklæring + privatlivserklæring Angiv som standard-browser @@ -435,22 +435,11 @@ Tilstanden Kun-HTTPS - - Reduktion af cookie-bannere Blokering af cookie-bannere Blokering af cookie-bannere i privat browsing - - Reducer cookie-bannere - - Fra - - Til - - - %1$s forsøger automatisk at afvise cookie-anmodninger på cookie-bannere. Slået fra for dette websted @@ -468,36 +457,17 @@ Webstedet understøttes ikke i øjeblikket - Slå reduktion af cookie-bannere til for %1$s? - Slå blokering af cookie-bannere til for %1$s? - - Slå reduktion af cookie-bannere fra for %1$s? Slå blokering af cookie-bannere fra for %1$s? %1$s kan ikke afvise cookie-anmodninger automatisk på dette websted. Du kan sende en anmodning om understøttelse af dette websted i fremtiden. - - %1$s vil rydde dette websteds cookies og genindlæse siden. Rydning af alle cookies kan logge dig ud eller tømme indkøbskurve. Slå funktionen fra - og %1$s vil rydde cookies og genindlæse webstedet. Dette kan logge dig ud eller tømme indkøbskurve. - %1$s forsøger automatisk at afvise alle cookie-anmodninger på understøttede websteder. - Slå funktionen til - og %1$s vil forsøge at afvise cookie-bannere automatisk på dette websted. - - Tillad %1$s at afvise cookie-bannere? - - %1$s kan automatisk afvise mange cookie-banner-anmodninger. - - Ikke nu - - Du vil få vist færre cookie-anmodninger - - - Tillad %1$s har lige afvist cookies for dig @@ -1272,8 +1242,6 @@ Afvis - Kunne ikke udskrive - Kunne ikke udskrive denne side Udskriv @@ -2171,8 +2139,6 @@ Højdepunkter stammer fra %s-anmeldelser fra de seneste 80 dage, som vi vurderer er pålidelige.]]> Læs mere om, %s. - - hvordan %s fra Mozilla afgør kvaliteten af anmeldelser hvordan %s afgør kvaliteten af anmeldelser @@ -2404,7 +2370,7 @@ Automatisk oversættelse - Vælg et sprog for at håndtere indstillingerne "oversæt altid" og "oversæt aldrig". + Vælg et sprog for at håndtere indstillingerne ”oversæt altid“ og ”oversæt aldrig“. diff --git a/fenix/app/src/main/res/values-de/strings.xml b/fenix/app/src/main/res/values-de/strings.xml index e2268dcae61e..f970da8caf36 100644 --- a/fenix/app/src/main/res/values-de/strings.xml +++ b/fenix/app/src/main/res/values-de/strings.xml @@ -247,6 +247,7 @@ Startbildschirm anpassen + Startbildschirm @@ -254,6 +255,9 @@ Browser-Chronik löschen + + Seite übersetzen + Gewählte Sprache @@ -265,8 +269,6 @@ Scannen - - Suchmaschine Suchmaschinen-Einstellungen @@ -322,14 +324,14 @@ - Benachrichtigungen helfen Ihnen, mehr aus %s zu machen + Benachrichtigungen helfen Ihnen, mehr aus %s zu machen - Synchronisieren Sie Ihre Tabs zwischen Geräten, verwalten Sie Downloads, erhalten Sie Tipps, wie Sie den Datenschutz von %s am besten nutzen können, und mehr. + Synchronisieren Sie Ihre Tabs zwischen Geräten, verwalten Sie Downloads, erhalten Sie Tipps, wie Sie den Datenschutz von %s am besten nutzen können, und mehr. - Fortsetzen + Fortsetzen - Nicht jetzt + Nicht jetzt @@ -447,21 +449,11 @@ Nur-HTTPS-Modus - - Reduzierung von Cookie-Bannern Cookie-Banner-Blocker Cookie-Banner-Blocker im privaten Modus - - Cookie-Banner reduzieren - - Aus - - Ein - - - %1$s versucht automatisch, Cookie-Anforderungen auf Cookie-Bannern abzulehnen. + Für diese Website deaktiviert @@ -479,35 +471,16 @@ Website derzeit nicht unterstützt - Cookie-Banner-Reduzierung für %1$s aktivieren? - Cookie-Banner-Blocker für %1$s aktivieren? - Cookie-Banner-Reduzierung für %1$s deaktivieren? - Cookie-Banner-Blocker für %1$s deaktivieren? %1$s kann Cookie-Anfragen auf dieser Website nicht automatisch ablehnen. Sie können eine Anfrage senden, um diese Website in Zukunft zu unterstützen. - - %1$s löscht die Cookies dieser Webseite und aktualisiert die Seite. Das Löschen aller Cookies kann Sie abmelden oder Warenkörbe leeren. Beim Deaktivieren löscht %1$s die Cookies und lädt die Website neu. Dies kann Sie abmelden oder Warenkörbe leeren. - %1$s versucht, alle Cookie-Anfragen auf unterstützten Websites automatisch abzulehnen. - Wenn dies aktiviert ist, wird %1$s versuchen, alle Cookie-Banner auf dieser Website automatisch abzulehnen. - - %1$s erlauben, Cookie-Banner abzulehnen? - - %1$s kann viele Cookie-Banner-Anfragen automatisch ablehnen. - - Nicht jetzt - - Sie sehen weniger Cookie-Anfragen - - - Erlauben %1$s hat Cookies für Sie abgelehnt @@ -1314,8 +1287,6 @@ Schließen - Drucken nicht möglich - Seite kann nicht gedruckt werden Drucken @@ -1943,7 +1914,7 @@ Richten Sie ein Gerätesperrmuster, eine PIN oder ein Passwort ein, um zu verhindern, dass auf Ihre gespeicherten Karten zugegriffen wird, wenn jemand anderes über Ihr Gerät verfügt. - Richten Sie ein Gerätesperrmuster, eine PIN oder ein Passwort ein, um zu verhindern, dass auf Ihre gespeicherten Karten zugegriffen wird, wenn jemand anderes über Ihr Gerät verfügt. + Richten Sie ein Gerätesperrmuster, eine PIN oder ein Passwort ein, um zu verhindern, dass auf Ihre gespeicherten Zahlungsmethoden zugegriffen wird, wenn jemand anderes über Ihr Gerät verfügt. Jetzt einrichten @@ -2105,12 +2076,12 @@ Passwort-Optionen Das bearbeitbare Textfeld für die Internetadresse der Zugangsdaten. - - Das bearbeitbare Textfeld für die Internetadresse des Passworts. + + Das bearbeitbare Textfeld für die Adresse der Website. Das bearbeitbare Textfeld für den Benutzernamen der Zugangsdaten. - - Das bearbeitbare Textfeld für den Benutzernamen des Passworts. + + Das bearbeitbare Textfeld für den Benutzernamen. Das bearbeitbare Textfeld für das Passwort der Zugangsdaten. @@ -2307,8 +2278,6 @@ Highlights stammen von %s-Bewertungen innerhalb der letzten 80 Tage, die wir für zuverlässig halten.]]> Weitere Informationen zu %s. - - Wie %s von Mozilla die Qualität der Bewertungen feststellt Wie %s die Qualität der Rezensionen bestimmt @@ -2492,6 +2461,8 @@ Übersetzung läuft + + Sprache auswählen Beim Übersetzen ist ein Problem aufgetreten. Bitte versuchen Sie es erneut. diff --git a/fenix/app/src/main/res/values-dsb/strings.xml b/fenix/app/src/main/res/values-dsb/strings.xml index a7f3174c372c..bbc3d240baff 100644 --- a/fenix/app/src/main/res/values-dsb/strings.xml +++ b/fenix/app/src/main/res/values-dsb/strings.xml @@ -243,6 +243,7 @@ Startowy bok pśiměriś + Startowa wobrazowka @@ -250,6 +251,9 @@ Pśeglědowańsku historiju lašowaś + + Bok pśełožyś + Wubrana rěc @@ -261,8 +265,6 @@ Scannowaś - - Pytnica Nastajenja pytnicow @@ -316,14 +318,14 @@ - Powěźeńki wam pomagaju, wěcej z %s cyniś + Powěźeńki wam pomagaju, wěcej z %s cyniś - Synchronizěrujśo swóje rejtariki mjazy rědami, zastojśo ześěgnjenja, dostańśo pokaze, aby mógał ze šcita priwatnosći %s nejlěpše wuwónoźeś , a wjace. + Synchronizěrujśo swóje rejtariki mjazy rědami, zastojśo ześěgnjenja, dostańśo pokaze, aby mógał ze šcita priwatnosći %s nejlěpše wuwónoźeś , a wjace. - Dalej + Dalej - Nic něnto + Nic něnto @@ -442,20 +444,10 @@ Modus Jano-HTTPS - - Reducěrowanje cookiejowych chórgojow Blokěrowak cookiejowych chórgojow Blokěrowak cookiejowych chórgojow w priwatnem modusu - - Cookieje chórgoje reducěrowaś - - Wušaltowany - - Zašaltowany - - %1$s awtomatiski wopytujo, cookiejowe napšašowanja na cookiejowych chórgojach wótpokazaś. Za toś to sedło znjemóžnjony @@ -473,34 +465,15 @@ Sedło se tuchylu njepódpěra - Reducěrowanje cookiejowych chórgojow za %1$s zmóžniś? - Blokěrowak cookiejowych chórgojow za %1$s zmóžniś? - Reducěrowanje cookiejowych chórgojow za %1$s znjemóžniś? - Blokěrowak cookiejowych chórgojow za %1$s znjemóžniś? %1$s njamóžo cookiejowe napšašowanja na toś tom sedle awtomatiski wótpokazaś. Móžośo pšosbu wó pódpěru toś togo sedła w pśichoźe pósłaś. - %1$s cookieje sedła lašujo a buźo bok aktualizěrowaś. Lašowanje wšych cookiejow móžo was pśizjawiś abo nakupowańske wózyki wuprozniś. - Pśi znjemóžnjanju %1$s cookieje lašujo a toś to sedło znowego zacytajo. To móžo was wótzjawiś abo nakupowańske kórbiki wuprozniś. - %1$s wopytujo wšykne cookiejowe napšašowanja na pódprětych sedłach awtomatiski wótpokazaś. - Zmóžniśo toś to nastajenje a %1$s wopytajo, wšykne cookiejowe chórgoje na toś tom sedle awtomatiski wótpokazaś. - - %1$s dowóliś, cookiejowe chórgoji wótpokazaś? - - %1$s móžo wjele napšašowanjow wó cookiejowych chórgojach awtomatiski wótpokazaś. - - Nic něnto - - Buźośo mjenjej cookiejowych napšašowanjow wiźeś - - - Dowóliś %1$s jo rowno wótpokazał cookieje za was @@ -1287,8 +1260,6 @@ Zachyśiś - Njedajo se śišćaś - Toś ten bok njedajo se śišćaś Śišćaś @@ -1909,7 +1880,7 @@ Nastajśo rědowy zastajeński muster, PIN abo gronidło, aby pśistupoju k swójim skłaźonym kreditowym kórtam zajźował, jolic něchten drugi ma waš rěd. - Nastajśo rědowy zastajeński muster, PIN abo gronidło, aby pśistupoju k swójim skłaźonym kórtam zajźował, jolic něchten drugi ma waš rěd. + Nastajśo rědowy zastajeński muster, PIN abo gronidło, aby pśistupoju k swójim skłaźonym płaśeńskim metodam zajźował, jolic něchten drugi ma waš rěd. Něnto konfigurěrowaś @@ -2071,12 +2042,12 @@ Gronidłowe nastajenja Wobźěłujobne tekstowe pólo za webadresu pśizjawjenja. - - Wobźěłujobne tekstowe pólo za adresu websedła gronidła. + + Wobźěłujobne tekstowe pólo za adresu websedła. Wobźěłujobne tekstowe pólo za wužywaŕske mě pśizjawjenja. - - Wobźěłujobne tekstowe pólo za wužywaŕske mě gronidła. + + Wobźěłujobne tekstowe pólo za wužywaŕske mě. Wobźěłujobne tekstowe pólo za gronidło pśizjawjenja. @@ -2275,8 +2246,6 @@ To buźo jano pomagaś, kwalitu pógódnośenjow pósuźiś, nic kwalitu produkt Wjerški su z pógódnośenjow %s w běgu slědnych 80 dnjow, kótarež mamy za spušćobne.]]> Zgóńśo wěcej wó %s. - - kak %s wót Mozilla kwalitu pógódnośenja póstaja kak %s kwalitu pógódnośenja póstaja @@ -2461,6 +2430,8 @@ To buźo jano pomagaś, kwalitu pógódnośenjow pósuźiś, nic kwalitu produkt Pśełoženje běžy + + Rěc wubraś Pśi pśełožowanju jo problem nastał. Pšosym wopytajśo hyšći raz. diff --git a/fenix/app/src/main/res/values-es-rAR/strings.xml b/fenix/app/src/main/res/values-es-rAR/strings.xml index 42eec1144a55..82c069db99ca 100644 --- a/fenix/app/src/main/res/values-es-rAR/strings.xml +++ b/fenix/app/src/main/res/values-es-rAR/strings.xml @@ -246,6 +246,7 @@ Personalizar inicio + Pantalla de inicio @@ -253,6 +254,9 @@ Borrar historial de navegación + + Traducir página + Idioma seleccionado @@ -1899,7 +1903,7 @@ Configurá un patrón de bloqueo del dispositivo, PIN o contraseña para proteger el acceso a tus tarjetas de crédito guardadas si alguien más tiene tu dispositivo. - Configurá un patrón de bloqueo del dispositivo, PIN o contraseña para proteger el acceso a tus tarjetas guardadas si alguien más tiene tu dispositivo. + Configurá un patrón de bloqueo del dispositivo, un PIN o una contraseña para proteger el acceso a tus métodos de pago guardados por si otra persona accede a tu dispositivo. Configurar ahora @@ -2063,12 +2067,12 @@ Opciones de contraseña El campo de texto editable para la dirección web del inicio de sesión. - - El campo de texto editable para la dirección del sitio web de la contraseña. + + El campo de texto editable para la dirección del sitio web. El campo de texto editable para el nombre de usuario del inicio de sesión. - - El campo de texto editable para el nombre de usuario de la contraseña. + + El campo de texto editable para el nombre de usuario. El campo de texto editable para la contraseña del inicio de sesión. @@ -2450,6 +2454,8 @@ Traducción en proceso + + Seleccionar un idioma Hubo un problema al traducir. Probá de nuevo. diff --git a/fenix/app/src/main/res/values-fi/strings.xml b/fenix/app/src/main/res/values-fi/strings.xml index b12aece6cf54..01e16e803004 100644 --- a/fenix/app/src/main/res/values-fi/strings.xml +++ b/fenix/app/src/main/res/values-fi/strings.xml @@ -247,6 +247,7 @@ Mukauta kotisivua + Aloitusnäkymä @@ -254,6 +255,9 @@ Tyhjennä selaushistoria + + Käännä sivu + Valittu kieli @@ -1895,8 +1899,6 @@ Suojaa tallennetut maksutavat Aseta laitteen avaukseen tarkoitettu kuvio, PIN-koodi tai salasana suojataksesi tallennetut luottokorttitiedot siltä varalta, että joku saa laitteesi haltuunsa. - - Määritä laitteen lukituskuvio, PIN-koodi tai salasana suojataksesi tallennettuja korttejasi, jos laitteesi on jollain toisella. Aseta nyt @@ -2059,12 +2061,8 @@ Salasanojen asetukset Muokattava tekstikenttä kirjautumisen verkkosivua varten. - - Salasanan verkkosivuston osoitteen muokattava tekstikenttä. Muokattava tekstikenttä kirjautumisen käyttäjätunnusta varten. - - Salasanan käyttäjätunnuksen muokattava tekstikenttä. Muokattava tekstikenttä kirjautumisen salasanaa varten. @@ -2426,6 +2424,8 @@ Käännös käynnissä + + Valitse kieli Käännettäessä ilmeni ongelma. Yritä uudelleen. diff --git a/fenix/app/src/main/res/values-fr/strings.xml b/fenix/app/src/main/res/values-fr/strings.xml index b833311408b0..c6e72ec33509 100644 --- a/fenix/app/src/main/res/values-fr/strings.xml +++ b/fenix/app/src/main/res/values-fr/strings.xml @@ -247,6 +247,7 @@ Personnaliser la page d’accueil + Écran d’accueil @@ -254,6 +255,9 @@ Effacer l’historique de navigation + + Traduire la page + Langue sélectionnée @@ -265,8 +269,6 @@ Scanner - - Moteur de recherche Paramètres du moteur de recherche @@ -322,14 +324,14 @@ - Les notifications vous aident à en faire plus avec %s + Les notifications vous aident à en faire plus avec %s - Synchronisez les onglets entre vos appareils, gérez les téléchargements, obtenez des conseils pour tirer le meilleur parti de la protection de la vie privée de %s, et bien plus. + Synchronisez les onglets entre vos appareils, gérez les téléchargements, obtenez des conseils pour tirer le meilleur parti de la protection de la vie privée de %s, et bien plus. - Continuer + Continuer - Plus tard + Plus tard @@ -448,21 +450,11 @@ Mode HTTPS uniquement - - Réduction des bannières de cookies Bloqueur de bannières de cookies Bloqueur de bannières de cookies en navigation privée - - Réduire les bannières de cookies - - Désactivée - - Activée - - - %1$s essaie automatiquement de refuser les demandes de dépôt de cookies quand une bannière de cookies s’affiche. + Désactivée pour ce site @@ -480,35 +472,16 @@ Site actuellement non pris en charge - Activer la réduction des bannières de cookies pour %1$s ? - Activer le bloqueur de bannières de cookies pour %1$s ? - Désactiver la réduction des bannières de cookies pour %1$s ? - Désactiver le bloqueur de bannières de cookies pour %1$s ? %1$s ne peut pas refuser automatiquement les demandes de dépôt de cookies sur ce site. Vous pouvez envoyer une demande afin que ce site soit pris en charge ultérieurement. - - %1$s effacera les cookies de ce site et actualisera la page. La suppression de tous les cookies peut vous déconnecter ou vider les paniers d’achats. Désactivez-le et %1$s effacera les cookies puis rechargera le site. Ces actions peuvent vous déconnecter ou vider votre panier. - %1$s peut essayer de refuser automatiquement les demandes de dépôt de cookies sur les sites compatibles. - Activez-le et %1$s tentera de refuser automatiquement les bannières de cookies sur ce site. - - Autoriser %1$s à refuser les bannières de cookies ? - - %1$s peut refuser automatiquement les demandes de dépôt de cookies. - - Plus tard - - Vous verrez moins de demandes de cookies - - - Autoriser %1$s a refusé les cookies pour vous @@ -1313,8 +1286,6 @@ Fermer - Impression impossible - Impression de la page impossible Imprimer @@ -1942,7 +1913,7 @@ Configurez un schéma de verrouillage, un code PIN ou un mot de passe pour protéger vos cartes bancaires enregistrées si jamais quelqu’un accède à votre appareil. - Configurez un schéma de verrouillage, un code PIN ou un mot de passe pour protéger vos cartes enregistrées si jamais quelqu’un accède à votre appareil. + Configurez un schéma de verrouillage, un code PIN ou un mot de passe pour protéger vos moyens de paiement enregistrés si jamais quelqu’un accède à votre appareil. Configurer maintenant @@ -2103,12 +2074,12 @@ Options de mot de passe Le champ de texte modifiable pour l’adresse web de l’identifiant. - - Le champ de texte modifiable pour l’adresse du site web du mot de passe. + + Le champ de texte modifiable pour l’adresse du site web. Le champ de texte modifiable pour le nom d’utilisateur de l’identifiant. - - Le champ de texte modifiable pour le nom d’utilisateur du mot de passe. + + Le champ de texte modifiable pour le nom d’utilisateur. Le champ de texte modifiable pour le mot de passe de l’identifiant. @@ -2306,8 +2277,6 @@ points essentiels proviennent des avis laissés sur %s au cours des 80 derniers jours que nous estimons fiables.]]> En savoir plus sur %s. - - la façon dont %s par Mozilla détermine la qualité d’un avis la façon dont %s détermine la qualité d’un avis @@ -2493,6 +2462,8 @@ Traduction en cours + + Choisissez une langue Un problème s’est produit lors de la traduction. Veuillez réessayer. diff --git a/fenix/app/src/main/res/values-fy-rNL/strings.xml b/fenix/app/src/main/res/values-fy-rNL/strings.xml index cd565c898a1d..2c2948d36c06 100644 --- a/fenix/app/src/main/res/values-fy-rNL/strings.xml +++ b/fenix/app/src/main/res/values-fy-rNL/strings.xml @@ -244,6 +244,7 @@ Startside oanpasse + Startskerm @@ -251,6 +252,9 @@ Navigaasjeskiednis wiskje + + Side oersette + Selektearre taal @@ -1874,7 +1878,7 @@ Stel in beskoattelingspatroan, pinkoade of wachtwurd foar jo apparaat yn om jo bewarre creditcards te beskermjen tsjin tagong as in oar jo apparaat hat. - Stel in beskoattelingspatroan, pinkoade of wachtwurd foar jo apparaat yn om jo bewarre kaarten te beskermjen tsjin tagong as in oar jo apparaat hat. + Stel in beskoattelingspatroan, pinkoade of wachtwurd foar jo apparaat yn om jo bewarre betellingsmetoaden te beskermjen tsjin tagong as in oar jo apparaat hat. No ynstelle @@ -2036,12 +2040,12 @@ Wachtwurdopsjes It bewurkbere tekstfjild foar it webadres fan de oanmelding. - - It bewurkbere tekstfjild foar it websiteadres fan it wachtwurd. + + It bewurkbere tekstfjild foar it websiteadres. It bewurkbere tekstfjild foar de brûkersnamme fan de oanmelding. - - It bewurkbere tekstfjild foar de brûkersnamme fan it wachtwurd. + + It bewurkbere tekstfjild foar de brûkersnamme. It bewurkbere tekstfjild foar it wachtwurd fan de oanmelding. @@ -2426,6 +2430,8 @@ Dizze analyze sil jo allinnich helpe om de beoardielingskwaliteit te beoardielen Oersetting wurdt útfierd + + Kies in taal Der is in probleem bard by it oersetten. Probearje it opnij. diff --git a/fenix/app/src/main/res/values-hsb/strings.xml b/fenix/app/src/main/res/values-hsb/strings.xml index 9858af0a4d5d..c3b5c4e7c235 100644 --- a/fenix/app/src/main/res/values-hsb/strings.xml +++ b/fenix/app/src/main/res/values-hsb/strings.xml @@ -243,6 +243,7 @@ Startowu stronu přiměrić + Startowa wobrazowka @@ -250,6 +251,9 @@ Přehladowansku historiju zhašeć + + Stronu přełožić + Wubrana rěč @@ -261,8 +265,6 @@ Skenować - - Pytawa Nastajenja pytawy @@ -316,14 +318,14 @@ - Zdźělenki wam pomhaja, wjace z %s činić + Zdźělenki wam pomhaja, wjace z %s činić - Synchronizujće swoje rajtarki mjez gratami, rjadujće sćehnjenja, dóstańće pokiwy, zo byšće móhł škit priwatnosće %s najlěpje zwužitkować, a wjace. + Synchronizujće swoje rajtarki mjez gratami, rjadujće sćehnjenja, dóstańće pokiwy, zo byšće móhł škit priwatnosće %s najlěpje zwužitkować, a wjace. - Dale + Dale - Nic nětko + Nic nětko @@ -441,21 +443,11 @@ Modus Jenož-HTTPS - - Redukowanje plackowych chorhojow Blokowak plackowych chorhojow Blokowak plackowych chorhojow w priwatnym modusu - - Plackowe chorhoje redukować - - - Wupinjeny - - Zapinjeny - - %1$s awtomatisce pospytuje, plackowe naprašowanja na plackowych chorhojach wotpokazać. + Za tute sydło znjemóžnjeny @@ -473,35 +465,15 @@ Sydło so tuchwilu njepodpěruje - Redukowanje plackowych chorhojow za %1$s zmóžnić? - Blokowak plackowych chorhojow za %1$s zmóžnić? - Redukowanje plackowych chorhojow za %1$s znjemóžnić? - Blokowak plackowych chorhojow za %1$s znjemóžnić? %1$s njemóže plackowe naprašowanja na tutym sydle awtomatisce wotpokazać. Móžeće próstwu wo podpěru tutoho sydła w přichodźe pósłać. - %1$s placki sydła zhaša a budźe stronu aktualizować. Zhašenje wšěch plackow móže was přizjewić abo nakupowanske wozyčki wuprózdnić. - Při znjemóžnjenju %1$s placki zhaša a tute sydło znowa začita. To móže was wotzjewić abo nakupowanske koše wuprózdnić. - %1$s pospytuje wšě plackowe naprašowanja na podpěranych sydłach awtomatisce wotpokazać. - Zmóžńće tute nastajenje a %1$s spyta, wšě plackowe chorhoje na tutym sydle awtomatisce wotpokazać. - - %1$s dowolić, plackowe chorhoje wotpokazać? - - %1$s móže wjele naprašowanjow wo plackowych chorhojach awtomatisce wotpokazać. - - Nic nětko - - - Budźeće mjenje plackowych naprašowanjow widźeć - - - Dowolić %1$s je runje placki za was wotpokazał @@ -1292,8 +1264,6 @@ Zaćisnyć - Njeda so ćišćeć - Tuta strona njeda so ćišćeć Ćišćeć @@ -1917,7 +1887,7 @@ Nastajće gratowy zawrjenski muster, PIN abo hesło, zo byšće přistupej k swojim składowanym kreditnym kartam zadźěwał, jeli něchtó druhi waš grat ma. - Nastajće gratowy zawrjenski muster, PIN abo hesło, zo byšće přistupej k swojim składowanym kartam zadźěwał, jeli něchtó druhi waš grat ma. + Nastajće gratowy zawrjenski muster, PIN abo hesło, zo byšće přistupej k swojim składowanym płácenskim metodam zadźěwał, jeli něchtó druhi waš grat ma. Nětko konfigurować @@ -2080,12 +2050,12 @@ Hesłowe nastajenja Wobdźěłujomne tekstowe polo za webadresu přizjewjenja. - - Wobdźěłujomne tekstowe polo za adresu websydła hesła. + + Wobdźěłujomne tekstowe polo za adresu websydła. Wobdźěłujomne tekstowe polo za wužiwarske mjeno přizjewjenja. - - Wobdźěłujomne tekstowe polo za wužiwarske mjeno hesła. + + Wobdźěłujomne tekstowe polo za wužiwarske mjeno. Wobdźěłujomne tekstowe polo za hesło přizjewjenja. @@ -2283,8 +2253,6 @@ To budźe jenož pomhać, kwalitu pohódnoćenjow posudźić, nic kwalitu produk Wjerški su z pohódnoćenjow %s w běhu poslednich 80 dnjow, kotrež mamy za spušćomne.]]> Zhońće wjace wo %s. - - kak %s wot Mozilla kwalitu pohódnoćenja postaja kak %s kwalitu pohódnoćenja postaja @@ -2469,6 +2437,8 @@ To budźe jenož pomhać, kwalitu pohódnoćenjow posudźić, nic kwalitu produk Přełoženje běži + + Rěč wubrać Při přełožowanju je problem nastał. Prošu spytajće hišće raz. diff --git a/fenix/app/src/main/res/values-hu/strings.xml b/fenix/app/src/main/res/values-hu/strings.xml index 3bbb88c795f7..3ffd638ea8a7 100644 --- a/fenix/app/src/main/res/values-hu/strings.xml +++ b/fenix/app/src/main/res/values-hu/strings.xml @@ -244,6 +244,7 @@ Kezdőoldal testreszabása + Kezdőképernyő @@ -251,6 +252,9 @@ Böngészési előzmények törlése + + Oldal fordítása + Kiválasztott nyelv @@ -262,8 +266,6 @@ Beolvasás - - Keresőszolgáltatás Keresőszolgáltatás-beállítások @@ -319,14 +321,14 @@ - Az értesítések segítségével még többet tehet a %s alkalmazással + Az értesítések segítségével még többet tehet a %s alkalmazással - Szinkronizálhatja lapjait az eszközök között, kezelheti a letöltéseket, tippeket kaphat a %s adatvédelmi funkcióinak maximális kihasználásához stb. + Szinkronizálhatja lapjait az eszközök között, kezelheti a letöltéseket, tippeket kaphat a %s adatvédelmi funkcióinak maximális kihasználásához stb. - Folytatás + Folytatás - Most nem + Most nem @@ -443,21 +445,11 @@ Csak HTTPS mód - - Sütibannerek számának csökkentése Sütibanner-blokkoló Sütibanner-blokkoló privát böngészésben - - A sütibannerek számának csökkentése - - Ki - - Be - - - A %1$s automatikusan megpróbálja elutasítani a sütibannereken lévő sütikéréseket. + Kikapcsolva erre az oldalra @@ -475,35 +467,16 @@ A webhely jelenleg nem támogatott - Bekapcsolja a sütibanner-csökkentést a következőnél: %1$s? - Bekapcsolja a sütibanner-blokkolót ennél a webhelynél: %1$s? - Kikapcsolja a sütibanner-csökkentést a következőnél: %1$s? - Kikapcsolja a sütibanner-blokkolót ennél a webhelynél: %1$s? A %1$s nem tudja automatikusan elutasítani a sütikéréseket ezen az oldalon. Küldhet egy kérést, hogy támogassák ezt az oldalt a jövőben. - - A %1$s törli a webhely sütijeit, és frissíti az oldalt. Az összes süti törlésével kijelentkezhet, vagy kiürítheti a kosarait. Kapcsolja ki, és a %1$s törli a sütiket, és újratölti a webhelyet. Ez kijelentkeztetheti, vagy kiürítheti a kosarait. - A %1$s automatikusan megpróbálja elutasítani az összes sütikérést a támogatott oldalakon. - Kapcsolja be, és a %1$s automatikusan megpróbálja elutasítani a sütibannereket ezen az oldalon. - - Engedélyezi a %1$s számára a sütibannerek elutasítását? - - A %1$s automatikusan elutasíthat számos sütibanneres kérést. - - Most nem - - Kevesebb sütikérést fog látni - - - Engedélyezés A %1$s most elutasította a sütiket Önnek @@ -1294,8 +1267,6 @@ Eltüntetés - Nem lehet kinyomtatni - Az oldal nem nyomtatható Nyomtatás @@ -1921,7 +1892,7 @@ Állítsa be az eszköz lezárási mintáját, PIN-kódját vagy jelszavát, hogy megvédje a mentett bankkártyáit, ha valaki hozzáfér az eszközéhez. - Állítsa be az eszköz lezárási mintáját, PIN-kódját vagy jelszavát, hogy megvédje a mentett kártyáit, ha valaki hozzáfér az eszközéhez. + Állítsa be az eszköz lezárási mintáját, PIN-kódját vagy jelszavát, hogy megvédje a mentett fizetési módjait, ha valaki hozzáfér az eszközéhez. Beállítás most @@ -2083,12 +2054,12 @@ Jelszóbeállítások A bejelentkezés webcíméhéz használandó szerkeszthető szövegmező. - - A jelszóhoz tartozó webhely címének szerkeszthető szövegmezője. + + A webhely címének szerkeszthető szövegmezője. A bejelentkezés felhasználónevéhez használandó szerkeszthető szövegmező. - - A jelszóhoz tartozó felhasználónév szerkeszthető szövegmezője. + + A felhasználónév szerkeszthető szövegmezője. A bejelentkezés jelszavához használandó szerkeszthető szövegmező. @@ -2286,8 +2257,6 @@ kiemelések a(z) %s értékeléseinek az elmúlt 80 napból származó és megbízhatónak ítélt elemei.]]> Tudjon meg többet arról, %s. - - hogy a %s by Mozilla hogyan határozza meg az értékelések minőségét hogyan határozza meg a %s az értékelések minőségét @@ -2477,6 +2446,8 @@ Fordítás folyamatban + + Válasszon nyelvet Hiba történt a fordítás során. Próbálja meg újra. diff --git a/fenix/app/src/main/res/values-ia/strings.xml b/fenix/app/src/main/res/values-ia/strings.xml index 0a3a6bcb5a28..9d9fe0724939 100644 --- a/fenix/app/src/main/res/values-ia/strings.xml +++ b/fenix/app/src/main/res/values-ia/strings.xml @@ -246,6 +246,7 @@ Personalisar pagina initial + Pagina initial @@ -253,6 +254,9 @@ Eliminar le chronologia de navigation + + Traducer le pagina + Lingua seligite @@ -264,8 +268,6 @@ Scannar - - Motor de recerca Parametros de motor de recerca @@ -321,15 +323,15 @@ - Le notificationes te adjuta a facer plus con %s + Le notificationes te adjuta a facer plus con %s - Synchronisa tu schedas inter apparatos, gere le discargamentos, recipe le suggestiones re maximisar le protection del confidentialitate de %s e altero ancora. + Synchronisa tu schedas inter apparatos, gere le discargamentos, recipe le suggestiones re maximisar le protection del confidentialitate de %s e altero ancora. - Continuar + Continuar - Non ora + Non ora @@ -448,22 +450,11 @@ Modo solo HTTPS - - Reduction de banner pro le cookie Blocada de bandiera pro cookie Blocada de bandiera pro cookie in navigation private - - Reducer banners pro le cookie - - - Disactivar - - Activar - - %1$s automaticamente prova a rejectar le requestas de cookies sur banners pro cookies. Disactivar pro iste sito @@ -481,36 +472,16 @@ Sito actualmente non supportate - Activar le reduction de banner pro cookie pro %1$s? - Activar le blocada de bandiera pro cookie pro %1$s? - Disactivar le reduction de banner pro cookie pro %1$s? - Disactivar le blocada de bandiera pro cookie pro %1$s? %1$s non pote automaticamente rejectar requestas de cookies sur iste sito. Tu pote inviar un requesta pro supportar iste sito in futuro. - - %1$s clarara le cookies de iste sito e actualisara le pagina. Clarar tote le cookies pote clauder tu connexion o vacuar tu carrettos de compras. Disactiva lo e %1$s clarara le cookies e recargara iste sito. Isto pote disconnecter le section o vacuara le carrettos de compras. - %1$s tenta rejectar automaticamente tote le requestas de cookies sur le sitos supportate. - Activa lo e %1$s essayara refusar automaticamente le bandieras pro cookies sur iste sito. - - Permitter a %1$s de rejectar bandieras pro cookies? - - %1$s pote rejectar automaticamente multe requestas de bandieras pro cookie. - - Non ora - - - Tu videra minus requestas de cookies - - - Permitter %1$s justo refusava cookies pro te @@ -1325,8 +1296,6 @@ Ignorar - Impossibile imprimer - Impossibile imprimer iste pagina Imprimer @@ -1961,7 +1930,7 @@ Implementa un patrono de blocada apparato, PIN o contrasigno pro proteger tu cartas de credito de esser accedite, si alcuno altere ha tu apparato. - Implementa un patrono de blocada apparato, PIN o contrasigno pro proteger tu cartas de esser accedite, si alcuno altere ha tu apparato. + Implementa un patrono de blocada apparato, PIN o contrasigno pro proteger tu methodos de pagamento salvate de esser accedite, si alcun altere ha tu apparato. Implementar ora @@ -2125,12 +2094,12 @@ Optiones de contrasigno Le campo de texto redigibile pro le adresse web del credentiales. - - Le campo de texto redigibile pro le adresse web del contrasigno. + + Le campo de texto redigibile pro le adresse del sito web. Le campo de texto redigibile pro le nomine de usator del accesso. - - Le campo de texto redigibile pro le nomine de usator del contrasigno. + + Le campo de texto redigibile pro le nomine de usator. Le campo de texto redigibile pro le contrasigno del credentiales. @@ -2328,8 +2297,6 @@ Aspectos notabile es ab %s recensiones in le ultime 80 dies que nos crede fidabile.]]> Pro saper plus re %s. - - como %s per Mozilla determina le qualitate de revision como %s determina le qualitate del revision @@ -2514,6 +2481,8 @@ Traduction in curso + + Elige un lingua Il habeva un problema traducente. Retenta. diff --git a/fenix/app/src/main/res/values-is/strings.xml b/fenix/app/src/main/res/values-is/strings.xml index 9028c3eeadf5..bdb531e46c93 100644 --- a/fenix/app/src/main/res/values-is/strings.xml +++ b/fenix/app/src/main/res/values-is/strings.xml @@ -242,6 +242,7 @@ Breyta Sérsníða upphafssíðu + Upphafsskjár @@ -249,6 +250,9 @@ Eyða vafurferli + + Þýða síðu + Valið tungumál @@ -260,8 +264,6 @@ Skanna - - Leitarvél Leitarvélastillingar @@ -316,14 +318,14 @@ - Tilkynningar hjálpa þér að gera meira með %s + Tilkynningar hjálpa þér að gera meira með %s - Samstilltu flipa á milli tækja, stýrðu niðurhali, fáðu ábendingar um að nýta persónuvernd %s sem best og fleira. + Samstilltu flipa á milli tækja, stýrðu niðurhali, fáðu ábendingar um að nýta persónuvernd %s sem best og fleira. - Halda áfram + Halda áfram - Ekki núna + Ekki núna @@ -441,21 +443,11 @@ Einungis-HTTPS-hamur - - Fækkun vefkökuborða Útilokun vefkökuborða Útilokun vefkökuborða í huliðsvafri - - Fækka vefkökuborðum - - Óvirkt - - Virkt - - - %1$s reynir sjálfkrafa að hafna vefkökubeiðnum á vefkökuborðum. + Slökkt fyrir þetta vefsvæði @@ -473,36 +465,17 @@ Vefsvæðið er ekki stutt í augnablikinu - Viltu kveikja á fækkun vefkökuborða fyrir %1$s? - Viltu kveikja á útilokun vefkökuborða fyrir %1$s? - - Viltu slökkva á fækkun vefkökuborða fyrir %1$s? Viltu slökkva á útilokun vefkökuborða fyrir %1$s? %1$s getur ekki hafnað sjálfvirkt vefkökubeiðnum á þessari síðu. Þú getur sent beiðni um stuðning við þessa síðu. - - %1$s mun hreinsa vefkökur þessa vefsvæðis og endurlesa síðuna. Að hreinsa allar vefkökur gæti skráð þig út eða tæmt innkaupakörfur. Slökktu á þessu og %1$s mun hreinsa vefkökur og endurlesa þetta vefsvæði. Það gæti skráð þig út eða tæmt innkaupakörfur. - %1$s reynir að hafna sjálfkrafa beiðnum um vefkökur á þeim vefsvæðum þar sem það er hægt. - Kveiktu á þessu og %1$s mun reyna að hafna sjálfkrafa öllum vefkökuborðum á þessu vefsvæði. - - Leyfa %1$s að hafna vefkökuborðum? - - %1$s getur reynt að hafna sjálfkrafa beiðnum um vefkökur. - - Ekki núna - - Þú munt sjá færri beiðnir um vefkökur - - - Leyfa %1$s var að hafna vefkökum fyrir þína hönd @@ -1283,8 +1256,6 @@ Afgreiða - Ekki hægt að prenta - Ekki er hægt að prenta þessa síðu Prenta @@ -1902,7 +1873,7 @@ Settu upp læsimynstur, PIN-númer eða lykilorð til að vernda vistuðu greiðslukortin þín ef ske kynni að einhver annar komist yfir tækið þitt. - Settu upp læsimynstur, PIN-númer eða lykilorð til að vernda vistuðu greiðslukortin þín ef ske kynni að einhver annar komist yfir tækið þitt. + Settu upp læsimynstur, PIN-númer eða lykilorð til að vernda vistuðu greiðslumátana þína ef ske kynni að einhver annar komist yfir tækið þitt. Setja upp núna @@ -2064,12 +2035,12 @@ Valkostir lykilorðs Breytilegi textareiturinn fyrir veffang þessarar innskráningarinnar. - - Breytanlegi textareiturinn fyrir veffang lykilorðsins. + + Breytanlegi textareiturinn fyrir vistfang vefsvæðisins. Breytilegi textareiturinn fyrir notandanafn innskráningarinnar. - - Breytanlegi textareiturinn fyrir notandanafn lykilorðsins. + + Breytanlegi textareiturinn fyrir notandanafnið. Breytilegi textareiturinn fyrir lykilorð innskráningarinnar. @@ -2267,8 +2238,6 @@ Hápunktar eru úr umsögnum um %s frá síðustu 80 dögum sem við teljum vera áreiðanlegar.]]> Frekari upplýsingar um %s. - - hvernig %s frá Mozilla ákvarðar gæði umsagna hvernig %s ákvarðar gæði umsagna @@ -2453,6 +2422,8 @@ Þýðing í gangi + + Veldu tungumál Vandamál kom upp við að þýða. Reyndu aftur. diff --git a/fenix/app/src/main/res/values-it/strings.xml b/fenix/app/src/main/res/values-it/strings.xml index 42e0da8f3d53..8e50ec4f74e0 100644 --- a/fenix/app/src/main/res/values-it/strings.xml +++ b/fenix/app/src/main/res/values-it/strings.xml @@ -247,6 +247,7 @@ Personalizza pagina iniziale + Schermata principale @@ -254,6 +255,9 @@ Elimina cronologia di navigazione + + Traduci pagina + Lingua selezionata @@ -265,8 +269,6 @@ Leggi - - Motore di ricerca Impostazioni motori di ricerca @@ -322,14 +324,14 @@ - Le notifiche ti aiutano a ottenere di più da %s + Le notifiche ti aiutano a ottenere di più da %s - Sincronizza le schede tra dispositivi, gestisci download, ottieni suggerimenti per sfruttare al meglio la protezione della privacy di %s e molto altro ancora. + Sincronizza le schede tra dispositivi, gestisci download, ottieni suggerimenti per sfruttare al meglio la protezione della privacy di %s e molto altro ancora. - Continua + Continua - Non adesso + Non adesso @@ -448,21 +450,11 @@ Modalità solo HTTPS - - Riduzione banner per i cookie Blocco banner per i cookie Blocco banner per i cookie in navigazione anonima - - Riduci i banner per i cookie - - Disattivata - - Attiva - - - %1$s cerca automaticamente di rifiutare le richieste di cookie quando viene visualizzato un banner per i cookie. + Disattivata per questo sito @@ -480,35 +472,16 @@ Sito attualmente non supportato - Attivare la riduzione banner per i cookie su %1$s? - Attivare il blocco banner per i cookie in %1$s? - Disattivare la riduzione banner per i cookie su %1$s? - Disattivare il blocco banner per i cookie in %1$s? %1$s non può rifiutare automaticamente le richieste di cookie su questo sito. Puoi inviare una richiesta per supportare questo sito in futuro. - - %1$s eliminerà i cookie per questo sito e aggiornerà la pagina. L’eliminazione dei cookie potrebbe disconnetterti dal sito o svuotare eventuali carrelli in sospeso. Dopo la disattivazione %1$s rimuove i cookie e ricarica la pagina. Questo potrebbe disconnetterti dal sito o svuotare eventuali carrelli in sospeso. - %1$s cerca di rifiutare automaticamente le richieste di cookie nei siti supportati. - Attivalo e %1$s cercherà di rifiutare automaticamente i banner per i cookie su questo sito. - - Consentire a %1$s di rifiutare i banner per i cookie? - - %1$s può rifiutare automaticamente i banner per i cookie in diversi siti. - - Non adesso - - Vedrai meno richieste per i cookie - - - Consenti %1$s ha appena rifiutato dei cookie per te @@ -1317,8 +1290,6 @@ Chiudi - Impossibile stampare - Impossibile stampare questa pagina Stampa @@ -1949,7 +1920,7 @@ Imposta una sequenza di blocco, PIN o password per impedire a chi si impossessa del dispositivo di visualizzare le carte di credito salvate. - Imposta una sequenza di blocco, PIN o password per impedire a chi si impossessa del dispositivo di visualizzare le carte di credito salvate. + Imposta una sequenza di blocco, PIN o password per impedire a chi si impossessa del dispositivo di visualizzare i metodi di pagamento salvati. Imposta adesso @@ -2112,12 +2083,12 @@ Opzioni password Il campo di testo modificabile per l’indirizzo web delle credenziali - - Il campo di testo modificabile per l’indirizzo del sito web della password. + + Il campo di testo modificabile per l’indirizzo del sito web. Il campo di testo modificabile per il nome utente delle credenziali - - Il campo di testo modificabile per il nome utente. + + Il campo di testo modificabile per il nome utente. Il campo di testo modificabile per la password delle credenziali @@ -2316,8 +2287,6 @@ in evidenza provengono dalle recensioni su %s degli ultimi 80 giorni che riteniamo affidabili.]]> Scopri ulteriori informazioni su %s. - - come %s by Mozilla determina la qualità delle recensioni come %s determina la qualità delle recensioni @@ -2505,6 +2474,8 @@ Traduzione in corso + + Scegli una lingua Si è verificato un problema durante la traduzione. Riprova. diff --git a/fenix/app/src/main/res/values-iw/strings.xml b/fenix/app/src/main/res/values-iw/strings.xml index 7ae3a56c490d..72c8c8a79542 100644 --- a/fenix/app/src/main/res/values-iw/strings.xml +++ b/fenix/app/src/main/res/values-iw/strings.xml @@ -242,6 +242,7 @@ התאמה אישית של מסך הבית + מסך הבית @@ -249,6 +250,9 @@ מחיקת היסטורית גלישה + + תרגום הדף + שפה נבחרת @@ -260,8 +264,6 @@ סריקה - - מנוע חיפוש הגדרות מנוע חיפוש @@ -316,14 +318,14 @@ - התראות עוזרות לך לעשות יותר עם %s + התראות עוזרות לך לעשות יותר עם %s - סנכרון הלשוניות שלך בין מכשירים, ניהול הורדות, קבלת טיפים להפקת המירב מהגנת הפרטיות של %s ועוד. + סנכרון הלשוניות שלך בין מכשירים, ניהול הורדות, קבלת טיפים להפקת המירב מהגנת הפרטיות של %s ועוד. - המשך + המשך - לא כעת + לא כעת @@ -440,20 +442,10 @@ מצב HTTPS בלבד - - צמצום כרזות עוגיות חוסם כרזות עוגיות חוסם כרזות עוגיות בגלישה פרטית - - צמצום כרזות עוגיות - - כבוי - - פעיל - - ‏%1$s מנסה לדחות בקשות עוגיות אוטומטית בכרזות עוגיות. כבוי עבור אתר זה @@ -472,33 +464,15 @@ האתר לא נתמך כרגע - להפעיל צמצום כרזות עוגיות לאתר %1$s? - להפעיל חוסם כרזות עוגיות לאתר %1$s? - להשבית צמצום כרזות עוגיות לאתר %1$s? - להשבית חוסם כרזות עוגיות לאתר %1$s? ל־%1$s אין אפשרות לדחות באופן אוטומטי בקשות עוגיות באתר הזה. אפשר לשלוח בקשה לתמוך באתר הזה בעתיד. - ‏%1$s ינקה את העוגיות של אתר זה וירענן את הדף. ניקוי כל העוגית עשוי לנתק את החשבון שלך מהאתר או לרוקן את עגלת הקניות שלך. - כיבוי אפשרות זו תגרום לכך ש־%1$s ינקה עוגיות ויטען מחדש את אתר זה. פעולה זו עשויה לנתק את החשבון שלך מהאתר או לרוקן את עגלת הקניות שלך. - ‏%1$s מנסה לדחות באופן אוטומטי את כל בקשות העוגיות באתרים נתמכים. - הפעלת אפשרות זו תגרום לכך ש־%1$s ינסה לסרב באופן אוטומטי לכל כרזות העוגיות באתר זה. - - לאפשר ל־%1$s לדחות כרזות עוגיות? - - ‏%1$s יכול לדחות באופן אוטומטי מגוון רחב של בקשות כרזות עוגיות. - - לא כעת - - תוצגנה פחות בקשות עוגיות - - לאפשר ‏%1$s הרגע סירב לעוגיות עבורך @@ -1290,8 +1264,6 @@ סגירה - לא ניתן להדפיס - לא ניתן להדפיס דף זה הדפסה @@ -1913,7 +1885,7 @@ ניתן להגדיר תבנית נעילת מכשיר, קוד או ססמה כדי להגן על כרטיסי האשראי השמורים שלך מפני גורמים בלתי מהימנים שמחזיקים במכשיר שלך. - ניתן להגדיר תבנית נעילת מכשיר, קוד או ססמה כדי להגן על אמצעי התשלום השמורים שלך מפני גורמים בלתי מהימנים שמחזיקים במכשיר שלך. + ניתן להגדיר תבנית נעילת מכשיר, קוד או ססמה כדי להגן על אמצעי התשלום השמורים שלך מפני גורמים בלתי מהימנים שמחזיקים במכשיר שלך. להגדיר כעת @@ -2075,12 +2047,12 @@ אפשרויות ססמה שדה הטקסט הניתן לעריכה עבור כתובת האתר של הכניסה. - - שדה הטקסט הניתן לעריכה עבור כתובת האתר של הססמה. + + שדה הטקסט הניתן לעריכה עבור כתובת האתר. שדה הטקסט הניתן לעריכה עבור שם המשתמש של הכניסה. - - שדה הטקסט הניתן לעריכה עבור שם המשתמש של הססמה. + + שדה הטקסט הניתן לעריכה עבור שם המשתמש. שדה הטקסט הניתן לעריכה עבור הססמה של הכניסה. @@ -2279,8 +2251,6 @@ הדגשים הם מסקירות של %s במהלך 80 הימים האחרונים, שאנו מאמינים שהן אמינות.]]> מידע נוסף על %s. - - כיצד %s מבית Mozilla קובע את איכות הסקירות כיצד %s קובע את איכות הסקירות @@ -2465,6 +2435,8 @@ התרגום בתהליך + + בחירת שפה אירעה שגיאה בתרגום. נא לנסות שוב. diff --git a/fenix/app/src/main/res/values-kab/strings.xml b/fenix/app/src/main/res/values-kab/strings.xml index 2e204dcc394e..cce974e94703 100644 --- a/fenix/app/src/main/res/values-kab/strings.xml +++ b/fenix/app/src/main/res/values-kab/strings.xml @@ -216,6 +216,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Ales amtawi Nadi deg usebter + + Suqel asebter Sekles ɣer tegrumma @@ -246,6 +248,7 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Sagen asebter agejdan + Agilal agejdan @@ -253,6 +256,10 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Sfeḍ azray n tunigin + + + Suqel asebter + Fren tutlayt @@ -264,8 +271,6 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Snirem - - Amsedday unadi Iɣewwaṛen n umsedday n unadi @@ -320,20 +325,25 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara - Ilɣa ttɛawanen ad tgeḍ ugar akked %s + Ilɣa ttɛawanen ad tgeḍ ugar akked %s - Mtawi iccaren-ik•im gar yibenkan, sefrek isadaren, awi iwellihen akken ad tfarseḍ deg ummesten n tbaḍnit n %s, d wugar. + Mtawi iccaren-ik•im gar yibenkan, sefrek isadaren, awi iwellihen akken ad tfarseḍ deg ummesten n tbaḍnit n %s, d wugar. - Kemmel + Kemmel - Mačči tura + Mačči tura + + + Tasertit tabaḍnit n Firefox Nḥemmel ad teqqimeḍ d aɣellsan + Iminig-nneɣ tettallit yiwet n tkebbanit ur nettnadi ɣef tedrimt, tessewḥal tikebbaniyin ara ak-iḍefren deg web. + Iminig-nneɣ tettallit yiwet n tkebbanit ur nettnadi ɣef tedrimt, tessewḥal tikebbaniyin ara ak-iḍefren deg web.\n\nIssin ugar ɣef tsertit-nneɣ n tbaḍnit. @@ -436,21 +446,11 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Askar HTTPS-Only - - Asenqes n yiɣarracen n yinagan n tuqqna Amsewḥel n yiɣarracen n yinagan n tuqqna Amsewḥal n uɣerrac n yinagan n tuqqna deg tunigin tusligt - - Senqes iɣarracen n yinagan n tuqqna - - Yensa - - Yermed - - - %1$s iɛerreḍ s wudem awurman ad yagi isuturen n yinagan n tuqqna deg yiɣarracen n yinagan n tuqqna. + Sens i usmel-a @@ -468,34 +468,15 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Asmel-a ur yettusefrak ara akka tura - Rmed asenqes n yiɣerracen n yinagan n tuqqna i %1$s? - Rmed amsewḥel n yiɣerracen n yinagan n tuqqna i %1$s? - - Sens asenqes n yiɣerracen n yinagan n tuqqna i %1$s? Sens amsewḥel n yiɣerracen n yinagan n tuqqna i %1$s? %1$s ur yezmir ara ad yagi issutar n trusi n yinagan n tuqqna s wudem awurman ɣef usmel-a. Tzemreḍ ad tazneḍ assuter i tallalt n usmel-a ɣer sdat. - - %1$s ad isfeḍ inagan n tuqqna n usmel-a syen ad issesfer asebter. Asfaḍ meṛṛa n yinagan n tuqqna yezmer ad ak·am-isseḥbes tuqqna neɣ ad yenɣel tiqecwalin n tiɣtin. Sens ma d %1$s ad yesfeḍ inagan n tuqqna sakin ad yales asali n usmel-a. Atagi ad ak-isuffeɣ neɣ ad isilem tikarḍiwin-ik n tiɣin. - - %1$s yettaɛraḍ s wudem awurman ad yagi issutar n yinagan n tuqqna deg yismal i ten-yessefraken. - - Sireg %1$s ad yagi iɣarracen n yinagan n tuqqna? - - %1$s yezmer ad yagi aṭas yissutar n yiɣarracen n yinagan n tuqqna s wudem awurman. - - Mačči tura - - Ad twaliḍ drus n yissutar n yinagan n tuqqna - - - Sireg %1$s yugi inagan n tuqqna i kečč @@ -602,6 +583,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Izegrar + + Sebded azegrir seg ufaylu Ilɣa @@ -711,6 +694,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Ticraḍ n yisebtar Inekcam + + Awalen uffiren Accaren yeldin @@ -738,6 +723,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Tikarḍiwin n usmad + + Tarrayin n uxelleṣ Tansiwin @@ -1283,8 +1270,6 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Zgel - Ur yizmir ara ad issigez - D awezɣi ad yettwasiggez usebtar-a Siggez @@ -1330,6 +1315,9 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Mdel iccaren usligen + + Mdel iccaren usligen? + Talzuzit @@ -1687,8 +1675,12 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Inekcam d wawalen uffiren + + Awalen uffiren Sekles inekcam d wawalen uffiren + + Sekles awalen uffiren Suter asekles @@ -1706,16 +1698,25 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Rnu anekcum + + Rnu awal uffir + Mtawi inekcam + + Mtawi awalen uffiren Mtawi inekcam gqr yibenkan Inekcam yettwakelsen + + Awalen uffiren yettwakelsen Anekcum i tḥerzeḍ ɣer %s ad d-ittwasken da. Issin ugar ɣef umtawi. + + Issin ugar ɣef umtawi Tisuraf @@ -1726,6 +1727,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Kkes akk tisuraf Nadi inekcam + + Nadi awalen uffiren Asmel web @@ -1785,6 +1788,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Tansiwin Tikarḍiwin n usmad + + Tarrayin n uxelleṣ Asekles d taččart tawurmant n tkarḍiwin @@ -1795,14 +1800,20 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Mtawi tikarḍiwin Rnu takarḍa n usmad + + Rnu takarḍa Sefrek tikerḍiwin yettwaskelsen + + Sefrek tikarḍiwin Rnu tansa Sefrek tansiwin Asekles d taččart tawurmant n tansiwin + + Sekles; teččareḍ tansiwin Seddu talɣut am wuṭṭunen, imayl akked tansiwin n usiweḍ @@ -1826,6 +1837,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Kkes takarḍa Tebɣiḍ s tidet ad tekkseḍ takarḍa-a n usmad? + + Kkes takarḍa? Kkes @@ -1840,8 +1853,12 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Ma ulac aɣilif sekcem uṭṭun ameɣtu n tkarḍa n usmad + + Sekcem uṭṭun n tkarḍa ameɣtu Ttxil-k·m ččar urti-a + + Rnu isem Kkes asekkeṛ i wakken ad twaliḍ tikerḍiwin-ik·im yettwaskelsen @@ -1894,6 +1911,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara D tidet tebɣiḍ ad tekkseḍ tansa-a? + + Kkes tansa-a? Kkes @@ -2008,14 +2027,24 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Urti n uḍris yettusenfal i wawal uffir n unekcum. Sekles isenfaln unekcum. + + Sekles isenfal. Ẓreg + + Ẓreg awal uffir Rnu anekcum amaynut + + Rnu awal uffir Awal uffir yettusra + + Sekcem awal uffir Isem n useqdac yettwasra + + Sekcem isem n useqdac Asenneftaɣ yettwasra @@ -2317,6 +2346,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Suqqel + + Fren tutlayt Yella wugur deg usuqqel. Ttxil-k ɛreḍ tikkelt niḍen. @@ -2333,6 +2364,9 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Ismenyifen n tsuqilt + + Sader tutlayin + Werǧin attsuqleḍ @@ -2356,6 +2390,10 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Tutlayin yellan iţusra + + %1$s (%2$s) Sader tutlayin @@ -2369,6 +2407,10 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Yettwafran + + Kkes %1$s (%2$s)? Kkes diff --git a/fenix/app/src/main/res/values-kk/strings.xml b/fenix/app/src/main/res/values-kk/strings.xml index d3f31dac6325..a960da8715bd 100644 --- a/fenix/app/src/main/res/values-kk/strings.xml +++ b/fenix/app/src/main/res/values-kk/strings.xml @@ -240,6 +240,7 @@ Үй бетін баптау + Бастапқы экран @@ -247,6 +248,9 @@ Шолу тарихын өшіру + + Парақты аудару + Таңдалған тіл @@ -259,8 +263,6 @@ Сканерлеу - - Іздеу жүйесі Іздеу жүйесінің параметрлері @@ -315,14 +317,14 @@ - Хабарландырулар %s арқылы көбірек жұмыс бітіруге көмектеседі + Хабарландырулар %s арқылы көбірек жұмыс бітіруге көмектеседі - Беттерді құрылғылар арасында синхрондаңыз, жүктемелерді басқарыңыз, %s жекелігін қорғау мүмкіндігін барынша пайдалану туралы кеңестер алыңыз және т.б. + Беттерді құрылғылар арасында синхрондаңыз, жүктемелерді басқарыңыз, %s жекелігін қорғау мүмкіндігін барынша пайдалану туралы кеңестер алыңыз және т.б. - Жалғастыру + Жалғастыру - Қазір емес + Қазір емес @@ -440,21 +442,11 @@ Тек-HTTPS режимі - - Cookie баннерлерін азайту Cookie баннерлерін бұғаттаушы Жекелік шолу режиміндегі cookie баннерлерін бұғаттаушы - - Cookie баннерлерін азайту - - Сөндірулі - - Іске қосулы - - - %1$s cookie баннерлеріндегі cookie сұрауларын автоматты түрде қабылдамау әрекетін жасайды. + Бұл сайт үшін сөндірілген @@ -473,37 +465,17 @@ Сайтқа ағымдағы уақытта қолдау жоқ - %1$s үшін cookie баннерлерін азайту мүмкіндігін іске қосу керек пе? - %1$s үшін cookie баннерлерін бұғаттаушын іске қосу керек пе? - - %1$s үшін cookie баннерлерін азайту мүмкіндігін сөндіру керек пе? %1$s үшін cookie баннерлерін бұғаттаушын сөндіру керек пе? %1$s бұл сайттағы cookie сұрауларын автоматты түрде қабылдамай алмайды. Болашақта осы сайтқа қолдау көрсету туралы сұраным жібере аласыз. - - %1$s осы сайттың cookie файлдарын тазартып, бетті жаңартады. Барлық cookie файлдарын тазарту салдарынан сіз сайттан шығуыңыз мүмкін немесе дүкен себеттері тазартылуы мүмкін. Сөндіріңіз, %1$s қолданбасы cookie файлдарын тазартып, бұл сайтты қайта жүктейді. Бұл әрекет сайттардан шығуға немесе себетті босатуы мүмкін. - %1$s қолдау көрсетілетін сайттардағы барлық cookie сұрауларын автоматты түрде қабылдамау әрекетін жасайды. - Іске қосыңыз, және де %1$s осы сайттағы барлық cookie баннерлерінен автоматты түрде бас тартуға тырысады. - - %1$s үшін cookie баннерлерін қабылдамауға рұқсат бересіз бе? - - %1$s көптеген cookie баннер сұрауларын автоматты түрде қабылдамау әрекетін жасай алады. - - Қазір емес - - - Сіз азырақ cookie сұрауларын көресіз - - - Рұқсат ету %1$s сіз үшін жаңа ғана cookie файлдарынан бас тартты @@ -1284,8 +1256,6 @@ Тайдыру - Баспаға шығару мүмкін емес - Бұл бетті басып шығару мүмкін емес Баспаға шығару @@ -1908,7 +1878,7 @@ Бөтен адам сіздің құрылғыңызда болса, одан сақталған несиелік карталарды қорғау үшін құрылғының бұғаттау үлгісін, PIN-кодын немесе парольді орнатыңыз. - Бөтен адам сіздің құрылғыңызда болса, одан сақталған карталарды қорғау үшін құрылғының бұғаттау үлгісін, PIN-кодын немесе парольді орнатыңыз. + Бөтен адам сіздің құрылғыңызда болса, одан сақталған төлем әдістерін қорғау үшін құрылғының бұғаттау үлгісін, PIN-кодын немесе парольді орнатыңыз. Қазір баптау @@ -2070,12 +2040,12 @@ Пароль опциялары Логиннің веб-адресі үшін түзетуге болатын мәтіндік өрісі. - - Парольдің веб-адресі үшін түзетуге болатын мәтіндік өрісі. + + Веб-сайт адресі үшін түзетуге болатын мәтіндік өрісі. Логиннің пайдаланушы аты үшін түзетуге болатын мәтіндік өрісі. - - Парольдің пайдаланушы аты үшін түзетуге болатын мәтіндік өрісі. + + Пайдаланушы аты үшін түзетуге болатын мәтіндік өрісі. Логиннің паролі үшін түзетуге болатын мәтіндік өрісі. @@ -2273,8 +2243,6 @@ Маңызды сәттер %s ішінен соңғы 80 күнде алынған, біз сенімді деп ойлайтын пікірлер негізінде алынды.]]> %s туралы көбірек білу. - - Mozilla ұсынған %s пікірлер сапасын қалай анықтайды %s пікірлер сапасын қалай анықтайды @@ -2461,6 +2429,8 @@ Аудару орындалуда + + Тілді таңдау Аудару кезінде мәселе орын алды. Қайталап көріңіз. diff --git a/fenix/app/src/main/res/values-ko/strings.xml b/fenix/app/src/main/res/values-ko/strings.xml index 157771aab48e..539fed7c058b 100644 --- a/fenix/app/src/main/res/values-ko/strings.xml +++ b/fenix/app/src/main/res/values-ko/strings.xml @@ -250,6 +250,7 @@ 홈페이지 개인화 + 홈 화면 @@ -257,6 +258,9 @@ 방문 기록 삭제 + + 페이지 번역 + 선택된 언어 @@ -268,8 +272,6 @@ 스캔 - - 검색 엔진 검색 엔진 설정 @@ -325,14 +327,14 @@ - 알림은 %s로 더 많은 작업을 수행하는 데 도움이 됩니다. + 알림은 %s로 더 많은 작업을 수행하는 데 도움이 됩니다. - 기기 간에 탭을 동기화하고, 다운로드를 관리하고, %s의 개인 정보 보호를 최대한 활용하는 방법에 대한 팁을 얻으세요. + 기기 간에 탭을 동기화하고, 다운로드를 관리하고, %s의 개인 정보 보호를 최대한 활용하는 방법에 대한 팁을 얻으세요. - 계속 + 계속 - 나중에 + 나중에 @@ -451,21 +453,11 @@ HTTPS 전용 모드 - - 쿠키 배너 감소 쿠키 배너 차단기 사생활 보호 모드의 쿠키 배너 차단기 - - 쿠키 배너 줄이기 - - 꺼짐 - - 켜짐 - - - %1$s는 자동으로 쿠키 배너에서 쿠키 요청을 거부하려고 시도합니다. + 이 사이트에서 꺼짐 @@ -483,37 +475,17 @@ 현재 지원되지 않는 사이트 - %1$s에 대해 쿠키 배너 감소를 켜시겠습니까? - %1$s에 쿠키 배너 차단기를 켜시겠습니까? - - %1$s에 대해 쿠키 배너 감소를 끄시겠습니까? %1$s에 쿠키 배너 차단기를 끄시겠습니까? %1$s는 이 사이트에서 쿠키 요청을 자동으로 거부할 수 없습니다. 나중에 이 사이트를 지원하도록 요청을 보낼 수 있습니다. - - %1$s는 이 사이트의 쿠키를 지우고 페이지를 새로 고침합니다. 모든 쿠키를 삭제하면 로그아웃되거나 장바구니가 비워질 수 있습니다. 끄면 %1$s가 쿠키를 지우고 이 사이트를 다시 로드합니다. 로그아웃되거나 장바구니가 비워질 수 있습니다. - %1$s는 지원되는 사이트에서 모든 쿠키 요청을 자동으로 거부하려고 시도합니다. - 켜면 %1$s가 이 사이트의 모든 쿠키 배너를 자동으로 거부하려고 시도합니다. - - %1$s가 쿠키 배너를 거부하도록 허용하시겠습니까? - - %1$s는 많은 쿠키 배너 요청을 자동으로 거부할 수 있습니다. - - 나중에 - - - 쿠키 요청이 더 적게 표시됩니다. - - - 허용 %1$s가 쿠키를 거부했습니다 @@ -1323,8 +1295,6 @@ 닫기 - 인쇄할 수 없음 - 이 페이지를 인쇄할 수 없음 인쇄 @@ -1957,11 +1927,11 @@ 신용 카드 보안 - 저장된 결제 수단을 보호하세요 + 저장된 결제 방법을 보호하세요 다른 사람이 내 기기를 가지고 있는 경우, 저장된 신용 카드에 접근하지 못하도록 기기 잠금 패턴, PIN 또는 비밀번호를 설정하세요. - 다른 사람이 내 기기를 가지고 있는 경우, 저장된 카드에 접근하지 못하도록 기기 잠금 패턴, PIN 또는 비밀번호를 설정하세요. + 다른 사람이 내 기기를 가지고 있는 경우, 저장된 결제 방법에 접근하지 못하도록 기기 잠금 패턴, PIN 또는 비밀번호를 설정하세요. 지금 설정 @@ -2124,12 +2094,12 @@ 비밀번호 옵션 로그인 웹 주소의 편집 가능한 텍스트 필드입니다. - - 비밀번호의 웹 사이트 주소에 대한 편집 가능한 텍스트 필드입니다. + + 웹 사이트 주소에 대한 편집 가능한 텍스트 필드입니다. 로그인 사용자 이름의 편집 가능한 텍스트 필드입니다. - - 비밀번호의 사용자 이름에 대한 편집 가능한 텍스트 필드입니다. + + 사용자 이름에 대한 편집 가능한 텍스트 필드입니다. 로그인 비밀번호의 편집 가능한 텍스트 필드입니다. @@ -2328,8 +2298,6 @@ 하이라이트는 지난 80일 동안 신뢰할 수 있는 %s의 리뷰에서 나온 것입니다.]]> %s에 대해 더 알아보세요. - - Mozilla의 %s이 리뷰 품질을 결정하는 방법 %s이 리뷰 품질을 결정하는 방법 @@ -2514,6 +2482,8 @@ 번역 진행 중 + + 언어 선택 번역하는 중에 문제가 발생했습니다. 다시 시도하세요. diff --git a/fenix/app/src/main/res/values-nl/strings.xml b/fenix/app/src/main/res/values-nl/strings.xml index 0018da0fa62f..27fb89c2f833 100644 --- a/fenix/app/src/main/res/values-nl/strings.xml +++ b/fenix/app/src/main/res/values-nl/strings.xml @@ -249,6 +249,7 @@ Startpagina aanpassen + Startscherm @@ -256,6 +257,9 @@ Navigatiegeschiedenis wissen + + Pagina vertalen + Geselecteerde taal @@ -267,8 +271,6 @@ Scannen - - Zoekmachine Instellingen zoekmachine @@ -324,14 +326,14 @@ - Meldingen helpen u meer te doen met %s + Meldingen helpen u meer te doen met %s - Synchroniseer uw tabbladen tussen apparaten, beheer downloads, ontvang tips over het optimaal benutten van de privacybescherming van %s en meer. + Synchroniseer uw tabbladen tussen apparaten, beheer downloads, ontvang tips over het optimaal benutten van de privacybescherming van %s en meer. - Doorgaan + Doorgaan - Niet nu + Niet nu @@ -448,21 +450,11 @@ Alleen-HTTPS-modus - - Reductie van cookiebanners Blokkering van cookiebanners Blokkering van cookiebanners tijdens privénavigatie - - Cookiebanners reduceren - - Uit - - Aan - - - %1$s probeert automatisch cookieverzoeken op cookiebanners te weigeren. + Uit voor deze website @@ -480,35 +472,16 @@ Website wordt momenteel niet ondersteund - Reductie van cookiebanners inschakelen voor %1$s? - Blokkering van cookiebanners inschakelen voor %1$s? - Reductie van cookiebanners uitschakelen voor %1$s? - Blokkering van cookiebanners uitschakelen voor %1$s? %1$s kan cookieverzoeken op deze website niet automatisch weigeren. U kunt een aanvraag sturen om deze website in de toekomst te ondersteunen. - - %1$s wist de cookies voor deze website en vernieuwt de pagina. Als alle cookies worden gewist, wordt u mogelijk afgemeld of worden winkelwagentjes geleegd. Schakel dit uit en %1$s zal cookies wissen en deze website opnieuw laden. Dit kan u afmelden of winkelwagentjes legen. - %1$s probeert alle cookieverzoeken op ondersteunde websites automatisch te weigeren. - Schakel dit in en %1$s zal proberen alle cookiebanners op deze website automatisch te weigeren. - - %1$s toestaan om cookiebanners te weigeren? - - %1$s kan veel cookiebannerverzoeken automatisch weigeren. - - Niet nu - - U ziet minder cookieverzoeken - - - Toestaan %1$s heeft zojuist cookies voor u geweigerd @@ -1297,8 +1270,6 @@ Sluiten - Kan niet afdrukken - Kan deze pagina niet afdrukken Afdrukken @@ -1921,7 +1892,7 @@ Stel een vergrendelingspatroon, pincode of wachtwoord voor uw apparaat in om uw opgeslagen creditcards te beschermen tegen toegang als iemand anders uw apparaat heeft. - Stel een vergrendelingspatroon, pincode of wachtwoord voor uw apparaat in om uw opgeslagen kaarten te beschermen tegen toegang als iemand anders uw apparaat heeft. + Stel een vergrendelingspatroon, pincode of wachtwoord voor uw apparaat in om uw opgeslagen betalingsmethoden te beschermen tegen toegang als iemand anders uw apparaat heeft. Nu instellen @@ -2083,12 +2054,12 @@ Wachtwoordopties Het bewerkbare tekstveld voor het webadres van de aanmelding. - - Het bewerkbare tekstveld voor het websiteadres van het wachtwoord. + + Het bewerkbare tekstveld voor het websiteadres. Het bewerkbare tekstveld voor de gebruikersnaam van de aanmelding. - - Het bewerkbare tekstveld voor de gebruikersnaam van het wachtwoord. + + Het bewerkbare tekstveld voor de gebruikersnaam. Het bewerkbare tekstveld voor het wachtwoord van de aanmelding. @@ -2286,8 +2257,6 @@ Hoogtepunten zijn afkomstig van beoordelingen van %s in de afgelopen 80 dagen die volgens ons betrouwbaar zijn.]]> Meer info over %s. - - hoe %s door Mozilla de beoordelingskwaliteit bepaalt hoe %s de beoordelingskwaliteit bepaalt @@ -2474,6 +2443,8 @@ Vertaling wordt uitgevoerd + + Kies een taal Er is een probleem opgetreden bij het vertalen. Probeer het opnieuw. diff --git a/fenix/app/src/main/res/values-pt-rBR/strings.xml b/fenix/app/src/main/res/values-pt-rBR/strings.xml index f31b19fc60cb..332fdda58ba0 100644 --- a/fenix/app/src/main/res/values-pt-rBR/strings.xml +++ b/fenix/app/src/main/res/values-pt-rBR/strings.xml @@ -245,6 +245,7 @@ Personalizar tela inicial + Tela inicial @@ -252,6 +253,9 @@ Apagar histórico de navegação + + Traduzir página + Selecionar idioma @@ -1884,7 +1888,7 @@ Configure um método de bloqueio do dispositivo (desenho, código PIN ou senha) para proteger o acesso a seus cartões de crédito salvos, caso outras pessoas usem seu dispositivo. - Configure um método de bloqueio do dispositivo (desenho, código PIN ou senha) para proteger o acesso a seus cartões salvos, caso outras pessoas usem seu dispositivo. + Configure um método de bloqueio do dispositivo (desenho, código PIN ou senha) para proteger o acesso a seus métodos de pagamento salvos, caso outras pessoas usem seu dispositivo. Configurar agora @@ -2047,12 +2051,12 @@ Opções de senhas O campo de texto editável do endereço web da conta. - - O campo de texto editável do endereço do site da senha. + + O campo de texto editável do endereço do site. O campo de texto editável do nome de usuário da conta. - - O campo de texto editável do nome de usuário da senha. + + O campo de texto editável do nome de usuário. O campo de texto editável da senha da conta. @@ -2439,6 +2443,8 @@ Tradução em andamento + + Escolha um idioma Houve um problema ao traduzir. Tente novamente. diff --git a/fenix/app/src/main/res/values-pt-rPT/strings.xml b/fenix/app/src/main/res/values-pt-rPT/strings.xml index 849bf639cec8..cfc3e91f19cb 100644 --- a/fenix/app/src/main/res/values-pt-rPT/strings.xml +++ b/fenix/app/src/main/res/values-pt-rPT/strings.xml @@ -244,6 +244,7 @@ Personalizar página inicial + Ecrã inicial @@ -251,6 +252,9 @@ Apagar histórico de navegação + + Traduzir página + Idioma selecionado @@ -1884,7 +1888,7 @@ Configure um padrão, PIN ou palavra-passe de bloqueio do dispositivo para impedir que os seus cartões de crédito guardados sejam acedidos por outra pessoa que tenha acesso ao seu dispositivo. - Configure um padrão, PIN ou palavra-passe de bloqueio do dispositivo para impedir que os seus cartões guardados sejam acedidos por outra pessoa que tenha acesso ao seu dispositivo. + Configure um padrão, PIN ou palavra-passe de bloqueio do dispositivo para impedir que os seus métodos de pagamento guardados sejam acedidos por outra pessoa que tenha acesso ao seu dispositivo. Configurar agora @@ -2046,12 +2050,12 @@ Opções de palavra-passe O campo de texto editável para o endereço de Internet da credencial. - - O campo de texto editável para o endereço da palavra-passe. + + O campo de texto editável para o endereço do site. O campo de texto editável para o nome de utilizador da credencial. - - O campo de texto editável para o nome de utilizador da palavra-passe. + + O campo de texto editável para o nome de utilizador. O campo de texto editável para a palavra-passe da credencial. @@ -2431,6 +2435,8 @@ Tradução Tradução em curso + + Escolha um idioma Ocorreu um problema com a tradução. Por favor, tente novamente. diff --git a/fenix/app/src/main/res/values-ru/strings.xml b/fenix/app/src/main/res/values-ru/strings.xml index 2e1347e2885e..6c1ec56f56a6 100644 --- a/fenix/app/src/main/res/values-ru/strings.xml +++ b/fenix/app/src/main/res/values-ru/strings.xml @@ -251,6 +251,7 @@ Изменить вид + Домашний экран @@ -258,6 +259,9 @@ Удалить историю веб-сёрфинга + + Перевести страницу + Текущий язык @@ -269,8 +273,6 @@ Считать - - Поисковая система Настройки поисковых систем @@ -326,14 +328,14 @@ - Уведомления помогают вам делать больше с %s + Уведомления помогают вам делать больше с %s - Синхронизируйте вкладки между устройствами, управляйте загрузками, получайте советы о том, как максимально эффективно использовать защиту конфиденциальности %s, и многое другое. + Синхронизируйте вкладки между устройствами, управляйте загрузками, получайте советы о том, как максимально эффективно использовать защиту конфиденциальности %s, и многое другое. - Продолжить + Продолжить - Не сейчас + Не сейчас @@ -451,22 +453,11 @@ Режим «Только HTTPS» - - Снижение числа уведомлений о куках - Блокировщик уведомления о куки Блокировщик уведомления о куки в приватном просмотре - - Снижать число уведомлений о куках - - Отключено - - Включено - - - %1$s автоматически пытается отклонить запросы кук в уведомлениях о куках. + Отключено для этого сайта @@ -484,35 +475,16 @@ В настоящее время сайт не поддерживается - Включить Снижение количества уведомлений о куках для %1$s? - Включить блокировщик уведомления о куки для %1$s? - Отключить Снижение количества уведомлений о куках для %1$s? - Выключить блокировщик уведомления о куки для %1$s? %1$s не может автоматически отклонять запросы на использование кук на этом сайте. Вы можете отправить запрос на поддержку этого сайта в будущем. - - %1$s удалит куки этого сайта и обновит страницу. Удаление всех кук может привести к выходу из системы или к пропаже покупок из корзины. Выключите, и %1$s удалит куки и перезагрузит этот сайт. Это может привести к выходу из системы или опустошению корзины покупок. - %1$s пытается автоматически отклонить все запросы кук на поддерживаемых сайтах. - Включите, и %1$s попытается автоматически отклонить все уведомления о куки на этом сайте. - - Разрешить %1$s отклонять уведомления о куках? - - %1$s может автоматически отклонять многие запросы уведомлений о куках. - - Не сейчас - - Вы увидите меньше запросов на принятие кук - - - Разрешить %1$s только что отказался от куки для вас @@ -1313,8 +1285,6 @@ Убрать - Невозможно распечатать - Не удалось распечатать эту страницу Печать @@ -1940,7 +1910,7 @@ Настройте графический ключ, Пин-код или пароль для блокировки устройства, чтобы защитить сохранённые банковские карты, если кто-либо ещё получит доступ к вашему устройству. - Настройте графический ключ, пин-код или пароль для разблокировки устройства, чтобы защитить сохранённые карты на случай, если кто-либо ещё получит доступ к вашему устройству. + Настройте графический ключ, Пин-код или пароль для разблокировки устройства, чтобы защитить сохранённые способы оплаты, на случай, если кто-либо ещё получит доступ к вашему устройству. Настроить сейчас @@ -2100,12 +2070,12 @@ Настройки пароля Редактируемое текстовое поле для веб-адреса логина. - - Редактируемое текстовое поле для адреса веб-сайта данного пароля. + + Редактируемое текстовое поле для адреса веб-сайта. Редактируемое текстовое поле для имени пользователя логина. - - Редактируемое текстовое поле для имени пользователя данного пароля. + + Редактируемое текстовое поле для имени пользователя. Редактируемое текстовое поле для пароля логина. @@ -2303,8 +2273,6 @@ Основные сведения взяты из отзывов на %s за последние 80 дней, которые мы считаем надежными.]]> Узнайте больше о %s. - - как %s от Mozilla определяет качество отзывов как %s определяет качество обзора @@ -2489,6 +2457,8 @@ Идёт перевод + + Выберите язык При переводе возникла проблема. Пожалуйста, попробуйте ещё раз. diff --git a/fenix/app/src/main/res/values-si/strings.xml b/fenix/app/src/main/res/values-si/strings.xml index 18e803ffd6cb..4cc16dd0fe7b 100644 --- a/fenix/app/src/main/res/values-si/strings.xml +++ b/fenix/app/src/main/res/values-si/strings.xml @@ -236,6 +236,7 @@ සංස්කරණය මුල්පිටුව අභිරුචිකරණය + මුල් තිරය @@ -243,6 +244,7 @@ පිරික්සුම් ඉතිහාසය මකන්න + තෝරාගත් භාෂාව @@ -1742,9 +1744,14 @@ ලිපින කළමනාකරණය ලිපින සුරැකීම හා ස්වයං පිරවීම + + ලිපින සුරැකීම හා පිරවීම අංක, වි-තැපැල් සහ බාර දීමේ ලිපින වැනි තොරතුරු ඇතුළත් කරන්න + + දුරකථන අංක සහ වි-තැපැල් ලිපින ඇතුළත් වේ + පත එක් කරන්න diff --git a/fenix/app/src/main/res/values-sv-rSE/strings.xml b/fenix/app/src/main/res/values-sv-rSE/strings.xml index 0f62e84dbea7..a7ab3de349d3 100644 --- a/fenix/app/src/main/res/values-sv-rSE/strings.xml +++ b/fenix/app/src/main/res/values-sv-rSE/strings.xml @@ -248,6 +248,7 @@ Anpassa startsidan + Startsidan @@ -255,6 +256,9 @@ Radera webbhistorik + + Översätt sida + Valt språk @@ -1893,7 +1897,7 @@ Konfigurera enhetens låsmönster, PIN eller lösenord för att skydda dina sparade kreditkort från åtkomst om någon annan har din enhet. - Konfigurera ett enhetslåsmönster, PIN-kod eller lösenord för att skydda dina sparade kort från att användas om någon annan använder din enhet. + Konfigurera ett enhetslåsmönster, PIN-kod eller lösenord för att skydda dina sparade betalningsmetoder från att användas om någon annan har din enhet. Konfigurera nu @@ -2056,12 +2060,12 @@ Lösenordsalternativ Det redigerbara textfältet för inloggningens webbadress. - - Det redigerbara textfältet för webbplatsadressen för lösenordet. + + Det redigerbara textfältet för webbplatsadressen. Det redigerbara textfältet för inloggningens användarnamn. - - Det redigerbara textfältet för användarnamnet till lösenordet. + + Det redigerbara textfältet för användarnamnet. Det redigerbara textfältet för inloggningens lösenord. @@ -2442,6 +2446,8 @@ Översättning pågår + + Välj ett språk Det uppstod ett problem med översättningen. Försök igen. diff --git a/fenix/app/src/main/res/values-tr/strings.xml b/fenix/app/src/main/res/values-tr/strings.xml index 0d816d01aeaf..927f22503d6f 100644 --- a/fenix/app/src/main/res/values-tr/strings.xml +++ b/fenix/app/src/main/res/values-tr/strings.xml @@ -244,6 +244,7 @@ Giriş sayfasını özelleştir + Ana ekran @@ -251,6 +252,9 @@ Gezinti geçmişini temizle + + Sayfayı çevir + Seçili dil @@ -1882,7 +1886,7 @@ Cihazınız başka birinin eline geçerse kayıtlı kartlarınıza erişilmesini önlemek için cihaz kilidi deseni, PIN veya parola ayarlayın. - Cihazınız başka birinin eline geçerse kayıtlı kartlarınıza erişilmesini önlemek için cihaz kilidi deseni, PIN veya parola ayarlayın. + Cihazınız başka birinin eline geçerse kayıtlı ödeme yöntemlerinize erişilmesini önlemek için cihaz kilidi deseni, PIN veya parola ayarlayın. Hemen ayarla @@ -2044,12 +2048,12 @@ Parola seçenekleri Hesabın web adresi için düzenlenebilir metin alanı. - - Parolanın web sitesi için düzenlenebilir metin alanı. + + Web sitesi adresi için düzenlenebilir metin alanı. Hesabın kullanıcı adı için düzenlenebilir metin alanı. - - Parolanın kullanıcı adı için düzenlenebilir metin alanı. + + Kullanıcı adı için düzenlenebilir metin alanı. Hesabın parolası için düzenlenebilir metin alanı. @@ -2432,6 +2436,8 @@ Çeviri devam ediyor + + Dil seçin Çeviri sırasında bir sorun oluştu. Lütfen yeniden deneyin. diff --git a/fenix/app/src/main/res/values-ug/strings.xml b/fenix/app/src/main/res/values-ug/strings.xml index 48fcd8d260b3..27f068117454 100644 --- a/fenix/app/src/main/res/values-ug/strings.xml +++ b/fenix/app/src/main/res/values-ug/strings.xml @@ -240,6 +240,7 @@ تەھرىرلەش باش بەتنى خاسلاشتۇر + باش ئېكران @@ -247,6 +248,9 @@ توركۆرگۈ تارىخىنى ئۆچۈر + + بەت تەرجىمىسى + تاللانغان تىل @@ -1864,7 +1868,7 @@ ئۈسكۈنە قۇلۇپلاش ئەندىزىسى، PIN ياكى ئىم ئورنىتىشنى تەڭشىسىڭىز، ئۈسكۈنىڭىز باشقىلارنىڭ قولىدا بولسىمۇ ساقلانغان ئىناۋەتلىك كارتىڭىزنى زىيارەت قىلالمايدۇ. - ئۈسكۈنە قۇلۇپلاش ئەندىزىسى، PIN ياكى ئىم ئورنىتىشنى تەڭشىسىڭىز، ئۈسكۈنىڭىز باشقىلارنىڭ قولىدا بولسىمۇ ساقلانغان كارتىلىرىڭىزنى زىيارەت قىلالمايدۇ. + ئۈسكۈنە قۇلۇپلاش ئەندىزىسى، PIN ياكى ئىم ئورنىتىشنى تەڭشىسىڭىز، ئۈسكۈنىڭىز باشقىلارنىڭ قولىدا بولسىمۇ ساقلانغان چىقىم قىلىش ئۇسۇلىڭىزنى زىيارەت قىلالمايدۇ. ھازىر تەڭشە @@ -2023,13 +2027,13 @@ ئىم تاللانمىسى كىرىشنىڭ تور ئادرېسىنى تەھرىرلىگىلى بولىدىغان تېكىست بۆلىكى. - - ئىمنىڭ تور بېكەت ئادرېسىدىكى تەھرىرلىگىلى بولىدىغان تېكىست بۆلىكى. + + تور بېكەت ئادرېسىنىڭ تەھرىرلىگىلى بولىدىغان تېكىست بۆلىكى. كىرىشنىڭ ئىشلەتكۈچى ئىسمىنى تەھرىرلىگىلى بولىدىغان تېكىست بۆلىكى. - - ئىمنىڭ ئىشلەتكۈچى ئىسمىدىكى تەھرىرلىگىلى بولىدىغان تېكىست بۆلىكى. + + ئىشلەتكۈچى ئاتىنىڭ تەھرىرلىگىلى بولىدىغان تېكىست بۆلىكى. كىرىشنىڭ ئىمىنى تەھرىرلىگىلى بولىدىغان تېكىست بۆلىكى. @@ -2413,6 +2417,8 @@ تەرجىمە قىلىنىۋاتىدۇ + + تىل تاللىنىدۇ تەرجىمە قىلىشتا مەسىلە كۆرۈلدى. قايتا سىناڭ. diff --git a/fenix/app/src/main/res/values-zh-rCN/strings.xml b/fenix/app/src/main/res/values-zh-rCN/strings.xml index abafc50e4578..d1402b96f239 100644 --- a/fenix/app/src/main/res/values-zh-rCN/strings.xml +++ b/fenix/app/src/main/res/values-zh-rCN/strings.xml @@ -250,6 +250,7 @@ 定制主页 + 主屏幕 @@ -257,6 +258,9 @@ 清除浏览历史 + + 翻译页面 + 选择的语言 @@ -268,8 +272,6 @@ 扫码 - - 搜索引擎 搜索引擎设置 @@ -327,14 +329,14 @@ - 允许通知可以让 %s 更贴心好用 + 允许通知可以让 %s 更贴心好用 - 在设备间同步标签页、管理下载、了解充分利用 %s 来保护隐私的窍门,还有更多实用功能。 + 在设备间同步标签页、管理下载、了解充分利用 %s 来保护隐私的窍门,还有更多实用功能。 - 继续 + 继续 - 暂时不要 + 暂时不要 @@ -449,21 +451,11 @@ HTTPS-Only 模式 - - 减少 Cookie 横幅 Cookie 横幅拦截器 隐私浏览中的 Cookie 横幅拦截器 - - 减少 Cookie 横幅 - - 关闭 - - 开启 - - - %1$s 会尝试自动拒绝 Cookie 横幅的 Cookie 请求。 + 在该网站关闭 @@ -481,36 +473,17 @@ 目前不支持该网站 - 要为 %1$s 开启“减少 Cookie 横幅”功能吗? - 要为 %1$s 开启 Cookie 横幅拦截器吗? - - 要为 %1$s 关闭“减少 Cookie 横幅”功能吗? 要为 %1$s 关闭 Cookie 横幅拦截器吗? %1$s 无法自动拒绝此站点上的 Cookie 请求。您可以请求将来对此站点的支持。 - - %1$s 将清除此网站的 Cookie 并刷新页面。清除 Cookie 可能会导致您退出登录,或清空购物车。 关闭后,%1$s 将清除 Cookie 并重新加载此网站。这可能导致退出登录或清空购物车。 - %1$s 会尝试在支持的网站上尽可能拒绝所有 Cookie 请求。 - 开启后,%1$s 将尝试自动拒绝此网站上的 Cookie 横幅。 - - 要允许 %1$s 拒绝 Cookie 横幅吗? - - %1$s 可自动拒绝许多 Cookie 横幅的请求。 - - 暂时不要 - - 您看到的 Cookie 请求会减少 - - - 允许 %1$s 刚刚为您拒绝了 Cookie 请求 @@ -1319,8 +1292,6 @@ 知道了 - 无法打印 - 无法打印此页面 打印 @@ -1803,7 +1774,7 @@ 保护您的登录名和密码 - 设置锁定方式、PIN 码或密码以保护您保存的登录名与密码,避免他人盗用。 + 设置设备锁定图案、PIN 或密码以保护您保存的登录名与密码,避免他人盗用。 稍后 @@ -1894,7 +1865,7 @@ 保护您的卡片信息 - 设置锁定方式、PIN 码或密码以保护您保存的卡片信息,避免他人盗用。 + 设置设备锁定图案、PIN 或密码以保护您保存的卡片信息,避免他人盗用。 立即设置 @@ -2233,8 +2204,6 @@ 最有帮助的评价选自我们认为可信的最近 80 天内的 %s 评价。]]> 详细了解%s - - 由 Mozilla 支持的 %s 判断评价质量的方式 %s 判断评价质量的方式 diff --git a/fenix/app/src/main/res/values-zh-rTW/strings.xml b/fenix/app/src/main/res/values-zh-rTW/strings.xml index 1ba4d2a4aa8b..eb86161ce3b0 100644 --- a/fenix/app/src/main/res/values-zh-rTW/strings.xml +++ b/fenix/app/src/main/res/values-zh-rTW/strings.xml @@ -248,6 +248,7 @@ 自訂首頁 + 主畫面 @@ -255,6 +256,9 @@ 清除瀏覽紀錄 + + 翻譯頁面 + 選擇的語言 @@ -266,8 +270,6 @@ 掃描 - - 搜尋引擎 搜尋引擎設定 @@ -323,14 +325,14 @@ - 透過通知,可幫助您使用 %s 做到更多事 + 透過通知,可幫助您使用 %s 做到更多事 - 在不同裝置間同步分頁、管理下載資料、獲得能讓 %s 的隱私權保護功能發揮到極致的使用秘訣,與更多資訊。 + 在不同裝置間同步分頁、管理下載資料、獲得能讓 %s 的隱私權保護功能發揮到極致的使用秘訣,與更多資訊。 - 繼續 + 繼續 - 現在不要 + 現在不要 @@ -448,21 +450,11 @@ 純 HTTPS 模式 - - 減少 Cookie 橫幅 Cookie 橫幅封鎖器 隱私瀏覽模式中的 Cookie 橫幅封鎖器 - - 減少 Cookie 橫幅 - - 關閉 - - 開啟 - - - %1$s 會自動嘗試拒絕網站 Cookie 橫幅上的設定請求。 + 對此網站關閉 @@ -480,36 +472,16 @@ 目前不支援的網站 - 要為 %1$s 開啟減少 Cookie 橫幅功能嗎? - 要為 %1$s 開啟 Cookie 橫幅封鎖器嗎? - 要為 %1$s 關閉減少 Cookie 橫幅功能嗎? - 要為 %1$s 關閉 Cookie 橫幅封鎖器嗎? %1$s 無法自動拒絕此網站上的 Cookie 請求。您可以請求我們未來支援此網站。 - - %1$s 將清除此網站的 Cookie 並重新載入頁面。清除 Cookie 可能會將您從網站登出,或清空購物車。 關閉封鎖器後,%1$s 將會清除此網站的 Cookie 並重新載入頁面。可能會導致您被登出或清空購物車。 - %1$s 可自動在支援的網站,為您拒絕網站設定 Cookie 的請求。 - 開啟封鎖器後,%1$s 就會對此網站自動嘗試拒絕所有 Cookie 橫幅。 - - 要讓 %1$s 為您拒絕 cookie 橫幅嗎? - - %1$s 可自動為您拒絕許多網站設定 Cookie 的請求。 - - 現在不要 - - - 您看到的 Cookie 請求會變少 - - - 允許 %1$s 剛為您拒絕了 Cookie @@ -1314,8 +1286,6 @@ 知道了! - 無法列印 - 無法列印此頁面 列印 @@ -1944,7 +1914,7 @@ 設定裝置解鎖圖形、PIN 碼或密碼來保護您儲存的信用卡資訊,避免別人盜用。 - 設定裝置解鎖圖形、PIN 碼或密碼來保護您儲存的卡片資訊,避免別人盜用。 + 設定裝置解鎖圖形、PIN 碼或密碼來保護您儲存的付款方式資訊,避免別人盜用。 立即設定 @@ -2106,12 +2076,12 @@ 密碼選項 登入資訊當中,網址的輸入欄位。 - - 網址的輸入欄位。 + + 網址的輸入欄位。 登入資訊當中,使用者名稱的輸入欄位。 - - 使用者名稱的輸入欄位。 + + 使用者名稱的輸入欄位。 登入資訊當中,密碼的輸入欄位。 @@ -2308,8 +2278,6 @@ 重點資訊是根據過去 80 天中,我們相信是可靠的 %s 評論所整理出的資訊。]]> 了解 %s 的更多資訊。 - - %s 如何判斷評論品質 %s 如何判斷評論品質 @@ -2493,6 +2461,8 @@ 翻譯中 + + 選擇一種語言 翻譯時發生問題,請再試一次。 diff --git a/focus-android/app/src/main/res/values-ia/strings.xml b/focus-android/app/src/main/res/values-ia/strings.xml index 91cdcc5e7c32..fe1a92ab36bf 100644 --- a/focus-android/app/src/main/res/values-ia/strings.xml +++ b/focus-android/app/src/main/res/values-ia/strings.xml @@ -85,6 +85,8 @@ Eliminar le chronologia de navigation? + Tocca o clara iste aviso pro cancellar con securitate tu chronologia de navigation. + Eliminar le chronologia de navigation From 35b79f9fa2780b18d8378f173291177ab2cabbac Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 1 Feb 2024 00:17:36 +0000 Subject: [PATCH 036/586] Update GeckoView (Nightly) to 124.0.20240131204036. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 703853914d63..43111b3e4b5b 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240131095100" + const val version = "124.0.20240131204036" /** * GeckoView channel From 6d10180e7bf63060768ebb07df68ed7844ed3185 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 31 Jan 2024 21:26:16 -0500 Subject: [PATCH 037/586] Bug 1877888 - Update Adjust to version 4.38.1 --- .../fenixdependencies/src/main/java/FenixDependenciesPlugin.kt | 2 +- .../focusdependencies/src/main/java/FocusDependenciesPlugin.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt b/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt index e4a769a07c2a..95761c572bc1 100644 --- a/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt +++ b/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt @@ -28,7 +28,7 @@ object FenixVersions { const val androidx_datastore = "1.0.0" const val google_accompanist = "0.30.1" - const val adjust = "4.35.1" + const val adjust = "4.38.1" const val installreferrer = "2.2" const val junit = "5.9.3" diff --git a/focus-android/plugins/focusdependencies/src/main/java/FocusDependenciesPlugin.kt b/focus-android/plugins/focusdependencies/src/main/java/FocusDependenciesPlugin.kt index d426a32f5866..95f9326d6c31 100644 --- a/focus-android/plugins/focusdependencies/src/main/java/FocusDependenciesPlugin.kt +++ b/focus-android/plugins/focusdependencies/src/main/java/FocusDependenciesPlugin.kt @@ -14,7 +14,7 @@ class FocusDependenciesPlugin : Plugin { object FocusVersions { object Adjust { - const val adjust = "4.35.1" + const val adjust = "4.38.1" const val install_referrer = "2.2" } From 165d04822f1d410e9d98d36e829c16e87d784c73 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 31 Jan 2024 21:27:11 -0500 Subject: [PATCH 038/586] Revert "Bug 1877888 - Update Adjust to version 4.38.1" This reverts commit 6d10180e7bf63060768ebb07df68ed7844ed3185. --- .../fenixdependencies/src/main/java/FenixDependenciesPlugin.kt | 2 +- .../focusdependencies/src/main/java/FocusDependenciesPlugin.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt b/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt index 95761c572bc1..e4a769a07c2a 100644 --- a/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt +++ b/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt @@ -28,7 +28,7 @@ object FenixVersions { const val androidx_datastore = "1.0.0" const val google_accompanist = "0.30.1" - const val adjust = "4.38.1" + const val adjust = "4.35.1" const val installreferrer = "2.2" const val junit = "5.9.3" diff --git a/focus-android/plugins/focusdependencies/src/main/java/FocusDependenciesPlugin.kt b/focus-android/plugins/focusdependencies/src/main/java/FocusDependenciesPlugin.kt index 95f9326d6c31..d426a32f5866 100644 --- a/focus-android/plugins/focusdependencies/src/main/java/FocusDependenciesPlugin.kt +++ b/focus-android/plugins/focusdependencies/src/main/java/FocusDependenciesPlugin.kt @@ -14,7 +14,7 @@ class FocusDependenciesPlugin : Plugin { object FocusVersions { object Adjust { - const val adjust = "4.38.1" + const val adjust = "4.35.1" const val install_referrer = "2.2" } From 211c245e045cac6f31a38566b2de51f21809c86f Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 1 Feb 2024 06:05:16 +0000 Subject: [PATCH 039/586] Update A-S to 124.20240201050339. --- .../plugins/dependencies/src/main/java/ApplicationServices.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt index eb0c7467df45..00ab62e97ad6 100644 --- a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt +++ b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // These lines are generated by android-components/automation/application-services-nightly-bump.py -val VERSION = "124.20240131050340" +val VERSION = "124.20240201050339" val CHANNEL = ApplicationServicesChannel.NIGHTLY object ApplicationServicesConfig { From cb7e919bec47ed1f39e8e86a39140e7ec5113f7b Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 30 Jan 2024 16:07:11 +0200 Subject: [PATCH 040/586] Bug 1877440 - Use only TestHelper snack bar verification function in UI tests --- .../java/org/mozilla/fenix/helpers/TestHelper.kt | 11 +++-------- .../java/org/mozilla/fenix/ui/BookmarksTest.kt | 1 + .../java/org/mozilla/fenix/ui/CollectionTest.kt | 3 ++- .../org/mozilla/fenix/ui/ComposeCollectionTest.kt | 2 +- .../org/mozilla/fenix/ui/ComposeContextMenusTest.kt | 1 + .../java/org/mozilla/fenix/ui/ContextMenusTest.kt | 1 + .../org/mozilla/fenix/ui/MediaNotificationTest.kt | 1 + .../java/org/mozilla/fenix/ui/SettingsHomepageTest.kt | 1 + .../java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt | 1 + .../java/org/mozilla/fenix/ui/TopSitesTest.kt | 1 + .../java/org/mozilla/fenix/ui/robots/BrowserRobot.kt | 5 ----- .../org/mozilla/fenix/ui/robots/CollectionRobot.kt | 3 --- .../org/mozilla/fenix/ui/robots/HomeScreenRobot.kt | 4 ---- .../fenix/ui/robots/SettingsSubMenuHomepageRobot.kt | 7 ------- .../org/mozilla/fenix/ui/robots/TabDrawerRobot.kt | 3 --- 15 files changed, 13 insertions(+), 32 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt index dedb39b2c2eb..a1f415a5cfc4 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt @@ -34,6 +34,8 @@ import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants.TAG +import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists +import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort @@ -103,14 +105,7 @@ object TestHelper { ).waitUntilGone(waitingTime) } - fun verifySnackBarText(expectedText: String) { - assertTrue( - mDevice.findObject( - UiSelector() - .textContains(expectedText), - ).waitForExists(waitingTime), - ) - } + fun verifySnackBarText(expectedText: String) = assertUIObjectExists(itemContainingText(expectedText)) fun verifyUrl(urlSubstring: String, resourceName: String, resId: Int) { waitUntilObjectIsFound(resourceName) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt index e99e0fc12b75..f5a9bd103e99 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt @@ -32,6 +32,7 @@ import org.mozilla.fenix.helpers.TestHelper.appContext import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem import org.mozilla.fenix.helpers.TestHelper.restartApp +import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.ui.robots.bookmarksMenu import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.homeScreen diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt index bf73f1682322..c917f4d3fc5f 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt @@ -18,6 +18,7 @@ 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.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.collectionRobot import org.mozilla.fenix.ui.robots.homeScreen @@ -490,7 +491,7 @@ class CollectionTest { selectTab(secondWebPage.title, numOfTabs = 2) }.clickSaveCollection { typeCollectionNameAndSave(collectionName) - verifySnackBarText("Tabs saved!") + verifySnackBarText("Collection saved!") } tabDrawer { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeCollectionTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeCollectionTest.kt index 990b02c892bd..a18366cc7453 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeCollectionTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeCollectionTest.kt @@ -475,7 +475,7 @@ class ComposeCollectionTest { verifyTabsMultiSelectionCounter(2) }.clickSaveCollection { typeCollectionNameAndSave(collectionName) - verifySnackBarText("Tabs saved!") + verifySnackBarText("Collection saved!") } composeTabDrawer(composeTestRule) { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeContextMenusTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeContextMenusTest.kt index 85a3e0c4ce2c..5e554b49d0a2 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeContextMenusTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeContextMenusTest.kt @@ -23,6 +23,7 @@ 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.clickSnackbarButton +import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.ui.robots.clickContextMenuItem import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.downloadRobot diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt index 4e95fba11bef..eeeec68a73e6 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt @@ -22,6 +22,7 @@ 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.clickSnackbarButton +import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.ui.robots.clickContextMenuItem import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.downloadRobot diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MediaNotificationTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MediaNotificationTest.kt index 5ea9084c6643..eba6aad2e6c6 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MediaNotificationTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MediaNotificationTest.kt @@ -20,6 +20,7 @@ import org.mozilla.fenix.helpers.HomeActivityTestRule 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.verifySnackBarText import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt index 4c525f09655d..bc4a78a9fbea 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt @@ -18,6 +18,7 @@ import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.restartApp +import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt index d09ac4e0c482..7072d6efaf9d 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt @@ -23,6 +23,7 @@ import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.closeApp import org.mozilla.fenix.helpers.TestHelper.restartApp +import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt index a8ecb175853e..a45320d365ef 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt @@ -20,6 +20,7 @@ import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton +import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.helpers.TestHelper.waitUntilSnackbarGone import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.homeScreen diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt index d2f2e0254134..c873372f26dd 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt @@ -163,11 +163,6 @@ class BrowserRobot { ), ) - fun verifySnackBarText(expectedText: String) { - mDevice.waitForObjects(mDevice.findObject(UiSelector().textContains(expectedText))) - assertUIObjectExists(itemContainingText(expectedText)) - } - fun verifyContextMenuForLocalHostLinks(containsURL: Uri) { // If the link is directing to another local asset the "Download link" option is not available // If the link is not re-directing to an external app the "Open link in external app" option is not available diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt index 029e5485d983..94626a88e5c8 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt @@ -169,9 +169,6 @@ class CollectionRobot { Log.i(TAG, "swipeTabRight: Waited for rule to be idle") } - fun verifySnackBarText(expectedText: String) = - itemContainingText(expectedText).waitForExists(waitingTime) - fun goBackInCollectionFlow() { backButton().click() Log.i(TAG, "goBackInCollectionFlow: Clicked collection creation flow back button") diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt index 286851db9994..5c7bfd4cb859 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt @@ -290,10 +290,6 @@ class HomeScreenRobot { fun swipeToTop() = onView(withId(R.id.sessionControlRecyclerView)).perform(ViewActions.swipeDown()) - fun verifySnackBarText(expectedText: String) { - mDevice.waitNotNull(findObject(By.text(expectedText)), waitingTime) - } - fun clickFirefoxLogo() = homepageWordmark().click() fun verifyThoughtProvokingStories(enabled: Boolean) { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHomepageRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHomepageRobot.kt index b6c9f1c7c2aa..6585616f2282 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHomepageRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHomepageRobot.kt @@ -23,8 +23,6 @@ import org.hamcrest.CoreMatchers.allOf import org.hamcrest.Matchers import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants -import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists -import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort import org.mozilla.fenix.helpers.TestHelper import org.mozilla.fenix.helpers.TestHelper.mDevice @@ -101,11 +99,6 @@ class SettingsSubMenuHomepageRobot { fun selectWallpaper(wallpaperName: String) = mDevice.findObject(UiSelector().description(wallpaperName)).click() - fun verifySnackBarText(expectedText: String) = - assertUIObjectExists( - itemContainingText(expectedText), - ) - fun verifySponsoredShortcutsCheckBox(checked: Boolean) = assertSponsoredShortcutsCheckBox(checked) class Transition { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt index c7b833dc85a6..419d2799af67 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt @@ -206,9 +206,6 @@ class TabDrawerRobot { } } - fun verifySnackBarText(expectedText: String) = - assertUIObjectExists(itemContainingText(expectedText)) - fun snackBarButtonClick(expectedText: String) { val snackBarButton = mDevice.findObject( From 6a1d384e3ecea83f015c2457a5b7587e7f0f4be9 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 1 Feb 2024 13:04:49 +0000 Subject: [PATCH 041/586] Update GeckoView (Nightly) to 124.0.20240201095346. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 43111b3e4b5b..f33deaacb17b 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240131204036" + const val version = "124.0.20240201095346" /** * GeckoView channel From 8d23695305a550ead07fb6c6ae43ee85462beca7 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Thu, 1 Feb 2024 11:31:43 +0200 Subject: [PATCH 042/586] Bug 1877938 - Remove redundant assertion functions from BookmarksRobot --- .../org/mozilla/fenix/ui/BookmarksTest.kt | 16 ++++----- .../mozilla/fenix/ui/ComposeBookmarksTest.kt | 17 ++++----- .../mozilla/fenix/ui/robots/BookmarksRobot.kt | 36 +++++-------------- 3 files changed, 26 insertions(+), 43 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt index f5a9bd103e99..2d2a1fc9723b 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt @@ -138,7 +138,7 @@ class BookmarksTest { clickAddFolderButton() addNewFolderName(bookmarksFolderName) navigateUp() - verifyKeyboardHidden() + verifyKeyboardHidden(isExpectedToBeVisible = false) verifyBookmarkFolderIsNotCreated(bookmarksFolderName) } } @@ -210,7 +210,7 @@ class BookmarksTest { ) {} }.openThreeDotMenu(defaultWebPage.title) { }.clickCopy { - verifyCopySnackBarText() + verifySnackBarText(expectedText = "URL copied") navigateUp() } @@ -497,7 +497,7 @@ class BookmarksTest { } bookmarksMenu { - verifyDeleteMultipleBookmarksSnackBar() + verifySnackBarText(expectedText = "Bookmarks deleted") clickUndoDeleteButton() verifyBookmarkedURL(firstWebPage.url.toString()) verifyBookmarkedURL(secondWebPage.url.toString()) @@ -515,7 +515,7 @@ class BookmarksTest { } bookmarksMenu { - verifyDeleteMultipleBookmarksSnackBar() + verifySnackBarText(expectedText = "Bookmarks deleted") } } @@ -603,7 +603,7 @@ class BookmarksTest { RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list)), ) { longTapDesktopFolder("Desktop Bookmarks") - verifySelectDefaultFolderSnackBarText() + verifySnackBarText(expectedText = "Can’t edit default folders") } } } @@ -626,7 +626,7 @@ class BookmarksTest { cancelDeletion() clickDeleteInEditModeButton() confirmDeletion() - verifyDeleteSnackBarText() + verifySnackBarText(expectedText = "Deleted") verifyBookmarkIsDeleted("Test_Page_1") } } @@ -787,13 +787,13 @@ class BookmarksTest { }.openThreeDotMenu("My Folder") { }.clickDelete { confirmDeletion() - verifyDeleteSnackBarText() + verifySnackBarText(expectedText = "Deleted") clickUndoDeleteButton() verifyFolderTitle("My Folder") }.openThreeDotMenu("My Folder") { }.clickDelete { confirmDeletion() - verifyDeleteSnackBarText() + verifySnackBarText(expectedText = "Deleted") verifyBookmarkIsDeleted("My Folder") verifyBookmarkIsDeleted("My Folder 2") verifyBookmarkIsDeleted("Test_Page_1") diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeBookmarksTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeBookmarksTest.kt index dbfd9afda1ae..26d31d920f28 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeBookmarksTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeBookmarksTest.kt @@ -28,6 +28,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem +import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.ui.robots.bookmarksMenu import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.homeScreen @@ -111,7 +112,7 @@ class ComposeBookmarksTest { clickAddFolderButton() addNewFolderName(bookmarksFolderName) navigateUp() - verifyKeyboardHidden() + verifyKeyboardHidden(isExpectedToBeVisible = false) verifyBookmarkFolderIsNotCreated(bookmarksFolderName) } } @@ -183,7 +184,7 @@ class ComposeBookmarksTest { ) {} }.openThreeDotMenu(defaultWebPage.title) { }.clickCopy { - verifyCopySnackBarText() + verifySnackBarText(expectedText = "URL copied") navigateUp() } @@ -469,7 +470,7 @@ class ComposeBookmarksTest { } bookmarksMenu { - verifyDeleteMultipleBookmarksSnackBar() + verifySnackBarText(expectedText = "Bookmarks deleted") clickUndoDeleteButton() verifyBookmarkedURL(firstWebPage.url.toString()) verifyBookmarkedURL(secondWebPage.url.toString()) @@ -487,7 +488,7 @@ class ComposeBookmarksTest { } bookmarksMenu { - verifyDeleteMultipleBookmarksSnackBar() + verifySnackBarText(expectedText = "Bookmarks deleted") } } @@ -575,7 +576,7 @@ class ComposeBookmarksTest { RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list)), ) { longTapDesktopFolder("Desktop Bookmarks") - verifySelectDefaultFolderSnackBarText() + verifySnackBarText(expectedText = "Can’t edit default folders") } } } @@ -598,7 +599,7 @@ class ComposeBookmarksTest { cancelDeletion() clickDeleteInEditModeButton() confirmDeletion() - verifyDeleteSnackBarText() + verifySnackBarText(expectedText = "Deleted") verifyBookmarkIsDeleted("Test_Page_1") } } @@ -764,13 +765,13 @@ class ComposeBookmarksTest { }.openThreeDotMenu("My Folder") { }.clickDelete { confirmDeletion() - verifyDeleteSnackBarText() + verifySnackBarText(expectedText = "Deleted") clickUndoDeleteButton() verifyFolderTitle("My Folder") }.openThreeDotMenu("My Folder") { }.clickDelete { confirmDeletion() - verifyDeleteSnackBarText() + verifySnackBarText(expectedText = "Deleted") verifyBookmarkIsDeleted("My Folder") verifyBookmarkIsDeleted("My Folder 2") verifyBookmarkIsDeleted("Test_Page_1") diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt index a8a143ae6d99..0176f326ce15 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt @@ -79,8 +79,6 @@ class BookmarksRobot { Log.i(TAG, "verifyCloseButton: Verified close bookmarks section button is visible") } - fun verifyDeleteMultipleBookmarksSnackBar() = assertSnackBarText("Bookmarks deleted") - fun verifyBookmarkFavicon(forUrl: Uri) { bookmarkFavicon(forUrl.toString()).check( matches( @@ -137,8 +135,6 @@ class BookmarksRobot { ) } - fun verifyDeleteSnackBarText() = assertSnackBarText("Deleted") - fun verifyUndoDeleteSnackBarButton() { snackBarUndoButton().check(matches(withText("UNDO"))) Log.i(TAG, "verifyUndoDeleteSnackBarButton: Verified bookmark deletion undo snack bar button") @@ -154,8 +150,6 @@ class BookmarksRobot { Log.i(TAG, "verifySnackBarHidden: Verified bookmark snack bar does not exist") } - fun verifyCopySnackBarText() = assertSnackBarText("URL copied") - fun verifyEditBookmarksView() = assertUIObjectExists( itemWithDescription("Navigate up"), @@ -167,7 +161,15 @@ class BookmarksRobot { itemWithResId("$packageName:id/bookmarkParentFolderSelector"), ) - fun verifyKeyboardHidden() = assertKeyboardVisibility(isExpectedToBeVisible = false) + fun verifyKeyboardHidden(isExpectedToBeVisible: Boolean) { + assertEquals( + isExpectedToBeVisible, + mDevice + .executeShellCommand("dumpsys input_method | grep mInputShown") + .contains("mInputShown=true"), + ) + Log.i(TAG, "assertKeyboardVisibility: Verified that the keyboard is visible: $isExpectedToBeVisible") + } fun verifyShareOverlay() { onView(withId(R.id.shareWrapper)).check(matches(isDisplayed())) @@ -189,8 +191,6 @@ class BookmarksRobot { Log.i(TAG, "verifyShareBookmarkUrl: Verified shared bookmarks url is displayed") } - fun verifySelectDefaultFolderSnackBarText() = assertSnackBarText("Can’t edit default folders") - fun verifyCurrentFolderTitle(title: String) { Log.i(TAG, "verifyCurrentFolderTitle: Looking for bookmark with title: $title") mDevice.findObject( @@ -468,21 +468,3 @@ private fun saveBookmarkButton() = onView(withId(R.id.save_bookmark_button)) private fun deleteInEditModeButton() = onView(withId(R.id.delete_bookmark_button)) private fun syncSignInButton() = onView(withId(R.id.bookmark_folders_sign_in)) - -private fun assertEmptyBookmarksList() = - onView(withId(R.id.bookmarks_empty_view)).check(matches(withText("No bookmarks here"))) - -private fun assertSnackBarText(text: String) { - snackBarText().check(matches(withText(containsString(text)))) - Log.i(TAG, "assertSnackBarText: Verified $text snack bar") -} - -private fun assertKeyboardVisibility(isExpectedToBeVisible: Boolean) { - assertEquals( - isExpectedToBeVisible, - mDevice - .executeShellCommand("dumpsys input_method | grep mInputShown") - .contains("mInputShown=true"), - ) - Log.i(TAG, "assertKeyboardVisibility: Verified that the keyboard is visible: $isExpectedToBeVisible") -} From e4485a15c7b22d10948dbf09ea2bb7d96ecca2d0 Mon Sep 17 00:00:00 2001 From: Gregory Mierzwinski Date: Thu, 1 Feb 2024 14:04:13 -0500 Subject: [PATCH 043/586] Bug 1682027 - Disable failing facebook android test. --- taskcluster/ci/browsertime/kind.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/taskcluster/ci/browsertime/kind.yml b/taskcluster/ci/browsertime/kind.yml index d250c257d537..72abff3d53c1 100644 --- a/taskcluster/ci/browsertime/kind.yml +++ b/taskcluster/ci/browsertime/kind.yml @@ -128,7 +128,8 @@ tasks: - [amazon-search, amazon-s] - [microsoft-support, micros-sup] - espn - - facebook + # Bug 1682027 - Disabled due to high failure rate + # - facebook - [youtube-watch, youtube-w] - allrecipes From 402df94d6a841b7b00733c9fb9529e8bfcb553d4 Mon Sep 17 00:00:00 2001 From: JohanLorenzo Date: Thu, 1 Feb 2024 19:32:05 +0000 Subject: [PATCH 044/586] Update Fenix initial_experiments.json based on the current first-run experiments in experimenter --- .../src/main/res/raw/initial_experiments.json | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/fenix/app/src/main/res/raw/initial_experiments.json b/fenix/app/src/main/res/raw/initial_experiments.json index 8543827c60f5..9369f46a4e9b 100644 --- a/fenix/app/src/main/res/raw/initial_experiments.json +++ b/fenix/app/src/main/res/raw/initial_experiments.json @@ -128,6 +128,99 @@ "locales": null, "publishedDate": "2024-01-25T17:36:03.153458Z" }, + { + "schemaVersion": "1.12.0", + "slug": "android-long-term-holdback-validation-first-run-sub-experiment", + "id": "android-long-term-holdback-validation-first-run-sub-experiment", + "arguments": {}, + "application": "org.mozilla.firefox_beta", + "appName": "fenix", + "appId": "org.mozilla.firefox_beta", + "channel": "beta", + "userFacingName": "Android Long-term Holdback Validation - First-run Sub-Experiment", + "userFacingDescription": "This is an internal test of new experiment tooling", + "isEnrollmentPaused": false, + "isRollout": false, + "bucketConfig": { + "randomizationUnit": "nimbus_id", + "namespace": "fenix-nimbus-is-ready-beta-1", + "start": 0, + "count": 10000, + "total": 10000 + }, + "featureIds": [ + "nimbus-is-ready" + ], + "probeSets": [], + "outcomes": [], + "branches": [ + { + "slug": "control", + "ratio": 1, + "feature": { + "featureId": "this-is-included-for-mobile-pre-96-support", + "enabled": false, + "value": {} + }, + "features": [ + { + "featureId": "nimbus-is-ready", + "enabled": true, + "value": { + "event-count": 2 + } + } + ] + }, + { + "slug": "treatment-a", + "ratio": 1, + "feature": { + "featureId": "this-is-included-for-mobile-pre-96-support", + "enabled": false, + "value": {} + }, + "features": [ + { + "featureId": "nimbus-is-ready", + "enabled": true, + "value": { + "event-count": 5 + } + } + ] + }, + { + "slug": "treatment-b", + "ratio": 1, + "feature": { + "featureId": "this-is-included-for-mobile-pre-96-support", + "enabled": false, + "value": {} + }, + "features": [ + { + "featureId": "nimbus-is-ready", + "enabled": true, + "value": { + "event-count": 10 + } + } + ] + } + ], + "targeting": "((is_already_enrolled) || ((isFirstRun == 'true') && (app_version|versionCompare('123.!') >= 0) && (enrollments_map['android-long-term-holdback-validation'] == 'delivery')))", + "startDate": "2024-02-01", + "enrollmentEndDate": null, + "endDate": null, + "proposedDuration": 28, + "proposedEnrollment": 7, + "referenceBranch": "control", + "featureValidationOptOut": false, + "localizations": null, + "locales": null, + "publishedDate": "2024-02-01T19:06:38.368231Z" + }, { "schemaVersion": "1.12.0", "slug": "beta-fx-122-android-set-to-default-notifications-timing-experiment", From e1e6e86bf6525a123518919bfc620108396ad3dc Mon Sep 17 00:00:00 2001 From: Matthew Tighe Date: Thu, 1 Feb 2024 10:32:59 -0800 Subject: [PATCH 045/586] Bug 1833666 - Update original RFC guidelines with stakeholders --- docs/rfcs/0001-rfc-process.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/rfcs/0001-rfc-process.md b/docs/rfcs/0001-rfc-process.md index 09919475460c..8f120399fa58 100644 --- a/docs/rfcs/0001-rfc-process.md +++ b/docs/rfcs/0001-rfc-process.md @@ -35,6 +35,7 @@ The high-level process of creating an RFC is: * Create an RFC document (like this one) using the template. * Open a pull request for the RFC document. * Ask for feedback on the pull request, via the [mailing list]() or in [chat](https://chat.mozilla.org/#/room/#android-components:mozilla.org). +* Assign or receive volunteers to act as stakeholders for the RFC. They will be responsible for a final decision on the proposal. This should include at least 2 internal team members, and at least 1 external team member if the proposal has been suggested from an external team. During the lifetime of an RFC: From 5c99d99d6fc22390f6cc8fbd9b1f3efbb834eedb Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 1 Feb 2024 22:48:39 +0000 Subject: [PATCH 046/586] Update GeckoView (Nightly) to 124.0.20240201173838. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index f33deaacb17b..fc7392c5d6e1 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240201095346" + const val version = "124.0.20240201173838" /** * GeckoView channel From a77ca3d09aa6102a24419e5d47a23ab31ef39225 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 2 Feb 2024 00:03:25 +0000 Subject: [PATCH 047/586] Import translations from android-l10n --- .../src/main/res/values-zh-rCN/strings.xml | 4 +- .../addons/src/main/res/values-am/strings.xml | 4 +- .../src/main/res/values-azb/strings.xml | 72 +++- .../addons/src/main/res/values-bg/strings.xml | 4 +- .../addons/src/main/res/values-ca/strings.xml | 2 + .../addons/src/main/res/values-cy/strings.xml | 4 +- .../addons/src/main/res/values-de/strings.xml | 4 +- .../src/main/res/values-dsb/strings.xml | 4 +- .../addons/src/main/res/values-el/strings.xml | 4 +- .../src/main/res/values-es-rAR/strings.xml | 4 +- .../src/main/res/values-es-rCL/strings.xml | 4 +- .../addons/src/main/res/values-fi/strings.xml | 4 +- .../src/main/res/values-fy-rNL/strings.xml | 4 +- .../src/main/res/values-hsb/strings.xml | 4 +- .../addons/src/main/res/values-ia/strings.xml | 4 +- .../addons/src/main/res/values-is/strings.xml | 4 +- .../addons/src/main/res/values-it/strings.xml | 4 +- .../addons/src/main/res/values-iw/strings.xml | 4 +- .../addons/src/main/res/values-kk/strings.xml | 4 +- .../addons/src/main/res/values-ko/strings.xml | 4 +- .../addons/src/main/res/values-nl/strings.xml | 4 +- .../addons/src/main/res/values-oc/strings.xml | 4 +- .../src/main/res/values-pa-rIN/strings.xml | 2 + .../src/main/res/values-pt-rBR/strings.xml | 4 +- .../src/main/res/values-pt-rPT/strings.xml | 4 +- .../addons/src/main/res/values-ru/strings.xml | 4 +- .../src/main/res/values-sv-rSE/strings.xml | 4 +- .../src/main/res/values-zh-rCN/strings.xml | 4 +- .../src/main/res/values-zh-rTW/strings.xml | 4 +- .../src/main/res/values-azb/strings.xml | 16 + .../src/main/res/values-azb/strings.xml | 45 +++ .../src/main/res/values-azb/strings.xml | 7 + .../src/main/res/values-azb/strings.xml | 53 +++ .../src/main/res/values-azb/strings.xml | 5 + .../src/main/res/values-azb/strings.xml | 59 +++ .../src/main/res/values-azb/strings.xml | 24 ++ .../src/main/res/values-azb/strings.xml | 5 + .../media/src/main/res/values-am/strings.xml | 11 +- .../media/src/main/res/values-azb/strings.xml | 18 + .../media/src/main/res/values-bg/strings.xml | 11 +- .../media/src/main/res/values-ca/strings.xml | 11 +- .../media/src/main/res/values-cy/strings.xml | 11 +- .../media/src/main/res/values-de/strings.xml | 11 +- .../media/src/main/res/values-dsb/strings.xml | 11 +- .../media/src/main/res/values-el/strings.xml | 11 +- .../src/main/res/values-es-rAR/strings.xml | 11 +- .../src/main/res/values-es-rCL/strings.xml | 11 +- .../media/src/main/res/values-fi/strings.xml | 11 +- .../media/src/main/res/values-fr/strings.xml | 11 +- .../src/main/res/values-fy-rNL/strings.xml | 11 +- .../media/src/main/res/values-hsb/strings.xml | 11 +- .../media/src/main/res/values-ia/strings.xml | 11 +- .../media/src/main/res/values-is/strings.xml | 11 +- .../media/src/main/res/values-it/strings.xml | 11 +- .../media/src/main/res/values-iw/strings.xml | 11 +- .../media/src/main/res/values-kk/strings.xml | 11 +- .../media/src/main/res/values-ko/strings.xml | 11 +- .../media/src/main/res/values-nl/strings.xml | 11 +- .../src/main/res/values-pa-rIN/strings.xml | 11 +- .../src/main/res/values-pt-rBR/strings.xml | 11 +- .../src/main/res/values-pt-rPT/strings.xml | 11 +- .../media/src/main/res/values-ru/strings.xml | 11 +- .../src/main/res/values-sv-rSE/strings.xml | 11 +- .../src/main/res/values-zh-rCN/strings.xml | 11 +- .../src/main/res/values-zh-rTW/strings.xml | 11 +- .../src/main/res/values-am/strings.xml | 36 ++ .../src/main/res/values-bg/strings.xml | 36 ++ .../src/main/res/values-ca/strings.xml | 36 ++ .../src/main/res/values-cy/strings.xml | 36 ++ .../src/main/res/values-de/strings.xml | 36 ++ .../src/main/res/values-dsb/strings.xml | 36 ++ .../src/main/res/values-el/strings.xml | 36 ++ .../src/main/res/values-es-rAR/strings.xml | 36 ++ .../src/main/res/values-es-rCL/strings.xml | 36 ++ .../src/main/res/values-fi/strings.xml | 36 ++ .../src/main/res/values-fr/strings.xml | 24 ++ .../src/main/res/values-fy-rNL/strings.xml | 36 ++ .../src/main/res/values-hsb/strings.xml | 36 ++ .../src/main/res/values-ia/strings.xml | 36 ++ .../src/main/res/values-is/strings.xml | 36 ++ .../src/main/res/values-it/strings.xml | 36 ++ .../src/main/res/values-iw/strings.xml | 36 ++ .../src/main/res/values-kk/strings.xml | 36 ++ .../src/main/res/values-ko/strings.xml | 36 ++ .../src/main/res/values-nl/strings.xml | 36 ++ .../src/main/res/values-oc/strings.xml | 25 ++ .../src/main/res/values-pa-rIN/strings.xml | 36 ++ .../src/main/res/values-pt-rBR/strings.xml | 36 ++ .../src/main/res/values-pt-rPT/strings.xml | 36 ++ .../src/main/res/values-ru/strings.xml | 36 ++ .../src/main/res/values-sv-rSE/strings.xml | 36 ++ .../src/main/res/values-zh-rCN/strings.xml | 36 ++ .../src/main/res/values-zh-rTW/strings.xml | 36 ++ fenix/app/src/main/res/values-ca/strings.xml | 358 ++++++++++++------ fenix/app/src/main/res/values-cy/strings.xml | 6 +- fenix/app/src/main/res/values-el/strings.xml | 64 +--- .../src/main/res/values-es-rCL/strings.xml | 61 +-- fenix/app/src/main/res/values-oc/strings.xml | 12 +- .../src/main/res/values-pa-rIN/strings.xml | 141 +++++-- .../src/main/res/values-zh-rCN/strings.xml | 101 ++++- .../src/main/res/values-zh-rTW/strings.xml | 18 +- .../src/main/res/values-zh-rCN/strings.xml | 3 + 102 files changed, 2084 insertions(+), 374 deletions(-) create mode 100644 android-components/components/feature/app-links/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/autofill/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/awesomebar/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/contextmenu/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/customtabs/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/downloads/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/findinpage/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/fxsuggest/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/media/src/main/res/values-azb/strings.xml diff --git a/android-components/components/browser/engine-system/src/main/res/values-zh-rCN/strings.xml b/android-components/components/browser/engine-system/src/main/res/values-zh-rCN/strings.xml index 5aeb03d3f798..52a4d15cfbd3 100644 --- a/android-components/components/browser/engine-system/src/main/res/values-zh-rCN/strings.xml +++ b/android-components/components/browser/engine-system/src/main/res/values-zh-rCN/strings.xml @@ -1,10 +1,10 @@ - 域名为 %1$s 的页面说: + 域名为 %1$s 的页面提示: - %2$s 要求您输入用户名和密码。该网站说:“%1$s” + %2$s 要求您输入用户名和密码。该网站提示:“%1$s” %1$s 要求您输入用户名和密码。 diff --git a/android-components/components/feature/addons/src/main/res/values-am/strings.xml b/android-components/components/feature/addons/src/main/res/values-am/strings.xml index a25dfd64053d..eafe800bd414 100644 --- a/android-components/components/feature/addons/src/main/res/values-am/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-am/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> በ%1$d ሌሎች ጎራዎች ላይ የእርስዎን ውሂብ ይድረሱበት + + %1$s፣ %2$d ከ%3$d የአሳሽ ትሮችን ይድረሱ @@ -75,7 +77,7 @@ ደራሲ - ደራሲያን + ደራሲያን መጨረሻ የተሻሻለው diff --git a/android-components/components/feature/addons/src/main/res/values-azb/strings.xml b/android-components/components/feature/addons/src/main/res/values-azb/strings.xml index 1e3e38101288..97a75c331cd5 100644 --- a/android-components/components/feature/addons/src/main/res/values-azb/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-azb/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> باشقا %1$d دامنه‌‌لرده دیتالاریزا ال چاتما + + %3$d -دن %2$d و %1$s موروچو تاغلارینا ال چاتما @@ -148,6 +150,8 @@ تاخیلان مودیریتی تاخیلان‌لار گئچیجی اولاراق گوجدن سالینمیش. + + بیر ویا نئچه تاخیلان دایاندیریلدی، بودا سیستمیزی ثابیتسیز ائله‌دی. تاخیلان‌لاری یئنی‌دن باشلات @@ -170,20 +174,86 @@ یئنی تاخیلان الده وار یئنی تاخیلان‌لار الده وار + + %2$s -یه %1$s اکله‌یین + + %1$s و %2$s\'یی %3$s\'ا اکله‌یین + + بونلاری %1$s\'ا اکله‌ییه + + فایرفاکس‌‍ین تاخیلان تکنولوژیسی مدرنلشیر. بو تاخیلان‌لار فایرفاکس ۷۵ و سونراکی یازیملارلا توتوشمایان چرچیوه‌لردن ایستیفاده ائدیر. + + ایندی توصیه اولونان اوزانتی‌لارین ایلک سئچیمی اوچون ساپورت وئریریق. + + تاخیلان یئندیریلیر و دوغرولانیر... + + تاخیلان‌لاری سورغولاماق آلینمادی. + + یئرلی %1$s اوچون و %2$s وارساییلان دیل اوچون ترجومه تاپیلمادی. باشاریلی قورولدو %1$s %1$s قورماسی قیریلدی بو تاخیلانین قورماسی قیریلدی + + باغلانتی خطاسی سببینه گؤره بو تاخیلان یئندیری‌لنمه‌دی. + + بو تاخیلانی قورماق مومکون اولمادی، چونکی خاراب گؤرونور. + + بو تاخیلانی قورماق مومکون اولمادی، چونکی دوغرولانمیب. + + %1$s قورولا بیلمه‌دی، چونکی او، %2$s %3$s ایله اویغون دئییل. + + %1$s قورماق اولمادی، چونکی اونون ثابیتلیک و یا امنیت موشکول‌لرینه سبب اولماسینین ریسکی چوخدور. %1$s باشاریلی گوجلندی. + + %1$s گوجلندیرمه‌سی قیریلدی %1$s باشاریلی گوجدن سالیندی. %1$s گوجدن سالماسی قیریلدی %1$s باشاریلی قالدیریلدی + + %1$s ایشدن سالماسی قیریلدی %1$s باشاریلی قالدیریلدی - + + %1$s قالدیریلماسی قیریلدی + + بو تاخیلان %1$s -ین اؤنجه‌کی بیر یازیمیندان داشیندی. + + تاخیلان + + %1$s تاخیلان + + آرتیق بیلین + + باشاریلی گونجللندی. + + هئچ گونجللمه یوخ + + خطا + + گونجل‌لییجی بیلگی‌لری + + سون چالیشما: + + دوروم: + + %1$s، %2$s لیستینه اکلندی. + + منودا آچین + + تامام، باشا دوشدوم + + آرتیق بیلین + + امنیت ویا ثابیتلیک موشکول‌لری سببی ایله %1$s گوجدن سالیندی. + + %1$s -نین گوونلی اولدوغو دوغورلانمادی و گوجدن سالیندی. + + %1$s سیزین %2$s یازیمیزا (%3$s یازیمی) اویغون دئییل. + diff --git a/android-components/components/feature/addons/src/main/res/values-bg/strings.xml b/android-components/components/feature/addons/src/main/res/values-bg/strings.xml index b463f2fe32f7..c1bbe47b67b9 100644 --- a/android-components/components/feature/addons/src/main/res/values-bg/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-bg/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Достъп до вашите данни от %1$d други домейни + + %1$s, %2$d от %3$d Достъп до разделите @@ -75,7 +77,7 @@ Автор - Автори + Автори Последно обновяване diff --git a/android-components/components/feature/addons/src/main/res/values-ca/strings.xml b/android-components/components/feature/addons/src/main/res/values-ca/strings.xml index 3d1a1782bdd6..9d877a50fb8a 100644 --- a/android-components/components/feature/addons/src/main/res/values-ca/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-ca/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Accedir a les vostres dades de %1$d altres dominis + + %1$s, %2$d de %3$d Accedir a les pestanyes del navegador diff --git a/android-components/components/feature/addons/src/main/res/values-cy/strings.xml b/android-components/components/feature/addons/src/main/res/values-cy/strings.xml index 8a3b0066306d..b64909330d48 100644 --- a/android-components/components/feature/addons/src/main/res/values-cy/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-cy/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Cael mynediad at eich data o %1$d parth arall + + %1$s, %2$d o %3$d Cael mynediad at dabiau’r porwyr @@ -75,7 +77,7 @@ Awdur - Awduron + Awduron Diweddarwyd diwethaf diff --git a/android-components/components/feature/addons/src/main/res/values-de/strings.xml b/android-components/components/feature/addons/src/main/res/values-de/strings.xml index 19093c735480..99b9d7da22fc 100644 --- a/android-components/components/feature/addons/src/main/res/values-de/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-de/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Auf Ihre Daten in %1$d anderen Domains zugreifen + + %1$s, %2$d von %3$d Auf Browsertabs zugreifen @@ -75,7 +77,7 @@ Autor - Autoren + Autoren Zuletzt aktualisiert diff --git a/android-components/components/feature/addons/src/main/res/values-dsb/strings.xml b/android-components/components/feature/addons/src/main/res/values-dsb/strings.xml index d6ed04fc4085..f1975e4088ba 100644 --- a/android-components/components/feature/addons/src/main/res/values-dsb/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-dsb/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Mějśo pśistup na swóje daty na %1$d dalšnych domenach + + %1$s, %2$d z %3$d Mějśo pśistup k rejtarikam wobglědowaka @@ -75,7 +77,7 @@ Awtor - Awtory + Awtory Slědna aktualizacija diff --git a/android-components/components/feature/addons/src/main/res/values-el/strings.xml b/android-components/components/feature/addons/src/main/res/values-el/strings.xml index e229acecc499..9687e5e82de5 100644 --- a/android-components/components/feature/addons/src/main/res/values-el/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-el/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Πρόσβαση στα δεδομένα σας σε %1$d ακόμα τομείς + + %1$s, %2$d από %3$d Πρόσβαση στις καρτέλες προγράμματος περιήγησης @@ -75,7 +77,7 @@ Δημιουργός - Δημιουργοί + Δημιουργοί Τελευταία ενημέρωση diff --git a/android-components/components/feature/addons/src/main/res/values-es-rAR/strings.xml b/android-components/components/feature/addons/src/main/res/values-es-rAR/strings.xml index 464a7e085a4f..1682f9966043 100644 --- a/android-components/components/feature/addons/src/main/res/values-es-rAR/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-es-rAR/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Acceso a los datos en %1$d otros dominios + + %1$s, %2$d de %3$d Acceder a pestañas del navegador @@ -75,7 +77,7 @@ Autor - Autores + Autores Última actualización diff --git a/android-components/components/feature/addons/src/main/res/values-es-rCL/strings.xml b/android-components/components/feature/addons/src/main/res/values-es-rCL/strings.xml index bd68dc9c66ec..f3a8750dc35c 100644 --- a/android-components/components/feature/addons/src/main/res/values-es-rCL/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-es-rCL/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Acceder a tus datos en %1$d dominios más + + %1$s, %2$d de %3$d Acceder a las pestañas del navegador @@ -75,7 +77,7 @@ Autor - Autores + Autores Última actualización diff --git a/android-components/components/feature/addons/src/main/res/values-fi/strings.xml b/android-components/components/feature/addons/src/main/res/values-fi/strings.xml index e2cacb8db56f..9c1dc35c874d 100644 --- a/android-components/components/feature/addons/src/main/res/values-fi/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-fi/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Pääsy tietoihisi %1$d muussa verkkotunnuksessa + + %1$s, %2$d/%3$d Käytä selaimen välilehtiä @@ -75,7 +77,7 @@ Tekijä - Tekijät + Tekijät Viimeksi päivitetty diff --git a/android-components/components/feature/addons/src/main/res/values-fy-rNL/strings.xml b/android-components/components/feature/addons/src/main/res/values-fy-rNL/strings.xml index fb00c7188b64..a167df46711b 100644 --- a/android-components/components/feature/addons/src/main/res/values-fy-rNL/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-fy-rNL/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Jo gegevens op %1$d oar domeinen benaderje + + %1$s, %2$d fan %3$d Browserljepblêden benaderje @@ -75,7 +77,7 @@ Auteur - Skriuwers + Skriuwers Lêst bywurke diff --git a/android-components/components/feature/addons/src/main/res/values-hsb/strings.xml b/android-components/components/feature/addons/src/main/res/values-hsb/strings.xml index 8a2f4fabd0d6..3dfe7a45ecab 100644 --- a/android-components/components/feature/addons/src/main/res/values-hsb/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-hsb/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Mějće přistup k swojim datam na %1$d dalšich domenach + + %1$s, %2$d z %3$d Mějće přistup k rajtarkam wobhladowaka @@ -75,7 +77,7 @@ Awtor - Awtorojo + Awtorojo Poslednja aktualizacija diff --git a/android-components/components/feature/addons/src/main/res/values-ia/strings.xml b/android-components/components/feature/addons/src/main/res/values-ia/strings.xml index 2842e19c5567..c8c8a5cf6e62 100644 --- a/android-components/components/feature/addons/src/main/res/values-ia/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-ia/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Accede tu datos sur %1$d altere dominios + + %1$s, %2$d de %3$d Acceder al schedas del navigator @@ -75,7 +77,7 @@ Autor - Autores + Autores Ultime actualisation diff --git a/android-components/components/feature/addons/src/main/res/values-is/strings.xml b/android-components/components/feature/addons/src/main/res/values-is/strings.xml index aca05b4bf7a0..965080b8f789 100644 --- a/android-components/components/feature/addons/src/main/res/values-is/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-is/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Skoða gögnin þín fyrir %1$d önnur lén + + %1$s, %2$d af %3$d Skoða vafraflipa @@ -75,7 +77,7 @@ Höfundur - Höfundar + Höfundar Seinast uppfært diff --git a/android-components/components/feature/addons/src/main/res/values-it/strings.xml b/android-components/components/feature/addons/src/main/res/values-it/strings.xml index 1979b66115f5..148ade38e458 100644 --- a/android-components/components/feature/addons/src/main/res/values-it/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-it/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Accedere ai dati utente su %1$d altri domini + + %1$s, %2$d di %3$d Accedere alle schede del browser @@ -75,7 +77,7 @@ Autore - Autori + Autori Ultimo aggiornamento diff --git a/android-components/components/feature/addons/src/main/res/values-iw/strings.xml b/android-components/components/feature/addons/src/main/res/values-iw/strings.xml index 118a9fc25825..2a662f98a16d 100644 --- a/android-components/components/feature/addons/src/main/res/values-iw/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-iw/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> גישה לכל המידע שלך ב־%1$d שמות מתחם נוספים + + %1$s, %2$d מתוך %3$d גישה ללשוניות @@ -75,7 +77,7 @@ מחבר - יוצרים + יוצרים עדכון אחרון diff --git a/android-components/components/feature/addons/src/main/res/values-kk/strings.xml b/android-components/components/feature/addons/src/main/res/values-kk/strings.xml index 1e50a000b09c..5e6da873770d 100644 --- a/android-components/components/feature/addons/src/main/res/values-kk/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-kk/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Басқа %1$d домен үшін деректеріңізге қатынау + + %1$s, %2$d - %3$d ішінен Браузер беттеріне қатынау @@ -75,7 +77,7 @@ Автор - Авторлар + Авторлар Соңғы жаңартылған diff --git a/android-components/components/feature/addons/src/main/res/values-ko/strings.xml b/android-components/components/feature/addons/src/main/res/values-ko/strings.xml index fd88c8269582..f0a7144960b9 100644 --- a/android-components/components/feature/addons/src/main/res/values-ko/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-ko/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> 다른 도메인 %1$d개에 대한 사용자 데이터에 접근 + + %1$s, %2$d / %3$d 브라우저 탭에 접근 @@ -75,7 +77,7 @@ 제작자 - 제작자 + 제작자 마지막 업데이트 diff --git a/android-components/components/feature/addons/src/main/res/values-nl/strings.xml b/android-components/components/feature/addons/src/main/res/values-nl/strings.xml index 5fb6824c4a06..4b9745f5ad10 100644 --- a/android-components/components/feature/addons/src/main/res/values-nl/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-nl/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Uw gegevens op %1$d andere domeinen benaderen + + %1$s, %2$d van %3$d Browsertabbladen benaderen @@ -75,7 +77,7 @@ Schrijver - Auteurs + Auteurs Laatst bijgewerkt diff --git a/android-components/components/feature/addons/src/main/res/values-oc/strings.xml b/android-components/components/feature/addons/src/main/res/values-oc/strings.xml index 456cbedc29ab..3efbf0284503 100644 --- a/android-components/components/feature/addons/src/main/res/values-oc/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-oc/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Accedir a vòstras donadas per %1$d autres domenis + + %1$s, %2$d de %3$d Accedir als onglets del navegador @@ -75,7 +77,7 @@ Autor - Autors + Autors Darrièra mesa a jorn diff --git a/android-components/components/feature/addons/src/main/res/values-pa-rIN/strings.xml b/android-components/components/feature/addons/src/main/res/values-pa-rIN/strings.xml index ebda2f1cc817..9c057cc095bb 100644 --- a/android-components/components/feature/addons/src/main/res/values-pa-rIN/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-pa-rIN/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> %1$d ਹੋਰ ਡੋਮੇਨ ਉੱਤੇ ਤੁਹਾਡੇ ਡਾਟੇ ਲਈ ਪਹੁੰਚ + + %3$d ਵਿੱਚੋਂ %1$s, %2$d ਬਰਾਊਜ਼ਰ ਟੈਬਾਂ ਲਈ ਪਹੁੰਚ diff --git a/android-components/components/feature/addons/src/main/res/values-pt-rBR/strings.xml b/android-components/components/feature/addons/src/main/res/values-pt-rBR/strings.xml index f008dc3286e0..5df2c679e757 100644 --- a/android-components/components/feature/addons/src/main/res/values-pt-rBR/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-pt-rBR/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Acessar seus dados em %1$d outros domínios + + %1$s, %2$d de %3$d Acessar abas do navegador @@ -75,7 +77,7 @@ Autor - Autores + Autores Última atualização diff --git a/android-components/components/feature/addons/src/main/res/values-pt-rPT/strings.xml b/android-components/components/feature/addons/src/main/res/values-pt-rPT/strings.xml index 32c4e3e8258e..93bc453ff789 100644 --- a/android-components/components/feature/addons/src/main/res/values-pt-rPT/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-pt-rPT/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Aceder aos seus dados em %1$d outros domínios + + %1$s, %2$d de %3$d Aceder aos separadores do navegador @@ -75,7 +77,7 @@ Autor - Autores + Autores Última atualização diff --git a/android-components/components/feature/addons/src/main/res/values-ru/strings.xml b/android-components/components/feature/addons/src/main/res/values-ru/strings.xml index a3e064693b2c..1db019c56a81 100644 --- a/android-components/components/feature/addons/src/main/res/values-ru/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-ru/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Доступ к вашим данным на ещё %1$d доменах + + %1$s, %2$d из %3$d Доступ к вкладкам браузера @@ -75,7 +77,7 @@ Автор - Авторы + Авторы Последнее обновление diff --git a/android-components/components/feature/addons/src/main/res/values-sv-rSE/strings.xml b/android-components/components/feature/addons/src/main/res/values-sv-rSE/strings.xml index f48e5efc12c8..0ae3f20e3db0 100644 --- a/android-components/components/feature/addons/src/main/res/values-sv-rSE/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-sv-rSE/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Åtkomst till data på %1$d andra domäner + + %1$s, %2$d av %3$d Åtkomst till webbläsarens flikar @@ -75,7 +77,7 @@ Utvecklare - Utvecklare + Utvecklare Senast uppdaterad diff --git a/android-components/components/feature/addons/src/main/res/values-zh-rCN/strings.xml b/android-components/components/feature/addons/src/main/res/values-zh-rCN/strings.xml index 01865abc6f51..6c703f50c6d6 100644 --- a/android-components/components/feature/addons/src/main/res/values-zh-rCN/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-zh-rCN/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> 存取您在其他 %1$d 个域名的数据 + + %1$s,第 %2$d 项,共 %3$d 项 存取浏览器标签页 @@ -75,7 +77,7 @@ 作者 - 作者 + 作者 上次更新 diff --git a/android-components/components/feature/addons/src/main/res/values-zh-rTW/strings.xml b/android-components/components/feature/addons/src/main/res/values-zh-rTW/strings.xml index 37459872d360..4d8bc57b6ec8 100644 --- a/android-components/components/feature/addons/src/main/res/values-zh-rTW/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-zh-rTW/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> 存取您在另 %1$d 個網域中的資料 + + %1$s(第 %2$d 組,共 %3$d 組) 存取瀏覽器分頁 @@ -75,7 +77,7 @@ 作者 - 作者 + 作者 最近更新 diff --git a/android-components/components/feature/app-links/src/main/res/values-azb/strings.xml b/android-components/components/feature/app-links/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..34639febb954 --- /dev/null +++ b/android-components/components/feature/app-links/src/main/res/values-azb/strings.xml @@ -0,0 +1,16 @@ + + + + … دا آچین + + اپ‌ده آچیلسین؟ فعالیتیز آرتیق گیزلی اولمایا بیلیر. + + آیری اپ‌ده آچین + + بو موحتوایا باخماق اوچون %s -دن آیریلماق ایستییرسیز؟ + + آچ + + لغو + diff --git a/android-components/components/feature/autofill/src/main/res/values-azb/strings.xml b/android-components/components/feature/autofill/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..e231f52438bf --- /dev/null +++ b/android-components/components/feature/autofill/src/main/res/values-azb/strings.xml @@ -0,0 +1,45 @@ + + + + %1$s کیلیدینی آچ + + + ( هئچ قوللانیجی آدی یوخ) + + + %1$s اوچون رمز + + + دوغرولاما قیریلدی + + + %1$s اپلیکیشن‌ین صحتینی تایید ائلینمه‌دی. سئچیلن کیملیک بیلگی‌لرینی اوتوماتیک دولدورماغا دوام ائتمک ایستییرسیز؟ + + + هن + + + یوخ + + + %1$s -دا آختار + + + گیریش‌لرده آختار + diff --git a/android-components/components/feature/awesomebar/src/main/res/values-azb/strings.xml b/android-components/components/feature/awesomebar/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..441313eef056 --- /dev/null +++ b/android-components/components/feature/awesomebar/src/main/res/values-azb/strings.xml @@ -0,0 +1,7 @@ + + + + تاغاگئچ + diff --git a/android-components/components/feature/contextmenu/src/main/res/values-azb/strings.xml b/android-components/components/feature/contextmenu/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..97b092eb5f6e --- /dev/null +++ b/android-components/components/feature/contextmenu/src/main/res/values-azb/strings.xml @@ -0,0 +1,53 @@ + + + + باغلانتی‌نی یئنی تاغدا آچ + + باغلانتی‌نی گیزلی تاغدا آچ + + عکسی یئنی تاغدا آچ + + باغلانتی‌نی یئندیر + + باغلانتی‌نی پایلاش + + عکسی پایلاش + + باغلانتی‌نی کوپی ائله + + عکس یئرینی کوپی ائله + + عکسی ساخلا + + عکسی کوپی ائله + + فایلی جهازدا ساخلا + + یئنی تاغ آچیلدی + + یئنی گیزلی تاغ آچیلدی + + باغلانتی کلیپ‌بوردا کوپی اولدو + + بونا گئچ + + باغلانتی‌نی ائشیکده‌کی اپ‌ده آچ + + ایمیل آدرسی پایلاش + + ایمیل آدرسی کوپی ائله + + ایمیل آدرسی کلیپ‌بوردا کوپی اولدو + + موخاطب‌لره آرتیر + + آختاریش + + گیزلی آختاریش + + پایلاش + + ایمیل + + تماس + diff --git a/android-components/components/feature/customtabs/src/main/res/values-azb/strings.xml b/android-components/components/feature/customtabs/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..deac72bfb992 --- /dev/null +++ b/android-components/components/feature/customtabs/src/main/res/values-azb/strings.xml @@ -0,0 +1,5 @@ + + + اؤنجه‌کی اَپَه دؤن + باغلانتی‌نی پایلاش + diff --git a/android-components/components/feature/downloads/src/main/res/values-azb/strings.xml b/android-components/components/feature/downloads/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..701cc3f6ec1c --- /dev/null +++ b/android-components/components/feature/downloads/src/main/res/values-azb/strings.xml @@ -0,0 +1,59 @@ + + + + یئندیرنلر + + + یئندیرمه دایاندیریلدی + + + یئندیرمه کامیل اولدو + + یئندیرمه باشاریسیز + + + یئندیر (%1$s) + + یئندیر + + لغو + + %1$s بو فایل نوعونو یئندیره بیلمیر + + + فایل آچیلانمادی. + + + %1$s فایلی آچماق اوچون هئچ بیر اپ تاپیلمادی. + + + دایاندیر + + + سوردور + + لغو + + آچ + + یئنی‌دن چالیش + + + باغلا + + ایشه آلاراق حرکتی تماملایین + --> + %1$s آچیلمیر + + + فایل‌لاری یئندیرمک اوچون فایل‌لار و مدیا ایجازه‌سی ایسته‌نیلیر. اندروید تنظیم‌لرینه گئچین، ایجازه‌لره توخونون و ایجازه وئرین. + + + گیزلی یئندیرمه‌لر لغو ائدیلسین؟ + + ایندی بوتون گیزلی تاغلاری باغلاساز %1$s یئندیرمه‌سی لغو ائدیله‌جک. گیزلی موروچودان آیریلماق ایسته‌دیگیزه اطمینانیز وار؟ + + یئندیرمه‌لری لغو ائله + + گیزلی موروچودا قالین + diff --git a/android-components/components/feature/findinpage/src/main/res/values-azb/strings.xml b/android-components/components/feature/findinpage/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..265789981458 --- /dev/null +++ b/android-components/components/feature/findinpage/src/main/res/values-azb/strings.xml @@ -0,0 +1,24 @@ + + + + + صفحه‌ده تاپین + + + %1$d/%2$d + + + %2$d سونوچدان %1$d سونوچ + + + سونراکی سونوچو تاپ + + + اؤنجه‌کی سونوچو تاپ + + + صفحه‌ده تاپماغی باغلا + + diff --git a/android-components/components/feature/fxsuggest/src/main/res/values-azb/strings.xml b/android-components/components/feature/fxsuggest/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..303e6433d11d --- /dev/null +++ b/android-components/components/feature/fxsuggest/src/main/res/values-azb/strings.xml @@ -0,0 +1,5 @@ + + + + اسپانسرلی + diff --git a/android-components/components/feature/media/src/main/res/values-am/strings.xml b/android-components/components/feature/media/src/main/res/values-am/strings.xml index 06f9ab4c17cd..2a38313c9e26 100644 --- a/android-components/components/feature/media/src/main/res/values-am/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-am/strings.xml @@ -1,5 +1,5 @@ - + ሚዲያ @@ -23,9 +23,14 @@ ማስታወሻ፦ %1$s አሁንም ካሜራዎን እየተጠቀመ ነው። ትሩን ለመክፈት መታ ያድርጉ። - ማስታወሻ፦ %1$s አሁንም ማይክሮፎንዎን እየተጠቀመ ነው። ትሩን ለመክፈት መታ ያድርጉ + ማስታወሻ፦ %1$s አሁንም ማይክሮፎንዎን እየተጠቀመ ነው። ትሩን ለመክፈት መታ ያድርጉ + + ማስታወሻ፦ %1$s አሁንም የእርስዎን ማይክሮፎን እየተጠቀመ ነው። ትሩን ለመክፈት መታ ያድርጉ። + + ማስታወሻ፦ %1$s አሁንም የእርስዎን ማይክሮፎን እና ካሜራ እየተጠቀመ ነው። ትሩን ለመክፈት መታ ያድርጉ + - ማስታወሻ፦ %1$s አሁንም የእርስዎን ማይክሮፎን እና ካሜራ እየተጠቀመ ነው። ትሩን ለመክፈት መታ ያድርጉ + ማስታወሻ፦ %1$s አሁንም የእርስዎን ማይክሮፎን እና ካሜራ እየተጠቀመ ነው። ትሩን ለመክፈት መታ ያድርጉ። አጫውት diff --git a/android-components/components/feature/media/src/main/res/values-azb/strings.xml b/android-components/components/feature/media/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..c7d1ff607d52 --- /dev/null +++ b/android-components/components/feature/media/src/main/res/values-azb/strings.xml @@ -0,0 +1,18 @@ + + + + مدیا + + + کامئرا آچیق + + میکروفون آچیق + + کامئرا و میکروفون آچیق + + + + کامئرازدان ایستیفاده ائدن تاغی آچماق اوچون توخونون. + + + diff --git a/android-components/components/feature/media/src/main/res/values-bg/strings.xml b/android-components/components/feature/media/src/main/res/values-bg/strings.xml index 18a2631d8b75..b319aa23339d 100644 --- a/android-components/components/feature/media/src/main/res/values-bg/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-bg/strings.xml @@ -1,5 +1,5 @@ - + Медия @@ -21,9 +21,14 @@ Напомняне: %1$s все още използва камерата ви. Докоснете, за да отворите раздела. - Напомняне: %1$s все още използва микрофона ви. Докоснете, за да отворите раздела + Напомняне: %1$s все още използва микрофона ви. Докоснете, за да отворите раздела + + Напомняне: %1$s все още използва микрофона ви. Докоснете, за да отворите раздела. + + Напомняне: %1$s все още използва микрофона и камерата ви. Докоснете, за да отворите раздела + - Напомняне: %1$s все още използва микрофона и камерата ви. Докоснете, за да отворите раздела + Напомняне: %1$s все още използва микрофона и камерата ви. Докоснете, за да отворите раздела. Изпълняване diff --git a/android-components/components/feature/media/src/main/res/values-ca/strings.xml b/android-components/components/feature/media/src/main/res/values-ca/strings.xml index dd5ca3467af2..dc962103cb53 100644 --- a/android-components/components/feature/media/src/main/res/values-ca/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-ca/strings.xml @@ -1,5 +1,5 @@ - + Multimèdia @@ -21,9 +21,14 @@ Recordatori: %1$s encara usa la càmera. Toqueu per a obrir la pestanya. - Recordatori: %1$s encara usa el micròfon. Toqueu per a obrir la pestanya + Recordatori: %1$s encara usa el micròfon. Toqueu per a obrir la pestanya + + Recordatori: %1$s encara usa el micròfon. Toqueu per a obrir la pestanya. + + Recordatori: %1$s encara usa el micròfon i la càmera. Toqueu per a obrir la pestanya + - Recordatori: %1$s encara usa el micròfon i la càmera. Toqueu per a obrir la pestanya + Recordatori: %1$s encara usa el micròfon i la càmera. Toqueu per a obrir la pestanya. Reprodueix diff --git a/android-components/components/feature/media/src/main/res/values-cy/strings.xml b/android-components/components/feature/media/src/main/res/values-cy/strings.xml index a7bcd6953650..f8095ccf66d1 100644 --- a/android-components/components/feature/media/src/main/res/values-cy/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-cy/strings.xml @@ -1,5 +1,5 @@ - + Cyfrwng @@ -21,9 +21,14 @@ Nodyn atgoffa: Mae %1$s yn dal i ddefnyddio\'ch camera. Tapiwch i agor y tab. - Nodyn atgoffa: Mae %1$s yn dal i ddefnyddio\'ch meicroffon. Tapiwch i agor y tab + Nodyn atgoffa: Mae %1$s yn dal i ddefnyddio\'ch meicroffon. Tapiwch i agor y tab + + Nodyn atgoffa: Mae %1$s yn dal i ddefnyddio\'ch meicroffon. Tapiwch i agor y tab. + + Nodyn atgoffa: Mae %1$s yn dal i ddefnyddio\'ch meicroffon a\'ch camera. Tapiwch i agor y tab + - Nodyn atgoffa: Mae %1$s yn dal i ddefnyddio\'ch meicroffon a\'ch camera. Tapiwch i agor y tab + Nodyn atgoffa: Mae %1$s yn dal i ddefnyddio\'ch meicroffon a\'ch camera. Tapiwch i agor y tab. Chwarae diff --git a/android-components/components/feature/media/src/main/res/values-de/strings.xml b/android-components/components/feature/media/src/main/res/values-de/strings.xml index b654418bf2b4..6d14a70d334d 100644 --- a/android-components/components/feature/media/src/main/res/values-de/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-de/strings.xml @@ -1,5 +1,5 @@ - + Medien @@ -21,9 +21,14 @@ Erinnerung: %1$s verwendet noch Ihre Kamera. Antippen, um den Tab zu öffnen. - Erinnerung: %1$s verwendet noch Ihr Mikrofon. Antippen, um den Tab zu öffnen + Erinnerung: %1$s verwendet noch Ihr Mikrofon. Antippen, um den Tab zu öffnen + + Erinnerung: %1$s verwendet weiterhin Ihr Mikrofon. Antippen, um den Tab zu öffnen. + + Erinnerung: %1$s verwendet noch Ihr Mikrofon und Ihre Kamera. Antippen, um den Tab zu öffnen + - Erinnerung: %1$s verwendet noch Ihr Mikrofon und Ihre Kamera. Antippen, um den Tab zu öffnen + Erinnerung: %1$s verwendet weiterhin Ihr Mikrofon und Ihre Kamera. Antippen, um den Tab zu öffnen. Wiedergeben diff --git a/android-components/components/feature/media/src/main/res/values-dsb/strings.xml b/android-components/components/feature/media/src/main/res/values-dsb/strings.xml index 54404cff873e..5cc1b64ec4f5 100644 --- a/android-components/components/feature/media/src/main/res/values-dsb/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-dsb/strings.xml @@ -1,5 +1,5 @@ - + Medije @@ -21,9 +21,14 @@ Glědajśo: %1$s wašu kameru južo wužywa. Pótusniśo, aby rejtarik wócynił. - Glědajśo: %1$s waš mikrofon južo wužywa. Pótusniśo, aby rejtarik wócynił + Glědajśo: %1$s waš mikrofon južo wužywa. Pótusniśo, aby rejtarik wócynił + + Glědajśo: %1$s waš mikrofon južo wužywa. Pótusniśo, aby rejtarik wócynił. + + Glědajśo: %1$s waš mikrofon a wašu kameru južo wužywa. Pótusniśo, aby rejtarik wócynił + - Glědajśo: %1$s waš mikrofon a wašu kameru južo wužywa. Pótusniśo, aby rejtarik wócynił + Glědajśo: %1$s waš mikrofon a wašu kameru južo wužywa. Pótusniśo, aby rejtarik wócynił. Wótgraś diff --git a/android-components/components/feature/media/src/main/res/values-el/strings.xml b/android-components/components/feature/media/src/main/res/values-el/strings.xml index 3175f74d5d92..9d9c1eb674b9 100644 --- a/android-components/components/feature/media/src/main/res/values-el/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-el/strings.xml @@ -1,5 +1,5 @@ - + Πολυμέσα @@ -22,9 +22,14 @@ Υπενθύμιση: Το %1$s χρησιμοποιεί ακόμα την κάμερά σας. Πατήστε για άνοιγμα της καρτέλας. - Υπενθύμιση: Το %1$s χρησιμοποιεί ακόμα το μικρόφωνό σας. Πατήστε για άνοιγμα της καρτέλας + Υπενθύμιση: Το %1$s χρησιμοποιεί ακόμα το μικρόφωνό σας. Πατήστε για άνοιγμα της καρτέλας + + Υπενθύμιση: Το %1$s χρησιμοποιεί ακόμα το μικρόφωνό σας. Πατήστε για άνοιγμα της καρτέλας. + + Υπενθύμιση: Το %1$s χρησιμοποιεί ακόμα το μικρόφωνο και την κάμερά σας. Πατήστε για άνοιγμα της καρτέλας + - Υπενθύμιση: Το %1$s χρησιμοποιεί ακόμα το μικρόφωνο και την κάμερά σας. Πατήστε για άνοιγμα της καρτέλας + Υπενθύμιση: Το %1$s χρησιμοποιεί ακόμα το μικρόφωνο και την κάμερά σας. Πατήστε για άνοιγμα της καρτέλας. Αναπαραγωγή diff --git a/android-components/components/feature/media/src/main/res/values-es-rAR/strings.xml b/android-components/components/feature/media/src/main/res/values-es-rAR/strings.xml index e7285a84a44c..e89920b72133 100644 --- a/android-components/components/feature/media/src/main/res/values-es-rAR/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-es-rAR/strings.xml @@ -1,5 +1,5 @@ - + Medios @@ -21,9 +21,14 @@ Recordatorio: %1$s todavía está usando tu cámara. Tocá para abrir la pestaña. - Recordatorio: %1$s todavía está usando tu micrófono. Tocá para abrir la pestaña + Recordatorio: %1$s todavía está usando tu micrófono. Tocá para abrir la pestaña + + Recordatorio: %1$s todavía está usando tu micrófono. Tocá para abrir la pestaña. + + Recordatorio: %1$s todavía está usando tu micrófono y tu cámara. Tocá para abrir la pestaña + - Recordatorio: %1$s todavía está usando tu micrófono y tu cámara. Tocá para abrir la pestaña + Recordatorio: %1$s todavía está usando tu micrófono y tu cámara. Tocá para abrir la pestaña. Reproducir diff --git a/android-components/components/feature/media/src/main/res/values-es-rCL/strings.xml b/android-components/components/feature/media/src/main/res/values-es-rCL/strings.xml index 1299dac0f65f..cb20dbf5c7fa 100644 --- a/android-components/components/feature/media/src/main/res/values-es-rCL/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-es-rCL/strings.xml @@ -1,5 +1,5 @@ - + Medios @@ -21,9 +21,14 @@ Recordatorio: %1$s todavía está usando tu cámara. Toca para abrir la pestaña. - Recordatorio: %1$s todavía está usando tu micrófono. Toca para abrir la pestaña + Recordatorio: %1$s todavía está usando tu micrófono. Toca para abrir la pestaña + + Recordatorio: %1$s todavía está usando tu micrófono. Toca para abrir la pestaña. + + Recordatorio: %1$s todavía está usando tu micrófono y cámara. Toca para abrir la pestaña + - Recordatorio: %1$s todavía está usando tu micrófono y cámara. Toca para abrir la pestaña + Recordatorio: %1$s todavía está usando tu micrófono y cámara. Toca para abrir la pestaña. Reproducir diff --git a/android-components/components/feature/media/src/main/res/values-fi/strings.xml b/android-components/components/feature/media/src/main/res/values-fi/strings.xml index 42cc51b1784f..713dcededfd6 100644 --- a/android-components/components/feature/media/src/main/res/values-fi/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-fi/strings.xml @@ -1,5 +1,5 @@ - + Media @@ -21,9 +21,14 @@ Muistutus: %1$s käyttää edelleen kameraasi. Avaa välilehti napauttamalla. - Muistutus: %1$s käyttää edelleen mikrofoniasi. Avaa välilehti napauttamalla + Muistutus: %1$s käyttää edelleen mikrofoniasi. Avaa välilehti napauttamalla + + Muistutus: %1$s käyttää edelleen mikrofoniasi. Avaa välilehti napauttamalla. + + Muistutus: %1$s käyttää edelleen mikrofoniasi ja kameraasi. Avaa välilehti napauttamalla + - Muistutus: %1$s käyttää edelleen mikrofoniasi ja kameraasi. Avaa välilehti napauttamalla + Muistutus: %1$s käyttää edelleen mikrofoniasi ja kameraasi. Avaa välilehti napauttamalla. Toista diff --git a/android-components/components/feature/media/src/main/res/values-fr/strings.xml b/android-components/components/feature/media/src/main/res/values-fr/strings.xml index 93760889bcbf..6f02a1be949b 100644 --- a/android-components/components/feature/media/src/main/res/values-fr/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-fr/strings.xml @@ -1,5 +1,5 @@ - + Multimédia @@ -21,9 +21,14 @@ Rappel : %1$s utilise toujours votre appareil photo. Appuyez pour ouvrir l’onglet. - Rappel : %1$s utilise toujours votre microphone. Appuyez pour ouvrir l’onglet + Rappel : %1$s utilise toujours votre microphone. Appuyez pour ouvrir l’onglet + + Rappel : %1$s utilise toujours votre microphone. Appuyez pour ouvrir l’onglet. + + Rappel : %1$s utilise toujours votre microphone et votre appareil photo. Appuyez pour ouvrir l’onglet + - Rappel : %1$s utilise toujours votre microphone et votre appareil photo. Appuyez pour ouvrir l’onglet + Rappel : %1$s utilise toujours votre microphone et votre appareil photo. Appuyez pour ouvrir l’onglet. Lecture diff --git a/android-components/components/feature/media/src/main/res/values-fy-rNL/strings.xml b/android-components/components/feature/media/src/main/res/values-fy-rNL/strings.xml index 68947239bdce..a04d2a4bd61a 100644 --- a/android-components/components/feature/media/src/main/res/values-fy-rNL/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-fy-rNL/strings.xml @@ -1,5 +1,5 @@ - + Media @@ -21,10 +21,15 @@ Oantinken: %1$s brûkt jo kamera noch hieltyd. Tik om it ljepblêd te iepenjen. - Oantinken: %1$s brûkt jo mikrofoan noch hieltyd. Tik om it ljepblêd te iepenjen. + Oantinken: %1$s brûkt jo mikrofoan noch hieltyd. Tik om it ljepblêd te iepenjen. + + + Oantinken: %1$s brûkt jo mikrofoan noch hieltyd. Tik om it ljepblêd te iepenjen. + + Oantinken: %1$s brûkt jo mikrofoan en kamera noch hieltyd. Tik om it ljepblêd te iepenjen. - Oantinken: %1$s brûkt jo mikrofoan en kamera noch hieltyd. Tik om it ljepblêd te iepenjen. + Oantinken: %1$s brûkt jo mikrofoan en kamera noch hieltyd. Tik om it ljepblêd te iepenjen. Ofspylje diff --git a/android-components/components/feature/media/src/main/res/values-hsb/strings.xml b/android-components/components/feature/media/src/main/res/values-hsb/strings.xml index efa34451d7fb..b623f5732200 100644 --- a/android-components/components/feature/media/src/main/res/values-hsb/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-hsb/strings.xml @@ -1,5 +1,5 @@ - + Medije @@ -21,9 +21,14 @@ Kedźbu: %1$s wašu kameru hižo wužiwa. Podótkńće so, zo byšće rajtark wočinił. - Kedźbu: %1$s waš mikrofon hižo wužiwa. Podótkńće so, zo byšće rajtark wočinił + Kedźbu: %1$s waš mikrofon hižo wužiwa. Podótkńće so, zo byšće rajtark wočinił + + Kedźbu: %1$s waš mikrofon hižo wužiwa. Podótkńće so, zo byšće rajtark wočinił. + + Kedźbu: %1$s waš mikrofon a wašu kameru hižo wužiwa. Podótkńće so, zo byšće rajtark wočinił + - Kedźbu: %1$s waš mikrofon a wašu kameru hižo wužiwa. Podótkńće so, zo byšće rajtark wočinił + Kedźbu: %1$s waš mikrofon a wašu kameru hižo wužiwa. Podótkńće so, zo byšće rajtark wočinił. Wothrać diff --git a/android-components/components/feature/media/src/main/res/values-ia/strings.xml b/android-components/components/feature/media/src/main/res/values-ia/strings.xml index 2d026696d833..8103d9133c71 100644 --- a/android-components/components/feature/media/src/main/res/values-ia/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-ia/strings.xml @@ -1,5 +1,5 @@ - + Medios @@ -23,10 +23,15 @@ Memento: %1$s ancora usa tu camera. Tocca pro aperir le scheda. - Memento: %1$s ancora usa tu microphono. Tocca pro aperir le scheda. + Memento: %1$s ancora usa tu microphono. Tocca pro aperir le scheda. + + + Memento: %1$s ancora usa tu microphono. Tocca pro aperir le scheda. + + Memento: %1$s ancora usa tu microphono e camera. Tocca pro aperir le scheda. - Memento: %1$s ancora usa tu microphono e camera. Tocca pro aperir le scheda. + Memento: %1$s ancora usa tu microphono e camera. Tocca pro aperir le scheda. Reproducer diff --git a/android-components/components/feature/media/src/main/res/values-is/strings.xml b/android-components/components/feature/media/src/main/res/values-is/strings.xml index 63e65b7820b8..5d54639a357f 100644 --- a/android-components/components/feature/media/src/main/res/values-is/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-is/strings.xml @@ -1,5 +1,5 @@ - + Miðill @@ -21,9 +21,14 @@ Áminning: %1$s er enn að nota myndavélina þína. Ýttu á til að opna flipann. - Áminning: %1$s er enn að nota hljóðnemann þinn. Ýttu á til að opna flipann + Áminning: %1$s er enn að nota hljóðnemann þinn. Ýttu á til að opna flipann + + Áminning: %1$s er enn að nota hljóðnemann þinn. Ýttu á til að opna flipann. + + Áminning: %1$s er enn að nota hljóðnemann og myndavélina. Ýttu á til að opna flipann + - Áminning: %1$s er enn að nota hljóðnemann og myndavélina. Ýttu á til að opna flipann + Áminning: %1$s er enn að nota hljóðnemann og myndavélina. Ýttu á til að opna flipann. Spila diff --git a/android-components/components/feature/media/src/main/res/values-it/strings.xml b/android-components/components/feature/media/src/main/res/values-it/strings.xml index a3ce4b97dab9..3a2f06de81a5 100644 --- a/android-components/components/feature/media/src/main/res/values-it/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-it/strings.xml @@ -1,5 +1,5 @@ - + Media @@ -22,10 +22,15 @@ Promemoria: %1$s sta ancora utilizzando la fotocamera. Tocca per aprire la scheda. - Promemoria: %1$s sta ancora utilizzando il microfono. Tocca per aprire la scheda + Promemoria: %1$s sta ancora utilizzando il microfono. Tocca per aprire la scheda + + + Promemoria: %1$s sta ancora utilizzando il microfono. Tocca per aprire la scheda. + + Promemoria: %1$s sta ancora utilizzando il microfono e la fotocamera. Tocca per aprire la scheda - Promemoria: %1$s sta ancora utilizzando il microfono e la fotocamera. Tocca per aprire la scheda + Promemoria: %1$s sta ancora utilizzando il microfono e la fotocamera. Tocca per aprire la scheda. Riproduci diff --git a/android-components/components/feature/media/src/main/res/values-iw/strings.xml b/android-components/components/feature/media/src/main/res/values-iw/strings.xml index 55c0e8eb74b3..b8d89869a351 100644 --- a/android-components/components/feature/media/src/main/res/values-iw/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-iw/strings.xml @@ -1,5 +1,5 @@ - + מדיה @@ -21,9 +21,14 @@ תזכורת: %1$s עדיין משתמש במצלמה שלך. יש להקיש כדי לפתוח את הלשונית. - תזכורת: %1$s עדיין משתמש במיקרופון שלך. יש להקיש כדי לפתוח את הלשונית. + תזכורת: %1$s עדיין משתמש במיקרופון שלך. יש להקיש כדי לפתוח את הלשונית. + + תזכורת: %1$s עדיין משתמש במיקרופון שלך. יש להקיש כדי לפתוח את הלשונית. + + תזכורת: %1$s עדיין משתמש במיקרופון ובמצלמה שלך. יש להקיש כדי לפתוח את הלשונית + - תזכורת: %1$s עדיין משתמש במיקרופון ובמצלמה שלך. יש להקיש כדי לפתוח את הלשונית + תזכורת: %1$s עדיין משתמש במיקרופון ובמצלמה שלך. יש להקיש כדי לפתוח את הלשונית. ניגון diff --git a/android-components/components/feature/media/src/main/res/values-kk/strings.xml b/android-components/components/feature/media/src/main/res/values-kk/strings.xml index eacabd253b2d..03ebec011aa0 100644 --- a/android-components/components/feature/media/src/main/res/values-kk/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-kk/strings.xml @@ -1,5 +1,5 @@ - + Медиа @@ -21,9 +21,14 @@ Еске салу: %1$s әлі де камераңызды пайдалануда. Бетті ашу үшін шертіңіз. - Еске салу: %1$s әлі де микрофоныңызды пайдалануда. Бетті ашу үшін шертіңіз + Еске салу: %1$s әлі де микрофоныңызды пайдалануда. Бетті ашу үшін шертіңіз + + Еске салу: %1$s әлі де микрофоныңызды пайдалануда. Бетті ашу үшін шертіңіз. + + Еске салу: %1$s әлі де микрофоныңыз бен камераңызды пайдалануда. Бетті ашу үшін шертіңіз + - Еске салу: %1$s әлі де микрофоныңыз бен камераңызды пайдалануда. Бетті ашу үшін шертіңіз + Еске салу: %1$s әлі де микрофоныңыз бен камераңызды пайдалануда. Бетті ашу үшін шертіңіз. Ойнату diff --git a/android-components/components/feature/media/src/main/res/values-ko/strings.xml b/android-components/components/feature/media/src/main/res/values-ko/strings.xml index 32143b5ae978..7c97ebc40b8e 100644 --- a/android-components/components/feature/media/src/main/res/values-ko/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-ko/strings.xml @@ -1,5 +1,5 @@ - + 미디어 @@ -22,9 +22,14 @@ 미리 알림: %1$s가 아직 카메라를 사용하고 있습니다. 탭을 열려면 누르세요. - 미리 알림: %1$s가 아직 마이크를 사용하고 있습니다. 탭을 열려면 누르세요. + 미리 알림: %1$s가 아직 마이크를 사용하고 있습니다. 탭을 열려면 누르세요. + + 미리 알림: %1$s가 아직 마이크를 사용하고 있습니다. 탭을 열려면 누르세요. + + 미리 알림: %1$s가 아직 마이크와 카메라를 사용하고 있습니다. 탭을 열려면 누르세요. + - 미리 알림: %1$s가 아직 마이크와 카메라를 사용하고 있습니다. 탭을 열려면 누르세요. + 미리 알림: %1$s가 아직 마이크와 카메라를 사용하고 있습니다. 탭을 열려면 누르세요. 재생 diff --git a/android-components/components/feature/media/src/main/res/values-nl/strings.xml b/android-components/components/feature/media/src/main/res/values-nl/strings.xml index efbeb430698c..69af62dea2c3 100644 --- a/android-components/components/feature/media/src/main/res/values-nl/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-nl/strings.xml @@ -1,5 +1,5 @@ - + Media @@ -21,9 +21,14 @@ Herinnering: %1$s gebruikt uw camera nog steeds. Tik om het tabblad te openen. - Herinnering: %1$s gebruikt uw microfoon nog steeds. Tik om het tabblad te openen. + Herinnering: %1$s gebruikt uw microfoon nog steeds. Tik om het tabblad te openen. + + Herinnering: %1$s gebruikt uw microfoon nog steeds. Tik om het tabblad te openen. + + Herinnering: %1$s gebruikt uw microfoon en camera nog steeds. Tik om het tabblad te openen. + - Herinnering: %1$s gebruikt uw microfoon en camera nog steeds. Tik om het tabblad te openen. + Herinnering: %1$s gebruikt uw microfoon en camera nog steeds. Tik om het tabblad te openen. Afspelen diff --git a/android-components/components/feature/media/src/main/res/values-pa-rIN/strings.xml b/android-components/components/feature/media/src/main/res/values-pa-rIN/strings.xml index 467b22ad1cbe..530ee56bc48f 100644 --- a/android-components/components/feature/media/src/main/res/values-pa-rIN/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-pa-rIN/strings.xml @@ -1,5 +1,5 @@ - + ਮੀਡਿਆ @@ -22,9 +22,14 @@ ਰੀਮਾਈਂਡਰ: %1$s ਹਾਲੇ ਵੀ ਤੁਹਾਡੇ ਕੈਮਰੇ ਨੂੰ ਵਰਤ ਰਹੀ ਹੈ। ਟੈਬ ਨੂੰ ਖੋਲ੍ਹਣ ਲਈ ਛੂਹੋ। - ਰੀਮਾਈਂਡਰ: %1$s ਹਾਲੇ ਵੀ ਤੁਹਾਡੇ ਮਾਈਕਰੋਫ਼ੋਨ ਨੂੰ ਵਰਤ ਰਹੀ ਹੈ। ਟੈਬ ਨੂੰ ਖੋਲ੍ਹਣ ਲਈ ਛੂਹੋ। + ਰੀਮਾਈਂਡਰ: %1$s ਹਾਲੇ ਵੀ ਤੁਹਾਡੇ ਮਾਈਕਰੋਫ਼ੋਨ ਨੂੰ ਵਰਤ ਰਹੀ ਹੈ। ਟੈਬ ਨੂੰ ਖੋਲ੍ਹਣ ਲਈ ਛੂਹੋ। + + ਰੀਮਾਈਂਡਰ: %1$s ਹਾਲੇ ਵੀ ਤੁਹਾਡੇ ਮਾਈਕਰੋਫ਼ੋਨ ਨੂੰ ਵਰਤ ਰਹੀ ਹੈ। ਟੈਬ ਨੂੰ ਖੋਲ੍ਹਣ ਲਈ ਛੂਹੋ। + + ਰੀਮਾਈਂਡਰ: %1$s ਹਾਲੇ ਵੀ ਤੁਹਾਡੇ ਮਾਈਕਰੋਫ਼ੋਨ ਅਤੇ ਕੈਮਰੇ ਨੂੰ ਵਰਤ ਰਹੀ ਹੈ। ਟੈਬ ਨੂੰ ਖੋਲ੍ਹਣ ਲਈ ਛੂਹੋ। + - ਰੀਮਾਈਂਡਰ: %1$s ਹਾਲੇ ਵੀ ਤੁਹਾਡੇ ਮਾਈਕਰੋਫ਼ੋਨ ਅਤੇ ਕੈਮਰੇ ਨੂੰ ਵਰਤ ਰਹੀ ਹੈ। ਟੈਬ ਨੂੰ ਖੋਲ੍ਹਣ ਲਈ ਛੂਹੋ। + ਰੀਮਾਈਂਡਰ: %1$s ਹਾਲੇ ਵੀ ਤੁਹਾਡੇ ਮਾਈਕਰੋਫ਼ੋਨ ਅਤੇ ਕੈਮਰੇ ਨੂੰ ਵਰਤ ਰਹੀ ਹੈ। ਟੈਬ ਨੂੰ ਖੋਲ੍ਹਣ ਲਈ ਛੂਹੋ। ਚਲਾਓ diff --git a/android-components/components/feature/media/src/main/res/values-pt-rBR/strings.xml b/android-components/components/feature/media/src/main/res/values-pt-rBR/strings.xml index 2c5325724bc8..90ba3f4b26ca 100644 --- a/android-components/components/feature/media/src/main/res/values-pt-rBR/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-pt-rBR/strings.xml @@ -1,5 +1,5 @@ - + Mídia @@ -21,10 +21,15 @@ Lembrete: O %1$s ainda está usando sua câmera. Toque para abrir a aba. - Lembrete: O %1$s ainda está usando seu microfone. Toque para abrir a aba + Lembrete: O %1$s ainda está usando seu microfone. Toque para abrir a aba + + + Lembrete: O %1$s ainda está usando seu microfone. Toque para abrir a aba. + + Lembrete: O %1$s ainda está usando seu microfone e câmera. Toque para abrir a aba - Lembrete: O %1$s ainda está usando seu microfone e câmera. Toque para abrir a aba + Lembrete: O %1$s ainda está usando seu microfone e câmera. Toque para abrir a aba. Reproduzir diff --git a/android-components/components/feature/media/src/main/res/values-pt-rPT/strings.xml b/android-components/components/feature/media/src/main/res/values-pt-rPT/strings.xml index 83823ae58ff4..86658e844cbd 100644 --- a/android-components/components/feature/media/src/main/res/values-pt-rPT/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-pt-rPT/strings.xml @@ -1,5 +1,5 @@ - + Multimédia @@ -21,9 +21,14 @@ Lembrete: %1$s ainda está a utilizar a sua câmara. Toque para abrir o separador. - Lembrete: %1$s ainda está a utilizar o seu microfone. Toque para abrir o separador + Lembrete: %1$s ainda está a utilizar o seu microfone. Toque para abrir o separador + + Lembrete: %1$s ainda está a utilizar o seu microfone. Toque para abrir o separador. + + Lembrete: %1$s ainda está a utilizar o seu microfone e câmara. Toque para abrir o separador + - Lembrete: %1$s ainda está a utilizar o seu microfone e câmara. Toque para abrir o separador + Lembrete: %1$s ainda está a utilizar o seu microfone e câmara. Toque para abrir o separador. Reproduzir diff --git a/android-components/components/feature/media/src/main/res/values-ru/strings.xml b/android-components/components/feature/media/src/main/res/values-ru/strings.xml index 310d143967d8..3c45e590bc7e 100644 --- a/android-components/components/feature/media/src/main/res/values-ru/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-ru/strings.xml @@ -1,5 +1,5 @@ - + Медиа @@ -21,9 +21,14 @@ Напоминание: %1$s всё ещё использует вашу камеру. Нажмите, чтобы открыть вкладку. - Напоминание: %1$s всё ещё использует ваш микрофон. Нажмите, чтобы открыть вкладку + Напоминание: %1$s всё ещё использует ваш микрофон. Нажмите, чтобы открыть вкладку + + Напоминание: %1$s всё ещё использует ваш микрофон. Нажмите, чтобы открыть вкладку. + + Напоминание: %1$s всё ещё использует ваш микрофон и камеру. Нажмите, чтобы открыть вкладку + - Напоминание: %1$s всё ещё использует ваш микрофон и камеру. Нажмите, чтобы открыть вкладку + Напоминание: %1$s всё ещё использует ваш микрофон и камеру. Нажмите, чтобы открыть вкладку. Воспроизвести diff --git a/android-components/components/feature/media/src/main/res/values-sv-rSE/strings.xml b/android-components/components/feature/media/src/main/res/values-sv-rSE/strings.xml index 3dae57f196bb..e629afb3f9a9 100644 --- a/android-components/components/feature/media/src/main/res/values-sv-rSE/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-sv-rSE/strings.xml @@ -1,5 +1,5 @@ - + Media @@ -22,10 +22,15 @@ Påminnelse: %1$s använder fortfarande din kamera. Tryck här för att öppna fliken. - Påminnelse: %1$s använder fortfarande din mikrofon. Tryck här för att öppna fliken + Påminnelse: %1$s använder fortfarande din mikrofon. Tryck här för att öppna fliken + + + Påminnelse: %1$s använder fortfarande din mikrofon. Tryck här för att öppna fliken. + + Påminnelse: %1$s använder fortfarande din mikrofon och kamera. Tryck här för att öppna fliken - Påminnelse: %1$s använder fortfarande din mikrofon och kamera. Tryck här för att öppna fliken + Påminnelse: %1$s använder fortfarande din mikrofon och kamera. Tryck här för att öppna fliken. Spela diff --git a/android-components/components/feature/media/src/main/res/values-zh-rCN/strings.xml b/android-components/components/feature/media/src/main/res/values-zh-rCN/strings.xml index 814959a38c83..954fa795a512 100644 --- a/android-components/components/feature/media/src/main/res/values-zh-rCN/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-zh-rCN/strings.xml @@ -1,5 +1,5 @@ - + 媒体 @@ -21,9 +21,14 @@ 提醒:%1$s 仍在使用您的相机。点按可打开相关标签页。 - 提醒:%1$s 仍在使用您的麦克风。点按可打开相关标签页。 + 提醒:%1$s 仍在使用您的麦克风。点按可打开相关标签页。 + + 提醒:%1$s 仍在使用您的麦克风。点按可打开相关标签页。 + + 提醒:%1$s 仍在使用您的麦克风和相机。点按可打开相关标签页。 + - 提醒:%1$s 仍在使用您的麦克风和相机。点按可打开相关标签页。 + 提醒:%1$s 仍在使用您的麦克风和相机。点按可打开相关标签页。 播放 diff --git a/android-components/components/feature/media/src/main/res/values-zh-rTW/strings.xml b/android-components/components/feature/media/src/main/res/values-zh-rTW/strings.xml index 7ac51396927a..f2cc374801b2 100644 --- a/android-components/components/feature/media/src/main/res/values-zh-rTW/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-zh-rTW/strings.xml @@ -1,5 +1,5 @@ - + 媒體 @@ -21,9 +21,14 @@ 提醒:%1$s 正在使用您的攝影機,點擊此處即可開啟該分頁。 - 提醒:%1$s 正在使用您的麥克風,點擊此處即可開啟該分頁。 + 提醒:%1$s 正在使用您的麥克風,點擊此處即可開啟該分頁。 + + 提醒:%1$s 正在使用您的麥克風,點擊此處即可開啟該分頁。 + + 提醒:%1$s 正在使用您的麥克風與攝影機,點擊此處即可開啟該分頁。 + - 提醒:%1$s 正在使用您的麥克風與攝影機,點擊此處即可開啟該分頁。 + 提醒:%1$s 正在使用您的麥克風與攝影機,點擊此處即可開啟該分頁。 播放 diff --git a/android-components/components/feature/prompts/src/main/res/values-am/strings.xml b/android-components/components/feature/prompts/src/main/res/values-am/strings.xml index 993ebd3dae9d..a0d6b1b70824 100644 --- a/android-components/components/feature/prompts/src/main/res/values-am/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-am/strings.xml @@ -19,6 +19,8 @@ የይለፍ ቃል አታስቀምጥ + + አሁን አይሆንም በጭራሽ አታስቀምጥ @@ -27,16 +29,26 @@ አስቀምጥ አታዘምን + + አሁን አይሆንም አዘምን የይለፍ ቃል ባዶ መሆን የለበትም + የይለፍ ቃል ያስገቡ + መግባትን ማስቀመጥ አልተቻለም + + የይለፍ ቃል ማስቀመጥ አልተቻለም ይህ መግቢያ ይቀመጥ? + + የይለፍ ቃል ይቀመጥ? ይህ መግቢያ ይዘምን? + + የይለፍ ቃል ይዘምን? የተጠቃሚ ስም በተቀመጠው ይለፍ ቃል ላይ ይታከል? @@ -87,13 +99,22 @@ ስዓት ይሙሉ መግቢያዎችን ያስተዳድሩ + + የይለፍ ቃሎችን አስተዳድር የተጠቆሙ መግቢያዎችን ዘርጋ + + የተቀመጡ የይለፍ ቃሎችን ዘርጋ የተጠቆሙ መግቢያዎችን ሰብስብ + + የተቀመጡ የይለፍ ቃሎችን ሰብስብ የተጠቆሙ መግቢያዎች + + የተቀመጡ የይለፍ ቃሎች + ጠንካራ የይለፍ ቃል ጥቆማ @@ -114,12 +135,20 @@ ክሬዲት ካርድ ይምረጡ + + የተቀመጠ ካርድ ተጠቀም የተጠቆሙ ክሬዲት ካርዶችን ዘርጋ + + የተቀመጡ ካርዶችን ዘርጋ የተጠቆሙ ክሬዲት ካርዶችን ሰብስብ + + የተቀመጡ ካርዶችን ሰብስብ ክሬዲት ካርዶችን ያስተዳድሩ + + ካርዶችን ያስተዳድሩ ይህን ካርድ ደህንነቱ በተጠበቀ ሁኔታ ይቀመጥ? @@ -128,13 +157,20 @@ የካርድ ቁጥር ይሰወራል ። የደህንነት የሚስጥር ፅሑፍ አይቀመጥም። + + %s የካርድ ቁጥርዎን ያመስጥራል። የደህንነት ኮድዎ አይቀመጥም። + አድራሻ ይምረጡ የተጠቆሙ አድራሻዎችን ዘርጋ + + የተቀመጡ አድራሻዎችን ዘርጋ የተጠቆሙ አድራሻዎችን ሰብስብ + + የተቀመጡ አድራሻዎችን ሰብስብ አድራሻዎችን ያስተዳድሩ diff --git a/android-components/components/feature/prompts/src/main/res/values-bg/strings.xml b/android-components/components/feature/prompts/src/main/res/values-bg/strings.xml index 3e809b564bdb..410a7b581d50 100644 --- a/android-components/components/feature/prompts/src/main/res/values-bg/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-bg/strings.xml @@ -18,6 +18,8 @@ Парола Без запазване + + Не сега Без запазване @@ -26,16 +28,26 @@ Запазване Без обновяване + + Не сега Обновяване Полето за парола не трябва да е празно + Въведете парола + Данните за вход не могат да бъдат запазени + + Паролата не може да бъде запазена Запазване на регистрацията? + + Запазване на паролата? Обновяване на регистрацията? + + Актуализиране на паролата? Добавяне на потребител към запазената парола? @@ -85,13 +97,22 @@ Задаване на време Управление на регистрации + + Управление на пароли Разгъване на предложени регистрации + + Разгъване на запазените пароли Сгъване на предложени регистрации + + Сгъване на запазените пароли Предложени регистрации + + Запазени пароли + Предлагане на силна парола @@ -110,12 +131,20 @@ Изберете банкова карта + + Използване на запазена карта Разгъва предложения списък с банкови карти + + Разгъване на запазените карти Сгъва предложения списък с банкови карти + + Сгъване на запазените карти Управление на банкови карти + + Управление на карти Защитено запазване на картата? @@ -124,13 +153,20 @@ Номерът на карата ще бъде шифрован. Кодът за сигурност няма да бъде запазен. + + %s шифрова номера на картата ви. Кодът ви за сигурност няма да бъде запазен. + Изберете адрес Разгъване на предложени адреси + + Разгъване на запазените адреси Свиване на предложени адреси + + Сгъване на запазените адреси Управление на адреси diff --git a/android-components/components/feature/prompts/src/main/res/values-ca/strings.xml b/android-components/components/feature/prompts/src/main/res/values-ca/strings.xml index 716b4ae9be4c..63d52c09b91a 100644 --- a/android-components/components/feature/prompts/src/main/res/values-ca/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-ca/strings.xml @@ -18,6 +18,8 @@ Contrasenya No desis + + Ara no No desis mai @@ -26,16 +28,26 @@ Desa No actualitzis + + Ara no Actualitza El camp de la contrasenya no pot estar buit + Escriviu una contrasenya + No es pot desar l’inici de sessió + + No s\'ha pogut desar la contrasenya Voleu desar aquest inici de sessió? + + Voleu desar la contrasenya? Voleu actualitzar aquest inici de sessió? + + Voleu actualitzar la contrasenya? Voleu afegir el nom d’usuari a la contrasenya desada? @@ -85,13 +97,22 @@ Defineix l’hora Gestiona els inicis de sessió + + Gestiona les contrasenyes Amplia els inicis de sessió suggerits + + Amplia les contrasenyes desades Redueix els inicis de sessió suggerits + + Redueix les contrasenyes desades Inicis de sessió suggerits + + Contrasenyes desades + Suggereix una contrasenya segura @@ -110,12 +131,20 @@ Seleccioneu una targeta de crèdit + + Usa una targeta desada Amplia les targetes de crèdit suggerides + + Amplia les targetes desades Redueix les targetes de crèdit suggerides + + Redueix les targetes desades Gestiona les targetes de crèdit + + Gestiona les targetes Voleu desar aquesta targeta de forma segura? @@ -123,13 +152,20 @@ El número de targeta es xifrarà. El codi de seguretat no es desarà. + + %s xifra el número de la targeta. El codi de seguretat no es desarà. + Trieu l’adreça Amplia les adreces suggerides + + Amplia les adreces desades Redueix les adreces suggerides + + Redueix les adreces desades Gestiona les adreces diff --git a/android-components/components/feature/prompts/src/main/res/values-cy/strings.xml b/android-components/components/feature/prompts/src/main/res/values-cy/strings.xml index 8ac983a2bfdb..d6e70ad31a96 100644 --- a/android-components/components/feature/prompts/src/main/res/values-cy/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-cy/strings.xml @@ -18,6 +18,8 @@ Cyfrinair Peidio â chadw + + Nid nawr Byth cadw @@ -26,16 +28,26 @@ Cadw Peidio â diweddaru + + Nid nawr Diweddaru Rhaid i faes cyfrinair beidio â bod yn wag + Rhowch gyfrinair + Methu cadw mewngofnod + + Methu cadw cyfrinair Cadw’r mewngofnod hwn? + + Cadw cyfrinair? Diweddaru’r mewngofnod hwn? + + Diweddaru cyfrinair? Ychwanegu enw defnyddiwr i gyfrinair wedi’i gadw? @@ -85,13 +97,22 @@ Gosod yr amser Rheoli mewngofnodion + + Rheoli cyfrineiriau Ehangu’r mewngofnodion + + Ehangu cyfrineiriau sydd wedi\'u cadw Lleihau’r mewngofnodion + + Cau cyfrineiriau sydd wedi\'u cadw Mewngofnodion + + Cyfrineiriau wedi\'u cadw + Awgrym o gyfrinair cryf @@ -110,12 +131,20 @@ Dewiswch gerdyn credyd + + Defnyddio cerdyn sydd wedi\'i gadw Ehangu awgrymiad y cardiau credyd + + Ehangu cardiau sydd wedi\'u cadw Lleihau awgrymiad y cardiau credyd + + Cau cardiau sydd wedi\'u cadw Rheoli cardiau credyd + + Rheoli cardiau Cadw’r cerdyn hwn yn ddiogel? @@ -123,13 +152,20 @@ Bydd rhif y cerdyn yn cael ei amgryptio. Ni fydd y cod diogelwch yn cael ei gadw. + + Mae %s yn amgryptio rhif eich cerdyn. Ni fydd eich cod diogelwch yn cael ei gadw. + Dewiswch gyfeiriad Ehangu awgrymiadau cyfeiriadau + + Ehangu cyfeiriadau sydd wedi\'u cadw Lleihau awgrymiadau cyfeiriadau + + Cau cyfeiriadau sydd wedi\'u cadw Rheoli cyfeiriadau diff --git a/android-components/components/feature/prompts/src/main/res/values-de/strings.xml b/android-components/components/feature/prompts/src/main/res/values-de/strings.xml index 0ffffc354c13..de995ecc074e 100644 --- a/android-components/components/feature/prompts/src/main/res/values-de/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-de/strings.xml @@ -26,6 +26,8 @@ Nicht speichern + + Nicht jetzt Nie speichern @@ -34,16 +36,26 @@ Speichern Nicht aktualisieren + + Nicht jetzt Aktualisieren Das Passwortfeld darf nicht leer bleiben + Passwort eingeben + Zugangsdaten konnten nicht gespeichert werden + + Passwort kann nicht gespeichert werden Diese Zugangsdaten speichern? + + Passwort speichern? Diese Zugangsdaten aktualisieren? + + Passwort aktualisieren? Benutzernamen zum gespeicherten Passwort hinzufügen? @@ -97,13 +109,22 @@ Zeit einstellen Zugangsdaten verwalten + + Passwörter verwalten Vorgeschlagene Zugangsdaten ausklappen + + Gespeicherte Passwörter ausklappen Vorgeschlagene Zugangsdaten einklappen + + Gespeicherte Passwörter einklappen Vorgeschlagene Zugangsdaten + + Gespeicherte Passwörter + Starkes Passwort vorschlagen @@ -122,12 +143,20 @@ Kreditkarte auswählen + + Eine gespeicherte Karte verwenden Vorgeschlagene Kreditkarten ausklappen + + Gespeicherte Karten ausklappen Vorgeschlagene Kreditkarten einklappen + + Gespeicherte Karten einklappen Kreditkarten verwalten + + Karten verwalten Soll diese Karte sicher gespeichert werden? @@ -135,13 +164,20 @@ Die Kartennummer wird verschlüsselt. Der Sicherheitscode wird nicht gespeichert. + + %s verschlüsselt Ihre Kartennummer. Ihr Sicherheitscode wird nicht gespeichert. + Adresse auswählen Vorgeschlagene Adressen ausklappen + + Gespeicherte Adressen ausklappen Vorgeschlagene Adressen einklappen + + Gespeicherte Adressen einklappen Adressen verwalten diff --git a/android-components/components/feature/prompts/src/main/res/values-dsb/strings.xml b/android-components/components/feature/prompts/src/main/res/values-dsb/strings.xml index a54f51346016..36188bb0bc69 100644 --- a/android-components/components/feature/prompts/src/main/res/values-dsb/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-dsb/strings.xml @@ -18,6 +18,8 @@ Gronidło Njeskładowaś + + Nic něnto Nigda njeskładowaś @@ -26,16 +28,26 @@ Składowaś Njeaktualizěrowaś + + Nic něnto Aktualizěrowaś Gronidłowe pólo njesmějo prozne byś + Gronidło zapódaś + Pśizjawjenje njedajo se składowaś + + Gronidło njedajo se składowaś Toś to pśizjawjenje składowaś? + + Gronidło składowaś? Toś to pśizjawjenje aktualizěrowaś? + + Gronidło aktualizěrowaś? Wužywaŕske mě skłaźonemu gronidłoju pśidaś? @@ -85,13 +97,22 @@ Cas nastajiś Pśizjawjenja zastojaś + + Gronidła zastojaś Naraźone pśizjawjenja pokazaś + + Skłaźone gronidła pokazaś Naraźone pśizjawjenja schowaś + + Skłaźone gronidła schowaś Naraźone pśizjawjenja + + Skłaźone gronidła + Mócne gronidło naraźiś @@ -110,12 +131,20 @@ Kreditowu kórtu wubraś + + Skłaźonu kórtu wužywaś Naraźone kreditowe kórty pokazaś + + Skłaźone kórty pokazaś Naraźone kreditowe kórty schowaś + + Skłaźone kórty schowaś Kreditowe kórty zastojaś + + Kórty zastojaś Toś tu kórtu wěsće składowaś? @@ -123,13 +152,20 @@ Numer kórty buźo se koděrowaś. Wěstotny kod njebuźo se składowaś. + + %s waš kórtowy numer koděrujo. Waš wěstotny kod njebuźo se składowaś. + Adresu wubraś Naraźone adrese pokazaś + + Skłaźone adrese pokazaś Naraźone adrese schowaś + + Skłaźone adrese schowaś Adrese zastojaś diff --git a/android-components/components/feature/prompts/src/main/res/values-el/strings.xml b/android-components/components/feature/prompts/src/main/res/values-el/strings.xml index 3e996c44224f..44f632fa99d8 100644 --- a/android-components/components/feature/prompts/src/main/res/values-el/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-el/strings.xml @@ -18,6 +18,8 @@ Κωδικός πρόσβασης Χωρίς αποθήκευση + + Όχι τώρα Ποτέ αποθήκευση @@ -26,16 +28,26 @@ Αποθήκευση Να μη γίνει ενημέρωση + + Όχι τώρα Ενημέρωση Το πεδίο κωδικού πρόσβασης δεν πρέπει να είναι κενό + Εισαγάγετε έναν κωδικό πρόσβασης + Αποτυχία αποθήκευσης σύνδεσης + + Αδυναμία αποθήκευσης κωδικού πρόσβασης Αποθήκευση σύνδεσης; + + Αποθήκευση κωδικού πρόσβασης; Ενημέρωση σύνδεσης; + + Ενημέρωση κωδικού πρόσβασης; Προσθήκη ονόματος χρήστη στον αποθηκευμένο κωδικό πρόσβασης; @@ -85,13 +97,22 @@ Ορισμός ώρας Διαχείριση συνδέσεων + + Διαχείριση κωδικών πρόσβασης Ανάπτυξη προτεινόμενων συνδέσεων + + Ανάπτυξη των αποθηκευμένων κωδικών πρόσβασης Σύμπτυξη προτεινόμενων συνδέσεων + + Σύμπτυξη αποθηκευμένων κωδικών πρόσβασης Προτεινόμενες συνδέσεις + + Αποθηκευμένοι κωδικοί πρόσβασης + Πρόταση ισχυρού κωδικού πρόσβασης @@ -110,12 +131,20 @@ Επιλογή πιστωτικής κάρτας + + Χρήση αποθηκευμένης κάρτας Ανάπτυξη προτεινόμενων πιστωτικών καρτών + + Ανάπτυξη αποθηκευμένων καρτών Σύμπτυξη προτεινόμενων πιστωτικών καρτών + + Σύμπτυξη αποθηκευμένων καρτών Διαχείριση πιστωτικών καρτών + + Διαχείριση καρτών Ασφαλής αποθήκευση κάρτας; @@ -123,13 +152,20 @@ Ο αριθμός της κάρτας θα κρυπτογραφηθεί. Ο κωδικός ασφαλείας δεν θα αποθηκευτεί. + + Το %s κρυπτογραφεί τον αριθμό της κάρτας σας. Ο κωδικός ασφαλείας σας δεν θα αποθηκευτεί. + Επιλογή διεύθυνσης Ανάπτυξη προτεινόμενων διευθύνσεων + + Ανάπτυξη αποθηκευμένων διευθύνσεων Σύμπτυξη προτεινόμενων διευθύνσεων + + Σύμπτυξη αποθηκευμένων διευθύνσεων Διαχείριση διευθύνσεων diff --git a/android-components/components/feature/prompts/src/main/res/values-es-rAR/strings.xml b/android-components/components/feature/prompts/src/main/res/values-es-rAR/strings.xml index 71ad735d95d0..b16d50b15a7e 100644 --- a/android-components/components/feature/prompts/src/main/res/values-es-rAR/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-es-rAR/strings.xml @@ -18,6 +18,8 @@ Contraseña No guardar + + No ahora No guardar nunca @@ -26,16 +28,26 @@ Guardar No actualizar + + No ahora Actualizar El campo de contraseña no puede estar vacío + Ingresar una contraseña + No se puede guardar el inicio de sesión + + No se puede guardar la contraseña ¿Guardar este inicio de sesión? + + ¿Guardar contraseña? ¿Actualizar este inicio de sesión? + + ¿Actualizar contraseña? ¿Agregar nombre de usuario a la contraseña guardada? @@ -85,13 +97,22 @@ Establecer hora Administrar inicios de sesión + + Administrar contraseñas Expandir los inicios de sesión sugeridos + + Expandir las contraseñas guardadas Contraer los inicios de sesión sugeridos + + Contraer contraseñas guardadas Inicios de sesión sugeridos + + Contraseñas guardadas + Sugerir contraseña segura @@ -111,12 +132,20 @@ Seleccionar tarjeta de crédito + + Usar tarjeta guardada Ampliar las tarjetas de crédito sugeridas + + Expandir tarjetas guardadas Contraer tarjetas de crédito sugeridas + + Contraer tarjetas guardadas Administrar tarjetas de crédito + + Administrar tarjetas ¿Guardar esta tarjeta de forma segura? @@ -124,13 +153,20 @@ El número de tarjeta será cifrado. El código de seguridad no se guardará. + + %s cifra tu número de tarjeta. El código de seguridad no se guardará. + Seleccionar dirección Expandir direcciones sugeridas + + Expandir las direcciones guardadas Contraer direcciones sugeridas + + Contraer direcciones guardadas Administrar direcciones diff --git a/android-components/components/feature/prompts/src/main/res/values-es-rCL/strings.xml b/android-components/components/feature/prompts/src/main/res/values-es-rCL/strings.xml index 17c22b0eeb56..ed1d9dd56fdc 100644 --- a/android-components/components/feature/prompts/src/main/res/values-es-rCL/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-es-rCL/strings.xml @@ -18,6 +18,8 @@ Contraseña No guardar + + Ahora no Nunca guardar @@ -26,16 +28,26 @@ Guardar No actualizar + + Ahora no Actualizar El campo de contraseña no puede estar vacío + Ingresar una contraseña + No se pudo guardar la credencial + + No se puede guardar la contraseña ¿Guardar esta credencial? + + ¿Guardar contraseña? ¿Actualizar esta credencial? + + ¿Actualizar contraseña? ¿Añadir nombre de usuario a la contraseña guardada? @@ -85,13 +97,22 @@ Ajustar hora Administrar credenciales + + Gestionar contraseñas Expandir credenciales sugeridas + + Expandir contraseñas guardadas Contraer credenciales sugeridas + + Contraer contraseñas guardadas Credenciales sugeridas + + Contraseñas guardadas + Sugerir contraseña segura @@ -110,12 +131,20 @@ Seleccionar tarjeta de crédito + + Usar tarjeta guardada Expandir tarjetas de crédito sugeridas + + Expandir tarjetas guardadas Ocultar tarjetas de crédito sugeridas + + Contraer tarjetas guardadas Gestionar tarjetas de crédito + + Gestionar tarjetas ¿Guardar esta tarjeta de forma segura? @@ -123,13 +152,20 @@ El número de la tarjeta será encriptado. El código de seguridad no será guardo. + + %s cifra tu número de tarjeta. Tu código de seguridad no será guardado. + Seleccionar dirección Expandir direcciones sugeridas + + Expandir direcciones guardadas Ocultar direcciones sugeridas + + Contraer direcciones guardadas Gestionar direcciones diff --git a/android-components/components/feature/prompts/src/main/res/values-fi/strings.xml b/android-components/components/feature/prompts/src/main/res/values-fi/strings.xml index 495c5c826184..c0c777120efa 100644 --- a/android-components/components/feature/prompts/src/main/res/values-fi/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-fi/strings.xml @@ -18,6 +18,8 @@ Salasana Älä tallenna + + Ei nyt Älä tallenna koskaan @@ -26,16 +28,26 @@ Tallenna Älä päivitä + + Ei nyt Päivitä Salasanakenttä ei saa olla tyhjä + Kirjoita salasana + Kirjautumistietojen tallennus epäonnistui + + Salasanaa ei voi tallentaa Tallennetaanko tämä kirjautumistieto? + + Tallennetaanko salasana? Päivitetäänkö tämä kirjautumistieto? + + Päivitetäänkö salasana? Lisätäänkö käyttäjänimi tallennettuun salasanaan? @@ -85,13 +97,22 @@ Aseta aika Hallitse kirjautumistietoja + + Hallitse salasanoja Laajenna ehdotetut kirjautumistiedot + + Laajenna tallennetut salasanat Supista ehdotetut kirjautumistiedot + + Supista tallennetut salasanat Ehdotetut kirjautumistiedot + + Tallennetut salasanat + Ehdota vahvaa salasanaa @@ -110,12 +131,20 @@ Valitse luottokortti + + Käytä tallennettua korttia Laajenna ehdotetut luottokortit + + Laajenna tallennetut kortit Supista ehdotetut luottokortit + + Supista tallennetut kortit Hallitse luottokortteja + + Hallitse kortteja Tallennetaanko tämä kortti turvallisesti? @@ -123,13 +152,20 @@ Kortin numero salataan. Suojakoodia ei tallenneta. + + %s salaa korttisi numeron. Turvakoodiasi ei tallenneta. + Valitse osoite Laajenna ehdotetut osoitteet + + Laajenna tallennetut osoitteet Supista ehdotetut osoitteet + + Supista tallennetut osoitteet Hallitse osoitteita diff --git a/android-components/components/feature/prompts/src/main/res/values-fr/strings.xml b/android-components/components/feature/prompts/src/main/res/values-fr/strings.xml index 23dced369419..222a50f1a11c 100644 --- a/android-components/components/feature/prompts/src/main/res/values-fr/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-fr/strings.xml @@ -24,6 +24,8 @@ Ne pas enregistrer + + Plus tard Ne jamais enregistrer @@ -32,16 +34,26 @@ Enregistrer Ne pas mettre à jour + + Plus tard Mettre à jour Le champ mot de passe ne doit pas être vide + Saisissez un mot de passe + Impossible d’enregistrer l’identifiant + + Impossible d’enregistrer le mot de passe Enregistrer ces identifiants ? + + Enregistrer le mot de passe ? Mettre à jour cet identifiant ? + + Mettre à jour le mot de passe ? Ajouter un nom d’utilisateur au mot de passe enregistré ? @@ -94,6 +106,8 @@ Choisir l’heure Gérer les identifiants + + Gérer les mots de passe Développer les identifiants suggérés @@ -101,6 +115,9 @@ Identifiants suggérés + + Mots de passe enregistrés + Suggérer un mot de passe fort @@ -119,12 +136,16 @@ Sélectionner une carte bancaire + + Utiliser une carte enregistrée Développer les cartes bancaires suggérées Réduire les cartes bancaires suggérées Gérer les cartes bancaires + + Gérer les cartes Enregistrer cette carte en toute sécurité ? @@ -132,6 +153,9 @@ Le numéro de carte sera chiffré. Le code de sécurité ne sera pas enregistré. + + %s chiffre votre numéro de carte. Votre code de sécurité ne sera pas enregistré. + Sélectionner une adresse diff --git a/android-components/components/feature/prompts/src/main/res/values-fy-rNL/strings.xml b/android-components/components/feature/prompts/src/main/res/values-fy-rNL/strings.xml index 2eb2fd6d5659..648aa71c19af 100644 --- a/android-components/components/feature/prompts/src/main/res/values-fy-rNL/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-fy-rNL/strings.xml @@ -18,6 +18,8 @@ Wachtwurd Net bewarje + + No net Nea bewarje @@ -26,16 +28,26 @@ Bewarje Net bywurkje + + No net Bywurkje Wachtwurdfjild mei net leech wêze + Folje in wachtwurd yn + Kin oanmelding net bewarje + + Kin wachtwurd net bewarje Dizze oanmelding bewarje? + + Wachtwurd bewarje? Dizze oanmelding bywurkje? + + Wachtwurd bywurkje? Brûkersnamme oan bewarre wachtwurd tafoegje? @@ -85,13 +97,22 @@ Tiid ynstelle Oanmeldingen beheare + + Wachtwurden beheare Foarstelde oanmeldingen útklappe + + Bewarre wachtwurden te útklappe Foarstelde oanmeldingen ynklappe + + Bewarre wachtwurden ynklappe Foarstelde oanmeldingen + + Bewarre wachtwurden + Sterk wachtwurd foarstelle @@ -110,12 +131,20 @@ Selektearje creditcard + + Bewarre kaart brûke Foarstelde creditcards útklappe + + Bewarre kaarten te útklappe Foarstelde creditcards ynklappe + + Bewarre kaarten ynklappe Creditcards beheare + + Kaarten beheare Dizze kaart feilich bewarje? @@ -123,13 +152,20 @@ It kaartnûmer sil fersifere wurde. De befeiligingskoade wurdt net bewarre. + + %s fersiferet jo kaartnûmer. Jo befeiligingskoade wurdt net bewarre. + Adres selektearje Foarstelde adressen útklappe + + Bewarre adressen útklappe Foarstelde adressen ynklappe + + Bewarre adressen ynklappe Adressen beheare diff --git a/android-components/components/feature/prompts/src/main/res/values-hsb/strings.xml b/android-components/components/feature/prompts/src/main/res/values-hsb/strings.xml index 959663b2c5e7..23d8daba551d 100644 --- a/android-components/components/feature/prompts/src/main/res/values-hsb/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-hsb/strings.xml @@ -18,6 +18,8 @@ Hesło Njeskładować + + Nic nětko Ženje njeskładować @@ -26,16 +28,26 @@ Składować Njeaktualizować + + Nic nětko Aktualizować Hesłowe polo njesmě prózdne być + Hesło zapodać + Přizjewjenje njeda so składować + + Hesło njeda so składować Tute přizjewjenje składować? + + Hesło składować? Tute přizjewjenje aktualizować? + + Hesło aktualizować? Wužiwarske mjeno składowanemu hesłu přidać? @@ -85,13 +97,22 @@ Čas nastajić Přizjewjenja rjadować + + Hesła rjadować Namjetowane přizjewjenja pokazać + + Składowane hesła pokazać Namjetowane přizjewjenja schować + + Składowane hesła schować Namjetowane přizjewjenja + + Składowane hesła + Sylne hesło namjetować @@ -110,12 +131,20 @@ Kreditnu kartu wubrać + + Składowanu kartu wužiwać Namjetowane kreditne karty pokazać + + Składowane karty pokazać Namjetowane kreditne karty schować + + Składowane karty schować Kreditne karty rjadować + + Karty rjadować Tutu kartu wěsće składować? @@ -123,13 +152,20 @@ Čisło karty budźe so zaklučować. Wěstotny kod njebudźe so składować. + + %s waše kartowe čisło zaklučuje. Waš wěstotny kod njebudźe so składować. + Adresu wubrać Namjetowane adresy pokazać + + Składowane adresy pokazać Namjetowane adresy schować + + Składowane adresy schować Adresy rjadować diff --git a/android-components/components/feature/prompts/src/main/res/values-ia/strings.xml b/android-components/components/feature/prompts/src/main/res/values-ia/strings.xml index d6b7a8b9b57c..d81b6b52e462 100644 --- a/android-components/components/feature/prompts/src/main/res/values-ia/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-ia/strings.xml @@ -18,6 +18,8 @@ Contrasigno Non salvar + + Non ora Non salvar mais @@ -26,16 +28,26 @@ Salvar Non actualisar + + Non ora Actualisar Le campo del contrasigno non debe esser vacue + Insere un contrasigno + Impossibile salvar le credentiales + + Impossibile salvar le contrasigno Salvar iste credentiales? + + Salvar le contrasigno? Actualisar iste credentiales? + + Actualisar le contrasigno? Adder le nomine de usator al contrasigno salvate? @@ -86,13 +98,22 @@ Gerer credentiales + + Gerer contrasignos Expander le credentiales suggerite + + Expander le contrasignos salvate Collaber le credentiales suggerite + + Comprimer le contrasignos salvate Credentiales suggerite + + Contrasignos salvate + Suggerer contrasigno complexe @@ -111,12 +132,20 @@ Eliger le carta de credito + + Usar un carta salvate Expander le cartas de credito suggerite + + Expander le cartas salvate Collaber le cartas de credito suggerite + + Comprimer le cartas salvate Gerer le cartas de credito + + Gerer le cartas Securmente salveguardar iste carta? @@ -124,13 +153,20 @@ Le numero de carta sera cryptate. Le codice de securitate non sera salvate. + + %s crypta tu numero de carta. Tu codice de securitate non sera salvate. + Seliger adress Expander adresses suggerite + + Expander adresses salvate Collaber adresses suggerite + + Collaber adresses salvate Gerer adresses diff --git a/android-components/components/feature/prompts/src/main/res/values-is/strings.xml b/android-components/components/feature/prompts/src/main/res/values-is/strings.xml index fc9c5657a640..790b620f4d3b 100644 --- a/android-components/components/feature/prompts/src/main/res/values-is/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-is/strings.xml @@ -18,6 +18,8 @@ Lykilorð Ekki vista + + Ekki núna Aldrei vista @@ -26,16 +28,26 @@ Vista Ekki uppfæra + + Ekki núna Uppfæra Lykilorðareiturinn má ekki vera tómur + Settu inn lykilorð + Gat ekki vistað innskráningarupplýsingar + + Get ekki vistað lykilorð Vista þessa innskráningu? + + Vista lykilorð? Uppfæra þessa innskráningu? + + Uppfæra lykilorð? Bæta notandanafni við vistað lykilorð? @@ -86,14 +98,23 @@ Sýsla með innskráningar + + Sýsla með lykilorð Fletta út tillögum að innskráningu + + Fletta út vistuð lykilorð Fella saman tillögur að innskráningu + + Fella saman vistuð lykilorð Tillögur að innskráningu + + Vistuð lykilorð + Stinga upp á sterku lykilorði @@ -112,12 +133,20 @@ Veldu greiðslukort + + Nota vistað kort Fletta út tillögum að greiðslukortum + + Fletta út vistuð greiðslukort Fella saman tillögur að greiðslukortum + + Fella saman vistuð greiðslukort Sýsla með greiðslukort + + Sýsla með greiðslukort Vista þetta kort á öruggan hátt? @@ -125,13 +154,20 @@ Kortanúmer verður dulritað. Öryggiskóði verður ekki vistaður. + + %s dulkóðar kortanúmerið þitt. Öryggiskóðinn þinn verður ekki vistaður. + Veldu póstfang Fletta út tillögum að póstföngum + + Fletta út vistuðum heimilisföngum Fella saman tillögur að póstföngum + + Fella saman vistuð heimilisföng Sýsla með póstföng diff --git a/android-components/components/feature/prompts/src/main/res/values-it/strings.xml b/android-components/components/feature/prompts/src/main/res/values-it/strings.xml index d826997ab929..55f05583930f 100644 --- a/android-components/components/feature/prompts/src/main/res/values-it/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-it/strings.xml @@ -18,6 +18,8 @@ Password Non salvare + + Non adesso Non salvare mai @@ -26,16 +28,26 @@ Salva Non aggiornare + + Non adesso Aggiorna È necessario inserire una password + Inserisci una password + Impossibile salvare le credenziali + + Impossibile salvare la password Salvare queste credenziali? + + Salvare la password? Aggiornare queste credenziali? + + Aggiornare la password? Aggiungere il nome utente alle credenziali salvate? @@ -85,13 +97,22 @@ Imposta ora Gestione credenziali + + Gestisci password Espandi le credenziali suggerite + + Espandi le password salvate Comprimi le credenziali suggerite + + Comprimi le password salvate Credenziali suggerite + + Password salvate + Suggerisci password complessa @@ -110,12 +131,20 @@ Seleziona carta di credito + + Utilizza carta salvata Espandi l’elenco delle carte di credito suggerite + + Espandi le carte salvate Comprimi l’elenco delle carte di credito suggerite + + Comprimi le carte salvate Gestisci carte di credito + + Gestisci carte Salvare questa carta in modo sicuro? @@ -123,13 +152,20 @@ Il numero della carta sarà crittato. Il codice di sicurezza non verrà salvato. + + %s critta il numero della tua carta. Il codice di sicurezza non verrà salvato. + Seleziona indirizzo Espandi gli indirizzi suggeriti + + Espandi gli indirizzi salvati Comprimi gli indirizzi suggeriti + + Comprimi gli indirizzi salvati Gestisci indirizzi diff --git a/android-components/components/feature/prompts/src/main/res/values-iw/strings.xml b/android-components/components/feature/prompts/src/main/res/values-iw/strings.xml index 6f1cc29b7ac8..879dd4dcc260 100644 --- a/android-components/components/feature/prompts/src/main/res/values-iw/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-iw/strings.xml @@ -18,6 +18,8 @@ ססמה לא לשמור + + לא כעת לעולם לא לשמור @@ -26,16 +28,26 @@ לשמור לא לעדכן + + לא כעת עדכון שדה הססמה לא יכול להישאר ריק + נא להכניס ססמה + לא ניתן לשמור את הכניסה + + לא ניתן לשמור את הססמה לשמור כניסה זו? + + לשמור את הססמה? לעדכן כניסה זו? + + לעדכן את הססמה? להוסיף שם משתמש לססמה השמורה? @@ -85,13 +97,22 @@ הגדרת זמן ניהול כניסות + + ניהול ססמאות הרחבת הכניסות המוצעות + + הרחבת ססמאות שמורות צמצום הכניסות המוצעות + + צמצום ססמאות שמורות כניסות מוצעות + + ססמאות שמורות + קבלת הצעה לססמה חזקה @@ -110,12 +131,20 @@ בחירת כרטיס אשראי + + שימוש בכרטיס השמור הרחבת כרטיסי האשראי המוצעים + + הרחבת כרטיסים שמורים צמצום כרטיסי האשראי המוצעים + + צמצום כרטיסים שמורים ניהול כרטיסי אשראי + + ניהול כרטיסים לשמור את הכרטיס הזה באופן מאובטח? @@ -123,13 +152,20 @@ מספר הכרטיס יוצפן. קוד האבטחה לא יישמר. + + ‏%s מצפין את מספר הכרטיס שלך. קוד האבטחה שלך לא יישמר. + בחירת כתובת הרחבת הכתובות המוצעות + + הרחבת כתובות דוא״ל צמצום הכתובות המוצעות + + צמצום כתובות דוא״ל ניהול כתובות diff --git a/android-components/components/feature/prompts/src/main/res/values-kk/strings.xml b/android-components/components/feature/prompts/src/main/res/values-kk/strings.xml index 86822adf1363..2dc4c617a54d 100644 --- a/android-components/components/feature/prompts/src/main/res/values-kk/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-kk/strings.xml @@ -18,6 +18,8 @@ Пароль Сақтамау + + Қазір емес Ешқашан сақтамау @@ -26,16 +28,26 @@ Сақтау Жаңартпау + + Қазір емес Жаңарту Пароль өрісі бос болмауы тиіс + Парольді енгізіңіз + Логинді сақтау мүмкін емес + + Парольді сақтау мүмкін емес Бұл логинді сақтау керек пе? + + Парольді сақтау керек пе? Бұл логинді жаңарту керек пе? + + Парольді жаңарту керек пе? Пайдаланушы атын сақталған парольге қосу керек пе? @@ -85,13 +97,22 @@ Уақытты орнату Логиндерді басқару + + Парольдерді басқару Ұсынылған логиндерді жазық қылу + + Сақталған парольдерді жазық қылу Ұсынылған логиндерді қайыру + + Сақталған парольдерді бүктеу Ұсынылған логиндер + + Сақталған парольдер + Мықты парольді ұсыну @@ -110,12 +131,20 @@ Несиелік картаны таңдау + + Сақталған картаны пайдалану Ұсынылған несиелік карталарды жаю + + Сақталған карталарды жазық қылу Ұсынылған несиелік карталарды жию + + Сақталған карталарды бүктеу Несиелік карталарды басқару + + Карталарды басқару Бұл картаны қауіпсіз сақтау керек пе? @@ -123,13 +152,20 @@ Карта нөмірі шифрленеді. Қауіпсіздік коды сақталмайды. + + %sкартаңыздың нөмірін шифрлейді. Қауіпсіздік кодыңыз сақталмайтын болады. + Адресті таңдау Ұсынылған адрестерді жазық қылу + + Сақталған адрестерді жазық қылу Ұсынылған адрестерді бүктеу + + Сақталған адрестерді бүктеу Адрестерді басқару diff --git a/android-components/components/feature/prompts/src/main/res/values-ko/strings.xml b/android-components/components/feature/prompts/src/main/res/values-ko/strings.xml index 3a9b9f5ca9de..69b227b80092 100644 --- a/android-components/components/feature/prompts/src/main/res/values-ko/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-ko/strings.xml @@ -18,6 +18,8 @@ 비밀번호 저장 안 함 + + 나중에 저장 안 함 @@ -26,16 +28,26 @@ 저장 업데이트 안 함 + + 나중에 업데이트 비밀번호 필드는 비워 둘 수 없습니다 + 비밀번호 입력 + 로그인을 저장할 수 없음 + + 비밀번호를 저장할 수 없음 이 로그인을 저장하시겠습니까? + + 비밀번호를 저장하시겠습니까? 이 로그인을 업데이트하시겠습니까? + + 비밀번호를 업데이트하시겠습니까? 저장된 비밀번호에 사용자 이름을 추가하시겠습니까? @@ -85,13 +97,22 @@ 시간 설정 로그인 관리 + + 비밀번호 관리 제안된 로그인 펼치기 + + 저장된 비밀번호 펼치기 제안된 로그인 접기 + + 저장된 비밀번호 접기 제안된 로그인 + + 저장된 비밀번호 + 강력한 비밀번호 제안 @@ -110,12 +131,20 @@ 신용 카드 선택 + + 저장된 카드 사용 제안된 신용 카드 펼치기 + + 저장된 비밀번호 펼치기 제안된 신용 카드 접기 + + 저장된 비밀번호 접기 신용 카드 관리 + + 카드 관리 이 카드를 안전하게 저장하시겠습니까? @@ -123,13 +152,20 @@ 카드 번호는 암호화됩니다. 보안 코드는 저장되지 않습니다. + + %s는 카드 번호를 암호화합니다. 보안 코드는 저장되지 않습니다. + 주소 선택 제안된 주소 펼치기 + + 저장된 주소 펼치기 제안된 주소 접기 + + 저장된 주소 접기 주소 관리 diff --git a/android-components/components/feature/prompts/src/main/res/values-nl/strings.xml b/android-components/components/feature/prompts/src/main/res/values-nl/strings.xml index d5770a392314..8f4e4757733d 100644 --- a/android-components/components/feature/prompts/src/main/res/values-nl/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-nl/strings.xml @@ -18,6 +18,8 @@ Wachtwoord Niet opslaan + + Niet nu Nooit opslaan @@ -26,16 +28,26 @@ Opslaan Niet bijwerken + + Niet nu Bijwerken Wachtwoordveld mag niet leeg zijn + Vul een wachtwoord in + Kan aanmelding niet opslaan + + Kan wachtwoord niet opslaan Deze aanmelding opslaan? + + Wachtwoord opslaan? Deze aanmelding bijwerken? + + Wachtwoord bijwerken? Gebruikersnaam aan opgeslagen wachtwoord toevoegen? @@ -85,13 +97,22 @@ Tijd instellen Aanmeldingen beheren + + Wachtwoorden beheren Voorgestelde aanmeldingen uitvouwen + + Opgeslagen wachtwoorden uitvouwen Voorgestelde aanmeldingen inklappen + + Opgeslagen wachtwoorden inklappen Voorgestelde aanmeldingen + + Opgeslagen wachtwoorden + Sterk wachtwoord voorstellen @@ -110,12 +131,20 @@ Selecteer creditcard + + Opgeslagen kaart gebruiken Voorgestelde creditcards uitbreiden + + Opgeslagen kaarten uitvouwen Voorgestelde creditcards inklappen + + Opgeslagen kaarten inklappen Creditcards beheren + + Kaarten beheren Deze kaart veilig opslaan? @@ -123,13 +152,20 @@ Het kaartnummer wordt versleuteld. De beveiligingscode wordt niet opgeslagen. + + %s versleutelt uw kaartnummer. Uw beveiligingscode wordt niet opgeslagen. + Adres selecteren Voorgestelde adressen uitvouwen + + Opgeslagen adressen uitvouwen Voorgestelde adressen inklappen + + Opgeslagen adressen inklappen Adressen beheren diff --git a/android-components/components/feature/prompts/src/main/res/values-oc/strings.xml b/android-components/components/feature/prompts/src/main/res/values-oc/strings.xml index e44b63c8ee96..4de8003601d7 100644 --- a/android-components/components/feature/prompts/src/main/res/values-oc/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-oc/strings.xml @@ -18,6 +18,8 @@ Senhal Enregistrar pas + + Pas ara Enregistrar pas jamai @@ -26,16 +28,26 @@ Enregistrar Metre pas a jorn + + Pas ara Metre a jorn Lo camp senhal pòt pas èsser void + Picatz un senhal + Impossible d’enregistrar l’identificant + + Enregistrament de senhal impossible Salvar aqueste identificant ? + + Salvar lo senhal ? Metre a jorn aqueste identificant ? + + Actualizar lo senhal ? Apondre un nom d’utilizaire al senhal salvat ? @@ -85,13 +97,22 @@ Causida del temps Gerir los identificants + + Gerir los senhals Espandir los identificants suggerits + + Desplegar los senhals salvats Plegar los identificants suggerits + + Plegar los senhals salvats Identificants recomandats + + Senhals salvats + Suggerir un senhal fòrt @@ -110,12 +131,16 @@ Seleccionar carta de crèdit + + Utilizar una carta enregistrada Espandir las cartas de crèdit suggeridas Plegar las cartas de crèdit suggeridas Gerir las cartas de crèdit + + Gerir las cartas Salvar d’un biais segur aquesta carta ? diff --git a/android-components/components/feature/prompts/src/main/res/values-pa-rIN/strings.xml b/android-components/components/feature/prompts/src/main/res/values-pa-rIN/strings.xml index c57c9ea770b8..8cc587826d49 100644 --- a/android-components/components/feature/prompts/src/main/res/values-pa-rIN/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-pa-rIN/strings.xml @@ -18,6 +18,8 @@ ਪਾਸਵਰਡ ਨਾ ਸੰਭਾਲੋ + + ਹੁਣੇ ਨਹੀਂ ਕਦੇ ਨਾ ਸੰਭਾਲੋ @@ -26,16 +28,26 @@ ਸੰਭਾਲੋ ਅੱਪਡੇਟ ਨਾ ਕਰੋ + + ਹੁਣੇ ਨਹੀਂ ਅੱਪਡੇਟ ਕਰੋ ਪਾਸਵਰਡ ਖੇਤਰ ਖਾਲੀ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ + ਪਾਸਵਰਡ ਦਿਓ + ਲਾਗਇਨ ਸੰਭਾਲਣ ਲਈ ਅਸਮਰੱਥ + + ਪਾਸਵਰਡ ਸੰਭਾਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ ਹੈ ਇਹ ਲਾਗਇਨ ਸੰਭਾਲਣਾ ਹੈ? + + ਪਾਸਵਰਡ ਸੰਭਾਲਣਾ ਹੈ? ਇਹ ਲਾਗਇਨ ਅੱਪਡੇਟ ਕਰਨਾ ਹੈ? + + ਪਾਸਵਰਡ ਅੱਪਡੇਟ ਕਰਨਾ ਹੈ? ਵਰਤੋਂਕਾਰ-ਨਾਂ ਨੂੰ ਸੰਭਾਲੇ ਪਾਸਵਰਡ ਵਿੱਚ ਜੋੜਨਾ ਹੈ? @@ -85,13 +97,22 @@ ਸਮਾਂ ਸੈੱਟ ਕਰੋ ਲਾਗਇਨਾਂ ਦਾ ਇੰਤਜ਼ਾਮ + + ਪਾਸਵਰਡਾਂ ਦਾ ਇੰਤਜ਼ਾਮ ਸੁਝਾਏ ਲਾਗਇਨ ਫੈਲਾਓ + + ਸੰਭਾਲੇ ਹੋਏ ਪਾਸਵਰਡਾਂ ਨੂੰ ਫੈਲਾਓ ਸੁਝਾਏ ਲਾਗਇਨ ਸਮੇਟੋ + + ਸੰਭਾਲੇ ਹੋਏ ਪਾਸਵਰਡਾਂ ਨੂੰ ਸਮੇਟੋ ਸੁਝਾਏ ਗਏ ਲਾਗਇਨ + + ਸੰਭਾਲੇ ਹੋਏ ਪਾਸਵਰਡ + ਮਜ਼ਬੂਤ ਪਾਸਵਰਡ ਲਈ ਸੁਝਾਅ @@ -111,12 +132,20 @@ ਕਰੈਡਿਟ ਕਾਰਡ ਚੁਣੋ + + ਸੰਭਾਲੇ ਕਾਰਡ ਨੂੰ ਵਰਤੋਂ ਸੁਝਾਏ ਗਏ ਕਰੈਡਿਟ ਕਾਰਡ ਨੂੰ ਫੈਲਾਓ + + ਸੰਭਾਲੇ ਹੋਏ ਕਾਰਡਾਂ ਨੂੰ ਫੈਲਾਓ ਸੁਝਾਏ ਗਏ ਕਰੈਡਿਟ ਕਾਰਡ ਨੂੰ ਸਮੇਟੋ + + ਸੰਭਾਲੇ ਹੋਏ ਕਾਰਡਾਂ ਨੂੰ ਸਮੇਟੋ ਕਰੈਡਿਟ ਕਾਰਡਾਂ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰੋ + + ਕਾਰਡਾਂ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰੋ ਇਹ ਕਾਰਡ ਨੂੰ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਸੰਭਾਲਣਾ ਹੈ? @@ -124,13 +153,20 @@ ਕਾਰਡ ਨੰਬਰ ਨੂੰ ਇੰਕ੍ਰਿਪਟ ਕੀਤਾ ਜਾਵੇਗਾ। ਸੁਰੱਖਿਆ ਕੋਡ ਸੰਭਾਲਿਆ ਨਹੀਂ ਜਾਵੇਗਾ। + + %s ਤੁਹਾਡੇ ਕਾਰਡ ਨੂੰ ਇੰਕ੍ਰਿਪਟ ਕਰਦਾ ਹੈ। ਤੁਹਾਡੇ ਸੁਰੱਖਿਆ ਕੋਡ ਨੂੰ ਸੰਭਾਲਿਆ ਨਹੀਂ ਜਾਵੇਗਾ। + ਸਿਰਨਾਵਾਂ ਚੁਣੋ ਸੁਝਾਏ ਸਿਰਨਾਵਿਆਂ ਨੂੰ ਫੈਲਾਓ + + ਸੰਭਾਲੇ ਹੋਏ ਸਿਰਨਾਵਿਆਂ ਨੂੰ ਫੈਲਾਓ ਸੁਝਾਏ ਸਿਰਨਾਵਿਆਂ ਨੂੰ ਸਮੇਟੋ + + ਸੰਭਾਲੇ ਹੋਏ ਸਿਰਨਾਵਿਆਂ ਨੂੰ ਸਮੇਟੋ ਸਿਰਨਾਵਿਆਂ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰੋ diff --git a/android-components/components/feature/prompts/src/main/res/values-pt-rBR/strings.xml b/android-components/components/feature/prompts/src/main/res/values-pt-rBR/strings.xml index 8349cc06a592..de8cab92f637 100644 --- a/android-components/components/feature/prompts/src/main/res/values-pt-rBR/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-pt-rBR/strings.xml @@ -18,6 +18,8 @@ Senha Não salvar + + Agora não Nunca salvar @@ -26,16 +28,26 @@ Salvar Não atualizar + + Agora não Atualizar O campo da senha não deve ficar vazio + Digite uma senha + Não foi possível salvar a conta + + Não foi possível salvar a senha Salvar esta conta? + + Salvar senha? Atualizar esta conta? + + Atualizar senha? Adicionar nome de usuário à senha salva? @@ -85,13 +97,22 @@ Ajustar hora Gerenciar contas + + Gerenciar senhas Expandir sugestão de contas + + Expandir senhas salvas Recolher sugestão de contas + + Recolher senhas salvas Sugestão de contas + + Senhas salvas + Sugerir senha forte @@ -110,12 +131,20 @@ Selecionar cartão de crédito + + Usar cartão salvo Expandir sugestões de cartão de crédito + + Expandir cartões salvos Recolher sugestões de cartão de crédito + + Recolher cartões salvos Gerenciar cartões de crédito + + Gerenciar cartões Salvar este cartão com segurança? @@ -123,13 +152,20 @@ O número do cartão será criptografado. O código de segurança não será salvo. + + O %s criptografa o número do seu cartão. O código de segurança não é salvo. + Selecionar endereço Expandir endereços sugeridos + + Expandir endereços salvos Recolher endereços sugeridos + + Recolher endereços salvos Gerenciar endereços diff --git a/android-components/components/feature/prompts/src/main/res/values-pt-rPT/strings.xml b/android-components/components/feature/prompts/src/main/res/values-pt-rPT/strings.xml index 3d2a9172fe53..72001b57aee7 100644 --- a/android-components/components/feature/prompts/src/main/res/values-pt-rPT/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-pt-rPT/strings.xml @@ -18,6 +18,8 @@ Palavra-passe Não guardar + + Agora não Nunca guardar @@ -26,16 +28,26 @@ Guardar Não atualizar + + Agora não Atualizar O campo de palavra-passe não deve estar vazio + Introduza uma palavra-passe + Não foi possível guardar a credencial + + Não foi possível guardar a palavra-passe Guardar esta credencial? + + Guardar palavra-passe? Atualizar esta credencial? + + Atualizar palavra-passe? Adicionar nome de utilizador à palavra-passe guardada? @@ -85,13 +97,22 @@ Definir hora Gerir credenciais + + Gerir palavras-passe Expandir credenciais sugeridas + + Expandir palavras-passe guardadas Colapsar credenciais sugeridas + + Colapsar palavras-passe guardadas Credenciais sugeridas + + Palavras-passe guardadas + Sugerir palavra-passe forte @@ -111,12 +132,20 @@ Selecionar cartão de crédito + + Utilizar cartão guardado Expandir os cartões de créditos sugeridos + + Expandir cartões guardados Colapsar os cartões de crédito sugeridos + + Colapsar cartões guardados Gerir cartões de crédito + + Gerir cartões Guardar este cartão com segurança? @@ -124,13 +153,20 @@ O número do cartão será encriptado. O código de segurança não será guardado. + + O %s encripta o número do seu cartão. O seu código de segurança não será guardado. + Selecionar endereço Expandir endereços sugeridos + + Expandir endereços guardados Colapsar endereços sugeridas + + Colapsar endereços guardados Gerir endereços diff --git a/android-components/components/feature/prompts/src/main/res/values-ru/strings.xml b/android-components/components/feature/prompts/src/main/res/values-ru/strings.xml index 868701bb50fa..ca198e6cd5d0 100644 --- a/android-components/components/feature/prompts/src/main/res/values-ru/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-ru/strings.xml @@ -18,6 +18,8 @@ Пароль Не сохранять + + Не сейчас Никогда не сохранять @@ -26,16 +28,26 @@ Сохранить Не обновлять + + Не сейчас Обновить Поле пароля не может быть пустым + Введите пароль + Не удалось сохранить логин + + Не удалось сохранить пароль Сохранить этот логин? + + Сохранить пароль? Обновить этот логин? + + Обновить пароль? Добавить имя пользователя к сохранённому паролю? @@ -85,13 +97,22 @@ Установка времени Управление паролями + + Управление паролями Развернуть предлагаемые пароли + + Развернуть сохранённые пароли Свернуть предлагаемые пароли + + Свернуть сохранённые пароли Предлагаемые пароли + + Сохранённые пароли + Предложить надежный пароль @@ -111,12 +132,20 @@ Выберите банковскую карту + + Использовать сохранённую карту Развернуть предлагаемые банковские карты + + Развернуть сохранённые карты Свернуть предлагаемые банковские карты + + Свернуть сохранённые карты Управление банковскими картами + + Управление картами Сохранить надёжно эту карту? @@ -124,13 +153,20 @@ Номер карты будет зашифрован. Код безопасности не будет сохранён. + + %s шифрует номер вашей карты. Ваш код безопасности не будет сохранён. + Выберите адрес Развернуть предлагаемые адреса + + Развернуть сохранённые адреса Свернуть предлагаемые адреса + + Свернуть сохранённые адреса Управление адресами diff --git a/android-components/components/feature/prompts/src/main/res/values-sv-rSE/strings.xml b/android-components/components/feature/prompts/src/main/res/values-sv-rSE/strings.xml index 6502457c8d71..a4c4cb0a8305 100644 --- a/android-components/components/feature/prompts/src/main/res/values-sv-rSE/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-sv-rSE/strings.xml @@ -18,6 +18,8 @@ Lösenord Spara inte + + Inte nu Spara aldrig @@ -26,16 +28,26 @@ Spara Uppdatera inte + + Inte nu Uppdatera Lösenordsfältet får inte vara tomt + Ange ett lösenord + Kunde inte spara inloggningsuppgifter + + Det går inte att spara lösenordet Spara den här inloggningen? + + Spara lösenord? Vill du uppdatera den här inloggningen? + + Uppdatera lösenord? Lägg till användarnamn till det sparade lösenordet? @@ -85,13 +97,22 @@ Ange tid Hantera inloggningar + + Hantera lösenord Expandera föreslagna inloggningar + + Expandera sparade lösenord Komprimera föreslagna inloggningar + + Komprimera sparade lösenord Föreslagna inloggningar + + Sparade lösenord + Föreslå ett starkt lösenord @@ -110,12 +131,20 @@ Välj kreditkort + + Använd sparat kort Expandera föreslagna kreditkort + + Expandera sparade kort Komprimera föreslagna kreditkort + + Komprimera sparade kort Hantera kreditkort + + Hantera kort Vill du spara det här kortet säkert? @@ -123,13 +152,20 @@ Kortnummer kommer att krypteras. Säkerhetskoden kommer inte att sparas. + + %s krypterar ditt kortnummer. Din säkerhetskod kommer inte att sparas. + Välj adress Expandera föreslagna adresser + + Expandera sparade adresser Komprimera föreslagna adresser + + Komprimera sparade adresser Hantera adresser diff --git a/android-components/components/feature/prompts/src/main/res/values-zh-rCN/strings.xml b/android-components/components/feature/prompts/src/main/res/values-zh-rCN/strings.xml index b6b9af29da92..4287c4213397 100644 --- a/android-components/components/feature/prompts/src/main/res/values-zh-rCN/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-zh-rCN/strings.xml @@ -26,6 +26,8 @@ 不保存 + + 暂时不要 永不保存 @@ -34,16 +36,26 @@ 保存 不更新 + + 暂时不要 更新 密码不能为空 + 请输入密码 + 无法保存登录信息 + + 无法保存密码 要保存此登录信息吗? + + 要保存密码吗? 要更新此登录信息吗? + + 要更新密码吗? 要将用户名添加到已存密码吗? @@ -97,13 +109,22 @@ 设置时间 管理登录信息 + + 管理密码 展开推荐的登录信息 + + 展开保存的密码 折叠推荐的登录信息 + + 折叠保存的密码 推荐的登录信息 + + 保存的密码 + 建议高强度密码 @@ -122,12 +143,20 @@ 选择信用卡 + + 使用保存的信用卡 展开建议的信用卡 + + 展开保存的信用卡 折叠建议的信用卡 + + 折叠保存的信用卡 管理信用卡 + + 管理信用卡 安全地保存此卡片? @@ -135,13 +164,20 @@ 卡号将被加密,且不会保存安全码。 + + %s 会将卡号加密保存。安全码不会被保存。 + 选择地址 展开建议的地址 + + 展开保存的地址 折叠建议的地址 + + 折叠保存的地址 管理地址 diff --git a/android-components/components/feature/prompts/src/main/res/values-zh-rTW/strings.xml b/android-components/components/feature/prompts/src/main/res/values-zh-rTW/strings.xml index 29c4d5623799..d435190102ab 100644 --- a/android-components/components/feature/prompts/src/main/res/values-zh-rTW/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-zh-rTW/strings.xml @@ -26,6 +26,8 @@ 不要儲存 + + 現在不要 永不儲存 @@ -34,16 +36,26 @@ 儲存 不要更新 + + 現在不要 更新 密碼不得為空白 + 輸入密碼 + 無法儲存登入資訊 + + 無法儲存密碼 要儲存這筆登入資訊嗎? + + 要儲存密碼嗎? 要更新這筆登入資訊嗎? + + 要更新密碼嗎? 要將使用者名稱加進儲存的密碼資訊嗎? @@ -97,13 +109,22 @@ 設定時間 管理登入密碼 + + 管理密碼 展開建議的登入資訊 + + 展開儲存的密碼 摺疊建議的登入資訊 + + 摺疊儲存的密碼 建議的登入資訊 + + 已存密碼 + 建議安全的密碼 @@ -122,12 +143,20 @@ 選擇信用卡 + + 使用儲存的卡片資訊 展開建議的信用卡 + + 展開儲存的卡片資訊 摺疊建議的信用卡 + + 摺疊儲存的卡片資訊 管理信用卡 + + 管理卡片 安全地儲存這張卡的資料? @@ -135,13 +164,20 @@ 將加密卡號,也不會儲存安全碼。 + + %s 會加密您的卡號,且不會儲存安全碼。 + 選擇地址 展開建議的地址 + + 展開儲存的地址資訊 摺疊建議的地址 + + 摺疊儲存的地址資訊 管理已存地址 diff --git a/fenix/app/src/main/res/values-ca/strings.xml b/fenix/app/src/main/res/values-ca/strings.xml index faff726e0fb6..f7c504166327 100644 --- a/fenix/app/src/main/res/values-ca/strings.xml +++ b/fenix/app/src/main/res/values-ca/strings.xml @@ -68,11 +68,6 @@ No deixeu rastre en aquest dispositiu - - El %1$s suprimeix les galetes, l’historial i les dades dels llocs en tancar totes les finestres privades. %2$s Cerca a la pàgina + + Tradueix la pàgina Desa a la col·lecció @@ -246,6 +243,7 @@ Personalitza la pàgina d’inici + Pantalla d’inici @@ -253,6 +251,9 @@ Esborra l’historial de navegació + + Tradueix la pàgina + Llengua seleccionada @@ -264,8 +265,6 @@ Escaneja - - Motor de cerca Paràmetres del motor de cerca @@ -321,40 +320,33 @@ - Les notificacions us ajuden a fer més coses amb el %s + Les notificacions us ajuden a fer més coses amb el %s - Sincronitzeu les vostres pestanyes entre dispositius, gestioneu les baixades, obteniu consells per treure el màxim profit de la protecció de privadesa del %s i molt més. + Sincronitzeu les vostres pestanyes entre dispositius, gestioneu les baixades, obteniu consells per treure el màxim profit de la protecció de privadesa del %s i molt més. - Continua + Continua - Ara no + Ara no - - Feu que el Firefox sigui el vostre navegador per defecte + + Avís de privadesa del Firefox + Ens encanta mantenir-vos segur - - El Firefox prioritza les persones sobre els beneficis i defensa la vostra privadesa blocant els elements de seguiment entre llocs.\n\nTrobareu més informació en l’avís de privadesa. - El nostre navegador sense ànim de lucre ajuda a evitar que les empreses us segueixin en secret al web.\n\nObteniu més informació al nostre avís de privadesa. + El nostre navegador sense ànim de lucre ajuda a evitar que les empreses us segueixin en secret al web.\n\nObteniu més informació al nostre avís de privadesa. - avís de privadesa + avís de privadesa Defineix com a navegador per defecte Ara no - Salteu del telèfon al portàtil, i viceversa - Manteniu el xifrat quan passeu d\'un aparell a un altre - - Recupereu les pestanyes i les contrasenyes dels altres dispositius per continuar des d’on ho havíeu deixat. Si teniu la sessió iniciada i sincronitzada, esteu més segur. Firefox xifra les contrasenyes, els marcadors i molt més. @@ -362,15 +354,9 @@ Inicia la sessió Ara no - - Les notificacions us ajuden a fer més coses amb el Firefox Les notificacions us ajuden a estar més segur amb el Firefox - - Envieu pestanyes entre dispositius, gestioneu les baixades i obteniu consells per a treure el màxim profit del Firefox. Envieu pestanyes de manera segura entre els vostres dispositius i descobriu altres funcions de privadesa al Firefox. @@ -412,8 +398,6 @@ Trieu-ne un - Gestioneu les dreceres de cerca - Gestiona els motors de cerca alternatius Editeu els motors visibles al menú de cerca @@ -427,8 +411,6 @@ Motors de cerca Suggeriments dels motors de cerca - - Barra d’adreces @@ -463,21 +445,11 @@ Mode només HTTPS - - Reducció de bàners de galetes Blocador de bàners de galetes Blocador de bàners de galetes en la navegació privada - - Redueix els bàners de galetes - - - Desactivada - - Activada - - El %1$s intenta rebutjar automàticament les sol·licituds de galetes que es mostren com a bàners de galetes. + Desactivada en aquest lloc @@ -495,35 +467,15 @@ Aquest lloc no és compatible ara per ara - Voleu activar la reducció de bàners de galetes per a %1$s? - Voleu activar el blocador de bàners de galetes per a %1$s? - Voleu desactivar la reducció de bàners de galetes per a %1$s? - Voleu desactivar el blocador de bàners de galetes per a %1$s? El %1$s no pot rebutjar automàticament les sol·licituds de galetes d’aquest lloc. Podeu enviar una sol·licitud per a fer que aquest lloc sigui compatible en el futur. - El %1$s esborrarà les galetes d’aquest lloc i actualitzarà la pàgina. En esborrar totes les galetes, pot ser que se us tanquin les sessions o que se us buidin els carros de la compra. - Si el desactiveu, el %1$s esborrarà les galetes i tornarà a carregar aquest lloc. Això pot fer que se us tanquin les sessions o que se us buidin els carros de la compra. - El %1$s intenta rebutjar automàticament totes les sol·licituds de galetes de tots els llocs compatibles. - Si l\'activeu, el %1$s intentarà rebutjar automàticament tots els bàners de galetes d\'aquest lloc. - - Voleu el %1$s rebutgi els bàners de galetes? - - El %1$s pot rebutjar automàticament moltes sol·licituds de bàners de galetes. - - Ara no - - - Veureu menys sol·licituds de galetes - - - Permet El %1$s ha rebutjat les galetes @@ -552,14 +504,10 @@ Tanmateix, també és possible que hi hagi implicat un atacant. Si seguiu en el lloc web, no hi introduïu cap informació confidencial. Si continueu, el mode només HTTPS es desactivarà temporalment per al lloc. Accessibilitat - - Servidor de comptes del Firefox personalitzat Servidor de comptes de Mozilla personalitzat Servidor del Sync personalitzat - - S’ha modificat el servidor de comptes del Firefox o del Sync. L’aplicació es tancarà per aplicar els canvis… S’ha modificat el servidor de comptes de Mozilla o del Sync. L’aplicació es tancarà per aplicar els canvis… @@ -577,8 +525,6 @@ Inicieu la sessió per sincronitzar pestanyes, adreces d’interès, contrasenyes i més. - Compte del Firefox - Compte de Mozilla Torneu-vos a connectar per reprendre la sincronització @@ -590,8 +536,6 @@ Recollida de dades Depuració remota per USB - - Mostra els motors de cerca Mostra suggeriments de cerca @@ -722,12 +666,6 @@ Explora els complements - - - El complement no és compatible - - El complement ja està instal·lat - Els complements s’han desactivat temporalment @@ -754,6 +692,8 @@ Adreces d’interès Inicis de sessió + + Contrasenyes Pestanyes obertes @@ -780,6 +720,8 @@ Targetes de crèdit + + Formes de pagament Adreces @@ -1316,8 +1258,6 @@ Descarta - No s’ha pogut imprinir - No s’ha pogut imprimir aquesta pàgina Imprimeix @@ -1362,6 +1302,10 @@ Tanca les pestanyes privades + + + Voleu tancar les pestanyes privades? + Màrqueting @@ -1602,6 +1546,8 @@ Totes les galetes (farà que alguns llocs web no funcionin) Aïlla les galetes entre llocs + + Sol·licita als llocs web que no comparteixin ni venguin les meves dades Contingut que fa seguiment @@ -1717,9 +1663,13 @@ Inicis de sessió i contrasenyes + + Contrasenyes Desa els inicis de sessió i contrasenyes + + Desa les contrasenyes Demana-m’ho @@ -1736,16 +1686,30 @@ Afegeix un inici de sessió + + Afegeix una contrasenya + Sincronitza els inicis de sessió + + Sincronitza les contrasenyes Sincronitza els inicis de sessió entre dispositius + + Sincronitza les contrasenyes entre dispositius Inicis de sessió desats + + Contrasenyes desades Aquí es mostren els inicis de sessió que deseu o sincronitzeu en el %s. + + Les contrasenyes que deseu o sincronitzeu amb el %s es mostraran aquí. Totes les contrasenyes que deseu estan xifrades. + Més informació sobre el Sync. + + Més informació sobre la sincronització Excepcions @@ -1815,6 +1779,8 @@ Targetes de crèdit + + Formes de pagament Desa i emplena automàticament les targetes @@ -1825,8 +1791,12 @@ Sincronitza les targetes Afegeix una targeta de crèdit + + Afegeix una targeta Gestiona les targetes desades + + Gestiona les targetes Afegeix una adreça @@ -1834,9 +1804,14 @@ Desa i emplena automàticament les adreces + + Desa i emplena automàticament les adreces Inclou informació com números, adreces electròniques i adreces d’enviament + + Inclou números de telèfon i adreces de correu electrònic + Afegeix una targeta @@ -1857,6 +1832,8 @@ Suprimeix la targeta Segur que voleu suprimir aquesta targeta de crèdit? + + Voleu suprimir la targeta? Suprimeix @@ -1869,8 +1846,12 @@ Targetes desades Introduïu un número de targeta de crèdit vàlid + + Introduïu un número de targeta vàlid Empleneu aquest camp + + Afegiu un nom Desbloqueu per veure les targetes desades @@ -1923,6 +1904,8 @@ Segur que voleu suprimir aquesta adreça? + + Voleu suprimir aquesta adreça? Suprimeix @@ -1938,28 +1921,18 @@ Afegeix un motor de cerca Edita el motor de cerca - - Afegeix - - Desa Edita Suprimeix - - Altres Nom - - Nom Nom del motor de cerca URL de la cadena de cerca - Cadena de cerca que s’utilitzarà - URL s’utilitzarà per a la cerca Substituïu la consulta per «%s». Per exemple:\nhttps://www.google.com/search?q=%s @@ -2038,6 +2011,8 @@ Cancel·la Opcions d’inici de sessió + + Opcions de la contrasenya Camp de text editable per a l’adreça web de l’inici de sessió. @@ -2046,16 +2021,28 @@ Camp de text editable per a la contrasenya de l’inici de sessió. Desa els canvis de l’inici de sessió. + + Desa els canvis. Edita + + Edita la contrasenya Afegeix un inici de sessió nou + + Afegeix una contrasenya Cal una contrasenya + + Escriviu una contrasenya Cal el nom d’usuari + + Escriviu un nom d\'usuari Cal el nom del servidor + + Escriviu una adreça web Cerca per veu @@ -2190,8 +2177,6 @@ - Verificador de ressenyes - Verificador de ressenyes Ressenyes fiables @@ -2205,7 +2190,7 @@ Valoració ajustada - S’han eliminat les ressenyes poc fiables + S’han eliminat les ressenyes poc fiables Punts destacats de les ressenyes recents @@ -2217,22 +2202,16 @@ puntuació alfabètica de la A a la F.]]> Les ressenyes són fiables. Pensem que probablement són de clients reals honestos i no estan esbiaixades. - - Creiem que les ressenyes són fiables. Creiem que hi ha una barreja de ressenyes fiables i poc fiables. Les ressenyes són poc fiables. Creiem que poden ser falses o esbiaixades. - - Creiem que les ressenyes són poc fiables. puntuació ajustada només es basa en les ressenyes que creiem fiables.]]> destacats provenen de %s ressenyes dels darrers 80 dies que creiem que són fiables.]]> Més informació sobre %s. - - com %s de Mozilla determina la qualitat de la ressenya com determina %s la qualitat de la ressenya @@ -2240,8 +2219,6 @@ Mostra anuncis al verificador de ressenyes - Veureu anuncis ocasionals de productes rellevants. Tots els anuncis han de complir els nostres estàndards de qualitat de revisió. %s - Veureu anuncis ocasionals de productes rellevants. Només anunciem productes amb ressenyes fiables. %s Més informació @@ -2264,23 +2241,21 @@ Quan aquest producte tingui més ressenyes, podrem comprovar-ne la qualitat. - El producte no està disponible + El producte no està disponible - Si veieu que torna a haver-hi estoc del producte, informeu-nos i en comprovarem les ressenyes. - - Informa que torna a haver-hi estoc del producte + Si veieu que torna a haver-hi estoc del producte, informeu-nos i en comprovarem les ressenyes. - Informa que hi ha estoc del producte + Informa que hi ha estoc del producte - S\'està comprovant la qualitat de la ressenya + S\'està comprovant la qualitat de la ressenya - S\'està comprovant la qualitat de la ressenya + S\'està comprovant la qualitat de la ressenya Això pot trigar uns 60 segons. - Gràcies per informar-ne! + Gràcies per informar-ne! - Hauríem de tenir informació sobre les ressenyes del producte d\'aquí a 24 hores. Torneu més tard. + Hauríem de tenir informació sobre les ressenyes del producte d\'aquí a 24 hores. Torneu més tard. No podem comprovar aquestes ressenyes @@ -2318,17 +2293,17 @@ Més informació - En seleccionar «Sí, prova-ho», accepteu %1$s de %2$s i %3$s de Mozilla. + En seleccionar «Sí, prova-ho», accepteu %1$s de %2$s i %3$s de Mozilla. - En seleccionar «Sí, prova-ho», accepteu les polítiques i condicions següents de %1$s: + En seleccionar «Sí, prova-ho», accepteu les polítiques i condicions següents de %1$s: - política de privadesa + política de privadesa - Política de privadesa + Política de privadesa - condicions d\'ús + condicions d\'ús - Condicions d\'ús + Condicions d\'ús Sí, prova-ho @@ -2364,6 +2339,9 @@ Competitivitat + + «%s» + reduir @@ -2381,4 +2359,152 @@ obrir l’enllaç i veure més informació %s, encapçalament + + + Enllaços + + + + + + Voleu traduir aquesta pàgina? + + Més informació + + Tradueix de: + + Tradueix a: + + Ara no + + Fet + + Tradueix + + S\'està traduint + + Trieu una llengua + + Hi ha hagut un problema en traduir. Torneu-ho a provar. + + Més informació + + + + Opcions de la traducció + + Tradueix sempre %1$s + + No tradueixis mai %1$s + + No tradueixis mai aquest lloc + + Paràmetres de les traduccions + + Quant a les traduccions al %1$s + + + + Traduccions + + + Preferències de traducció + + Traducció automàtica + + No tradueixis mai aquests llocs + + + Baixa les llengües + + + + Traducció automàtica + + + El %1$s oferirà traduir llocs en aquesta llengua. + + Tradueix sempre + + + No tradueixis mai + + El %1$s no oferirà mai traduir llocs en aquesta llengua. + + + Elimina %1$s + + Voleu suprimir %1$s? + + Suprimeix + + Cancel·la + + + Més informació + + Llengües disponibles + + necessari + + Baixa llengües + + Totes les llengües + + Suprimeix + + En curs + + + Baixa + + + Voleu suprimir %1$s (%2$s)? + + Voleu suprimir totes les llengües (%1$s)? + + Suprimeix + + Cancel·la + + + Baixa + + Baixa i tradueix + + Cancel·la + + + + Eines de depuració + + Vés enrere + + Eines de pestanyes + + Recompte de pestanyes + + Actives + + Inactives + + Privades + + Total + + Eina de creació de pestanyes + + Nombre de pestanyes a crear + + Afegeix a les pestanyes actives + + Afegeix a les pestanyes inactives + + Afegeix a les pestanyes privades diff --git a/fenix/app/src/main/res/values-cy/strings.xml b/fenix/app/src/main/res/values-cy/strings.xml index 4f1c27f9cead..37ff8d461f12 100644 --- a/fenix/app/src/main/res/values-cy/strings.xml +++ b/fenix/app/src/main/res/values-cy/strings.xml @@ -1878,7 +1878,7 @@ Gosodwch batrwm cloi dyfais, PIN, neu gyfrinair i ddiogelu eich mewngofnodion a’ch cyfrineiriau sydd wedi’u cadw rhag i rhywun arall sydd â mynediad i’ch dyfais. - Sefydlwch batrwm clo dyfais, PIN, neu gyfrinair i amddiffyn eich dulliau talu a arbedwyd rhag cael mynediad iddynt os oes gan rywun arall eich dyfais. + Gosodwch batrwm clo dyfais, PIN, neu gyfrinair i ddiogelu eich dulliau talu rhag i rywun arall sydd â\'ch dyfais gael mynediad iddyn nhw. Gosod nawr @@ -2041,11 +2041,11 @@ Maes testun golygadwy cyfeiriad gwe’r mewngofnodi. - Y maes testun y gellir ei olygu ar gyfer cyfeiriad y wefan. + Maes testun golygadwy y wefan. Maes testun golygadwy enw defnyddiwr y mewngofnodi. - Y maes testun y gellir ei olygu ar gyfer yr enw defnyddiwr. + Maes testun golygadwy yr enw defnyddiwr. Maes testun golygadwy cyfrinair y mewngofnodi. diff --git a/fenix/app/src/main/res/values-el/strings.xml b/fenix/app/src/main/res/values-el/strings.xml index 4cc2310faacf..7f8b4eb65304 100644 --- a/fenix/app/src/main/res/values-el/strings.xml +++ b/fenix/app/src/main/res/values-el/strings.xml @@ -249,6 +249,7 @@ Προσαρμογή αρχικής σελίδας + Αρχική οθόνη @@ -256,6 +257,9 @@ Διαγραφή ιστορικού περιήγησης + + Μετάφραση σελίδας + Επιλεγμένη γλώσσα @@ -268,8 +272,6 @@ Σάρωση - - Μηχανή αναζήτησης Ρυθμίσεις μηχανής αναζήτησης @@ -324,14 +326,14 @@ - Οι ειδοποιήσεις σάς βοηθούν να κάνετε περισσότερα με το %s + Οι ειδοποιήσεις σάς βοηθούν να κάνετε περισσότερα με το %s - Συγχρονίστε τις καρτέλες σας με τις συσκευές σας, διαχειριστείτε λήψεις, λάβετε συμβουλές για την αξιοποίηση της προστασίας απορρήτου του %s στο έπακρο και πολλά άλλα. + Συγχρονίστε τις καρτέλες σας με τις συσκευές σας, διαχειριστείτε λήψεις, λάβετε συμβουλές για την αξιοποίηση της προστασίας απορρήτου του %s στο έπακρο και πολλά άλλα. - Συνέχεια + Συνέχεια - Όχι τώρα + Όχι τώρα @@ -449,21 +451,11 @@ Λειτουργία «Μόνο HTTPS» - - Μείωση μηνυμάτων για cookie Αποκλεισμός μηνυμάτων για cookie Αποκλεισμός μηνυμάτων για cookie σε ιδιωτική περιήγηση - - Μείωση μηνυμάτων για cookie - - Ανενεργή - - Ενεργή - - - Το %1$s προσπαθεί να απορρίπτει αυτόματα τα μηνύματα αιτημάτων για cookie. + Ανενεργή για αυτόν τον ιστότοπο @@ -481,36 +473,17 @@ Ο ιστότοπος δεν υποστηρίζεται - Ενεργοποίηση μείωσης μηνυμάτων για cookie στο %1$s; - Ενεργοποίηση αποκλεισμού μηνυμάτων για cookie για το %1$s; - - Απενεργοποίηση μείωσης μηνυμάτων για cookie στο %1$s; Απενεργοποίηση αποκλεισμού μηνυμάτων για cookie για το %1$s; Το %1$s δεν μπορεί να απορρίψει αυτόματα τα αιτήματα για cookie σε αυτόν τον ιστότοπο. Μπορείτε να στείλετε ένα αίτημα για υποστήριξη αυτού του ιστοτόπου στο μέλλον. - - Το %1$s θα απαλείψει τα cookie του ιστοτόπου και θα ανανεώσει τη σελίδα. Η απαλοιφή όλων των cookie ενδέχεται να σας αποσυνδέσει ή να αδειάσει τα καλάθια αγορών. Απενεργοποιήστε το και το %1$s θα διαγράψει τα cookie και θα φορτώσει ξανά αυτόν τον ιστότοπο. Μπορεί να αποσυνδεθείτε ή να αδειάσουν τα καλάθια αγορών σας. - Το %1$s προσπαθεί να απορρίψει αυτόματα όλα τα αιτήματα για cookie σε υποστηριζόμενους ιστοτόπους. - Ενεργοποιήστε το και το %1$s θα προσπαθεί να απορρίπτει αυτόματα όλα τα μηνύματα για cookie σε αυτόν τον ιστότοπο. - - Να επιτρέπεται στο %1$s η απόρριψη μηνυμάτων για cookie; - - Το %1$s μπορεί να απορρίπτει αυτόματα πολλά μηνύματα αιτημάτων για cookie. - - Όχι τώρα - - Θα βλέπετε λιγότερα αιτήματα για cookie - - - Αποδοχή Το %1$s μόλις αρνήθηκε τα cookie για εσάς @@ -1299,8 +1272,6 @@ Απόρριψη - Αδυναμία εκτύπωσης - Δεν είναι δυνατή η εκτύπωση αυτής της σελίδας Εκτύπωση @@ -1829,6 +1800,9 @@ Ταξινόμηση μενού σύνδεσης + + Μενού ταξινόμησης κωδικών πρόσβασης + Αυτόματη συμπλήρωση @@ -1926,7 +1900,7 @@ Ορίστε ένα μοτίβο κλειδώματος συσκευής, ένα ΡΙΝ ή έναν κωδικό πρόσβασης για την προστασία των αποθηκευμένων πιστωτικών καρτών σας, σε περίπτωση που κάποιος τρίτος αποκτήσει πρόσβαση στη συσκευή σας. - Ορίστε ένα μοτίβο κλειδώματος συσκευής, ένα ΡΙΝ ή έναν κωδικό πρόσβασης για την προστασία των αποθηκευμένων καρτών σας, σε περίπτωση που κάποιος τρίτος αποκτήσει πρόσβαση στη συσκευή σας. + Ορίστε ένα μοτίβο κλειδώματος της συσκευής, ένα ΡΙΝ ή έναν κωδικό πρόσβασης για την προστασία των αποθηκευμένων καρτών σας, σε περίπτωση που κάποιος τρίτος αποκτήσει πρόσβαση στη συσκευή σας. Ρύθμιση τώρα @@ -2091,12 +2065,12 @@ Επιλογές κωδικών πρόσβασης Το επεξεργάσιμο πεδίο κειμένου της διεύθυνσης ιστού της σύνδεσης. - - Το επεξεργάσιμο πεδίο κειμένου της διεύθυνσης ιστοτόπου του κωδικού πρόσβασης. + + Το επεξεργάσιμο πεδίο κειμένου της διεύθυνσης ιστοτόπου. Το επεξεργάσιμο πεδίο κειμένου για το όνομα χρήστη της σύνδεσης. - - Το επεξεργάσιμο πεδίο κειμένου για το όνομα χρήστη του κωδικού πρόσβασης. + + Το επεξεργάσιμο πεδίο κειμένου για το όνομα χρήστη. Το επεξεργάσιμο πεδίο κειμένου για τον κωδικό πρόσβασης της σύνδεσης. @@ -2294,8 +2268,6 @@ σημαντικά σημεία προέρχονται από κριτικές για το %s, οι οποίες γράφτηκαν τις τελευταίες 80 ημέρες και πιστεύουμε ότι είναι αξιόπιστες.]]> Μάθετε περισσότερα σχετικά με το %s. - - πώς το %s της Mozilla προσδιορίζει την ποιότητα των κριτικών πώς το %s προσδιορίζει την ποιότητα των κριτικών @@ -2480,6 +2452,8 @@ Μετάφραση σε εξέλιξη + + Επιλέξτε μια γλώσσα Προέκυψε πρόβλημα με τη μετάφραση. Παρακαλούμε δοκιμάστε ξανά. diff --git a/fenix/app/src/main/res/values-es-rCL/strings.xml b/fenix/app/src/main/res/values-es-rCL/strings.xml index 1d017aff4e3a..883e691fad29 100644 --- a/fenix/app/src/main/res/values-es-rCL/strings.xml +++ b/fenix/app/src/main/res/values-es-rCL/strings.xml @@ -242,6 +242,7 @@ Personalizar página de inicio + Pantalla de inicio @@ -249,6 +250,9 @@ Eliminar historial de navegación + + Traducir página + Idioma seleccionado @@ -260,8 +264,6 @@ Escanear - - Motor de búsqueda Ajustes del motor de búsqueda @@ -316,14 +318,14 @@ - Las notificaciones te ayudan a hacer más con %s + Las notificaciones te ayudan a hacer más con %s - Sincroniza tus pestañas entre dispositivos, administra descargas, obtén consejos sobre cómo aprovechar al máximo la protección de privacidad de %s y más. + Sincroniza tus pestañas entre dispositivos, administra descargas, obtén consejos sobre cómo aprovechar al máximo la protección de privacidad de %s y más. - Continuar + Continuar - Ahora no + Ahora no @@ -440,21 +442,11 @@ Modo solo HTTPS - - Reducción de anuncios de cookies Bloqueador de anuncios de cookies Bloqueador de anuncios de cookies en navegación privada - - Reducir los anuncios de cookies - - No - - - - - %1$s intenta rechazar automáticamente las solicitudes de cookies en los anuncios de cookies. + DESACTIVADA para este sitio @@ -472,35 +464,16 @@ Sitio actualmente no soportado - ¿Activar la reducción de anuncios de cookies para %1$s? - ¿Activar el bloqueo de anuncios de cookies para %1$s? - ¿Desactivar la reducción de anuncios de cookies para %1$s? - ¿Desactivar el bloqueo de anuncios de cookies para %1$s? %1$s no puede rechazar automáticamente las solicitudes de cookies en este sitio. Puedes enviar una solicitud para soportar este sitio en el futuro. - - %1$s borrará las cookies de este sitio y recargará la página. Borrar todas las cookies puede cerrar tu sesión o vaciar los carritos de compras. Desactívalo y %1$s borrará las cookies y recargará este sitio. Esto podría cerrar tu sesión o vaciar tus carritos de compras. - %1$s intenta rechazar automáticamente todas las solicitudes de cookies en sitios soportados. - Actívalo y %1$s intentará rechazar automáticamente todos los anuncios de cookies en este sitio. - - ¿Permitir que %1$s rechace los anuncios de cookies? - - %1$s puede rechazar automáticamente muchos anuncios de cookies. - - Ahora no - - Verás menos solicitudes de cookies - - - Permitir %1$s acaba de rechazar las cookies por ti @@ -1285,8 +1258,6 @@ Ocultar - No se pudo imprimir - No se puede imprimir esta página Imprimir @@ -1906,7 +1877,7 @@ Configura un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus tarjetas de crédito guardadas, y así no sean accedidas si alguien más tiene tu dispositivo. - Configura un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus tarjetas guardadas, y así no sean accedidas si alguien más tiene tu dispositivo. + Configura un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus métodos de pago guardados, y así no sean accedidos si alguien más tiene tu dispositivo. Configurar ahora @@ -2067,12 +2038,12 @@ Opciones de contraseña El campo de texto editable para la dirección web de la credencial. - - El campo de texto editable para la dirección del sitio web de la contraseña. + + El campo de texto editable para la dirección del sitio web. El campo de texto editable para el nombre de usuario de la credencial. - - El campo de texto editable para el nombre de usuario de la contraseña. + + El campo de texto editable para el nombre de usuario. El campo de texto editable para la contraseña de la credencial. @@ -2269,8 +2240,6 @@ puntos destacados provienen de reseñas de %s de los últimos 80 días que creemos que son confiables.]]> Aprender más sobre %s. - - cómo %s de Mozilla determina la calidad de las reseñas cómo %s determina la calidad de las reseñas @@ -2455,6 +2424,8 @@ Traducción en proceso + + Elige un idioma Hubo un problema al traducir. Por favor, vuelve a intentarlo. diff --git a/fenix/app/src/main/res/values-oc/strings.xml b/fenix/app/src/main/res/values-oc/strings.xml index 3220d9990dcb..8e8f92aa1375 100644 --- a/fenix/app/src/main/res/values-oc/strings.xml +++ b/fenix/app/src/main/res/values-oc/strings.xml @@ -243,6 +243,7 @@ Personalizar la pagina d’acuèlh + Ecran d’acuèlh @@ -250,6 +251,9 @@ Netejar l’istoric de navegacion + + Traduire la pagina + Lenga seleccionada @@ -1909,8 +1913,6 @@ Securizatz los metòdes de pagament enregistrats Configuratz un esquèma de verrolhatge, un còdi PIN o un senhal per protegir vòstres identificants de cartas de crèdit enregistrats se per cas qualqu’un accedisca a vòstre periferic. - - Configuratz un esquèma de desverrolhatge, un còdi PIN o un senhal per protegir vòstras cartas salvadas se per cas qualqu’un accedisca a vòstre aparelh. Configurar ara @@ -2075,12 +2077,8 @@ Exemple :\nhttps://suggestqueries.google.com/complete/search?client=firefox& Opcions de senhal Lo camp de tèxt modificable per l’adreça web de l’identificant. - - Lo camp de tèxt modificable per l’adreça web del senhal. Lo camp de tèxt modificable pel nom d’utilizaire de l’identificant. - - Lo camp de tèxt modificable pel nom d’utilizaire del senhal. Lo camp de tèxt modificable pel senhal de l’identificant. @@ -2463,6 +2461,8 @@ Exemple :\nhttps://suggestqueries.google.com/complete/search?client=firefox& Traduccion en cors + + Causir una lenga I a agut un problèma al moment de traduire. Ensajatz tornamai. diff --git a/fenix/app/src/main/res/values-pa-rIN/strings.xml b/fenix/app/src/main/res/values-pa-rIN/strings.xml index d4a5a7f5df0f..f5c180e02c36 100644 --- a/fenix/app/src/main/res/values-pa-rIN/strings.xml +++ b/fenix/app/src/main/res/values-pa-rIN/strings.xml @@ -249,6 +249,7 @@ ਮੁੱਖ-ਸਫ਼ੇ ਨੂੰ ਕਸਟਮਾਈਜ਼ ਕਰੋ + ਮੁੱਖ ਸਕਰੀਨ @@ -256,6 +257,9 @@ ਬਰਾਊਜ਼ ਕਰਨ ਦਾ ਅਤੀਤ ਮਿਟਾਓ + + ਸਫ਼ੇ ਦਾ ਉਲੱਥਾ ਕਰੋ + ਚੁਣੀ ਹੋਈ ਬੋਲੀ @@ -267,8 +271,6 @@ ਸਕੈਨ ਕਰੋ - - ਖੋਜ ਇੰਜਣ ਖੋਜ ਇੰਜਣ ਸੈਟਿੰਗਾਂ @@ -324,14 +326,14 @@ - ਨੋਟੀਫ਼ਿਕੇਸ਼ਨ ਤੁਹਾਨੂੰ %s ਨਾਲ ਹੋਰ ਕਰਨ ਦੀ ਮਦਦ ਕਰਦੇ ਹਨ + ਨੋਟੀਫ਼ਿਕੇਸ਼ਨ ਤੁਹਾਨੂੰ %s ਨਾਲ ਹੋਰ ਕਰਨ ਦੀ ਮਦਦ ਕਰਦੇ ਹਨ - ਡਿਵਾਈਸਾਂ ਵਿਚਾਲੇ ਆਪਣੀਆਂ ਟੈਬਾਂ ਨੂੰ ਸਿੰਕ ਕਰੋ, ਡਾਊਨਲੋਡ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰੋ, %s ਦੀ ਪਰਦੇਦਾਰੀ ਸੁਰੱਖਿਆ ਦਾ ਪੂਰਾ ਫ਼ਾਇਦਾ ਲੈਣ ਲਈ ਗੁਰ ਲਵੋ ਅਤੇ ਹੋਰ + ਡਿਵਾਈਸਾਂ ਵਿਚਾਲੇ ਆਪਣੀਆਂ ਟੈਬਾਂ ਨੂੰ ਸਿੰਕ ਕਰੋ, ਡਾਊਨਲੋਡ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰੋ, %s ਦੀ ਪਰਦੇਦਾਰੀ ਸੁਰੱਖਿਆ ਦਾ ਪੂਰਾ ਫ਼ਾਇਦਾ ਲੈਣ ਲਈ ਗੁਰ ਲਵੋ ਅਤੇ ਹੋਰ - ਜਾਰੀ ਰੱਖੋ + ਜਾਰੀ ਰੱਖੋ - ਹੁਣੇ ਨਹੀਂ + ਹੁਣੇ ਨਹੀਂ @@ -449,22 +451,11 @@ ਸਿਰਫ਼-HTTPS ਢੰਗ - - ਕੂਕੀਜ਼ ਬੈਨਰ ਘਟਾਉਣਾ ਕੂਕੀ ਬੈਨਰ ਰੋਕੂ ਪ੍ਰਾਈਵੇਟ ਬਰਾਊਜ਼ਿੰਗ ਵਿੱਚ ਕੂਕੀ ਬੈਨਰ ਰੋਕੂ - - ਕੂਕੀਜ਼ ਬੈਨਰ ਘਟਾਓ - - - ਬੰਦ - - ਚਾਲੂ - - %1$s ਕੂਕੀ ਬੈਨਰਾਂ ਤੋਂ ਕੂਕੀ ਬੇਨਤੀਆਂ ਨੂੰ ਆਪਣੇ-ਆਪਹੀ ਰੱਦ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦਾ ਹੈ। ਇਸ ਸਾਈਟ ਲਈ ਬੰਦ @@ -483,36 +474,17 @@ ਸਾਈਟ ਇਸ ਵੇਲੇ ਸਹਾਇਕ ਨਹੀਂ ਹੈ - %1$s ਲਈ ਕੁਕੀ ਬੈਨਰ ਘਟਾਉਣੇ ਚਾਲੂ ਕਰਨੇ ਹਨ? - ਕੀ %1$s ਲਈ ਕੂਕੀ ਬੈਨਰ ਰੋਕੂ ਚਾਲੂ ਕਰਨਾ ਹੈ? - - %1$s ਲਈ ਕੁਕੀ ਬੈਨਰ ਘਟਾਉਣੇ ਬੰਦ ਕਰਨੇ ਹਨ? ਕੀ %1$s ਲਈ ਕੂਕੀ ਬੈਨਰ ਰੋਕੂ ਬੰਦ ਕਰਨਾ ਹੈ? %1$s ਇਸ ਸਾਈਟ ਲਈ ਆਪਣੇ-ਆਪ ਕੂਕੀ ਬੇਨਤੀਆਂ ਨੂੰ ਰੱਦ ਨਹੀਂ ਕਰ ਸਕਦਾ ਹੈ। ਤੁਸੀਂ ਭਵਿੱਖ ਵਿੱਚ ਇਸ ਸਾਈਟ ਵਾਸਤੇ ਸਹਾਇਤਾ ਲਈ ਬੇਨਤੀ ਕਰ ਸਕਦੇ ਹੋ। - - %1$s ਇਸ ਸਾਈਟ ਦੀਆਂ ਕੁਕੀਆਂ ਨੂੰ ਸਾਫ਼ ਕਰ ਕੇ ਵਰਕੇ ਨੂੰ ਸੱਜਰਾ ਕਰ ਦੇਵੇਗਾ। ਸਾਰੀਆਂ ਕੁਕੀਆਂ ਨੂੰ ਸਾਫ਼ ਕਰਨ ਨਾਲ ਤੁਸੀਂ ਸਾਈਨ ਆਊਟ ਹੋ ਸਕਦੇ ਹੋ ਜਾਂ ਖਰੀਦਦਾਰੀ ਵਾਲੀ ਟੋਕਰੀ ਖਾਲੀ ਹੋ ਸਕਦੀ ਹੈ। ਬੰਦ ਕਰਨ ਨਾਲ %1$s ਇਸ ਸਾਈਟ ਲਈ ਕੂਕੀਜ਼ ਮਿਟਾ ਕੇ ਇਸ ਨੂੰ ਮੁੜ ਲੋਡ ਕਰੇਗਾ। ਇਹ ਤੁਹਾਨੂੰ ਸਾਈਟ ਆਉਟ ਜਾਂ ਤੁਹਾਡੀ ਖਰੀਦਦਾਰੀ ਕਾਰਟਾਂ ਨੂੰ ਖਾਲੀ ਕਰੇਗਾ। - %1$s ਸਹਾਇਤਾ ਪ੍ਰਾਪਤ ਸਾਈਟਾਂ ਉੱਤੇ ਸਾਰੀਆਂ ਕੂਕੀ ਬੇਨਤੀਆਂ ਨੂੰ ਆਪਣੇ-ਆਪ ਰੱਦ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦਾ ਹੈ। - ਚਾਲੂ ਕਰੋ ਅਤੇ %1$s ਇਸ ਸਾਈਟ ਵਾਸਤੇ ਕੂਕੀ ਬੈਨਰ ਨੂੰ ਆਪਣੇ-ਆਪ ਇਨਕਾਰ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੇਗਾ। - - %1$s ਨੂੰ ਕੂਕੀ ਬੈਨਰ ਰੱਦ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ? - - %1$s ਕੂਕੀ ਬੇਨਤੀਆਂ ਨੂੰ ਆਪਣੇ-ਆਪ ਹੀ ਰੱਦ ਕਰ ਸਕਦਾ ਹੈ। - - ਹੁਣੇ ਨਹੀਂ - - ਤੁਸੀਂ ਬਹੁਤ ਘੱਟ ਕੂਕੀ ਬੇਨਤੀਆਂ ਵੇਖੋਗੇ - - - ਮਨਜ਼ੂਰ %1$s ਨੇ ਹੁਣੇ ਤੁਹਾਡੇ ਲਈ ਕੂਕੀਜ਼ ਤੋਂ ਇਨਕਾਰ ਕੀਤਾ ਹੈ @@ -732,6 +704,8 @@ ਬੁੱਕਮਾਰਕ ਲਾਗਇਨ + + ਪਾਸਵਰਡ ਟੈਬਾਂ ਖੋਲ੍ਹੋ @@ -759,6 +733,8 @@ ਕਰੈਡਿਟ ਕਾਰਡ + + ਭੁਗਤਾਨ ਦੇ ਢੰਗ ਸਿਰਨਾਵੇਂ @@ -1303,8 +1279,6 @@ ਖ਼ਾਰਜ ਕਰੋ - ਛਾਪਣ ਲਈ ਅਸਮਰੱਥ ਹੈ - ਇਹ ਸਫ਼ਾ ਛਾਪਣ ਲਈ ਅਸਮਰੱਥ ਹੈ ਪਰਿੰਟ ਕਰੋ @@ -1712,8 +1686,12 @@ ਲਾਗਇਨ ਅਤੇ ਪਾਸਵਰਡ + + ਪਾਸਵਰਡ ਲਾਗਇਨ ਅਤੇ ਪਾਸਵਰਡ ਸੰਭਾਲੋ + + ਪਾਸਵਰਡਾਂ ਨੂੰ ਸੰਭਾਲੋ ਸੰਭਾਲਣ ਲਈ ਪੁੱਛੋ @@ -1730,26 +1708,45 @@ ਲਾਗਇਨ ਜੋੜੋ + + ਪਾਸਵਰਡ ਜੋੜੋ + ਲਾਗਇਨ ਸਿੰਕ ਕਰੋ + + ਪਾਸਵਰਡ ਸਿੰਕ ਕਰੋ ਡਿਵਾਈਸਾਂ ਵਿਚਾਲੇ ਲਾਗਇਨਾਂ ਨੂੰ ਸਿੰਕ ਕਰੋ + + ਪਾਸਵਰਡ ਡਿਵਾਈਸਾਂ ਵਿਚਾਲੇ ਸਿੰਕ ਕਰੋ ਸੰਭਾਲੇ ਹੋਏ ਲਾਗਇਨ + + ਸੰਭਾਲੇ ਹੋਏ ਪਾਸਵਰਡ ਤੁਹਾਡੇ ਵਲੋਂ ਸੰਭਾਲੇ ਲਾਗਇਨ ਜਾਂ %s ਨਾਲ ਸਿੰਕ ਕੀਤੇ ਇੱਥੇ ਵੇਖਾਏ ਜਾਣਗੇ। + + ਤੁਹਾਡੇ ਵਲੋਂ %s ਵਿੱਚ ਸੰਭਾਲੇ ਜਾਂ ਸਿੰਕ ਕੀਤੇ ਪਾਸਵਰਡਾਂ ਨੂੰ ਇੱਥੇ ਦਿਖਾਇਆ ਜਾਵੇਗਾ। ਤੁਹਾਡੇ ਸਾਰੇ ਸੰਭਾਲੇ ਪਾਸਵਰਡ ਇੰਕ੍ਰਿਪਟ ਕੀਤੇ ਹੁੰਦੇ ਹਨ। ਸਿੰਕ ਬਾਰੇ ਹੋਰ ਜਾਣੋ। + + ਸਿੰਕ ਬਾਰੇ ਹੋਰ ਜਾਣੋ ਛੋਟਾਂ ਨਾ ਸੰਭਾਲੇ ਹੋਏ ਲਾਗਇਨ ਅਤੇ ਪਾਸਵਰਡਾਂ ਨੂੰ ਇੱਥੇ ਸੰਭਾਲਿਆ ਜਾਵੇਗਾ। + + %s ਇੱਥੇ ਦਿੱਤੀਆਂ ਹੋਈਆਂ ਸਾਈਟਾਂ ਲਈ ਪਾਸਵਰਡ ਨਹੀਂ ਸੰਭਾਲੇਗਾ। ਇਹਨਾਂ ਸਾਈਟਾਂ ਲਈ ਲਾਗਇਨ ਅਤੇ ਪਾਸਵਰਡ ਨਹੀਂ ਸੰਭਾਲੇ ਜਾਣਗੇ। + + %s ਇਹਨਾਂ ਸਾਈਟਾਂ ਲਈ ਪਾਸਵਰਡ ਨਹੀਂ ਸੰਭਾਲੇਗਾ। ਸਾਰੀਆਂ ਛੋਟਾਂ ਹਟਾ ਦਿਓ ਲਾਗਇਨ ਖੋਜੋ + + ਪਾਸਵਰਡ ਖੋਜੋ ਸਾਈਟ @@ -1778,10 +1775,16 @@ ਪਾਸਵਰਡ ਲੁਕਾਓ ਆਪਣੇ ਸੰਭਾਲੇ ਲਾਗਇਨ ਵੇਖਣ ਲਈ ਅਣ-ਲਾਕ ਕਰੋ + + ਆਪਣੇ ਸੰਭਾਲੇ ਹੋਏ ਪਾਸਵਰਡ ਵੇਖਣ ਲਈ ਅਣ-ਲਾਕ ਕਰੋ ਆਪਣੇ ਲਾਗਇਨ ਅਤੇ ਪਾਸਵਰਡ ਸੁਰੱਖਿਅਤ ਕਰੋ + + ਆਪਣੇ ਸੰਭਾਲੇ ਹੋਏ ਪਾਸਵਰਡਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰੋ ਆਪਣੇ ਲਾਗਇਨਾਂ ਅਤੇ ਪਾਸਵਰਡਾਂ ਨੂੰ ਤੁਹਾਡੇ ਡਿਵਾਈਸ ਨੂੰ ਰੱਖਣ ਵਾਲੇ ਕਿਸੇ ਦੀ ਪਹੁੰਚ ਤੋਂ ਸੁਰੱਖਿਅਤ ਰੱਖਣ ਲਈ ਡਿਵਾਈਸ ਲਾਕ ਪੈਟਰਨ, ਪਿੰਨ ਜਾਂ ਪਾਸਵਰਡ ਸੈਟ ਅੱਪ ਕਰੋ। + + ਆਪਣੇ ਸੰਭਾਲੇ ਹੋਏ ਪਾਸਵਰਡਾਂ ਨੂੰ ਤੁਹਾਡੇ ਡਿਵਾਈਸ ਉੱਤੇ ਕਿਸੇ ਹੋਰ ਵੱਲੋਂ ਪਹੁੰਚ ਕਰਨ ਤੋਂ ਬਚਾਉਣ ਤੋਂ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ ਡਿਵਾਈਸ ਲਾਕ ਪੈਟਰਨ, ਪਿੰਨ ਜਾਂ ਪਾਸਵਰਡ ਸੈੱਟ ਕਰੋ। ਬਾਅਦ \'ਚ @@ -1801,6 +1804,9 @@ ਲਾਗਇਨ ਲੜੀਬਧ ਮੇਨੂ + + ਪਾਸਵਰਡ ਮੇਨੂ ਨੂੰ ਲੜੀਬੱਧ ਕਰੋ + ਆਪੇ-ਭਰੋ @@ -1808,27 +1814,42 @@ ਸਿਰਨਾਵੇਂ ਕਰੈਡਿਟ ਕਾਰਡ + + ਭੁਗਤਾਨ ਦੇ ਢੰਗ ਕਾਰਡ ਸੰਭਾਲੋ ਅਤੇ ਆਪਣੇ-ਆਪ ਭਰੋ + + ਭੁਗਤਾਨ ਦੇ ਢੰਗ ਸੰਭਾਲੋ ਅਤੇ ਭਰੋ ਡਾਟਾ ਇੰਕ੍ਰਿਪਟ ਕੀਤਾ ਹੈ + + %s ਤੁਹਾਡੇ ਵਲੋਂ ਸੰਭਾਲੇ ਸਾਰੇ ਭੁਗਤਾਨ ਢੰਗਾਂ ਨੂੰ ਇੰਕ੍ਰਿਪਟ ਕਰਦਾ ਹੈ ਡਿਵਾਈਸਾਂ ਵਿਚਾਲੇ ਕਾਰਡਾਂ ਨੂੰ ਸਿੰਕ ਕਰੋ ਕਾਰਡ ਸਿੰਕ ਕਰੋ ਕਰੈਡਿਟ ਕਾਰਡ ਜੋੜੋ + + ਕਾਰਡ ਜੋੜੋ ਸੰਭਾਲੇ ਹੋਏ ਕਾਰਡਾਂ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰੋ + + ਕਾਰਡਾਂ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰੋ ਸਿਰਨਾਵਾਂ ਜੋੜੋ ਸਿਰਨਾਵਿਆਂ ਦਾ ਇੰਤਜ਼ਾਮ ਕਰੋ ਸਿਰਨਾਵੇਂ ਸੰਭਾਲੋ ਅਤੇ ਆਪਣੇ-ਆਪ ਭਰੋ + + ਸਿਰਨਾਵਿਆਂ ਨੂੰ ਸੰਭਾਲੋ ਅਤੇ ਭਰੋ ਨੰਬਰ, ਈਮੇਲ ਅਤੇ ਭੇਜਣ ਵਾਲੇ ਸਿਰਨਾਵਿਆਂ ਸਮੇਤ ਜਾਣਕਾਰੀ + + ਫ਼ੋਨ ਨੰਬਰਾਂ ਅਤੇ ਈਮੇਲ ਸਿਰਨਾਵਿਆਂ ਸਮੇਤ + ਕਾਰਡ ਜੋੜੋ @@ -1849,6 +1870,8 @@ ਕਾਰਡ ਨੂੰ ਹਟਾਓ ਕੀ ਤੁਸੀਂ ਇਹ ਕਰੈਡਿਟ ਕਾਰਡ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? + + ਕਾਰਡ ਨੂੰ ਹਟਾਉਣਾ ਹੈ? ਹਟਾਓ @@ -1864,14 +1887,22 @@ ਵਾਜਬ ਕਰੈਡਿਟ ਕਾਰਡ ਨੰਬਰ ਦਿਓ ਜੀ + + ਵਾਜਬ ਕਾਰਡ ਨੰਬਰ ਭਰੋ ਇਹ ਖੇਤਰ ਭਰੋ + + ਨਾਂ ਜੋੜੋ ਆਪਣੇ ਸੰਭਾਲੇ ਹੋਏ ਕਾਰਡ ਵੇਖਣ ਲਈ ਅਣ-ਲਾਕ ਕਰੋ ਆਪਣੇ ਕਰੈਡਿਟ ਕਾਰਡ ਸੁਰੱਖਿਅਤ ਕਰੋ + + ਆਪਣੇ ਸੰਭਾਲੇ ਹੋਏ ਭੁਗਤਾਨ ਢੰਗਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰੋ ਆਪਣੀ ਡਿਵਾਇਸ ਲਈ ਲਾਕ ਪੈਟਰਨ, ਪਿੰਨ, ਜਾਂ ਪਾਸਵਰਡ ਸੈੱਟ ਕਰੋ ਤਾਂ ਜੋ ਕਿਸੇ ਹੋਰ ਹੱਥ ਤੁਹਾਡਾ ਡਿਵਾਇਸ ਹੋਣ ਉੱਤੇ ਤੁਹਾਡੇ ਸੰਭਾਲੇ ਪਾਸਵਰਡ ਸੁਰੱਖਿਅਤ ਰਹਿਣ। + + ਆਪਣੇ ਸੰਭਾਲੇ ਹੋਏ ਪਾਸਵਰਡ ਢੰਗਾਂ ਨੂੰ ਤੁਹਾਡੇ ਡਿਵਾਈਸ ਉੱਤੇ ਕਿਸੇ ਹੋਰ ਵੱਲੋਂ ਪਹੁੰਚ ਕਰਨ ਤੋਂ ਬਚਾਉਣ ਤੋਂ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ ਡਿਵਾਈਸ ਲਾਕ ਪੈਟਰਨ, ਪਿੰਨ ਜਾਂ ਪਾਸਵਰਡ ਸੈੱਟ ਕਰੋ। ਹੁਣੇ ਸੈਟ ਅੱਪ ਕਰੋ @@ -1881,6 +1912,8 @@ ਸੰਭਾਲੀ ਕਰੈਡਿਟ ਕਾਰਡ ਜਾਣਕਾਰੀ ਵਰਤਣ ਲਈ ਅਣ-ਲਾਕ ਕਰੋ + + ਸੰਭਾਲੇ ਹੋਏ ਭੁਗਤਾਨ ਢੰਗਾਂ ਨੂੰ ਵਰਤਣ ਲਈ ਅਣ-ਲਾਕ ਕਰੋ ਸਿਰਨਾਵਾਂ ਜੋੜੋ @@ -1918,6 +1951,8 @@ ਕੀ ਤੁਸੀਂ ਇਹ ਸਿਰਨਾਵੇਂ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? + + ਇਹ ਸਿਰਨਾਵੇਂ ਨੂੰ ਹਟਾਉਣਾ ਹੈ? ਹਟਾਓ @@ -2016,6 +2051,8 @@ ਸੋਧੋ ਕੀ ਤੁਸੀਂ ਇਹ ਲਾਗਇਨ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? + + ਕੀ ਤੁਸੀਂ ਇਸ ਪਾਸਵਰਡ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? ਹਟਾਓ @@ -2023,24 +2060,44 @@ ਰੱਦ ਕਰੋ ਲਾਗਇਨ ਚੋਣਾਂ + + ਪਾਸਵਰਡ ਚੋਣਾਂ ਲਾਗਇਨ ਦੇ ਵੈੱਬ ਐਡਰੈਸ ਲਈ ਸੋਧਣਯੋਗ ਲਿਖਤ ਖੇਤਰ ਹੈ। + + ਵੈੱਬਸਾਈਟ ਸਿਰਨਾਵਿਆਂ ਲਈ ਸੋਧ ਕਰਨ ਯੋਗ ਲਿਖਤ ਖੇਤਰ। ਲਾਗਇਨ ਦੇ ਵਰਤੋਂਕਾਰ-ਨਾਂ ਲਈ ਸੋਧਣਯੋਗ ਲਿਖਤ ਖੇਤਰ ਹੈ। + + ਵਰਤੋਂਕਾਰ-ਨਾਂ ਲਈ ਸੋਧ ਕਰਨ ਯੋਗ ਲਿਖਤ ਖੇਤਰ। ਲਾਗਇਨ ਦੇ ਪਾਸਵਰਡ ਲਈ ਸੋਧਣਯੋਗ ਲਿਖਤ ਖੇਤਰ ਹੈ। + + ਪਾਸਵਰਡ ਲਈ ਸੋਧ ਕਰਨ ਯੋਗ ਲਿਖਤ ਖੇਤਰ। ਤਬਦੀਲੀਆਂ ਨੂੰ ਲਾਗਇਨ ਲਈ ਸੰਭਾਲੋ। + + ਤਬਦੀਲੀਆਂ ਨੂੰ ਸੰਭਾਲੋ। ਸੋਧੋ + + ਪਾਸਵਰਡ ਨੂੰ ਸੋਧੋ ਨਵਾਂ ਲਾਗਇਨ ਜੋੜੋ + + ਪਾਸਵਰਡ ਜੋੜੋ ਪਾਸਵਰਡ ਚਾਹੀਦਾ ਹੈ + + ਪਾਸਵਰਡ ਦਿਓ ਵਰਤੋਂਕਾਰ-ਨਾਂ ਚਾਹੀਦਾ ਹੈ + + ਵਰਤੋਂਕਾਰ-ਨਾਂ ਦਿਓ ਹੋਸਟ-ਨਾਂ ਚਾਹੀਦਾ ਹੈ + + ਵੈੱਬ ਸਿਰਨਾਵਾਂ ਦਿਓ ਆਵਾਜ਼ ਰਾਹੀਂ ਖੋਜੋ @@ -2209,8 +2266,6 @@ ਹਾਈਲਾਈਟ ਹਨ, ਜੋ ਸਾਨੂੰ ਜਾਪਦਾ ਹੈ ਕਿ ਭਰੋਸੇਯੋਗ ਹਨ।]]> %s ਬਾਰੇ ਹੋਰ ਸਿੱਖੋ। - - Mozilla ਵਲੋਂ %s ਰੀਵਿਊ ਦੀ ਕੁਆਲਟੀ ਕਿਵੇਂ ਪਤਾ ਕਰਦਾ ਹੈ %s ਰੀਵਿਊ ਦੀ ਕੁਆਲਟੀ ਕਿਵੇਂ ਪਤਾ ਕਰਦਾ ਹੈ @@ -2395,6 +2450,8 @@ ਉਲੱਥਾ ਜਾਰੀ ਹੈ + + ਭਾਸ਼ਾ ਚੁਣੋ ਅਨੁਵਾਦ ਕਰਨ ਦੌਰਾਨ ਸਮੱਸਿਆ ਆਈ ਸੀ। ਬਾਅਦ ਵਿੱਚ ਮੁੜ ਕੋਸ਼ਿਸ਼ ਕਰੋ। @@ -2415,6 +2472,10 @@ %1$s ਲਈ ਕਦੇ ਉਲੱਥਾ ਨਾ ਕਰੋ ਇਹ ਸਾਈਟ ਦਾ ਉਲੱਥਾ ਕਦੇ ਨਾ ਕਰੋ + + ਸਭ ਹੋਰ ਸੈਟਿੰਗਾਂ ਨੂੰ ਅਣਡਿੱਠਾ ਕਰੋ + + ਅਨੁਵਾਦ ਲਈ ਪੇਸ਼ਕਸ਼ਾਂ ਨੂੰ ਅਣਡਿੱਠਾ ਕਰੋ ਉਲੱਥਾ ਸੈਟਿੰਗਾਂ diff --git a/fenix/app/src/main/res/values-zh-rCN/strings.xml b/fenix/app/src/main/res/values-zh-rCN/strings.xml index d1402b96f239..8da4b77f7e01 100644 --- a/fenix/app/src/main/res/values-zh-rCN/strings.xml +++ b/fenix/app/src/main/res/values-zh-rCN/strings.xml @@ -338,10 +338,15 @@ 暂时不要 + + + Firefox 隐私声明 我们乐于为您护航 + 这款由非营利组织支持的浏览器会自动阻止大公司在网上偷偷跟踪您。 + 这款由非营利组织支持的浏览器会自动阻止大公司在网上偷偷跟踪您。\n\n请阅读我们的隐私声明详细了解。 @@ -703,6 +708,8 @@ 书签 登录信息 + + 密码 打开的标签页 @@ -730,6 +737,8 @@ 信用卡 + + 付款方式 邮政地址 @@ -1703,8 +1712,12 @@ 密码 + + 密码 保存登录名和密码 + + 保存密码 询问是否保存 @@ -1723,26 +1736,46 @@ 添加登录信息 + + 添加密码 + 同步登录信息 + + 同步密码 跨设备同步登录信息 + + 跨设备同步密码 保存的登录信息 + + 保存的密码 您保存或同步到 %s 的登录信息将显示于此处。 + + 保存和同步到 %s 的密码会显示在这里,所有密码均已加密保存。 + 详细了解“同步”。 + + 详细了解同步功能 例外 不保存登录名和密码的网站将显示于此处。 + + %s 将不会保存此处所列网站的密码。 将不保存这些网站的登录名和密码。 + + %s 将不会保存这些网站的密码。 删除所有例外 搜索登录信息 + + 搜索密码 网站 @@ -1771,10 +1804,16 @@ 隐藏密码 解锁以查看您保存的登录信息 + + 解锁以查看保存的密码 保护您的登录名和密码 + + 保护您保存的密码 设置设备锁定图案、PIN 或密码以保护您保存的登录名与密码,避免他人盗用。 + + 设置设备锁定图案、PIN 或密码以保护您保存的密码,避免他人盗用。 稍后 @@ -1793,6 +1832,9 @@ 排序登录信息菜单 + + 密码排序菜单 + 自动填充 @@ -1800,10 +1842,16 @@ 地址 信用卡 + + 付款方式 保存并自动填充信用卡信息 + + 保存和填写付款方式 数据已加密 + + %s 会加密您保存的所有付款方式 跨设备同步信用卡信息 @@ -1811,17 +1859,26 @@ 添加信用卡 + + 添加信用卡 管理保存的卡片 + + 管理信用卡 添加地址 管理地址 保存并自动填充地址 + + 保存和填充地址 包含号码、邮箱和收货地址等信息 + + 包括电话号码和邮箱地址 + 添加信用卡 @@ -1842,6 +1899,8 @@ 删除卡片 您确定要删除此信用卡吗? + + 确定删除信用卡吗? 删除 @@ -1857,15 +1916,23 @@ 请输入有效的信用卡卡号 + + 请输入有效卡号 请填写此栏 + + 请输入持卡人姓名 解锁后即可查看保存的卡片信息 保护您的卡片信息 + + 保护您保存的付款方式 设置设备锁定图案、PIN 或密码以保护您保存的卡片信息,避免他人盗用。 + + 设置设备锁定图案、PIN 或密码以保护您保存的付款方式,避免他人盗用。 立即设置 @@ -1876,6 +1943,8 @@ 解锁以使用存储的卡片信息 + + 解锁以使用保存的付款方式 添加地址 @@ -1913,6 +1982,8 @@ 您确定要删除此地址吗? + + 确定删除此地址吗? 删除 @@ -2011,30 +2082,52 @@ 编辑 您确定要删除此登录信息吗? + + 您确定要删除此密码吗? 删除 取消 登录选项 + + 密码选项 登录信息中的网址输入框。 + + 网址输入框。 登录信息中的用户名输入框。 + + 用户名输入框。 登录信息中的密码输入框。 + + 密码输入框。 保存编辑过的登录信息。 + + 保存更改。 编辑 + + 编辑密码 新建登录信息 + + 添加密码 需要密码 + + 请输入密码 用户名不能为空 + + 请输入用户名 主机名不能为空 + + 请输入网址 语音搜索 @@ -2320,7 +2413,7 @@ 打开核查评价 - 测试中 + 测试版 打开核查评价 @@ -2397,6 +2490,8 @@ 正在翻译 + + 选择语言 翻译时遇到问题,请重试。 @@ -2417,6 +2512,10 @@ 永不翻译%1$s 永不翻译此网站 + + 将覆盖其他所有设置 + + 将覆盖“询问是否翻译” 翻译设置 diff --git a/fenix/app/src/main/res/values-zh-rTW/strings.xml b/fenix/app/src/main/res/values-zh-rTW/strings.xml index eb86161ce3b0..6a8a722d63eb 100644 --- a/fenix/app/src/main/res/values-zh-rTW/strings.xml +++ b/fenix/app/src/main/res/values-zh-rTW/strings.xml @@ -2439,9 +2439,9 @@ 要翻譯此頁面嗎? - 在 %1$s 試用有隱私的翻譯功能 + 在 %1$s 試用保護隱私的翻譯功能 - 為了保護您的隱私,要翻譯的內容不會離開您的裝置。即將支援更多新語言並改善功能!%1$s + 為了保護您的隱私,要翻譯的內容不會離開您的裝置。未來將持續支援更多語言並改善功能!%1$s 更多資訊 @@ -2478,15 +2478,15 @@ 總是提供翻譯 - 總是翻譯 %1$s + 總是翻譯%1$s - 永不翻譯 %1$s + 永不翻譯%1$s 永不翻譯此網站 - 覆蓋所有其他設定 + 蓋過其他所有設定 - 覆蓋提供翻譯功能 + 蓋過翻譯功能提示 翻譯設定 @@ -2518,7 +2518,7 @@ 提供翻譯(預設) - %1$s 將提供此語言的網站翻譯內容 + %1$s 將提示是否要翻譯此語言的網站內容 總是翻譯 @@ -2527,7 +2527,7 @@ 永不翻譯 - %1$s 不會提供此語言的翻譯功能 + %1$s 不會提示此語言的網站翻譯功能 @@ -2576,7 +2576,7 @@ - 要刪除 %1$s(%2$s)嗎? + 要刪除%1$s(%2$s)嗎? 若您刪除此語言,%1$s 將在翻譯時下載部分語言檔到您的快取空間。 分享方式 + 需要清除浏览历史吗? + 点按或清除此通知,即可安全清除浏览历史。 + 清除浏览记录 From 7d0c8cacb416c627eec2c1bb97b7d13964736130 Mon Sep 17 00:00:00 2001 From: sarah541 Date: Fri, 26 Jan 2024 13:50:41 -0500 Subject: [PATCH 048/586] Bug 1868539 - Add method of changing remote server url --- .../telemetry/SerpTelemetryRepository.kt | 4 ++-- .../java/org/mozilla/fenix/components/Core.kt | 7 ++++++ .../fenix/settings/SecretSettingsFragment.kt | 9 ++++++- .../java/org/mozilla/fenix/utils/Settings.kt | 5 ++++ .../src/main/res/values/preference_keys.xml | 3 +++ .../src/main/res/values/static_strings.xml | 2 ++ .../res/xml/secret_settings_preferences.xml | 5 ++++ .../advanced/SecretSettingsFragment.kt | 8 +++++++ .../advanced/SharedPreferenceUpdater.kt | 24 +++++++++++++++++++ .../focus/telemetry/GleanMetricsService.kt | 10 ++++++++ .../java/org/mozilla/focus/utils/Settings.kt | 8 +++++++ .../src/main/res/values/preference_keys.xml | 2 ++ .../src/main/res/values/static_strings.xml | 3 +++ .../app/src/main/res/xml/secret_settings.xml | 6 +++++ 14 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 focus-android/app/src/main/java/org/mozilla/focus/settings/advanced/SharedPreferenceUpdater.kt diff --git a/android-components/components/feature/search/src/main/java/mozilla/components/feature/search/telemetry/SerpTelemetryRepository.kt b/android-components/components/feature/search/src/main/java/mozilla/components/feature/search/telemetry/SerpTelemetryRepository.kt index a7260c29b95a..436b0e22db2d 100644 --- a/android-components/components/feature/search/src/main/java/mozilla/components/feature/search/telemetry/SerpTelemetryRepository.kt +++ b/android-components/components/feature/search/src/main/java/mozilla/components/feature/search/telemetry/SerpTelemetryRepository.kt @@ -16,7 +16,7 @@ import org.json.JSONException import org.json.JSONObject import java.io.File -internal const val REMOTE_ENDPOINT_URL = "https://firefox.settings.services.mozilla.com" +internal const val REMOTE_PROD_ENDPOINT_URL = "https://firefox.settings.services.mozilla.com" internal const val REMOTE_ENDPOINT_BUCKET_NAME = "main" /** @@ -26,7 +26,7 @@ class SerpTelemetryRepository( rootStorageDirectory: File, private val readJson: () -> JSONObject, collectionName: String, - serverUrl: String = REMOTE_ENDPOINT_URL, + serverUrl: String = REMOTE_PROD_ENDPOINT_URL, bucketName: String = REMOTE_ENDPOINT_BUCKET_NAME, ) { val logger = Logger("SerpTelemetryRepository") diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt index 22447bbe2418..65778d279560 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt @@ -329,6 +329,11 @@ class Core( rootStorageDirectory = context.filesDir, readJson = readJson, collectionName = COLLECTION_NAME, + serverUrl = if (context.settings().useProductionRemoteSettingsServer) { + REMOTE_PROD_ENDPOINT_URL + } else { + REMOTE_STAGE_ENDPOINT_URL + }, ).updateProviderList() } // Install the "ads" WebExtension to get the links in an partner page. @@ -623,5 +628,7 @@ class Core( // collection name to fetch from server for SERP telemetry const val COLLECTION_NAME = "search-telemetry-v2" + internal const val REMOTE_PROD_ENDPOINT_URL = "https://firefox.settings.services.mozilla.com" + internal const val REMOTE_STAGE_ENDPOINT_URL = "https://firefox.settings.services.allizom.org" } } diff --git a/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt index 4f5c99085b91..2d91285fedfb 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt @@ -88,7 +88,8 @@ class SecretSettingsFragment : PreferenceFragmentCompat() { onPreferenceChangeListener = object : Preference.OnPreferenceChangeListener { override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean { val newBooleanValue = newValue as? Boolean ?: return false - val ingestionScheduler = requireContext().components.fxSuggest.ingestionScheduler + val ingestionScheduler = + requireContext().components.fxSuggest.ingestionScheduler if (newBooleanValue) { ingestionScheduler.startPeriodicIngestion() } else { @@ -129,6 +130,12 @@ class SecretSettingsFragment : PreferenceFragmentCompat() { requirePreference(R.string.pref_key_custom_sponsored_stories_parameters).apply { isVisible = Config.channel.isNightlyOrDebug } + + requirePreference(R.string.pref_key_remote_server_prod).apply { + isVisible = true + isChecked = context.settings().useProductionRemoteSettingsServer + onPreferenceChangeListener = SharedPreferenceUpdater() + } } override fun onPreferenceTreeClick(preference: Preference): Boolean { diff --git a/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt index 8a8bbd7064a2..7b8f0343e656 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -767,6 +767,11 @@ class Settings(private val appContext: Context) : PreferencesHolder { true, ) + val useProductionRemoteSettingsServer by booleanPreference( + key = appContext.getPreferenceKey(R.string.pref_key_remote_server_prod), + default = true, + ) + val enabledTotalCookieProtection: Boolean get() = mr2022Sections[Mr2022Section.TCP_FEATURE] == true diff --git a/fenix/app/src/main/res/values/preference_keys.xml b/fenix/app/src/main/res/values/preference_keys.xml index 59e41aebe469..6c161555677b 100644 --- a/fenix/app/src/main/res/values/preference_keys.xml +++ b/fenix/app/src/main/res/values/preference_keys.xml @@ -145,6 +145,9 @@ pref_key_privacy_pop_window + + pref_key_remote_server_prod + pref_key_light_theme pref_key_dark_theme diff --git a/fenix/app/src/main/res/values/static_strings.xml b/fenix/app/src/main/res/values/static_strings.xml index ffb95ee4e492..6432c5bedda1 100644 --- a/fenix/app/src/main/res/values/static_strings.xml +++ b/fenix/app/src/main/res/values/static_strings.xml @@ -34,6 +34,8 @@ Secret Settings Secret Debug Info + + Use Remote Settings Production server \n(Staging will be used when disabled) \n(requires restart) Use third party CA certificates diff --git a/fenix/app/src/main/res/xml/secret_settings_preferences.xml b/fenix/app/src/main/res/xml/secret_settings_preferences.xml index 48148593f6ff..0a74701ced87 100644 --- a/fenix/app/src/main/res/xml/secret_settings_preferences.xml +++ b/fenix/app/src/main/res/xml/secret_settings_preferences.xml @@ -61,4 +61,9 @@ app:iconSpaceReserved="false" android:title="@string/preferences_debug_settings_custom_sponsored_stories_parameters" /> + diff --git a/focus-android/app/src/main/java/org/mozilla/focus/settings/advanced/SecretSettingsFragment.kt b/focus-android/app/src/main/java/org/mozilla/focus/settings/advanced/SecretSettingsFragment.kt index 447550c9c619..4526f56f1941 100644 --- a/focus-android/app/src/main/java/org/mozilla/focus/settings/advanced/SecretSettingsFragment.kt +++ b/focus-android/app/src/main/java/org/mozilla/focus/settings/advanced/SecretSettingsFragment.kt @@ -10,6 +10,8 @@ import androidx.preference.SwitchPreferenceCompat import org.mozilla.focus.R import org.mozilla.focus.ext.getPreferenceKey import org.mozilla.focus.ext.requireComponents +import org.mozilla.focus.ext.requirePreference +import org.mozilla.focus.ext.settings import org.mozilla.focus.ext.showToolbar import org.mozilla.focus.settings.BaseSettingsFragment import kotlin.system.exitProcess @@ -26,6 +28,12 @@ class SecretSettingsFragment : override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.secret_settings) + + requirePreference(R.string.pref_key_remote_server_prod).apply { + isVisible = true + isChecked = context.settings.useProductionRemoteSettingsServer + onPreferenceChangeListener = SharedPreferenceUpdater() + } } override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String?) { diff --git a/focus-android/app/src/main/java/org/mozilla/focus/settings/advanced/SharedPreferenceUpdater.kt b/focus-android/app/src/main/java/org/mozilla/focus/settings/advanced/SharedPreferenceUpdater.kt new file mode 100644 index 000000000000..9f3760fbc8c8 --- /dev/null +++ b/focus-android/app/src/main/java/org/mozilla/focus/settings/advanced/SharedPreferenceUpdater.kt @@ -0,0 +1,24 @@ +/* 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.focus.settings.advanced + +import androidx.core.content.edit +import androidx.preference.Preference +import org.mozilla.focus.ext.settings + +/** + * Updates the corresponding [android.content.SharedPreferences] when the boolean [Preference] is changed. + * The preference key is used as the shared preference key. + */ +open class SharedPreferenceUpdater : Preference.OnPreferenceChangeListener { + + override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean { + val newBooleanValue = newValue as? Boolean ?: return false + preference.context.settings.preferences.edit { + putBoolean(preference.key, newBooleanValue) + } + return true + } +} diff --git a/focus-android/app/src/main/java/org/mozilla/focus/telemetry/GleanMetricsService.kt b/focus-android/app/src/main/java/org/mozilla/focus/telemetry/GleanMetricsService.kt index c36926212f7d..1b6aec961c00 100644 --- a/focus-android/app/src/main/java/org/mozilla/focus/telemetry/GleanMetricsService.kt +++ b/focus-android/app/src/main/java/org/mozilla/focus/telemetry/GleanMetricsService.kt @@ -60,6 +60,11 @@ class GleanMetricsService(context: Context) : MetricsService { companion object { // collection name to fetch from server for SERP telemetry const val COLLECTION_NAME = "search-telemetry-v2" + + // urls for prod and stage remote settings server + internal const val REMOTE_PROD_ENDPOINT_URL = "https://firefox.settings.services.mozilla.com" + internal const val REMOTE_STAGE_ENDPOINT_URL = "https://firefox.settings.services.allizom.org" + private val isEnabledByDefault: Boolean get() = !AppConstants.isKlarBuild @@ -122,6 +127,11 @@ class GleanMetricsService(context: Context) : MetricsService { rootStorageDirectory = context.filesDir, readJson = readJson, collectionName = COLLECTION_NAME, + serverUrl = if (context.settings.useProductionRemoteSettingsServer) { + REMOTE_PROD_ENDPOINT_URL + } else { + REMOTE_STAGE_ENDPOINT_URL + }, ).updateProviderList() } installSearchTelemetryExtensions(components, providerList) diff --git a/focus-android/app/src/main/java/org/mozilla/focus/utils/Settings.kt b/focus-android/app/src/main/java/org/mozilla/focus/utils/Settings.kt index e6ab3067e619..3b16490aa40d 100644 --- a/focus-android/app/src/main/java/org/mozilla/focus/utils/Settings.kt +++ b/focus-android/app/src/main/java/org/mozilla/focus/utils/Settings.kt @@ -412,6 +412,14 @@ class Settings( .commit() } + var useProductionRemoteSettingsServer: Boolean + get() = preferences.getBoolean(getPreferenceKey(R.string.pref_key_remote_server_prod), true) + set(value) { + preferences.edit() + .putBoolean(getPreferenceKey(R.string.pref_key_remote_server_prod), value) + .commit() + } + fun addSearchWidgetInstalled(count: Int) { val key = getPreferenceKey(R.string.pref_key_search_widget_installed) val newValue = preferences.getInt(key, 0) + count diff --git a/focus-android/app/src/main/res/values/preference_keys.xml b/focus-android/app/src/main/res/values/preference_keys.xml index 5b22aa0033af..6fbdb2dd5f35 100644 --- a/focus-android/app/src/main/res/values/preference_keys.xml +++ b/focus-android/app/src/main/res/values/preference_keys.xml @@ -10,6 +10,8 @@ pref_radio_search_engine_list pref_multiselect_search_engine_list + pref_key_remote_server_prod + pref_privacy_block_ads pref_privacy_block_analytics pref_privacy_block_social diff --git a/focus-android/app/src/main/res/values/static_strings.xml b/focus-android/app/src/main/res/values/static_strings.xml index d0557471cb32..c5deff31e59b 100644 --- a/focus-android/app/src/main/res/values/static_strings.xml +++ b/focus-android/app/src/main/res/values/static_strings.xml @@ -20,4 +20,7 @@ AS + + + Use Remote Settings Production server \n(Staging will be used when disabled) \n(requires restart) diff --git a/focus-android/app/src/main/res/xml/secret_settings.xml b/focus-android/app/src/main/res/xml/secret_settings.xml index 9083085d196d..2d61913bce4f 100644 --- a/focus-android/app/src/main/res/xml/secret_settings.xml +++ b/focus-android/app/src/main/res/xml/secret_settings.xml @@ -8,4 +8,10 @@ android:key="@string/pref_key_use_nimbus_preview" android:layout="@layout/focus_preference_no_icon" android:title="@string/preference_use_nimbus_preview" /> + + From 7ee4961adef98053723da91dcd5cb7f65e3ff313 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Fri, 2 Feb 2024 12:39:03 +0000 Subject: [PATCH 049/586] Update GeckoView (Nightly) to 124.0.20240202094312. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index fc7392c5d6e1..4ccc0b9020b4 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240201173838" + const val version = "124.0.20240202094312" /** * GeckoView channel From e5e884e3d84b10157d42aa356ce211497927b5df Mon Sep 17 00:00:00 2001 From: t-p-white Date: Thu, 1 Feb 2024 11:36:01 +0000 Subject: [PATCH 050/586] Bug 1813875 - Prevent the inherited theming implementation being applied to Custom Tab views --- .../engine/manifest/WebAppManifestParser.kt | 2 +- .../java/org/mozilla/fenix/HomeActivity.kt | 18 +++++++++++++----- .../fenix/browser/BaseBrowserFragment.kt | 13 ++++++++++--- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/manifest/WebAppManifestParser.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/manifest/WebAppManifestParser.kt index 132f95a36426..b5c0cd58122c 100644 --- a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/manifest/WebAppManifestParser.kt +++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/manifest/WebAppManifestParser.kt @@ -207,7 +207,7 @@ private fun parseFingerprints(app: JSONObject): List - activity.themeManager.applyStatusBarTheme(activity) + // ExternalAppBrowserActivity handles it's own theming as it can be customized. + if (activity !is ExternalAppBrowserActivity) { + activity.themeManager.applyStatusBarTheme(activity) + } } if (webAppToolbarShouldBeVisible) { browserToolbarView.view.isVisible = true From 4dd7c2dde04b354320b22978ad3c3a616f57f879 Mon Sep 17 00:00:00 2001 From: Ben Dean-Kawamura Date: Wed, 31 Jan 2024 17:10:06 -0500 Subject: [PATCH 051/586] Bug 1877847 - Remove Suggest error reporting --- .../feature/fxsuggest/FxSuggestStorage.kt | 6 +- .../feature/fxsuggest/FxSuggestStorageTest.kt | 98 ------------------- .../mozilla/fenix/components/Components.kt | 2 +- .../org/mozilla/fenix/components/FxSuggest.kt | 7 +- 4 files changed, 4 insertions(+), 109 deletions(-) delete mode 100644 android-components/components/feature/fxsuggest/src/test/java/mozilla/components/feature/fxsuggest/FxSuggestStorageTest.kt diff --git a/android-components/components/feature/fxsuggest/src/main/java/mozilla/components/feature/fxsuggest/FxSuggestStorage.kt b/android-components/components/feature/fxsuggest/src/main/java/mozilla/components/feature/fxsuggest/FxSuggestStorage.kt index c48fecfa5872..48e80729cbe7 100644 --- a/android-components/components/feature/fxsuggest/src/main/java/mozilla/components/feature/fxsuggest/FxSuggestStorage.kt +++ b/android-components/components/feature/fxsuggest/src/main/java/mozilla/components/feature/fxsuggest/FxSuggestStorage.kt @@ -26,10 +26,7 @@ import java.io.File * @param crashReporter An optional [CrashReporting] instance for reporting unexpected caught * exceptions. */ -class FxSuggestStorage( - context: Context, - private val crashReporter: CrashReporting? = null, -) { +class FxSuggestStorage(context: Context) { // Lazily initializes the store on first use. `cacheDir` and using the `File` constructor // does I/O, so `store.value` should only be accessed from the read or write scope. @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) @@ -99,7 +96,6 @@ class FxSuggestStorage( return try { operation() } catch (e: SuggestApiException) { - crashReporter?.submitCaughtException(e) logger.warn("Ignoring exception from `$name`", e) default } diff --git a/android-components/components/feature/fxsuggest/src/test/java/mozilla/components/feature/fxsuggest/FxSuggestStorageTest.kt b/android-components/components/feature/fxsuggest/src/test/java/mozilla/components/feature/fxsuggest/FxSuggestStorageTest.kt deleted file mode 100644 index 2ec69d31acab..000000000000 --- a/android-components/components/feature/fxsuggest/src/test/java/mozilla/components/feature/fxsuggest/FxSuggestStorageTest.kt +++ /dev/null @@ -1,98 +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 mozilla.components.feature.fxsuggest - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import kotlinx.coroutines.test.runTest -import mozilla.appservices.suggest.SuggestApiException -import mozilla.appservices.suggest.SuggestStore -import mozilla.appservices.suggest.Suggestion -import mozilla.appservices.suggest.SuggestionQuery -import mozilla.components.concept.base.crash.CrashReporting -import mozilla.components.support.test.any -import mozilla.components.support.test.mock -import mozilla.components.support.test.robolectric.testContext -import mozilla.components.support.test.whenever -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mockito.doNothing -import org.mockito.Mockito.never -import org.mockito.Mockito.spy -import org.mockito.Mockito.verify - -@RunWith(AndroidJUnit4::class) -class FxSuggestStorageTest { - @Test - fun `GIVEN an exception is thrown WHEN querying the store THEN the exception should be reported`() = runTest { - val store: SuggestStore = mock() - whenever(store.query(any())).then { - throw SuggestApiException.Other("Mercury in retrograde") - } - - val crashReporter: CrashReporting = mock() - val storage = spy(FxSuggestStorage(testContext, crashReporter)) - whenever(storage.store).thenReturn(lazy { store }) - - val suggestions = storage.query(SuggestionQuery("la", providers = emptyList())) - assertTrue(suggestions.isEmpty()) - verify(crashReporter).submitCaughtException(any()) - } - - @Test - fun `GIVEN an exception is not thrown WHEN querying the store THEN nothing should be reported`() = runTest { - val store: SuggestStore = mock() - whenever(store.query(any())).thenReturn( - listOf( - Suggestion.Wikipedia( - title = "Las Vegas", - url = "https://wikipedia.org/wiki/Las_Vegas", - icon = null, - fullKeyword = "las", - ), - ), - ) - - val crashReporter: CrashReporting = mock() - val storage = spy(FxSuggestStorage(testContext, crashReporter)) - whenever(storage.store).thenReturn(lazy { store }) - - val suggestions = storage.query(SuggestionQuery("la", providers = emptyList())) - assertEquals(1, suggestions.size) - verify(crashReporter, never()).submitCaughtException(any()) - } - - @Test - fun `GIVEN an exception is thrown WHEN ingesting THEN the exception should be reported`() = runTest { - val crashReporter: CrashReporting = mock() - val store: SuggestStore = mock() - whenever(store.ingest(any())).then { - throw SuggestApiException.Other("Mercury in retrograde") - } - - val storage = spy(FxSuggestStorage(testContext, crashReporter)) - whenever(storage.store).thenReturn(lazy { store }) - - val success = storage.ingest() - assertFalse(success) - verify(crashReporter).submitCaughtException(any()) - } - - @Test - fun `GIVEN an exception is not thrown WHEN ingesting THEN nothing should be reported`() = runTest { - val crashReporter: CrashReporting = mock() - val store: SuggestStore = mock() - doNothing().`when`(store).ingest(any()) - - val storage = spy(FxSuggestStorage(testContext, crashReporter)) - whenever(storage.store).thenReturn(lazy { store }) - - val success = storage.ingest() - assertTrue(success) - verify(crashReporter, never()).submitCaughtException(any()) - } -} diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt index 40d316b8accd..6a4ea2328c2e 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt @@ -238,7 +238,7 @@ class Components(private val context: Context) { ) } - val fxSuggest by lazyMonitored { FxSuggest(context, analytics.crashReporter) } + val fxSuggest by lazyMonitored { FxSuggest(context) } } /** diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/FxSuggest.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/FxSuggest.kt index 22a4444420bc..05593c97fc32 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/components/FxSuggest.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/components/FxSuggest.kt @@ -5,7 +5,6 @@ package org.mozilla.fenix.components import android.content.Context -import mozilla.components.concept.base.crash.CrashReporting import mozilla.components.feature.fxsuggest.FxSuggestIngestionScheduler import mozilla.components.feature.fxsuggest.FxSuggestStorage import org.mozilla.fenix.perf.lazyMonitored @@ -14,12 +13,10 @@ import org.mozilla.fenix.perf.lazyMonitored * Component group for Firefox Suggest. * * @param context The Android application context. - * @param crashReporter An optional [CrashReporting] instance for reporting unexpected caught - * exceptions. */ -class FxSuggest(context: Context, crashReporter: CrashReporting? = null) { +class FxSuggest(context: Context) { val storage by lazyMonitored { - FxSuggestStorage(context, crashReporter) + FxSuggestStorage(context) } val ingestionScheduler by lazyMonitored { From 4eda301f64a872bde822b154292808d8cee8353c Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Fri, 2 Feb 2024 16:41:07 +0000 Subject: [PATCH 052/586] Update A-S to 124.20240202162153. --- .../plugins/dependencies/src/main/java/ApplicationServices.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt index 00ab62e97ad6..2990706a87b4 100644 --- a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt +++ b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // These lines are generated by android-components/automation/application-services-nightly-bump.py -val VERSION = "124.20240201050339" +val VERSION = "124.20240202162153" val CHANNEL = ApplicationServicesChannel.NIGHTLY object ApplicationServicesConfig { From c5065db7619d868f8ebfcadd5a26c3cb1f134d5a Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Fri, 2 Feb 2024 22:21:08 +0000 Subject: [PATCH 053/586] Update GeckoView (Nightly) to 124.0.20240202164508. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 4ccc0b9020b4..b6e2a318ae30 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240202094312" + const val version = "124.0.20240202164508" /** * GeckoView channel From 4399f848fdae3e4c89d1ace23b1576269af6617d Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 3 Feb 2024 00:03:26 +0000 Subject: [PATCH 054/586] Import translations from android-l10n --- .../cfr/src/main/res/values-ckb/strings.xml | 5 + .../src/main/res/values-azb/strings.xml | 2 +- .../src/main/res/values-en-rGB/strings.xml | 4 +- .../addons/src/main/res/values-hu/strings.xml | 4 +- .../src/main/res/values-hy-rAM/strings.xml | 2 + .../media/src/main/res/values-azb/strings.xml | 27 ++- .../src/main/res/values-en-rGB/strings.xml | 11 +- .../media/src/main/res/values-hu/strings.xml | 11 +- .../src/main/res/values-hy-rAM/strings.xml | 11 +- .../media/src/main/res/values-sl/strings.xml | 11 +- .../src/main/res/values-azb/strings.xml | 5 + .../src/main/res/values-azb/strings.xml | 192 ++++++++++++++++++ .../src/main/res/values-en-rGB/strings.xml | 36 ++++ .../src/main/res/values-hu/strings.xml | 36 ++++ .../src/main/res/values-hy-rAM/strings.xml | 33 +++ .../src/main/res/values-sl/strings.xml | 18 ++ .../pwa/src/main/res/values-azb/strings.xml | 14 ++ .../qr/src/main/res/values-azb/strings.xml | 10 + .../src/main/res/values-azb/strings.xml | 29 +++ .../src/main/res/values-azb/strings.xml | 12 ++ .../src/main/res/values-ckb/strings.xml | 12 ++ .../src/main/res/values-azb/strings.xml | 48 +++++ .../tabs/src/main/res/values-azb/strings.xml | 5 + .../src/main/res/values-azb/strings.xml | 5 + .../crash/src/main/res/values-azb/strings.xml | 42 ++++ .../src/main/res/values-azb/strings.xml | 5 + .../base/src/main/res/values-azb/strings.xml | 7 + .../ktx/src/main/res/values-azb/strings.xml | 9 + .../src/main/res/values-azb/strings.xml | 17 ++ .../src/main/res/values-azb/strings.xml | 5 + fenix/app/src/main/res/values-azb/strings.xml | 36 ++++ .../src/main/res/values-en-rGB/strings.xml | 61 ++---- .../src/main/res/values-hy-rAM/strings.xml | 61 ++---- fenix/app/src/main/res/values-sl/strings.xml | 51 +---- .../src/main/res/values-zh-rCN/strings.xml | 2 +- 35 files changed, 689 insertions(+), 150 deletions(-) create mode 100644 android-components/components/compose/cfr/src/main/res/values-ckb/strings.xml create mode 100644 android-components/components/feature/privatemode/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/prompts/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/pwa/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/qr/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/readerview/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/search/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/search/src/main/res/values-ckb/strings.xml create mode 100644 android-components/components/feature/sitepermissions/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/tabs/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/feature/webnotifications/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/lib/crash/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/service/nimbus/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/support/base/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/support/ktx/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/ui/tabcounter/src/main/res/values-azb/strings.xml create mode 100644 android-components/components/ui/widgets/src/main/res/values-azb/strings.xml create mode 100644 fenix/app/src/main/res/values-azb/strings.xml diff --git a/android-components/components/compose/cfr/src/main/res/values-ckb/strings.xml b/android-components/components/compose/cfr/src/main/res/values-ckb/strings.xml new file mode 100644 index 000000000000..437dd527f513 --- /dev/null +++ b/android-components/components/compose/cfr/src/main/res/values-ckb/strings.xml @@ -0,0 +1,5 @@ + + + + پشتگوێخستن + diff --git a/android-components/components/feature/addons/src/main/res/values-azb/strings.xml b/android-components/components/feature/addons/src/main/res/values-azb/strings.xml index 97a75c331cd5..4669bf57bf02 100644 --- a/android-components/components/feature/addons/src/main/res/values-azb/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-azb/strings.xml @@ -185,7 +185,7 @@ ایندی توصیه اولونان اوزانتی‌لارین ایلک سئچیمی اوچون ساپورت وئریریق. - تاخیلان یئندیریلیر و دوغرولانیر... + تاخیلان یئندیریلیر و دوغرولانیر… تاخیلان‌لاری سورغولاماق آلینمادی. diff --git a/android-components/components/feature/addons/src/main/res/values-en-rGB/strings.xml b/android-components/components/feature/addons/src/main/res/values-en-rGB/strings.xml index e43627c16f8a..78b5a8f9f8c4 100644 --- a/android-components/components/feature/addons/src/main/res/values-en-rGB/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-en-rGB/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Access your data on %1$d other domains + + %1$s, %2$d of %3$d Access browser tabs @@ -75,7 +77,7 @@ Author - Authors + Authors Last updated diff --git a/android-components/components/feature/addons/src/main/res/values-hu/strings.xml b/android-components/components/feature/addons/src/main/res/values-hu/strings.xml index 43afb344301f..f9eefc6f90d7 100644 --- a/android-components/components/feature/addons/src/main/res/values-hu/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-hu/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Hozzáférés az adataihoz %1$d másik tartományban + + %1$s, %2$d / %3$d Böngészőlapok elérése @@ -75,7 +77,7 @@ Szerző - Szerzők + Szerzők Legutóbb frissítve diff --git a/android-components/components/feature/addons/src/main/res/values-hy-rAM/strings.xml b/android-components/components/feature/addons/src/main/res/values-hy-rAM/strings.xml index 5c82854dac9c..2b5dec004340 100644 --- a/android-components/components/feature/addons/src/main/res/values-hy-rAM/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-hy-rAM/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Մատչել ձեր տվյալներին %1$d այլ տիրույթներում + + %1$s, %2$d՝ %3$d-ից Մատչել դիտարկիչի ներդիրները diff --git a/android-components/components/feature/media/src/main/res/values-azb/strings.xml b/android-components/components/feature/media/src/main/res/values-azb/strings.xml index c7d1ff607d52..341d39582a2d 100644 --- a/android-components/components/feature/media/src/main/res/values-azb/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-azb/strings.xml @@ -15,4 +15,29 @@ کامئرازدان ایستیفاده ائدن تاغی آچماق اوچون توخونون. - + + میکروفونوزدان ایستیفاده ائدن تاغی آچماق اوچون توخونون. + + کامئرا و میکروفونوزدان ایستیفاده ائدن تاغی آچماق اوچون توخونون. + + + + یادا سالما: %1$s هله‌ده کامئرانیزدان ایستیفاده ائدیر. تاغی آچماق اوچون توخونون. + + یادا سالما: %1$s هله‌ده میکروفونوزدان ایستیفاده ائدیر. تاغی آچماق اوچون توخونون. + + یادا سالما: %1$s هله‌ده میکروفونوزدان ایستیفاده ائدیر. تاغی آچماق اوچون توخونون. + + یادا سالما: %1$s هله‌ده کامئرا و میکروفونوزدان ایستیفاده ائدیر. تاغی آچماق اوچون توخونون + + یادا سالما: %1$s هله‌ده کامئرا و میکروفونوزدان ایستیفاده ائدیر. تاغی آچماق اوچون توخونون. + + + اوینات + + + دایاندیر + + + بیر سایت مدیا اوینادیر + diff --git a/android-components/components/feature/media/src/main/res/values-en-rGB/strings.xml b/android-components/components/feature/media/src/main/res/values-en-rGB/strings.xml index d03d1fb5b90d..c794d4a23742 100644 --- a/android-components/components/feature/media/src/main/res/values-en-rGB/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-en-rGB/strings.xml @@ -1,5 +1,5 @@ - + Media @@ -21,9 +21,14 @@ Reminder: %1$s is still using your camera. Tap to open the tab. - Reminder: %1$s is still using your microphone. Tap to open the tab + Reminder: %1$s is still using your microphone. Tap to open the tab + + Reminder: %1$s is still using your microphone. Tap to open the tab. + + Reminder: %1$s is still using your microphone and camera. Tap to open the tab + - Reminder: %1$s is still using your microphone and camera. Tap to open the tab + Reminder: %1$s is still using your microphone and camera. Tap to open the tab. Play diff --git a/android-components/components/feature/media/src/main/res/values-hu/strings.xml b/android-components/components/feature/media/src/main/res/values-hu/strings.xml index 40ecc3b3dee3..81de265e5b29 100644 --- a/android-components/components/feature/media/src/main/res/values-hu/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-hu/strings.xml @@ -1,5 +1,5 @@ - + Média @@ -21,9 +21,14 @@ Emlékeztető: A %1$s még mindig használja a kameráját. Koppintson a lap megnyitásához. - Emlékeztető: A %1$s még mindig használja a mikrofonját. Koppintson a lap megnyitásához. + Emlékeztető: A %1$s még mindig használja a mikrofonját. Koppintson a lap megnyitásához. + + Emlékeztető: A %1$s még mindig használja a mikrofonját. Koppintson a lap megnyitásához. + + Emlékeztető: A %1$s még mindig használja a mikrofonját és kameráját. Koppintson a lap megnyitásához. + - Emlékeztető: A %1$s még mindig használja a mikrofonját és kameráját. Koppintson a lap megnyitásához. + Emlékeztető: A %1$s még mindig használja a mikrofonját és kameráját. Koppintson a lap megnyitásához. Lejátszás diff --git a/android-components/components/feature/media/src/main/res/values-hy-rAM/strings.xml b/android-components/components/feature/media/src/main/res/values-hy-rAM/strings.xml index 598f1f37342f..849dbb249613 100644 --- a/android-components/components/feature/media/src/main/res/values-hy-rAM/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-hy-rAM/strings.xml @@ -1,5 +1,5 @@ - + Մեդիա @@ -21,9 +21,14 @@ Հիշեցում. %1$s-ը դեռ օգտագործում է ձեր տեսախցիկը: Հպեք՝ ներդիրը բացելու համար: - Հիշեցում. %1$s-ը դեռ օգտագործում է ձեր բարձրախոսը: Հպեք՝ ներդիրը բացելու համար: + Հիշեցում. %1$s-ը դեռ օգտագործում է ձեր բարձրախոսը: Հպեք՝ ներդիրը բացելու համար: + + Հիշեցում. %1$s-ը դեռ օգտագործում է ձեր բարձրախոսը: Հպեք՝ ներդիրը բացելու համար: + + Հիշեցում. %1$s-ը դեռ օգտագործում է ձեր բարձրախոսը և տեսախցիկը: Հպեք՝ ներդիրը բացելու համար: + - Հիշեցում. %1$s-ը դեռ օգտագործում է ձեր բարձրախոսը և տեսախցիկը: Հպեք՝ ներդիրը բացելու համար: + Հիշեցում. %1$s-ը դեռ օգտագործում է ձեր բարձրախոսը և տեսախցիկը: Հպեք՝ ներդիրը բացելու համար: Նվագարկել diff --git a/android-components/components/feature/media/src/main/res/values-sl/strings.xml b/android-components/components/feature/media/src/main/res/values-sl/strings.xml index add139f87b96..8482100ccc24 100644 --- a/android-components/components/feature/media/src/main/res/values-sl/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-sl/strings.xml @@ -1,5 +1,5 @@ - + Predstavnost @@ -22,9 +22,14 @@ Opomnik: %1$s še vedno uporablja kamero. Tapnite, da odprete zavihek. - Opomnik: %1$s še vedno uporablja mikrofon. Tapnite, da odprete zavihek + Opomnik: %1$s še vedno uporablja mikrofon. Tapnite, da odprete zavihek + + Opomnik: %1$s še vedno uporablja mikrofon. Tapnite, da odprete zavihek. + + Opomnik: %1$s še vedno uporablja mikrofon in kamero. Tapnite, da odprete zavihek + - Opomnik: %1$s še vedno uporablja mikrofon in kamero. Tapnite, da odprete zavihek + Opomnik: %1$s še vedno uporablja mikrofon in kamero. Tapnite, da odprete zavihek. Predvajaj diff --git a/android-components/components/feature/privatemode/src/main/res/values-azb/strings.xml b/android-components/components/feature/privatemode/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..ec6fc61308e5 --- /dev/null +++ b/android-components/components/feature/privatemode/src/main/res/values-azb/strings.xml @@ -0,0 +1,5 @@ + + + + گیزلی مورور اوتورومو + diff --git a/android-components/components/feature/prompts/src/main/res/values-azb/strings.xml b/android-components/components/feature/prompts/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..c76429897f28 --- /dev/null +++ b/android-components/components/feature/prompts/src/main/res/values-azb/strings.xml @@ -0,0 +1,192 @@ + + + + تامام + + لغو + + بو صفحه‌نین ایضافی دیالوق‌لار یاراتماسی‌نین قارشیسینی آلین + + تنظیم ‌ائله + + پوز + + گیریش + + قوللانیجی آدی + + رمز + + ساخلاما + + ایندی یوخ + + هئچ زامان ساخلاما + + ایندی یوخ + + ساخلا + + + گونجل‌ ائله‌مه + + ایندی یوخ + + گونجلله + + + رمز یئرلیکی بوش اولمالیدیر + + بیر رمز وئر + + گیریشی ساخلاماق مومکون اولمادی + + رمزی یاددا ساخلاماق مومکون دئییل + + بو گیریش یاددا ساخلانسین؟ + + رمز یاددا ساخلانسین؟ + + بو گیریش گونجللنسین؟ + + رمز گونجللنسین؟ + + قوللانیجی آدی یاددا ساخلانمیش رمزه اکلنسین؟ + + + متن گیریش یئرلیکینه گیرمک اتیکتی + + بیر رنگ سئچ + + + ایجازه وئر + + رد + + سیز آرخایینسیز؟ + + بو سایتدان آییرلماق ایستییرسیز؟ گیردیگینیز دیتالار یاددا ساخلانیلمایا بیلر. + + قال + + آیریل + + بیر آی سئج + + ژانویه + + فوریه + + مارس + + آپریل + + می + + جون + + جولای + + آقوست + + سپتامبر + + اوکتوبر + + نووامبر + + دسامبر + + چاغ تنظیمی + + + اوتوروم‌لاری ایداره ائله + + رمزلری ایداره ائله + + توصیه اولونان گیریش‌لری گئنیش‌لت + + ساخلانمیش رمزلری گئنیش‌لت + + + توصیه اولونان گیریش‌لری یئغ + + + ساخلانمیش رمزلری یئغ + + توصیه اولونان گیریش‌لر + + ساخلانمیش رمزلر + + + گوجلو رمز تکلیف ائدین + + گوجلو رمز تکلیف ائدین + + گوجلو رمز ایستیفاده ائدین: %1$s + + + دیتا بو سایتا یئنی‌دن گؤندریلسین؟ + + بو صفحه‌نین رفرشی اؤده‌مه گؤندرمک ویا بیر باخیشی ایکی دفعه یایینلاماق کیمی سون حرکت‌لرین تیکرار اولماسینا باعیث اولار. + + دیتانی گئنه گؤندر + + لغو + + + + اعتباری کارتینی سئچین + + ساخلانمیش کارتدان ایستیفاده ائدین + + تکلیف اولونان اعتباری کارت‌لاری گئنیش‌لت + + ساخلانمیش کارت‌لاری گئنیش‌لت + + تکلیف اولونان اعتباری کارت‌لاری یئغ + + ساخلانمیش کارت‌لاری یئغ + + اعتباری کارت‌لاری ایداره ائله + + کارت‌لاری ایداره ائله + + بو کارت گوونلی شکیلده یاددا ساخلانسین؟ + + کارتین ایستیفاده موددیتی یئنی‌لنسین؟ + + کارت نومره‌سی رمزلشدیریله‌جک. گوونلیک کودو یاددا ساخلانمیاجاق. + + %s کارت نومره‌زی رمزله‌ییر. گوونلیک کودو یاددا ساخلانمیاجاق + + + + آدرس سئچین + + تکلیف اولونان آدرس‌لری گئنیش‌لت + + ساخلانمیش آدرس‌لری گئنیش‌لت + + تکلیف اولونان آدرس‌لری یئغ + + ساخلانمیش آدرس‌لری یئغ + + آدرس‌لری ایداره ائله + + + + حساب عکسی + + حساب ایرائه‌ وئره‌نی سئچین + + %1$s حسابی ایله گیرین + + %1$s اوتورم آچما ایرائه وئره‌نی کیمی ایشه آلین + + گیزلیلیک سیاستینه و خیدمت شرطلرینه باخیر. ]]> + + ایدامه وئر + + لغو + diff --git a/android-components/components/feature/prompts/src/main/res/values-en-rGB/strings.xml b/android-components/components/feature/prompts/src/main/res/values-en-rGB/strings.xml index bc6bbe77d2ae..b4cf291d22ed 100644 --- a/android-components/components/feature/prompts/src/main/res/values-en-rGB/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-en-rGB/strings.xml @@ -18,6 +18,8 @@ Password Don’t save + + Not now Never save @@ -26,16 +28,26 @@ Save Don’t update + + Not now Update Password field must not be empty + Enter a password + Unable to save login + + Can’t save password Save this login? + + Save password? Update this login? + + Update password? Add username to saved password? @@ -85,13 +97,22 @@ Set time Manage logins + + Manage passwords Expand suggested logins + + Expand saved passwords Collapse suggested logins + + Collapse saved passwords Suggested logins + + Saved passwords + Suggest strong password @@ -110,12 +131,20 @@ Select credit card + + Use saved card Expand suggested credit cards + + Expand saved cards Collapse suggested credit cards + + Collapse saved cards Manage credit cards + + Manage cards Securely save this card? @@ -123,13 +152,20 @@ Card number will be encrypted. Security code won’t be saved. + + %s encrypts your card number. Your security code won’t be saved. + Select address Expand suggested addresses + + Expand saved addresses Collapse suggested addresses + + Collapse saved addresses Manage addresses diff --git a/android-components/components/feature/prompts/src/main/res/values-hu/strings.xml b/android-components/components/feature/prompts/src/main/res/values-hu/strings.xml index c595fa314045..a480fe2bdd9e 100644 --- a/android-components/components/feature/prompts/src/main/res/values-hu/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-hu/strings.xml @@ -18,6 +18,8 @@ Jelszó Ne mentse + + Most nem Sose mentse @@ -26,16 +28,26 @@ Mentés Ne frissítse + + Most nem Frissítés A jelszómező nem lehet üres + Adjon meg egy jelszót + A bejelentkezés nem menthető + + A jelszó nem menthető Menti ezt a bejelentkezést? + + Menti a jelszót? Frissíti ezt a bejelentkezést? + + Jelszó frissítése? Hozzáadja a felhasználónevet a mentett jelszóhoz? @@ -85,13 +97,22 @@ Idő beállítása Bejelentkezések kezelése + + Jelszavak kezelése Javasolt bejelentkezések kibontása + + Mentett jelszavak kibontása Javasolt bejelentkezések összecsukása + + Mentett jelszavak összecsukása Javasolt bejelentkezések + + Mentett jelszavak + Erős jelszó javaslata @@ -110,12 +131,20 @@ Válasszon bankkártyát + + Mentett kártya használata Javasolt bankkártyák kibontása + + Mentett kártyák kibontása Javasolt bankkártyák összecsukása + + Mentett kártyák összecsukása Bankkártyák kezelése + + Kártyák kezelése Elmenti biztonságosan ezt a kártyát? @@ -123,13 +152,20 @@ A kártyaszám titkosítva lesz. A biztonsági kód nem kerül mentésre. + + A %s titkosítja a kártyaszámát. A biztonsági kód nem lesz mentve. + Cím kiválasztása Javasolt címek kibontása + + Mentett címek kibontása Javasolt címek összecsukása + + Mentett címek összecsukása Címek kezelése diff --git a/android-components/components/feature/prompts/src/main/res/values-hy-rAM/strings.xml b/android-components/components/feature/prompts/src/main/res/values-hy-rAM/strings.xml index d96933650863..4af6100e87d7 100644 --- a/android-components/components/feature/prompts/src/main/res/values-hy-rAM/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-hy-rAM/strings.xml @@ -18,6 +18,8 @@ Գաղտնաբառ Չպահպանել + + Ոչ հիմա Երբեք չպահպանել @@ -26,16 +28,26 @@ Պահպանել Չթարմացնել + + Ոչ հիմա Թարմացնել Գաղտնաբառի դաշտը չպետք է դատարկ լինի + Մուտքագրեք գաղտնաբառ + Անհնար է պահել մուտքանունը + + Հնարավոր չէ պահել գաղտնաբառը Պահպանե՞լ մուտքանունը + + Պահե՞լ գաղտնաբառը Թարմացնե՞լ մուտքանունը: + + Թարմացնե՞լ գաղտնաբառը: Ավելացնե՞լ օգտվողի անունը գաղտնաբառին: @@ -85,13 +97,22 @@ Կայել ժամանակ Կառավարել մուտքանունները + + Կառավարել գաղտնաբառերը Ընդլայնել առաջարկվող մուտքանունները + + Ընդարձակել պահված գաղտնաբառերը Կոծկել առաջարկվող մուտքանունները + + Կոծկել պահված գաղտնաբառերը Առաջարկվող մուտքանուններ + + Պահված գաղտնաբառեր + Առաջարկել ուժեղ գաղտնաբառ @@ -110,12 +131,20 @@ Ընտրեք բանկային քարտ + + Օգտագործել պահված քարտը Ընդարձակել առաջարկվող բանկային քարտերը + + Ընդարձակել պահված քարտերը Կոծկել առաջարկվող բանկային քարտերը + + Կոծկել պահված քարտերը Կառավարել բանկային քարտերը + + Կառավարել քարտերը Ապահով պահե՞լ այս քարտը: @@ -128,8 +157,12 @@ Ընտրեք հասցե Ընդլայնել առաջարկվող հասցեները + + Ընդարձակել պահված հասցեները Կոծկել առաջարկվող հասցեները + + Կոծկել պահված հասցեները Կառավարել հասցեները diff --git a/android-components/components/feature/prompts/src/main/res/values-sl/strings.xml b/android-components/components/feature/prompts/src/main/res/values-sl/strings.xml index bbccdfecff3f..948040aa9823 100644 --- a/android-components/components/feature/prompts/src/main/res/values-sl/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-sl/strings.xml @@ -18,6 +18,8 @@ Geslo Ne shrani + + Ne zdaj Nikoli ne shranjuj @@ -26,12 +28,18 @@ Shrani Ne posodobi + + Ne zdaj Posodobi Polje za geslo ne sme biti prazno + Vnesite geslo + Ni mogoče shraniti povezave + + Gesla ni mogoče shraniti Shranim to prijavo? @@ -92,6 +100,9 @@ Predlagane prijave + + Shranjena gesla + Predlagaj močno geslo @@ -110,12 +121,16 @@ Izberite kreditno kartico + + Uporabi shranjeno kartico Razširi predlagane kreditne kartice Strni predlagane kreditne kartice Upravljanje kreditnih kartic + + Upravljanje kartic Želite varno shraniti to kartico? @@ -123,6 +138,9 @@ Številka kartice bo šifrirana. Varnostna koda ne bo shranjena. + + %s šifrira številko vaše kartice. Varnostna koda se ne bo shranila. + Izbira naslova diff --git a/android-components/components/feature/pwa/src/main/res/values-azb/strings.xml b/android-components/components/feature/pwa/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..b7d75d181f05 --- /dev/null +++ b/android-components/components/feature/pwa/src/main/res/values-azb/strings.xml @@ -0,0 +1,14 @@ + + + + وبسایت + + + بوتون صفحه سایت کونترول‌لاری + + بو اپ‌ین اینترنت آدرسینی کوپی ائتمک اوچون توخونون. + + رفرش + + اینترنت آدرسی کوپی اولدو. + diff --git a/android-components/components/feature/qr/src/main/res/values-azb/strings.xml b/android-components/components/feature/qr/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..e101130566ec --- /dev/null +++ b/android-components/components/feature/qr/src/main/res/values-azb/strings.xml @@ -0,0 +1,10 @@ + + + + + QR اسکنچی‌سی + + + جهازدا کامئرا یوخ + + diff --git a/android-components/components/feature/readerview/src/main/res/values-azb/strings.xml b/android-components/components/feature/readerview/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..6f89a979db92 --- /dev/null +++ b/android-components/components/feature/readerview/src/main/res/values-azb/strings.xml @@ -0,0 +1,29 @@ + + + + سریف‌سیز + + سریف‌سیز فونت + + سریف‌لی + + سریف‌لی فونت + + + فونت اؤلچوسونون آزالماسی + + + فونت اؤلچوسونون چوخالماسی + + قارانلیق + + قارانلیق رنگ طرحی + + تورپاق + + تورپاق رنگی طرحی + + آچیق + + آچیق رنگ طرحی + diff --git a/android-components/components/feature/search/src/main/res/values-azb/strings.xml b/android-components/components/feature/search/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..dad76ea236ad --- /dev/null +++ b/android-components/components/feature/search/src/main/res/values-azb/strings.xml @@ -0,0 +1,12 @@ + + + + + یئنی بیر %1$s تاغی آچین + + آختاریش + + وب‌ده آختار + + سس‌لی آختاریش + diff --git a/android-components/components/feature/search/src/main/res/values-ckb/strings.xml b/android-components/components/feature/search/src/main/res/values-ckb/strings.xml new file mode 100644 index 000000000000..4f31f2232fab --- /dev/null +++ b/android-components/components/feature/search/src/main/res/values-ckb/strings.xml @@ -0,0 +1,12 @@ + + + + + بازدەرێکی %1$sی نوێ بکەرەوە + + گەڕان + + بە وێبدا بگەڕێ + + گەڕانی دەنگی + diff --git a/android-components/components/feature/sitepermissions/src/main/res/values-azb/strings.xml b/android-components/components/feature/sitepermissions/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..26d646b79042 --- /dev/null +++ b/android-components/components/feature/sitepermissions/src/main/res/values-azb/strings.xml @@ -0,0 +1,48 @@ + + + + %1$s بیلدیریش گؤندره ‌بیلسین؟ + + %1$s کامئرازی ایشه آلسین؟ + + %1$s میکروفونوزو ایشه آلسین؟ + + %1$s قونوموزو ایشه آلسین؟ + + %1$s کامئرا و میکروفونوزو ایشه آلسین؟ + + میکروفون + + سلفی کامئرا + + قاباق کامئرا + + ایجازه وئر + + ایجازه وئرمه + + بو سایت اوچون قراری یاددا ساخلا + + هر زامان + + هئچ زامان + + %1$s قالیجی مخزنینده دیتا ساخلیا بیلسین؟ + + %1$s سایتی DRM-کونترول موحتوالاری اوینادا بیلسین؟ + + %1$s، کوکی‌لرینی %2$s سایتیندا ایشه آلسین؟ + + %s سایتینین بو دیتایا نیه احتیاج اولدوغونو بیلمیرسیز ال‌چاتمانی مسدود ائلیه بیلرسیز. + + مسدود ائله + + آرتیق بیلین + diff --git a/android-components/components/feature/tabs/src/main/res/values-azb/strings.xml b/android-components/components/feature/tabs/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..f9282d3cd0f6 --- /dev/null +++ b/android-components/components/feature/tabs/src/main/res/values-azb/strings.xml @@ -0,0 +1,5 @@ + + + + تاغ‌لار + diff --git a/android-components/components/feature/webnotifications/src/main/res/values-azb/strings.xml b/android-components/components/feature/webnotifications/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..42ea59b47780 --- /dev/null +++ b/android-components/components/feature/webnotifications/src/main/res/values-azb/strings.xml @@ -0,0 +1,5 @@ + + + + سایت بیلدیریش‌لری + diff --git a/android-components/components/lib/crash/src/main/res/values-azb/strings.xml b/android-components/components/lib/crash/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..f17a92f5a063 --- /dev/null +++ b/android-components/components/lib/crash/src/main/res/values-azb/strings.xml @@ -0,0 +1,42 @@ + + + + + باغیشلایین. %1$s موشکولونه اوزلشدی و سیندی. + + + سینماق راپورتونو %1$s -یه گؤندر + + + باغلا + + + %1$s اَپینی یئنی‌دن باشلات + + + سینماق‌لار + + + باغیشلایین، %1$s اپینده موشکول قاباغا گلدی. + + + راپورت + + + سینماق راپورتو %1$s-یا گؤندریلیر + + + سینماق دیتالاری یئغیلیر + + + سینماق تله‌متری دیتاسی یئغیلیر + + + سینماق راپورت‌لاری + + + هئچ بیر سینماق راپورتو گؤندیریلمه‌دی + + + پایلاش + diff --git a/android-components/components/service/nimbus/src/main/res/values-azb/strings.xml b/android-components/components/service/nimbus/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..47a749951b0a --- /dev/null +++ b/android-components/components/service/nimbus/src/main/res/values-azb/strings.xml @@ -0,0 +1,5 @@ + + + + بورادا تجروبه یوخدور + diff --git a/android-components/components/support/base/src/main/res/values-azb/strings.xml b/android-components/components/support/base/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..f30b03f0e7f6 --- /dev/null +++ b/android-components/components/support/base/src/main/res/values-azb/strings.xml @@ -0,0 +1,7 @@ + + + + تنظیم‌لره گئدین + + باغلا + diff --git a/android-components/components/support/ktx/src/main/res/values-azb/strings.xml b/android-components/components/support/ktx/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..af07dcca5bb3 --- /dev/null +++ b/android-components/components/support/ktx/src/main/res/values-azb/strings.xml @@ -0,0 +1,9 @@ + + + + … -دان تماس توت + + … ایله ایمیل یوللا + … ایله پایلاش + پایلاش + diff --git a/android-components/components/ui/tabcounter/src/main/res/values-azb/strings.xml b/android-components/components/ui/tabcounter/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..9f856c949a07 --- /dev/null +++ b/android-components/components/ui/tabcounter/src/main/res/values-azb/strings.xml @@ -0,0 +1,17 @@ + + + + آچیق تاغ. تاغ‌لاری دگیشدیرمک اوچون توخونون. + + %1$s آچیق تاغ. تاغلاری دگیشدیرمک اوچون توخونون. + + یئنی تاغ + + یئنی گیزلی تاغ + + تاغی باغلا + + تاغی ایکی‌له + + تاغ سایی‌جی‌نین تولبار دویمه‌سی. + diff --git a/android-components/components/ui/widgets/src/main/res/values-azb/strings.xml b/android-components/components/ui/widgets/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..706d6474591e --- /dev/null +++ b/android-components/components/ui/widgets/src/main/res/values-azb/strings.xml @@ -0,0 +1,5 @@ + + + + عکس کلیپ‌بوردا کوپی اولدو + diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..3e4cdcd3a9d5 --- /dev/null +++ b/fenix/app/src/main/res/values-azb/strings.xml @@ -0,0 +1,36 @@ + + + + گیزلی %s + + %s (گیزلی) + + + + + داها چوخ سئچه‌نک + + گیزلی مورورو گوجلندیر + + + + گیزلی مورورو گوجدن سال + + + + آختارین یا آدرسی گیرین + + وب‌ده آختارین + + + + مورور گئچمیشینده آختار + + بوکمارک‌دا آختار + + تاغ‌لاردا آختار + + + + + diff --git a/fenix/app/src/main/res/values-en-rGB/strings.xml b/fenix/app/src/main/res/values-en-rGB/strings.xml index a6c8cbcab86f..ea001e9be880 100644 --- a/fenix/app/src/main/res/values-en-rGB/strings.xml +++ b/fenix/app/src/main/res/values-en-rGB/strings.xml @@ -241,6 +241,7 @@ Customise homepage + Home screen @@ -248,6 +249,9 @@ Erase browsing history + + Translate page + Selected language @@ -259,8 +263,6 @@ Scan - - Search engine Search engine settings @@ -315,14 +317,14 @@ - Notifications help you do more with %s + Notifications help you do more with %s - Synchronise your tabs between devices, manage downloads, get tips about making the most of %s’s privacy protection, and more. + Synchronise your tabs between devices, manage downloads, get tips about making the most of %s’s privacy protection, and more. - Continue + Continue - Not now + Not now @@ -439,21 +441,11 @@ HTTPS-Only Mode - - Cookie Banner Reduction Cookie Banner Blocker Cookie Banner Blocker in private browsing - - Reduce cookie banners - - Off - - On - - - %1$s automatically tries to reject cookie requests on cookie banners. + Off for this site @@ -471,35 +463,16 @@ Site currently not supported - Turn on Cookie Banner Reduction for %1$s? - Turn on Cookie Banner Blocker for %1$s? - Turn off Cookie Banner Reduction for %1$s? - Turn off Cookie Banner Blocker for %1$s? %1$s can’t automatically reject cookie requests on this site. You can send a request to support this site in the future. - - %1$s will clear this site’s cookies and refresh the page. Clearing all cookies may sign you out or empty shopping carts. Turn off and %1$s will clear cookies and reload this site. This may sign you out or empty shopping carts. - %1$s tries to automatically reject all cookie requests on supported sites. - Turn on and %1$s will try to automatically refuse all cookie banners on this site. - - Allow %1$s to reject cookie banners? - - %1$s can automatically reject many cookie banner requests. - - Not Now - - You’ll see fewer cookie requests - - - Allow %1$s just refused cookies for you @@ -1283,8 +1256,6 @@ Dismiss - Unable to print - Unable to print this page Print @@ -1901,7 +1872,7 @@ Set up a device lock pattern, PIN, or password to protect your saved credit cards from being accessed if someone else has your device. - Set up a device lock pattern, PIN, or password to protect your saved cards from being accessed if someone else has your device. + Set up a device lock pattern, PIN, or password to protect your saved payment methods from being accessed if someone else has your device. Set up now @@ -2062,12 +2033,12 @@ Password options The editable text field for the web address of the login. - - The editable text field for the web site address of the password. + + The editable text field for the web site address. The editable text field for the username of the login. - - The editable text field for the username of the password. + + The editable text field for the username. The editable text field for the password of the login. @@ -2264,8 +2235,6 @@ Highlights are from %s reviews within the last 80 days that we believe to be reliable.]]> Learn more about %s. - - how %s by Mozilla determines review quality how %s determines review quality @@ -2449,6 +2418,8 @@ Translation in Progress + + Choose a language There was a problem translating. Please try again. diff --git a/fenix/app/src/main/res/values-hy-rAM/strings.xml b/fenix/app/src/main/res/values-hy-rAM/strings.xml index 033294777572..50cd8346f91e 100644 --- a/fenix/app/src/main/res/values-hy-rAM/strings.xml +++ b/fenix/app/src/main/res/values-hy-rAM/strings.xml @@ -242,6 +242,7 @@ Հարմարեցնել տնայինը + Հիմնական էկրան @@ -249,6 +250,9 @@ Ջնջել դիտարկման պատմությունը + + Թարգմանել էջը + Ընտրված լեզուն @@ -260,8 +264,6 @@ Սկանավորել - - Որոնիչ Որոնիչի կարգավորումներ @@ -315,14 +317,14 @@ - Ծանուցումներն օգնում են ձեզ ավելին անել %s-ի հետ + Ծանուցումներն օգնում են ձեզ ավելին անել %s-ի հետ - Համաժամացրեք ձեր ներդիրները սարքերի միջև, կառավարեք ներբեռնումները, ստացեք խորհուրդներ %s-ի գաղտնիության պաշտպանությունից առավելագույնս օգտագործելու մասին և այլն: + Համաժամացրեք ձեր ներդիրները սարքերի միջև, կառավարեք ներբեռնումները, ստացեք խորհուրդներ %s-ի գաղտնիության պաշտպանությունից առավելագույնս օգտագործելու մասին և այլն: - Շարունակել + Շարունակել - Ոչ հիմա + Ոչ հիմա @@ -439,21 +441,11 @@ HTTPS կերպ միայն - - Թխուկների դրոշակի կրճատում Թխուկների ազդերիզի արգելափակիչ Թխուկների ազդերիզի արգելափակիչ մասնավոր զննարկումում - - Նվազեցնել թխուկների պաստառները - - Անջ. - - Միաց. - - - %1$s-ն ինքնաբար փորձում է մերժել թխուկների հարցումները թխուկների ցուցանակների վրա: + Անջատված է այս կայքի համար @@ -471,35 +463,16 @@ Կայքը ներկայումս չի աջակցվում - Միացնե՞լ Cookie Banner կրճատումը %1$s-ի համար: - Միացնե՞լ Թխուկների ազդերիզի արգելափակիչը %1$s-ում: - Անջատե՞լ Cookie Banner կրճատումը %1$s-ի համար: - Անջատե՞լ Թխուկների ազդերիզի արգելափակիչը %1$s-ում: %1$s-ը չի կարող ինքնաշխատ մերժել թխուկների հարցումներն այս կայքում: Դուք կարող եք հարցում ուղարկել այս կայքին ապագայում աջակցելու համար: - - %1$s-ը կջնջի այս կայքի թխուկները և կթարմացնի էջը: Բոլոր թխուկները մաքրելը կարող է դուրս գրել Ձեզ կամ դատարկել գնումների զամբյուղները: Անջատեք և %1$s-ը կմաքրի թխուկները և կրկին կբեռնի այս կայքը: Դա կարող է ձեզ դուրս գրել կամ դատարկել գնումների զամբյուղը: - %1$s-ը փորձում է ինքնաբար մերժել թխուկների հարցումները աջակցվող կայքերում: - Միացրեք և %1$s-ը ինքնաբար կմերժի թխուկների բոլոր ազդերիզները այս կայքում: - - Թույլատրե՞լ %1$s-ին մերժել թխուկների պաստառները: - - %1$s-ը կարող է ինքնաբար մերժել թխուկների պաստառների հարցումները: - - Ոչ հիմա - - Դուք կտեսնեք ավելի քիչ թխուկների հարցումներ - - - Թույլատրել %1$s-ը հենց նոր մերժեց թխուկները ձեզ համար @@ -1284,8 +1257,6 @@ Բաց թողնել - Անհնար է տպել - Չհաջողվեց տպել այս էջը Տպել @@ -1905,7 +1876,7 @@ Տեղակայեք սարքի կողպման նախշ, PIN կամ գաղտնաբառ՝ պաշտպանելու պահված բանկային քարտերը այն դեպքում, եթե որևէ մեկը ևս մուտք ունի Ձեր սարքին: - Տեղակայեք սարքի կողպման նախշ, PIN կամ գաղտնաբառ՝ պաշտպանելու ձեր քարտերն այն դեպքում, եթե որևէ մեկը ևս մուտք ունենա Ձեր սարքին: + Տեղակայեք սարքի կողպման նախշ, PIN կամ գաղտնաբառ՝ պաշտպանելու ձեր քարտերն այն դեպքում, եթե որևէ մեկը ևս մուտք ունենա Ձեր սարքին: Տեղակայել հիմա @@ -2064,12 +2035,12 @@ Գաղտնաբառի ընտրանքներ Խմբագրելի տեքստի դաշտը մուտքի վեբ հասցեի համար: - - Խմբագրելի տեքստի դաշտ գաղտնաբառի վեբ հասցեի համար: + + Խմբագրելի տեքստի դաշտ կայքի հասցեի համար: Խմբագրելի տեքստի դաշտը մուտք գործողի համար: - - Խմբագրելի տեքստի դաշտ գաղտնաբառի օգտվողի համար: + + Խմբագրելի տեքստի դաշտ օգտվողի անվան համար: Խմբագրելի տեքստի դաշտը մուտքի գաղտնաբառի համար: @@ -2268,8 +2239,6 @@ Գունանշումները վերջին 80 օրվա ընթացքում %s կարծիքներից են, որոնք, մեր կարծիքով, հուսալի են:]]> Իմացեք ավելին %s-ի մասին: - - ինչպես %s-ը է Mozilla-ի կողմից որոշում կարծիքների որակը ինչպես է %s-ը որոշում կարծիքների որակը @@ -2454,6 +2423,8 @@ Թարգմանությունն ընթացքի մեջ է + + Ընտրեք լեզուն Թարգմանության հետ կապված խնդիր։ Կրկին փորձեք; diff --git a/fenix/app/src/main/res/values-sl/strings.xml b/fenix/app/src/main/res/values-sl/strings.xml index dcb16bbaad38..8f3a2ebfdc00 100644 --- a/fenix/app/src/main/res/values-sl/strings.xml +++ b/fenix/app/src/main/res/values-sl/strings.xml @@ -244,6 +244,7 @@ Prilagodi domačo stran + Domači zaslon @@ -251,6 +252,9 @@ Počisti zgodovino brskanja + + Prevedi stran + Izbrani jezik @@ -262,8 +266,6 @@ Skeniraj - - Iskalnik Nastavitve iskalnika @@ -318,14 +320,14 @@ - Obvestila vam pomagajo pri delu s programom %s + Obvestila vam pomagajo pri delu s programom %s - Sinhronizirajte zavihke med napravami, upravljajte prenose, pridobite nasvete za kar najboljši izkoristek %sovih zmožnosti in še več. + Sinhronizirajte zavihke med napravami, upravljajte prenose, pridobite nasvete za kar najboljši izkoristek %sovih zmožnosti in še več. - Nadaljuj + Nadaljuj - Ne zdaj + Ne zdaj @@ -443,20 +445,10 @@ Način "samo HTTPS" - - Zmanjšanje števila pasic s piškotki Zavračanje pasic s piškotki Zavračanje pasic s piškotki v zasebnem brskanju - - Zmanjšaj število pasic s piškotki - - Izključeno - - Vključeno - - %1$s poskuša samodejno zavrniti zahteve pasic po shranjevanju piškotkov. Izključeno na tem spletnem mestu @@ -474,35 +466,16 @@ Spletno mesto trenutno ni podprto - Vključim zmanjšanje števila pasic s piškotki za %1$s? - Vključim zavračanje pasic s piškotki za %1$s? - Izključim zmanjšanje števila pasic s piškotki za %1$s? - Izključim zavračanje pasic s piškotki za %1$s? %1$s na tem spletnem mestu ni mogel samodejno zavrniti zahtev za shranjevanje piškotkov. Pošljete lahko zahtevek, naj se v prihodnosti uvede podpora za to spletno mesto. - - %1$s bo počistil piškotke tega spletnega mesta in osvežil stran. Če počistite vse piškotke, boste morda odjavljeni ali se bo izpraznila vaša nakupovalna košarica. Izklopite in %1$s bo izbrisal piškotke ter znova naložil stran, kar vas lahko odjavi in izprazni vaš nakupovalni voziček. - %1$s poskuša samodejno zavrniti vse zahteve za shranjevanje piškotkov na spletnih mestih, ki so podprta. - Vklopite to možnost in %1$s bo skušal na tem spletnem mestu samodejno zavrniti pasice s piškotki. - - Dovolite %1$su, da zavrača pasice s piškotki? - - %1$s lahko samodejno zavrne številne zahteve za shranjevanje piškotkov. - - Ne zdaj - - Prikazovalo se vam bo manj zahtev za shranjevanje piškotkov - - - Dovoli %1$s je pravkar zavrnil piškotke v vašem imenu @@ -1297,8 +1270,6 @@ Zapri - Tiskanje ni mogoče - Te strani ni mogoče natisniti Natisni @@ -2049,12 +2020,8 @@ Možnosti gesel Besedilno polje za urejanje spletnega naslova prijave. - - Besedilno polje za urejanje naslova spletnega mesta, ki mu pripada geslo. Besedilno polje za urejanje uporabniškega imena prijave. - - Besedilno polje za urejanje uporabniškega imena, ki pripada geslu. Besedilno polje za urejanje gesla prijave. @@ -2252,8 +2219,6 @@ Poudarki so vzeti iz mnenj v trgovini %s v zadnjih 80 dneh, za katera menimo, da so zanesljiva.]]> Več o %s. - - kako Mozilla %s določa kakovost mnenj kako %s določa kakovost mnenj diff --git a/fenix/app/src/main/res/values-zh-rCN/strings.xml b/fenix/app/src/main/res/values-zh-rCN/strings.xml index 8da4b77f7e01..247d17f85b8b 100644 --- a/fenix/app/src/main/res/values-zh-rCN/strings.xml +++ b/fenix/app/src/main/res/values-zh-rCN/strings.xml @@ -2467,7 +2467,7 @@ 要翻译此页面吗? - 试用 %1$s 注重隐私的翻译功能 + 试试 %1$s 注重隐私的翻译功能 为保护隐私,翻译过程只会在本地进行。我们很快会支持更多语言并带来改进!%1$s From 7643cdbf0d67ecf58a6c71f4a4fa119cffd1c9b1 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Sat, 3 Feb 2024 13:20:27 +0000 Subject: [PATCH 055/586] Update GeckoView (Nightly) to 124.0.20240203092120. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index b6e2a318ae30..d46af461d2ce 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240202164508" + const val version = "124.0.20240203092120" /** * GeckoView channel From c3289072f6ed10ea83fc97e5fe2cd8cc825e3666 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Sat, 3 Feb 2024 05:20:53 +0000 Subject: [PATCH 056/586] Update A-S to 124.20240203050301. --- .../plugins/dependencies/src/main/java/ApplicationServices.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt index 2990706a87b4..b73afcae4026 100644 --- a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt +++ b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // These lines are generated by android-components/automation/application-services-nightly-bump.py -val VERSION = "124.20240202162153" +val VERSION = "124.20240203050301" val CHANNEL = ApplicationServicesChannel.NIGHTLY object ApplicationServicesConfig { From bc797f3a3384c3be48c22c6d0f3ebd54b47573e9 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 4 Feb 2024 00:03:39 +0000 Subject: [PATCH 057/586] Import translations from android-l10n --- .../addons/src/main/res/values-bs/strings.xml | 4 +- .../src/main/res/values-fur/strings.xml | 4 +- .../addons/src/main/res/values-tr/strings.xml | 4 +- .../addons/src/main/res/values-ug/strings.xml | 4 +- .../addons/src/main/res/values-vi/strings.xml | 2 + .../src/main/res/values-zh-rCN/strings.xml | 4 +- .../media/src/main/res/values-bs/strings.xml | 11 +++- .../media/src/main/res/values-fur/strings.xml | 11 +++- .../media/src/main/res/values-oc/strings.xml | 11 +++- .../media/src/main/res/values-tr/strings.xml | 11 +++- .../media/src/main/res/values-ug/strings.xml | 11 +++- .../media/src/main/res/values-vi/strings.xml | 11 +++- .../src/main/res/values-br/strings.xml | 31 ++++++++++ .../src/main/res/values-bs/strings.xml | 36 +++++++++++ .../src/main/res/values-fur/strings.xml | 36 +++++++++++ .../src/main/res/values-oc/strings.xml | 11 ++++ .../src/main/res/values-tr/strings.xml | 36 +++++++++++ .../src/main/res/values-ug/strings.xml | 36 +++++++++++ .../src/main/res/values-vi/strings.xml | 36 +++++++++++ fenix/app/src/main/res/values-br/strings.xml | 48 +++------------ fenix/app/src/main/res/values-bs/strings.xml | 58 +++++------------- fenix/app/src/main/res/values-fur/strings.xml | 16 +++-- fenix/app/src/main/res/values-oc/strings.xml | 6 ++ fenix/app/src/main/res/values-vi/strings.xml | 61 +++++-------------- .../src/main/res/values-zh-rCN/strings.xml | 22 +++---- 25 files changed, 353 insertions(+), 168 deletions(-) diff --git a/android-components/components/feature/addons/src/main/res/values-bs/strings.xml b/android-components/components/feature/addons/src/main/res/values-bs/strings.xml index a322af9cbef9..61fed10d22ff 100644 --- a/android-components/components/feature/addons/src/main/res/values-bs/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-bs/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Pristupite vašim podacima na %1$d drugih domena + + %1$s, %2$d od %3$d Pristup tabovima browsera @@ -75,7 +77,7 @@ Autor - Autori + Autori Zadnje ažuriranje diff --git a/android-components/components/feature/addons/src/main/res/values-fur/strings.xml b/android-components/components/feature/addons/src/main/res/values-fur/strings.xml index f896e865ef43..dd7b3d5fd757 100644 --- a/android-components/components/feature/addons/src/main/res/values-fur/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-fur/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Acedi ai tiei dâts su %1$d altris dominis + + %1$s, %2$d di %3$d Acedi aes schedis dal navigadôr @@ -75,7 +77,7 @@ Autôr - Autôrs + Autôrs Ultin inzornament diff --git a/android-components/components/feature/addons/src/main/res/values-tr/strings.xml b/android-components/components/feature/addons/src/main/res/values-tr/strings.xml index 56af53231529..58f296540fd1 100644 --- a/android-components/components/feature/addons/src/main/res/values-tr/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-tr/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> %1$d diğer alan adındaki verilerinize erişme + + %1$s, %2$d/%3$d Tarayıcı sekmelerine erişme @@ -75,7 +77,7 @@ Geliştiren - Yazarlar + Yazarlar Son güncelleme diff --git a/android-components/components/feature/addons/src/main/res/values-ug/strings.xml b/android-components/components/feature/addons/src/main/res/values-ug/strings.xml index da66b2131b8f..a86fdf69e740 100644 --- a/android-components/components/feature/addons/src/main/res/values-ug/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-ug/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> باشقا %1$d دائىرىدىكى سانلىق مەلۇماتلىرىڭىزنى زىيارەت قىلىدۇ + + %1$s، %2$d / %3$d توركۆرگۈ بەتكۈچلىرىنى زىيارەت قىلىش @@ -75,7 +77,7 @@ يازغۇچى - ئاپتورلار + ئاپتورلار ئاخىرقى قېتىم يېڭىلانغان diff --git a/android-components/components/feature/addons/src/main/res/values-vi/strings.xml b/android-components/components/feature/addons/src/main/res/values-vi/strings.xml index ef38cb5ebe88..a256a6172f0d 100644 --- a/android-components/components/feature/addons/src/main/res/values-vi/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-vi/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Truy cập dữ liệu của bạn trên %1$d tên miền khác + + %1$s, %2$d của %3$d Truy cập các thẻ trên trình duyệt diff --git a/android-components/components/feature/addons/src/main/res/values-zh-rCN/strings.xml b/android-components/components/feature/addons/src/main/res/values-zh-rCN/strings.xml index 6c703f50c6d6..a0b6ca60deae 100644 --- a/android-components/components/feature/addons/src/main/res/values-zh-rCN/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-zh-rCN/strings.xml @@ -35,7 +35,7 @@ 读取和修改浏览器设置 - 清除最近的浏览记录、Cookie 及有关数据 + 清除最近的浏览历史、Cookie 及有关数据 获取剪贴板数据 @@ -43,7 +43,7 @@ 拦截任何页面上的内容 - 读取您的浏览记录 + 读取您的浏览历史 下载文件和读写浏览器的下载历史 diff --git a/android-components/components/feature/media/src/main/res/values-bs/strings.xml b/android-components/components/feature/media/src/main/res/values-bs/strings.xml index fed237d81e38..25f1b10a39c6 100644 --- a/android-components/components/feature/media/src/main/res/values-bs/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-bs/strings.xml @@ -1,5 +1,5 @@ - + Mediji @@ -21,9 +21,14 @@ Podsjetnik: %1$s još uvijek koristi vašu kameru. Dodirnite da otvorite tab. - Podsjetnik: %1$s još uvijek koristi vaš mikrofon. Dodirnite da otvorite tab + Podsjetnik: %1$s još uvijek koristi vaš mikrofon. Dodirnite da otvorite tab + + Podsjetnik: %1$s još uvijek koristi vaš mikrofon. Dodirnite da otvorite tab. + + Podsjetnik: %1$s još uvijek koristi vaš mikrofon i kameru. Dodirnite da otvorite tab + - Podsjetnik: %1$s još uvijek koristi vaš mikrofon i kameru. Dodirnite da otvorite tab + Podsjetnik: %1$s još uvijek koristi vaš mikrofon i kameru. Dodirnite da otvorite tab. Pokreni diff --git a/android-components/components/feature/media/src/main/res/values-fur/strings.xml b/android-components/components/feature/media/src/main/res/values-fur/strings.xml index 5c5bcf667db1..898cc3292c71 100644 --- a/android-components/components/feature/media/src/main/res/values-fur/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-fur/strings.xml @@ -1,5 +1,5 @@ - + Multimedia @@ -21,9 +21,14 @@ Promemoria: %1$s al sta ancjemò doprant la fotocjamare. Tocje parvierzi la schede. - Promemoria: %1$s al sta ancjemò doprant il microfon. Tocje par vierzi la schede + Promemoria: %1$s al sta ancjemò doprant il microfon. Tocje par vierzi la schede + + Pro memoria: %1$s al sta ancjemò doprant il to microfon. Tocje par vierzi la schede. + + Promemoria: %1$s al sta ancjemò doprant il microfon e la fotocjamare. Tocje par vierzi la schede + - Promemoria: %1$s al sta ancjemò doprant il microfon e la fotocjamare. Tocje par vierzi la schede + Pro memoria: %1$s al sta ancjemò doprant il microfon e la fotocjamare. Tocje par vierzi la schede. Riprodûs diff --git a/android-components/components/feature/media/src/main/res/values-oc/strings.xml b/android-components/components/feature/media/src/main/res/values-oc/strings.xml index c64cb1f97ab0..4d177d34e226 100644 --- a/android-components/components/feature/media/src/main/res/values-oc/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-oc/strings.xml @@ -1,5 +1,5 @@ - + Mèdias @@ -21,9 +21,14 @@ Rapèl : %1$s utiliza encara la camèra. Tocatz per dobrir l’onglet. - Rapèl : %1$s utiliza encara lo microfòn. Tocatz per dobrir l’onglet. + Rapèl : %1$s utiliza encara lo microfòn. Tocatz per dobrir l’onglet. + + Rapèl : %1$s utiliza encara lo microfòn. Tocatz per dobrir l’onglet. + + Rapèl : %1$s utiliza encara la camèra e lo microfòn. Tocatz per dobrir l’onglet. + - Rapèl : %1$s utiliza encara la camèra e lo microfòn. Tocatz per dobrir l’onglet. + Rapèl : %1$s utiliza encara la camèra e lo microfòn. Tocatz per dobrir l’onglet. Lectura diff --git a/android-components/components/feature/media/src/main/res/values-tr/strings.xml b/android-components/components/feature/media/src/main/res/values-tr/strings.xml index 7367471e9226..c137298b46db 100644 --- a/android-components/components/feature/media/src/main/res/values-tr/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-tr/strings.xml @@ -1,5 +1,5 @@ - + Ortam @@ -21,9 +21,14 @@ Anımsatıcı: %1$s hâlâ kameranızı kullanıyor. Sekmeyi açmak için dokunun. - Anımsatma: %1$s hâlâ mikrofonunuzu kullanıyor. Sekmeyi açmak için dokunun. + Anımsatma: %1$s hâlâ mikrofonunuzu kullanıyor. Sekmeyi açmak için dokunun. + + Anımsatma: %1$s hâlâ mikrofonunuzu kullanıyor. Sekmeyi açmak için dokunun. + + Anımsatma: %1$s hâlâ mikrofonunuzu ve kameranızı kullanıyor. Sekmeyi açmak için dokunun. + - Anımsatma: %1$s hâlâ mikrofonunuzu ve kameranızı kullanıyor. Sekmeyi açmak için dokunun. + Anımsatma: %1$s hâlâ mikrofonunuzu ve kameranızı kullanıyor. Sekmeyi açmak için dokunun. Oynat diff --git a/android-components/components/feature/media/src/main/res/values-ug/strings.xml b/android-components/components/feature/media/src/main/res/values-ug/strings.xml index 20c318a0a8a3..87924ebdc342 100644 --- a/android-components/components/feature/media/src/main/res/values-ug/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-ug/strings.xml @@ -1,5 +1,5 @@ - + ۋاسىتە @@ -22,9 +22,14 @@ ئەسكەرتىش: %1$s كامېرايىڭىزنى ئىشلىتىۋاتىدۇ. چېكىلسە بەتكۈچنى ئاچىدۇ. - ئەسكەرتىش: %1$s مېكروفونىڭىزنى ئىشلىتىۋاتىدۇ. چېكىلسە بەتكۈچنى ئاچىدۇ + ئەسكەرتىش: %1$s مېكروفونىڭىزنى ئىشلىتىۋاتىدۇ. چېكىلسە بەتكۈچنى ئاچىدۇ + + ئەسكەرتىش: %1$s مېكروفونىڭىزنى ئىشلىتىۋاتىدۇ. چېكىلسە بەتكۈچنى ئاچىدۇ. + + ئەسكەرتىش: %1$s مېكروفون ۋە كامېرايىڭىزنى ئىشلىتىۋاتىدۇ. چېكىلسە بەتكۈچنى ئاچىدۇ + - ئەسكەرتىش: %1$s مېكروفون ۋە كامېرايىڭىزنى ئىشلىتىۋاتىدۇ. چېكىلسە بەتكۈچنى ئاچىدۇ + ئەسكەرتىش: %1$s مېكروفون ۋە كامېرايىڭىزنى ئىشلىتىۋاتىدۇ. چېكىلسە بەتكۈچنى ئاچىدۇ. باشلاش diff --git a/android-components/components/feature/media/src/main/res/values-vi/strings.xml b/android-components/components/feature/media/src/main/res/values-vi/strings.xml index 14b1781b0f39..7fa420995ff2 100644 --- a/android-components/components/feature/media/src/main/res/values-vi/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-vi/strings.xml @@ -1,5 +1,5 @@ - + Đa phương tiện @@ -21,9 +21,14 @@ Lời nhắc: %1$s vẫn đang sử dụng máy ảnh của bạn. Nhấn để mở thẻ. - Lời nhắc: %1$s vẫn đang sử dụng micrô của bạn. Nhấn để mở thẻ + Nhắc nhở: %1$s vẫn đang sử dụng micrô của bạn. Nhấn để mở thẻ + + Nhắc nhở: %1$s vẫn đang sử dụng micrô của bạn. Chạm để mở thẻ. + + Nhắc nhở: %1$s vẫn đang sử dụng micrô và máy ảnh của bạn. Nhấn để mở thẻ + - Lời nhắc: %1$s vẫn đang sử dụng micrô và máy ảnh của bạn. Nhấn để mở thẻ + Nhăc nhở: %1$s vẫn đang sử dụng micrô và máy ảnh của bạn. Chạm để mở thẻ. Phát diff --git a/android-components/components/feature/prompts/src/main/res/values-br/strings.xml b/android-components/components/feature/prompts/src/main/res/values-br/strings.xml index ed73b5459395..ee0603602917 100644 --- a/android-components/components/feature/prompts/src/main/res/values-br/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-br/strings.xml @@ -18,6 +18,8 @@ Ger-tremen Na enrollañ + + Diwezhatoc’h Na enrollañ biken @@ -26,16 +28,26 @@ Enrollañ Na hizivaat + + Diwezhatoc’h Hizivaat Ar vaezienn ger-tremen a rank bezañ leuniet + Enankit ur ger-tremen + Ne cʼhaller ket enrollañ an titour kennaskañ + + N’haller ket enrollañ ar ger-tremen Enrollañ an titour kennaskañ-mañ? + + Enrollañ ar ger-tremen? Hizivaat an titour kennaskañ-mañ? + + Hizivaat ar ger-tremen? Ouzhpennañ an anv arveriad dʼar gerioù-tremen enrollet? @@ -85,13 +97,22 @@ Dibab an eur Ardoer titouroù kennaskañ + + Merañ ar gerioù-tremen Brasaat an titouroù kennaskañ aliet + + Dispakañ ar gerioù-tremen enrollet Berraat an titouroù kennaskañ aliet + + Kuzhat ar gerioù-tremen enrollet Titouroù kennaskañ aliet + + Gerioù-tremen enrollet + Kas roadennoù en-dro d’al lec’hienn? Azbevaat ar bajenn a c’hallfe eilañ ar gweredoù nevez, evel kas ur paeamant pe embann un evezhiadenn div wech. @@ -105,11 +126,17 @@ Diuzañ ur gartenn gred Astenn ar cʼhartennoù kred kinniget + + Dispakañ ar c’hartennoù enrollet Bihanaat ar cʼhartennoù kred kinniget + + Kuzhat ar c’hartennoù enrollet Merañ ar cʼhartennoù kred + + Merañ ar c’hartennoù Enrollañ ar gartenn-mañ en surentez? @@ -122,8 +149,12 @@ Dibab ur chomlec’h Displegañ ar chomlec’hioù kinniget + + Dispakañ ar chomlec’hioù enrollet Plegañ ar chomlec’hioù kinniget + + Kuzhat ar chomlec’hioù enrollet Merañ ar chomlec’hioù diff --git a/android-components/components/feature/prompts/src/main/res/values-bs/strings.xml b/android-components/components/feature/prompts/src/main/res/values-bs/strings.xml index 9c38315d8e15..d43b77b4a059 100644 --- a/android-components/components/feature/prompts/src/main/res/values-bs/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-bs/strings.xml @@ -18,6 +18,8 @@ Lozinka Nemoj spasiti + + Ne sada Nikad ne spašavaj @@ -26,16 +28,26 @@ Spasi Nemoj ažurirati + + Ne sada Ažuriraj Polje za lozinku ne smije biti prazno + Unesite lozinku + Ne mogu spasiti prijavu + + Nije moguće sačuvati lozinku Spasi ovu prijavu? + + Sačuvati lozinku? Ažurirati ovu prijavu? + + Ažurirati lozinku? Dodaj korisničko ime uz sačuvanu lozinku? @@ -85,13 +97,22 @@ Postavi vrijeme Upravljanje prijavama + + Upravljajte lozinkama Proširi predložene prijave + + Proširi sačuvane lozinke Sažmi predložene prijave + + Sažmi sačuvane lozinke Predložene prijave + + Sačuvane lozinke + Predloži jaku lozinku @@ -110,12 +131,20 @@ Odaberite kreditnu karticu + + Koristi sačuvanu karticu Proširite predložene kreditne kartice + + Proširi sačuvane kartice Sažmi predložene kreditne kartice + + Sažmi sačuvane kartice Upravljaj kreditnim karticama + + Upravljajte karticama Sigurno sačuvati ovu karticu? @@ -123,13 +152,20 @@ Broj kartice će biti šifrovan. Sigurnosni kod neće biti sačuvan. + + %s šifruje broj vaše kartice. Vaš sigurnosni kod neće biti sačuvan. + Odaberi adresu Proširite predložene adrese + + Proširi sačuvane adrese Sažmi predložene adrese + + Sažmi sačuvane adrese Upravljaj adresama diff --git a/android-components/components/feature/prompts/src/main/res/values-fur/strings.xml b/android-components/components/feature/prompts/src/main/res/values-fur/strings.xml index 6ecf0083f6f6..0e81b65ce855 100644 --- a/android-components/components/feature/prompts/src/main/res/values-fur/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-fur/strings.xml @@ -18,6 +18,8 @@ Password No sta salvâ + + No cumò No sta salvâ mai @@ -26,17 +28,27 @@ Salve No sta inzornâ + + No cumò Inzorne Il cjamp de password nol à di sei vueit + Inserìs une password + Impussibil salvâ lis credenziâls + + Impussibil salvâ la password Salvâ cheste credenziâl? + + Salvâ la password? Inzornâ cheste credenziâl? + + Inzornâ la password? Zontâ il non utent ae password salvade? @@ -87,13 +99,22 @@ Gjestìs credenziâls + + Gjestìs passwords Slargje lis credenziâls sugjeridis + + Slargje lis passwords salvadis Comprim lis credenziâls sugjeridis + + Strenç lis passwords salvadis Credenziâls sugjeridis + + Passwords salvadis + Sugjerìs password complesse @@ -112,13 +133,21 @@ Selezione cjarte di credit + + Dopre cjarte salvade Slargje la liste des cjartis di credit sugjeridis + + Slargje lis cjartis salvadis Comprim la liste des cjartis di credit sugjeridis + + Strenç lis cjartis salvadis Gjestìs cjartis di credit + + Gjestìs cjartis Salvâ cheste cjarte in maniere sigure? @@ -126,13 +155,20 @@ Il numar de cjarte al sarà cifrât. Il codiç di sigurece nol vignarà salvât. + + %s al cifre il numar de tô cjarte. Il codiç di sigurece nol vignarà salvât. + Selezione recapit Slargje i recapits sugjerîts + + Slargje lis direzions salvadis Comprim recapits sugjerîts + + Strenç lis direzions salvadis Gjestìs recapits diff --git a/android-components/components/feature/prompts/src/main/res/values-oc/strings.xml b/android-components/components/feature/prompts/src/main/res/values-oc/strings.xml index 4de8003601d7..f835c12ef6e7 100644 --- a/android-components/components/feature/prompts/src/main/res/values-oc/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-oc/strings.xml @@ -135,8 +135,12 @@ Utilizar una carta enregistrada Espandir las cartas de crèdit suggeridas + + Desplegar las cartas enregistradas Plegar las cartas de crèdit suggeridas + + Plegar las cartas enregistradas Gerir las cartas de crèdit @@ -148,13 +152,20 @@ Los numèros de carta son chifrats. Se gardarà pas lo còdi de seguretat. + + %s chifra lo numèro de carta. Lo còdi de seguretat s’enregistrarà pas. + Seleccion d’adreça Espandir las adreças suggeridas + + Desplegar las adreças enregistradas Plegar las adreças suggeridas + + Plegar las adreças enregistradas Gestion de las adreças diff --git a/android-components/components/feature/prompts/src/main/res/values-tr/strings.xml b/android-components/components/feature/prompts/src/main/res/values-tr/strings.xml index 47886dde28cc..868387a03497 100644 --- a/android-components/components/feature/prompts/src/main/res/values-tr/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-tr/strings.xml @@ -18,6 +18,8 @@ Parola Kaydetme + + Şimdi değil Asla kaydetme @@ -26,16 +28,26 @@ Kaydet Güncelleme + + Şimdi değil Güncelle Parola alanı boş olmamalıdır + Parola girin + Hesap kaydedilemedi + + Parola kaydedilemedi Bu hesap kaydedilsin mi? + + Parola kaydedilsin mi? Bu hesap güncellensin mi? + + Parola güncellensin mi? Kayıtlı parolaya kullanıcı adı eklensin mi? @@ -85,13 +97,22 @@ Zamanı ayarla Hesapları yönet + + Parolaları yönet Önerilen hesapları genişlet + + Kayıtlı parolaları genişlet Önerilen hesapları daralt + + Kayıtlı parolaları daralt Önerilen hesaplar + + Kayıtlı parolalar + Güçlü parola öner @@ -110,12 +131,20 @@ Kredi kartı seç + + Kayıtlı kartı kullan Önerilen kredi kartlarını genişlet + + Kayıtlı kartları genişlet Önerilen kredi kartlarını daralt + + Kayıtlı kartları daralt Kredi kartlarını yönet + + Kartları yönet Bu kart güvenli bir şekilde kaydedilsin mi? @@ -123,13 +152,20 @@ Kart numarası şifrelenecektir. Güvenlik kodu kaydedilmeyecektir. + + %s kart numaranızı şifreler. Güvenlik kodunuz kaydedilmez. + Adres seçin Önerilen adresleri genişlet + + Kayıtlı adresleri genişlet Önerilen adresleri daralt + + Kayıtlı adresleri daralt Adresleri yönet diff --git a/android-components/components/feature/prompts/src/main/res/values-ug/strings.xml b/android-components/components/feature/prompts/src/main/res/values-ug/strings.xml index ecc8b100ee21..e04458982280 100644 --- a/android-components/components/feature/prompts/src/main/res/values-ug/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-ug/strings.xml @@ -18,6 +18,8 @@ پارول ساقلىما + + ھازىر ئەمەس ھەرگىز ساقلىما @@ -26,16 +28,26 @@ ساقلا يېڭىلانمىسۇن + + ھازىر ئەمەس يېڭىلاش ئىم بۆلىكى بوش قالمايدۇ + ئىم كىرگۈزۈلىدۇ + كىرىش ئۇچۇرىنى ساقلىيالمايدۇ + + ئىم ساقلىيالمايدۇ بۇ كىرىشنى ساقلامدۇ؟ + + ئىم ساقلامدۇ؟ بۇ كىرىشنى يېڭىلامدۇ؟ + + ئىم يېڭىلامدۇ؟ ساقلانغان ئىمغا ئىشلەتكۈچى ئاتىنى قوشامدۇ؟ @@ -87,13 +99,22 @@ ۋاقىت تەڭشىكى كىرىشنى باشقۇرۇش + + ئىم باشقۇرۇش تەۋسىيە كىرىشنى كېڭەيتىدۇ + + ساقلىغان ئىمنى ياي تەۋسىيە كىرىشنى يىغ + + ساقلىغان ئىمنى يىغ تەۋسىيە كىرىش + + ساقلانغان ئىم + كۈچلۈك ئىم تەۋسىيە قىلىنىدۇ @@ -112,12 +133,20 @@ ئىناۋەتلىك كارتا تاللىنىدۇ + + ساقلانغان كارتىنى ئىشلەت تەۋسىيە قىلىنغان ئىناۋەتلىك كارتىنى كېڭەيتىدۇ + + ساقلانغان كارتىنى ياي تەۋسىيە قىلىنغان ئىناۋەتلىك كارتىنى يىغىدۇ + + ساقلانغان كارتىنى يىغ ئىناۋەتلىك كارتا باشقۇرۇش + + كارتا باشقۇرۇش بۇ كارتىنى بىخەتەر ساقلامدۇ؟ @@ -125,14 +154,21 @@ كارتا نومۇرى شىفىرلىنىدۇ. بىخەتەرلىك كودى ساقلانمايدۇ. + + %s كارتا نومۇرىڭىزنى شىفىرلايدۇ. بىخەتەرلىك كودىڭىز ساقلانمايدۇ. + ئادرېس تاللىنىدۇ تەۋسىيە ئادرېسنى كېڭەيتىدۇ + + ساقلانغان ئادرېسنى ياي تەۋسىيە ئادرېسنى يىغىدۇ + + ساقلانغان ئادرېسنى يىغ ئادرېس باشقۇرۇش diff --git a/android-components/components/feature/prompts/src/main/res/values-vi/strings.xml b/android-components/components/feature/prompts/src/main/res/values-vi/strings.xml index 68ab4c460ad6..c3ade7b30b57 100644 --- a/android-components/components/feature/prompts/src/main/res/values-vi/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-vi/strings.xml @@ -18,6 +18,8 @@ Mật khẩu Không lưu + + Không phải bây giờ Không bao giờ lưu @@ -26,16 +28,26 @@ Lưu Đừng cập nhật + + Không phải bây giờ Cập nhật Trường mật khẩu không được để trống + Nhập mật khẩu + Không thể lưu thông tin đăng nhập + + Không thể lưu mật khẩu Lưu thông tin đăng nhập này? + + Lưu mật khẩu? Cập nhật thông tin đăng nhập này? + + Cập nhật lại mật khẩu? Thêm tên người dùng vào mật khẩu đã lưu? @@ -85,13 +97,22 @@ Cài đặt thời gian Quản lý đăng nhập + + Quản lý mật khẩu Mở rộng thông tin đăng nhập được đề xuất + + Mở rộng mật khẩu đã lưu Thu gọn thông tin đăng nhập được đề xuất + + Thu gọn mật khẩu đã lưu Thông tin đăng nhập được đề xuất + + Mật khẩu đã lưu + Đề xuất mật khẩu mạnh @@ -110,12 +131,20 @@ Chọn thẻ tín dụng + + Sử dụng thẻ đã lưu Mở rộng thẻ tín dụng được đề xuất + + Mở rộng thẻ đã lưu Thu gọn thẻ tín dụng được đề xuất + + Thu gọn thẻ đã lưu Quản lý thẻ tín dụng + + Quản lý thẻ tín dụng Lưu thẻ này một cách an toàn? @@ -123,13 +152,20 @@ Số thẻ sẽ được mã hóa. Mã bảo mật sẽ không được lưu. + + %s mã hóa số thẻ của bạn. Mã bảo mật của bạn sẽ không được lưu. + Chọn địa chỉ Mở rộng các địa chỉ được đề xuất + + Mở rộng địa chỉ đã lưu Thu gọn các địa chỉ được đề xuất + + Thu gọn địa chỉ đã lưu Quản lý địa chỉ diff --git a/fenix/app/src/main/res/values-br/strings.xml b/fenix/app/src/main/res/values-br/strings.xml index 25c988085dab..f9fc661f16f4 100644 --- a/fenix/app/src/main/res/values-br/strings.xml +++ b/fenix/app/src/main/res/values-br/strings.xml @@ -230,6 +230,7 @@ Personelaat an degemer + Skramm degemer @@ -237,6 +238,9 @@ Skarzhañ ar roll istor + + Treiñ ar bajenn + Yezh dibabet @@ -248,8 +252,6 @@ Cʼhwilerviñ - - Lusker enklask Arventennoù al lusker klask @@ -302,14 +304,14 @@ - Gant ar rebuzadurioù e c’hallit ober muioc’h a draoù gant %s + Gant ar rebuzadurioù e c’hallit ober muioc’h a draoù gant %s - Goubredit hoc’h ivinelloù etre ho trevnadoù, merit ho pellgargadurioù, lennit alioù evit tapout seizh gwellañ gwarez buhez prevez %s ha muioc’h c’hoazh. + Goubredit hoc’h ivinelloù etre ho trevnadoù, merit ho pellgargadurioù, lennit alioù evit tapout seizh gwellañ gwarez buhez prevez %s ha muioc’h c’hoazh. - Kenderc’hel + Kenderc’hel - Ket bremañ + Ket bremañ @@ -399,17 +401,6 @@ Mod HTTPS-hepken - - Bihanadur banniel an toupinoù - - Bihanaat banniel an toupinoù - - - Diweredekaet - - Gweredekaet - - %1$s a glask nac’hañ ar goulennoù toupinoù ent emgefreek pa vez skrammet ur banniel toupinoù. Diweredekaet evit al lec’hienn-mañ @@ -426,28 +417,9 @@ Goulenn skor kaset N’eo ket skoret al lec’hienn-mañ c’hoazh - - Gweredekaat bihanaat banniel an toupinoù evit %1$s? - - Diweredekaat bihanaat banniel an toupinoù evit %1$s? %1$s n’hall ket nac’hañ ar goulennoù toupinoù war al lec’hienn-mañ. Gallout a rit goulenn e vefe skoret al lec’hienn-mañ en dazont. - - %1$s a skarzho toupinoù al lec’hienn-mañ hag adkargañ a raio ar bajenn. Skarzhañ an holl doupinoù a c’hallfe digennaskañ ac’hanoc’h pe goullonderiñ ho panerioù. - - %1$s a c’hall klask nac’hañ ent emgefreek ar goulennoù toupinoù war al lec’hiennoù skoret. - - Aotren %1$s da nac’hañ ar goulennoù toupinoù? - - %1$s a c’hall nac’hañ ent emgefreek goulennoù ar bannieloù toupinoù. - - Ket bremañ - - Nebeutoc’h a c’houlennoù toupinoù a vo gwelet ganeoc’h - - Aotren - Klask kennaskañ ent emgefreek gant ar c’homenad HTTPS evit muioc’h a surentez. @@ -1211,8 +1183,6 @@ Argas - N’haller ket moullañ - N’haller ket moullañ ar bajenn-mañ Moullañ @@ -2139,8 +2109,6 @@ Penaos e termenomp perzhded an alioù Gouzout muioc’h diwar-benn %s. - - penaos e termen %s gant Mozilla perzhded an alioù penaos e vez priziet perzhded an alioù gant %s diff --git a/fenix/app/src/main/res/values-bs/strings.xml b/fenix/app/src/main/res/values-bs/strings.xml index 777059a7bba8..819e7f7a9700 100644 --- a/fenix/app/src/main/res/values-bs/strings.xml +++ b/fenix/app/src/main/res/values-bs/strings.xml @@ -235,12 +235,16 @@ Uredi Prilagodi početnu stranicu + Početni ekran Izbriši historiju pretraživanja + + Prevedi stranicu + Izabrani jezik @@ -253,8 +257,6 @@ Skeniraj - - Pretraživač Postavke pretraživača @@ -304,14 +306,14 @@ - Obavještenja vam pomažu da učinite više sa %s + Obavještenja vam pomažu da učinite više sa %s - Sinhronizujte svoje tabove između uređaja, upravljajte preuzimanjima, primajte savjete o tome kako maksimalno iskoristiti %s zaštitu privatnosti i još mnogo toga. + Sinhronizujte svoje tabove između uređaja, upravljajte preuzimanjima, primajte savjete o tome kako maksimalno iskoristiti %s zaštitu privatnosti i još mnogo toga. - Nastavi + Nastavi - Ne sada + Ne sada @@ -430,20 +432,10 @@ Način rada samo za HTTPS - - Smanjivanje pojavljivanja dijaloga kolačića Blokiranje pojavljivanja dijaloga kolačića Smanjivanje pojavljivanja dijaloga kolačića u privatnom pretraživanju - - Smanji pojavljivanje dijaloga kolačića - - Isključeno - - Uključeno - - %1$s automatski pokušava odbiti zahtjeve za kolačiće na dijalozima kolačića. Isključeno za ovu stranicu @@ -461,34 +453,16 @@ Stranica trenutno nije podržana - Uključiti smanjenje dijaloga kolačića za %1$s? - Uključiti blokiranje dijaloga kolačića za %1$s? - Isključiti smanjenje dijaloga kolačića za %1$s? - Isključiti blokiranje dijaloga kolačića za %1$s? %1$s ne može automatski odbiti zahtjeve za kolačiće na ovoj stranici. Možete poslati zahtjev za podršku ovoj stranici u budućnosti. - %1$s će očistiti kolačiće ove stranice i osvježiti stranicu. Čišćenje svih kolačića može vas odjaviti ili isprazniti kolica za kupovinu. - Isključite i %1$s će očistiti kolačiće i ponovo učitati ovu stranicu. Ovo vas može odjaviti ili isprazniti korpe za kupovinu. - %1$s pokušava automatski odbiti sve zahtjeve za kolačiće na podržanim web stranicama. - Uključite i %1$s će pokušati automatski odbiti sve banere kolačića na ovoj stranici. - - Dozvoliti %1$s da odbije banere kolačića? - - %1$s može automatski odbiti mnoge zahtjeve za kolačićima. - - Ne sada - - Vidjet ćete manje zahtjeva za kolačiće - - Dozvoli %1$s je upravo odbio kolačiće umjesto vas @@ -1266,8 +1240,6 @@ Odbaci - Nije moguće štampati - Nije moguće štampati ovu stranicu Štampaj @@ -1884,7 +1856,7 @@ Postavite obrazac za zaključavanje uređaja, PIN ili lozinku da zaštitite svoje sačuvane kreditne kartice od pristupa ako neko drugi ima vaš uređaj. - Postavite obrazac za zaključavanje uređaja, PIN ili lozinku da zaštitite svoje sačuvane kartice od pristupa ako neko drugi ima vaš uređaj. + Postavite obrazac za zaključavanje uređaja, PIN ili lozinku da zaštitite sačuvane načine plaćanja od pristupa ako neko drugi ima vaš uređaj. Podesi odmah @@ -2044,12 +2016,12 @@ Opcije lozinke Izmjenjivo tekstualno polje za web adresu prijave. - - Tekstualno polje koje se može uređivati za adresu web stranice lozinke. + + Tekstualno polje koje se može uređivati za adresu web stranice. Izmjenjivo tekstualno polje za korisničko ime prijave. - - Tekstualno polje koje se može uređivati za korisničko ime lozinke. + + Tekstualno polje koje se može uređivati za korisničko ime. Izmjenjivo tekstualno polje za lozinku prijave. @@ -2244,8 +2216,6 @@ Saznajte više o %su. - - kako %s od Mozilla određuje kvalitet recenzije kako %s određuje kvalitet recenzije @@ -2430,6 +2400,8 @@ Prevođenje u toku + + Odaberi jezik Došlo je do problema pri prevođenju. Molimo pokušajte ponovo. diff --git a/fenix/app/src/main/res/values-fur/strings.xml b/fenix/app/src/main/res/values-fur/strings.xml index 94313f628586..c01770abef49 100644 --- a/fenix/app/src/main/res/values-fur/strings.xml +++ b/fenix/app/src/main/res/values-fur/strings.xml @@ -242,6 +242,7 @@ Modifiche Personalize pagjine iniziâl + Schermade principâl @@ -249,6 +250,9 @@ Scancele la cronologjie di navigazion + + Tradûs pagjine + Lenghe selezionade @@ -1879,7 +1883,7 @@ Configure une secuence di bloc, PIN o password par protezi lis tôs cjartis di credit salvadis, cussì che se cualchidun altri al varà il to dispositîf nol rivarà a doprâlis. - Configure une secuence di bloc, PIN o password par protezi lis tôs cjartis salvadis, cussì che se cualchidun altri al varà il to dispositîf nol rivarà a doprâlis. + Configure une secuence di bloc, PIN o password par protezi i tiei metodis di paiament salvâts, cussì che se cualchidun altri al varà il to dispositîf nol rivarà a doprâju. Configure cumò @@ -2038,12 +2042,12 @@ Opzions password Il cjamp di test modificabil pe direzion web de credenziâl. - - Il cjamp di test che si pues modificâ pe direzion dal sît web de password. + + Il cjamp di test che si pues modificâ pe direzion dal sît web. Il cjamp di test modificabil pal non utent de credenziâl. - - Il cjamp di test che si pues modificâ pal non utent de password. + + Il cjamp di test che si pues modificâ pal non utent. Il cjamp di test modificabil pe password de credenziâl. @@ -2426,6 +2430,8 @@ Traduzion in cors + + Sielç une lenghe Al è vignût fûr un probleme tal tradusi. Torne prove. diff --git a/fenix/app/src/main/res/values-oc/strings.xml b/fenix/app/src/main/res/values-oc/strings.xml index 8e8f92aa1375..25873903b86e 100644 --- a/fenix/app/src/main/res/values-oc/strings.xml +++ b/fenix/app/src/main/res/values-oc/strings.xml @@ -1913,6 +1913,8 @@ Securizatz los metòdes de pagament enregistrats Configuratz un esquèma de verrolhatge, un còdi PIN o un senhal per protegir vòstres identificants de cartas de crèdit enregistrats se per cas qualqu’un accedisca a vòstre periferic. + + Configuratz un esquèma de desverrolhatge, un còdi PIN o un senhal per protegir vòstres mejans de pagament se per cas qualqu’un accedisca a vòstre aparelh. Configurar ara @@ -2077,8 +2079,12 @@ Exemple :\nhttps://suggestqueries.google.com/complete/search?client=firefox& Opcions de senhal Lo camp de tèxt modificable per l’adreça web de l’identificant. + + Lo camp de tèxt modificable per l’adreça del site web. Lo camp de tèxt modificable pel nom d’utilizaire de l’identificant. + + Lo camp de tèxt modificable pel nom d’utilizaire. Lo camp de tèxt modificable pel senhal de l’identificant. diff --git a/fenix/app/src/main/res/values-vi/strings.xml b/fenix/app/src/main/res/values-vi/strings.xml index abfc03fa7cd0..736a82c332fc 100644 --- a/fenix/app/src/main/res/values-vi/strings.xml +++ b/fenix/app/src/main/res/values-vi/strings.xml @@ -242,6 +242,7 @@ Tùy biến trang chủ + Màn hình chính @@ -249,6 +250,9 @@ Xóa lịch sử duyệt web + + Dịch trang + Ngôn ngữ được chọn @@ -260,8 +264,6 @@ Quét - - Công cụ tìm kiếm Cài đặt công cụ tìm kiếm @@ -316,14 +318,14 @@ - Thông báo giúp bạn làm được nhiều việc hơn với %s + Thông báo giúp bạn làm được nhiều việc hơn với %s - Đồng bộ hóa các thẻ của bạn giữa các thiết bị, quản lý tải xuống, nhận các mẹo về cách tận dụng tối đa khả năng bảo vệ quyền riêng tư của %s và nhiều hơn nữa. + Đồng bộ hóa các thẻ của bạn giữa các thiết bị, quản lý tải xuống, nhận các mẹo về cách tận dụng tối đa khả năng bảo vệ quyền riêng tư của %s và nhiều hơn nữa. - Tiếp tục + Tiếp tục - Không phải bây giờ + Không phải bây giờ @@ -441,21 +443,11 @@ Chế độ chỉ HTTPS - - Giảm biểu ngữ cookie Trình chặn biểu ngữ cookie Trình chặn biểu ngữ cookie trong trình duyệt riêng tư - - Giảm biểu ngữ cookie - - Tắt - - Bật - - - %1$s tự động cố gắng từ chối yêu cầu cookie trên biểu ngữ cookie. + Tắt cho trang web này @@ -473,35 +465,16 @@ Trang web hiện tại không được hỗ trợ - Bật giảm biểu ngữ cookie cho %1$s? - Bật trình chặn biểu ngữ cookie cho %1$s? - Tắt giảm biểu ngữ cookie cho %1$s? - Tắt trình chặn biểu ngữ cookie cho %1$s? %1$s không thể tự động từ chối yêu cầu cookie trên trang web này. Bạn có thể gửi yêu cầu hỗ trợ trang web này trong tương lai. - - %1$s sẽ xóa cookie của trang web này và làm mới trang. Xóa tất cả cookie có thể khiến bạn đăng xuất hoặc làm trống giỏ hàng. Tắt và %1$s sẽ xóa cookie và tải lại trang web này. Điều này có thể khiến bạn bị đăng xuất hoặc bị xóa sạch giỏ hàng. - %1$s thử tự động từ chối tất cả các yêu cầu cookie trên các trang web được hỗ trợ. - Bật và %1$s sẽ thử tự động từ chối tất cả các biểu ngữ cookie trên trang web này. - - Cho phép %1$s từ chối biểu ngữ cookie? - - %1$s có thể tự động từ chối nhiều yêu cầu biểu ngữ cookie. - - Không phải bây giờ - - Bạn sẽ thấy ít yêu cầu cookie hơn - - - Cho phép %1$s vừa từ chối cookie cho bạn @@ -1283,8 +1256,6 @@ Bỏ qua - Không thể in - Không thể in trang này In @@ -1900,7 +1871,7 @@ Thiết lập màn hình khóa thiết bị với mẫu hình, mã PIN hoặc mật khẩu để bảo vệ thẻ tín dụng đã lưu của bạn không bị truy cập nếu người khác có thiết bị của bạn. - Đặt mật khẩu thiết bị dạng mẫu hình, mã PIN hoặc mật khẩu để bảo vệ thẻ đã lưu của bạn không bị truy cập nếu người khác lấy đuọc thiết bị của bạn. + Đặt mật khẩu thiết bị dạng mẫu hình, mã PIN hoặc mật khẩu để bảo vệ phương thức thanh toán đã lưu của bạn không bị truy cập nếu người khác lấy đuọc thiết bị của bạn. Thiết lập ngay @@ -2061,12 +2032,12 @@ Cài đặt mật khẩu Trường văn bản có thể chỉnh sửa cho địa chỉ web của thông tin đăng nhập. - - Trường văn bản có thể chỉnh sửa cho địa chỉ trang web của mật khẩu. + + Trường văn bản có thể chỉnh sửa cho địa chỉ trang web. Trường văn bản có thể chỉnh sửa cho tên người dùng của thông tin đăng nhập. - - Trường văn bản có thể chỉnh sửa cho tên người dùng của mật khẩu. + + Trường văn bản có thể chỉnh sửa cho tên người dùng. Trường văn bản có thể chỉnh sửa cho mật khẩu của thông tin đăng nhập. @@ -2263,8 +2234,6 @@ Điểm nổi bật từ %s đánh giá trong vòng 80 ngày qua mà chúng tôi tin là đáng tin cậy.]]> Tìm hiểu thêm về %s. - - cách %s bởi Mozilla xác định chất lượng đánh giá cách %s xác định chất lượng đánh giá @@ -2449,6 +2418,8 @@ Đang dịch trang + + Chọn ngôn ngữ Đã xảy ra sự cố khi dịch. Hãy thử lại. diff --git a/focus-android/app/src/main/res/values-zh-rCN/strings.xml b/focus-android/app/src/main/res/values-zh-rCN/strings.xml index cf3d876791ad..37409520f81a 100644 --- a/focus-android/app/src/main/res/values-zh-rCN/strings.xml +++ b/focus-android/app/src/main/res/values-zh-rCN/strings.xml @@ -18,11 +18,11 @@ 全自动的私密浏览。\n无痕浏览,不必劳心。 - 您的浏览记录已清除。 + 您的浏览历史已清除。 浏览历史已清除 - 已清除标签页浏览记录。 + 已清除标签页浏览历史。 搜索 %1$s @@ -86,7 +86,7 @@ 需要清除浏览历史吗? 点按或清除此通知,即可安全清除浏览历史。 - 清除浏览记录 + 清除浏览历史 打开 @@ -102,7 +102,7 @@ - 清除浏览记录 + 清除浏览历史 - 清除浏览记录 + 清除浏览历史 - 隐私保护考量,我们会在您关闭应用程序时,自动清除浏览记录。 + 隐私保护考量,我们会在您关闭应用程序时,自动清除历史记录。 @@ -600,10 +600,10 @@ * To understand what notification channels are, see: https://www.androidcentral.com/notification-channels * To see how this string will look like in Android's UI, see: https://github.com/mozilla-mobile/focus-android/issues/863#issuecomment-324105723 --> - 通知您可以一键清除您的 %1$s 浏览记录。清除无需打开应用或查看浏览器中的内容。 + 推送通知可让您一键清除 %1$s 浏览状态。这样就无需事先打开应用,同时可以避免显露出浏览器中浏览的内容。 - 清除浏览记录 + 清除浏览历史 @@ -965,7 +965,7 @@ 抱歉, 此标签页出现问题并已崩溃。 - 作为一款隐私浏览器,我们不会保存浏览记录,因此无法还原此标签页。 + 作为一款隐私浏览器,我们不会保存浏览历史,因此无法还原此标签页。 关闭标签页 @@ -1078,7 +1078,7 @@ 知道了 - 点按此处即可删除浏览记录、Cookie 等所有数据,并新建一个全新标签页。 + 点按此处即可删除浏览历史、Cookie 等所有数据,并新建一个全新标签页。 From 2b7a785fafd661558bc743c8ed344b3dd91b7bdd Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Sun, 4 Feb 2024 00:48:31 +0000 Subject: [PATCH 058/586] Update GeckoView (Nightly) to 124.0.20240203210212. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index d46af461d2ce..1c3bf6d76d30 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240203092120" + const val version = "124.0.20240203210212" /** * GeckoView channel From f87534be3de87634a3988e7cf6586a6411cd3baf Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Sun, 4 Feb 2024 13:21:45 +0000 Subject: [PATCH 059/586] Update GeckoView (Nightly) to 124.0.20240204092554. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 1c3bf6d76d30..b0f752026098 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240203210212" + const val version = "124.0.20240204092554" /** * GeckoView channel From d5457bfa55a8fed1309a3d97619d43630788013e Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 5 Feb 2024 00:03:30 +0000 Subject: [PATCH 060/586] Import translations from android-l10n --- .../src/main/res/values-azb/strings.xml | 25 ++++++ .../addons/src/main/res/values-cs/strings.xml | 4 +- .../src/main/res/values-kab/strings.xml | 2 + .../addons/src/main/res/values-sk/strings.xml | 4 +- .../addons/src/main/res/values-uk/strings.xml | 2 + .../media/src/main/res/values-sk/strings.xml | 11 ++- .../media/src/main/res/values-th/strings.xml | 21 ++++- .../media/src/main/res/values-uk/strings.xml | 11 ++- .../src/main/res/values-cs/strings.xml | 29 +++++++ .../src/main/res/values-kab/strings.xml | 19 +++++ .../src/main/res/values-sk/strings.xml | 36 +++++++++ .../src/main/res/values-uk/strings.xml | 36 +++++++++ fenix/app/src/main/res/values-azb/strings.xml | 30 +++++++ fenix/app/src/main/res/values-cs/strings.xml | 20 +++++ fenix/app/src/main/res/values-kab/strings.xml | 26 ++++++ fenix/app/src/main/res/values-sk/strings.xml | 80 ++++++------------- fenix/app/src/main/res/values-sl/strings.xml | 9 +++ fenix/app/src/main/res/values-th/strings.xml | 54 +++++++++++++ fenix/app/src/main/res/values-uk/strings.xml | 16 ++-- .../app/src/main/res/values-cs/strings.xml | 8 +- .../app/src/main/res/values-ja/strings.xml | 7 +- 21 files changed, 373 insertions(+), 77 deletions(-) create mode 100644 android-components/components/browser/errorpages/src/main/res/values-azb/strings.xml diff --git a/android-components/components/browser/errorpages/src/main/res/values-azb/strings.xml b/android-components/components/browser/errorpages/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000000..b2ddb78caa35 --- /dev/null +++ b/android-components/components/browser/errorpages/src/main/res/values-azb/strings.xml @@ -0,0 +1,25 @@ + + + + یئنی‌دن چالیش + + + ایستک قورتارا بیلمیر + + + بو موشکول و خطا ایله ایلگیلی آرتیقراق بیلگی هله یوخدور.

]]>
+ + + گوونلی باغلانتی اوغورسوز اولدو + + + قاباغجیل + + قاییت(توصیه اولونور) + + ریسکی قبول ائلییرک دوام ائدین + + + بو سایت گوونلی باغلانتی ایسته ییر. + +
diff --git a/android-components/components/feature/addons/src/main/res/values-cs/strings.xml b/android-components/components/feature/addons/src/main/res/values-cs/strings.xml index 06087a10dba9..cbe8ac84b286 100644 --- a/android-components/components/feature/addons/src/main/res/values-cs/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-cs/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Přistupovat k vašim datům z %1$d dalších domén + + %1$s, %2$d z %3$d Přistupovat k panelům prohlížeče @@ -75,7 +77,7 @@ Autor - Autor + Autor Poslední aktualizace diff --git a/android-components/components/feature/addons/src/main/res/values-kab/strings.xml b/android-components/components/feature/addons/src/main/res/values-kab/strings.xml index c84982f30908..a11aa586d76a 100644 --- a/android-components/components/feature/addons/src/main/res/values-kab/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-kab/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Kcem ɣer yisefka-inek·nem ɣef %1$d n tɣula-nniḍen + + %1$s, %2$d n %3$d Kcem γer icarren n iminig diff --git a/android-components/components/feature/addons/src/main/res/values-sk/strings.xml b/android-components/components/feature/addons/src/main/res/values-sk/strings.xml index 9ea102a6ac11..38b7631e06c2 100644 --- a/android-components/components/feature/addons/src/main/res/values-sk/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-sk/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Pristupovať k vašim údajom na %1$d ďalších doménach + + %1$s, %2$d z %3$d Prístup ku kartám prehliadača @@ -75,7 +77,7 @@ Autor - Autori + Autori Posledná aktualizácia diff --git a/android-components/components/feature/addons/src/main/res/values-uk/strings.xml b/android-components/components/feature/addons/src/main/res/values-uk/strings.xml index cb56b1c054b9..ed6fc14cb9d9 100644 --- a/android-components/components/feature/addons/src/main/res/values-uk/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-uk/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Отримувати доступ до ваших даних на %1$d інших доменах + + %1$s, %2$d з %3$d Доступ до вкладок браузера diff --git a/android-components/components/feature/media/src/main/res/values-sk/strings.xml b/android-components/components/feature/media/src/main/res/values-sk/strings.xml index 5f7a5eac6f63..a895411f7264 100644 --- a/android-components/components/feature/media/src/main/res/values-sk/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-sk/strings.xml @@ -1,5 +1,5 @@ - + Médiá @@ -21,9 +21,14 @@ Pripomenutie: %1$s stále používa vašu kameru. Ťuknutím otvoríte kartu. - Pripomenutie: %1$s stále používa váš mikrofón. Ťuknutím otvoríte kartu. + Pripomenutie: %1$s stále používa váš mikrofón. Ťuknutím otvoríte kartu. + + Pripomenutie: %1$s stále používa váš mikrofón. Ťuknutím otvoríte kartu. + + Pripomenutie: %1$s stále používa váš mikrofón a kameru. Ťuknutím otvoríte kartu. + - Pripomenutie: %1$s stále používa váš mikrofón a kameru. Ťuknutím otvoríte kartu. + Pripomenutie: %1$s stále používa váš mikrofón a kameru. Ťuknutím otvoríte kartu. Prehrať diff --git a/android-components/components/feature/media/src/main/res/values-th/strings.xml b/android-components/components/feature/media/src/main/res/values-th/strings.xml index 0b7788d880e3..bae10ac0c56d 100644 --- a/android-components/components/feature/media/src/main/res/values-th/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-th/strings.xml @@ -1,5 +1,5 @@ - + สื่อ @@ -10,6 +10,25 @@ กล้องและไมโครโฟนเปิดอยู่ + + แตะเพื่อเปิดแท็บที่กำลังใช้กล้องของคุณ + + แตะเพื่อเปิดแท็บที่กำลังใช้ไมโครโฟนของคุณ + + แตะเพื่อเปิดแท็บที่กำลังใช้ไมโครโฟนและกล้องของคุณ + + + + คำเตือน: %1$s ยังใช้กล้องของคุณอยู่ แตะเพื่อเปิดแท็บ + + คำเตือน: %1$s ยังใช้ไมโครโฟนของคุณอยู่ แตะเพื่อเปิดแท็บ + + คำเตือน: %1$s ยังใช้ไมโครโฟนของคุณอยู่ แตะเพื่อเปิดแท็บ + + คำเตือน: %1$s ยังใช้ไมโครโฟนและกล้องของคุณอยู่ แตะเพื่อเปิดแท็บ + + คำเตือน: %1$s ยังใช้ไมโครโฟนและกล้องของคุณอยู่ แตะเพื่อเปิดแท็บ + เล่น diff --git a/android-components/components/feature/media/src/main/res/values-uk/strings.xml b/android-components/components/feature/media/src/main/res/values-uk/strings.xml index 87721c907477..b2b982a78ea0 100644 --- a/android-components/components/feature/media/src/main/res/values-uk/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-uk/strings.xml @@ -1,5 +1,5 @@ - + Медіа @@ -21,9 +21,14 @@ Нагадування: %1$s досі використовує вашу камеру. Торкніться, щоб відкрити вкладку. - Нагадування: %1$s досі використовує ваш мікрофон. Торкніться, щоб відкрити вкладку. + Нагадування: %1$s досі використовує ваш мікрофон. Торкніться, щоб відкрити вкладку. + + Нагадування: %1$s досі використовує ваш мікрофон. Торкніться, щоб відкрити вкладку. + + Нагадування: %1$s досі використовує ваші мікрофон і камеру. Торкніться, щоб відкрити вкладку. + - Нагадування: %1$s досі використовує ваші мікрофон і камеру. Торкніться, щоб відкрити вкладку. + Нагадування: %1$s досі використовує ваші мікрофон і камеру. Торкніться, щоб відкрити вкладку. Відтворити diff --git a/android-components/components/feature/prompts/src/main/res/values-cs/strings.xml b/android-components/components/feature/prompts/src/main/res/values-cs/strings.xml index 9d054363713c..9b47bdb74451 100644 --- a/android-components/components/feature/prompts/src/main/res/values-cs/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-cs/strings.xml @@ -18,6 +18,8 @@ Heslo Neukládat + + Teď ne Nikdy neukládat @@ -26,16 +28,26 @@ Uložit Neaktualizovat + + Teď ne Aktualizovat Heslo nesmí být prázdné + Zadejte heslo + Přihlašovací údaje nelze uložit + + Heslo není možné uložit Uložit tyto přihlašovací údaje? + + Uložit heslo? Aktualizovat tyto přihlašovací údaje? + + Aktualizovat heslo? Přidat k uloženému heslu uživatelské jméno? @@ -85,13 +97,22 @@ Nastavit čas Správa přihlašovacích údajů + + Správa přihlašovacích údajů Zobrazit navrhované přihlašovací údaje + + Rozbalit uložená hesla Skýt navrhované přihlašovací údaje + + Sbalit uložená hesla Navrhované přihlašovací údaje + + Uložená hesla + Navrhnout silné heslo @@ -110,12 +131,20 @@ Vyberte platební kartu + + Použít uloženou kartu Zobrazit návrhy platebních karet + + Rozbalit uložené karty Skrýt návrhy platebních karet + + Sbalit uložené karty Správa platebních karet + + Spravovat karty Bezpečně uložit tuto kartu? diff --git a/android-components/components/feature/prompts/src/main/res/values-kab/strings.xml b/android-components/components/feature/prompts/src/main/res/values-kab/strings.xml index 114f4be40826..0da6d4656b34 100644 --- a/android-components/components/feature/prompts/src/main/res/values-kab/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-kab/strings.xml @@ -18,6 +18,8 @@ Awal uffir Ur seklas ara + + Mačči tura Urǧin sekles @@ -26,16 +28,24 @@ Sekles Ur leqqem ara + + Mačči tura Leqqem Urti n wawal uffir ur ilaq ara ad yili d ilem + Sekcem awal uffir + Ur yezmir ara ad isekles anekcum Sekles anekcum-agi? + + Sekles awal uffir? Leqqem anekcum-agi? + + Leqqem awal uffir? Rnu isem n useqdac ɣer wawal uffir yettwaskelsen? @@ -85,6 +95,8 @@ Sbadu akud Sefrek inekcam + + Sefrek awalen uffiren Sken-d inekcam isumar @@ -92,6 +104,9 @@ Inekcam yettwasumren + + Awalen uffiren yettwakelsen + SuƔer awal uffir iǧehden @@ -108,12 +123,16 @@ Fren takarḍa n usmad + + Seqdec tkarḍa yettwaskelsen Semɣer tikerḍiwin n usmad i d-yettusumren Fneẓ tikerḍiwin n usmad i d-yettusumren Sefrektikarḍiwin n usmad + + Sefrek tikarḍiwin Asekles n tkarḍa-a s wudem aɣellsan? diff --git a/android-components/components/feature/prompts/src/main/res/values-sk/strings.xml b/android-components/components/feature/prompts/src/main/res/values-sk/strings.xml index 8ff11eacbf55..b0d1818daa64 100644 --- a/android-components/components/feature/prompts/src/main/res/values-sk/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-sk/strings.xml @@ -18,6 +18,8 @@ Heslo Neuložiť + + Teraz nie Nikdy neukladať @@ -26,16 +28,26 @@ Uložiť Neaktualizovať + + Teraz nie Aktualizovať Pole s heslom nesmie byť prázdne + Zadajte heslo + Prihlasovacie údaje sa nepodarilo uložiť + + Heslo nie je možné uložiť Chcete uložiť tieto prihlasovacie údaje? + + Uložiť heslo? Chcete aktualizovať tieto prihlasovacie údaje? + + Aktualizovať heslo? Chcete k uloženému heslu pridať používateľské meno? @@ -85,13 +97,22 @@ Nastaviť čas Spravovať prihlasovacie údaje + + Spravovať heslá Rozbaliť navrhované prihlasovacie údaje + + Rozbaliť uložené heslá Zbaliť navrhované prihlasovacie údaje + + Zbaliť uložené heslá Navrhované prihlasovacie údaje + + Uložené heslá + Navrhnúť silné heslo @@ -110,12 +131,20 @@ Vyberte platobnú kartu + + Použiť uloženú kartu Rozbaliť navrhované platobné karty + + Rozbaliť uložené karty Zbaliť navrhované platobné karty + + Zbaliť uložené karty Spravovať platobné karty + + Spravovať karty Bezpečne uložiť túto kartu? @@ -123,13 +152,20 @@ Číslo karty bude zašifrované. Bezpečnostný kód sa neuloží. + + %s zašifruje číslo vašej karty. Váš bezpečnostný kód sa neuloží. + Vyberte adresu Rozbaliť navrhované adresy + + Rozbaliť uložené adresy Zbaliť navrhované adresy + + Zbaliť uložené adresy Spravovať adresy diff --git a/android-components/components/feature/prompts/src/main/res/values-uk/strings.xml b/android-components/components/feature/prompts/src/main/res/values-uk/strings.xml index f1c0eb83fbb9..4edeea324b7d 100644 --- a/android-components/components/feature/prompts/src/main/res/values-uk/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-uk/strings.xml @@ -18,6 +18,8 @@ Пароль Не зберігати + + Не зараз Ніколи не зберігати @@ -26,16 +28,26 @@ Зберегти Не оновлювати + + Не зараз Оновити Поле пароля не повинно бути порожнім + Введіть пароль + Не вдається зберегти запис + + Не вдається зберегти пароль Зберегти цей пароль? + + Зберегти пароль? Оновити цей пароль? + + Оновити пароль? Додати ім’я користувача до збереженого пароля? @@ -85,13 +97,22 @@ Налаштувати час Керувати паролями + + Керувати паролями Розгорнути запропоновані паролі + + Розгорнути збережені паролі Згорнути запропоновані паролі + + Згорнути збережені паролі Пропоновані паролі + + Збережені паролі + Запропонувати надійний пароль @@ -110,12 +131,20 @@ Виберіть кредитну картку + + Використати збережену картку Розгорнути запропоновані кредитні картки + + Розгорнути збережені картки Згорнути запропоновані кредитні картки + + Згорнути збережені картки Керувати кредитними картками + + Керувати картками Зберегти надійно цю картку? @@ -123,13 +152,20 @@ Номер картки буде зашифровано. Код безпеки не буде збережено. + + %s шифрує номер вашої картки. Ваш код безпеки не буде збережено. + Вибрати адресу Розгорнути пропоновані адреси + + Розгорнути збережені адреси Згорнути пропоновані адреси + + Згорнути збережені адреси Керувати адресами diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml index 3e4cdcd3a9d5..eee28262ea11 100644 --- a/fenix/app/src/main/res/values-azb/strings.xml +++ b/fenix/app/src/main/res/values-azb/strings.xml @@ -31,6 +31,36 @@ تاغ‌لاردا آختار + + آختاریش شرطلرینی گیر + + آچیق تاغ‌لاریز بوردا گؤستریله‌جک + + سیزین گیزلی تاغ‌لاریز بوردا گؤستریله‌جک + + + + %1$d سئچیلیدی + + یئنی مجموعه اکله + + آد + + + + مجموعه سئچین + + چوخ‌سئچیم مودوندان چیخ + + سئچیلن تاغلاری مجموعه‌ده ساخلا + + سئچیلدی + + + + سون ساخلانان‌لار + + diff --git a/fenix/app/src/main/res/values-cs/strings.xml b/fenix/app/src/main/res/values-cs/strings.xml index 00d15612370b..d257bf7c056b 100644 --- a/fenix/app/src/main/res/values-cs/strings.xml +++ b/fenix/app/src/main/res/values-cs/strings.xml @@ -249,6 +249,7 @@ Přizpůsobit + Domovská obrazovka @@ -256,6 +257,10 @@ Vymazat historii prohlížení + + + Přeložit stránku + Vybraný jazyk @@ -1716,6 +1721,8 @@ Uložená hesla Uložené nebo synchronizované údaje aplikace %s se zobrazí tady. + + Hesla, která uložíte nebo synchronizujete s aplikací %s, budou uvedena zde. Všechna uložená hesla jsou šifrována. Zjistit více o službě Sync. @@ -1772,6 +1779,8 @@ Zabezpečte svá uložená hesla Nastavte si gesto, PIN nebo heslo zámku obrazovky, který ochrání vaše uložené přihlašovací údaje, pokud by se vaše zařízení dostalo do ruky někomu jinému. + + Nastavte si gesto, PIN nebo heslo zámku obrazovky, který ochrání vaše uložená hesla, pokud by se vaše zařízení dostalo do ruky někomu jinému. Později @@ -1792,6 +1801,9 @@ Seřadit podle + + Nabídka pro řazení hesel + Automatické vyplňování @@ -1897,6 +1909,8 @@ Odemkněte pro použití informací o platební kartě + + Odemknout pro použití uložených způsobů platby Přidat adresu @@ -2052,6 +2066,8 @@ Textové pole pro uživatelské jméno z přihlašovacích údajů. Textové pole pro heslo z přihlašovacích údajů. + + Upravitelné textové pole pro heslo. Uložit změny přihlašovacích údajů. @@ -2428,6 +2444,8 @@ Probíhá překlad Právě probíhá překlad + + Vyberte jazyk Při překladu došlo k chybě. Zkuste to prosím znovu. @@ -2450,6 +2468,8 @@ Nikdy nepřekládat tuto stránku Přepíše všechna ostatní nastavení + + Přepíše nabídky k překladu Nastavení překladu diff --git a/fenix/app/src/main/res/values-kab/strings.xml b/fenix/app/src/main/res/values-kab/strings.xml index cce974e94703..780162870679 100644 --- a/fenix/app/src/main/res/values-kab/strings.xml +++ b/fenix/app/src/main/res/values-kab/strings.xml @@ -2019,6 +2019,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Sefsex Iɣewwaren n unekcum + + Tixtiṛiyin n wawal uffir Urti n uḍris yettusenfal i tansa n unekcum n web. @@ -2234,6 +2236,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Adenqed n tɣara n yilɣa Adenqed n tɣara n yilɣa + + Adenqed n tɣara n yilɣa (%s) Aya yezmer ad yeṭṭef 60 tsinin. @@ -2355,9 +2359,18 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Sumer yal tikkelt tasuqqilt + + Sueqqel yal tikkelt %1$s + + Ur suqqul ara %1$s Werǧin asuqel n usmel-a + + Iɣewwaren n usuqqel + + Γef tsuqqilin deg %1$s + Tisuqilin @@ -2367,9 +2380,14 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Sader tutlayin + + Sueqqel yal tikkelt Werǧin attsuqleḍ + + + Ur suqqul ara ismal-a Kkes %1$s @@ -2411,6 +2429,10 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara The dialog will be presented when the user requests deletion of a language. The first parameter is the name of the language, for example, "Spanish" and the second parameter is the size in kilobytes or megabytes of the language file. --> Kkes %1$s (%2$s)? + + Kkes akk tutlayin (%1$s)? Kkes @@ -2418,6 +2440,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Sader + + Sader syen suqqel Sefsex @@ -2425,6 +2449,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Inig ar deffir Ifecka n yiccer + + Amḍan n waccaren Urmid diff --git a/fenix/app/src/main/res/values-sk/strings.xml b/fenix/app/src/main/res/values-sk/strings.xml index 8dcbb001cab4..03d13eb44897 100644 --- a/fenix/app/src/main/res/values-sk/strings.xml +++ b/fenix/app/src/main/res/values-sk/strings.xml @@ -247,6 +247,7 @@ Upraviť domovskú stránku + Úvodná obrazovka @@ -254,6 +255,10 @@ Vymazať históriu prehliadania + + + Preložiť stránku + Vybraný jazyk @@ -265,8 +270,6 @@ Skenovať - - Vyhľadávač Nastavenia vyhľadávania @@ -323,14 +326,14 @@ - Upozornenia vám pomôžu vyťažiť z prehliadača %s ešte viac + Upozornenia vám pomôžu vyťažiť z prehliadača %s ešte viac - Synchronizujte svoje karty medzi zariadeniami, spravujte sťahovanie, získajte tipy, ako čo najlepšie využiť ochranu súkromia prehliadača %s a ďalšie. + Synchronizujte svoje karty medzi zariadeniami, spravujte sťahovanie, získajte tipy, ako čo najlepšie využiť ochranu súkromia prehliadača %s a ďalšie. - Pokračovať + Pokračovať - Teraz nie + Teraz nie @@ -449,21 +452,11 @@ Režim "Len HTTPS" - - Zníženie počtu bannerov k súborom cookie Blokovanie bannerov k súborom cookie Blokovať bannery k súborom cookie v súkromnom prehliadaní - - Znižovať počet bannerov k súborom cookie - - Vypnuté - - Zapnuté - - - %1$s sa automaticky pokúša odmietnuť žiadosti o súbory cookie na banneroch k súborom cookie. + Vypnuté pre túto stránku @@ -481,36 +474,17 @@ Stránka momentálne nie je podporovaná - Zapnúť znižovanie počtu bannerov k súborom cookie pre %1$s? - Zapnúť blokovanie bannerov k súborom cookie pre %1$s? - Vypnúť znižovanie počtu bannerov k súborom cookie pre %1$s? - Vypnúť blokovanie bannerov k súborom cookie pre %1$s? %1$s nemôže automaticky odmietnuť žiadosti o súbory cookie na tejto stránke. Môžete však poslať žiadosť o podporu tejto stránky v budúcnosti. - - %1$s vymaže súbory cookie tohto webu a obnoví stránku. Vymazanie všetkých súborov cookie vás môže odhlásiť zo stránky alebo vyprázdniť nákupné košíky. Po vypnutí %1$s vymaže súbory cookie a znova načíta túto lokalitu. Môže vás to odhlásiť alebo vyprázdniť nákupné košíky. - - %1$s sa pokúša automaticky odmietnuť všetky žiadosti o súbory cookie na podporovaných stránkach. Po zapnutí sa %1$s pokúsi automaticky odmietnuť všetky bannery k súborom cookie na tejto stránke. - - Povoliť prehliadaču %1$s odmietnuť bannery k súborom cookie? - - %1$s môže automaticky odmietnuť mnoho žiadostí o povolenie súborov cookie. - - Teraz nie - - Uvidíte menej žiadostí o súbory cookie - - - Povoliť %1$s pre vás práve odmietol súbory cookie @@ -1299,8 +1273,6 @@ Zavrieť - Chyba tlače - Túto stránku nie je možné vytlačiť Tlačiť @@ -1920,7 +1892,7 @@ Nastavte si vzor, kód alebo heslo, ktorým ochránite svoje uložené kreditné karty v prípade, že vaše zariadenie bude používať niekto iný. - Nastavte si vzor, kód alebo heslo, ktorým ochránite svoje uložené karty v prípade, že vaše zariadenie bude používať niekto iný. + Nastavte si vzor, kód alebo heslo, ktorým ochránite svoje uložené spôsoby platby v prípade, že vaše zariadenie bude používať niekto iný. Nastaviť teraz @@ -2081,12 +2053,12 @@ Možnosti hesiel Upraviteľné textové pole pre webovú adresu. - - Upraviteľné textové pole pre webovú stránku, kde používate toto heslo. + + Upraviteľné textové pole pre webovú adresu. Upraviteľné textové pole pre používateľské meno. - - Upraviteľné textové pole pre používateľské meno, ktoré používate s týmto heslom. + + Upraviteľné textové pole pre používateľské meno. Upraviteľné textové pole pre heslo. @@ -2284,8 +2256,6 @@ Najdôležitejšie informácie pochádzajú z recenzií v obchode %s uverejnených za posledných 80 dní, ktoré považujeme za spoľahlivé.]]> Ďalšie informácie o tom, %s. - - ako %s od Mozilly určuje kvalitu recenzie ako %s určuje kvalitu recenzie @@ -2470,6 +2440,8 @@ Práve prebieha preklad + + Zvoľte jazyk Pri preklade sa vyskytol problém. Prosím skúste to znova. @@ -2483,19 +2455,19 @@ Nastavenia prekladov - Vždy ponúkať preklad + Vždy ponúknuť preklad - Vždy prekladať jazyk %1$s + Vždy prekladať z jazyka %1$s Nikdy neprekladať z jazyka %1$s Nikdy neprekladať túto stránku - Prepíše všetky ostatné nastavenia + Má prednosť pred ostatnými nastaveniami - Prepíše ponuky na preklad + Nebude ponúkať preklad - Nastavenia prekladu + Nastavenia prekladov Informácie o prekladoch v aplikácii %1$s @@ -2505,13 +2477,13 @@ Ak je to možné, ponúknuť preklad - Vždy sťahovať jazyky v režime šetrenia dát + Sťahovať jazyky aj v režime šetrenia dát Nastavenia prekladania obsahu Automatický preklad - Nikdy neprekladať tieto stránky + Neprekladať tieto stránky Stiahnuť jazyky @@ -2520,7 +2492,7 @@ Automatický preklad - Vyberte jazyk, pre ktorý chcete spravovať predvoľby „vždy prekladať“ a „nikdy neprekladať“. + Vyberte jazyk, pre ktorý chcete spravovať predvoľby „Vždy prekladať“ a „Nikdy neprekladať“. @@ -2557,7 +2529,7 @@ Stiahnite si jazyky - Stiahnite si kompletné jazyky pre rýchlejšie preklady a preklady offline. %1$s + Ak chcete rýchlejšie preklady alebo preklady offline, musíte si stiahnuť kompletné jazykové balíky. %1$s Ďalšie informácie diff --git a/fenix/app/src/main/res/values-sl/strings.xml b/fenix/app/src/main/res/values-sl/strings.xml index 8f3a2ebfdc00..403d88a38763 100644 --- a/fenix/app/src/main/res/values-sl/strings.xml +++ b/fenix/app/src/main/res/values-sl/strings.xml @@ -1790,6 +1790,8 @@ Kreditne kartice Shrani in samodejno izpolni kartice + + Shranjuj in izpolnjuj načine plačila Podatki so šifrirani @@ -1816,6 +1818,9 @@ Vključi podatke, kot so številke, e-poštni naslovi in naslovi za dostavo + + Vključuje telefonske številke in e-poštne naslove + Dodaj kartico @@ -2402,6 +2407,8 @@ Prevajanje poteka + + Izberite jezik Pri prevajanju je prišlo do težave. Poskusite znova. @@ -2498,6 +2505,8 @@ Prekliči + + Vedno prenesi tudi ob varčevanju s podatki Prenesi diff --git a/fenix/app/src/main/res/values-th/strings.xml b/fenix/app/src/main/res/values-th/strings.xml index 5dbb20346c32..152ab7fc32e5 100644 --- a/fenix/app/src/main/res/values-th/strings.xml +++ b/fenix/app/src/main/res/values-th/strings.xml @@ -241,6 +241,7 @@ ปรับแต่งหน้าแรก + หน้าแรก @@ -248,6 +249,7 @@ ล้างประวัติการเรียกดู + ภาษาที่เลือก @@ -1304,6 +1306,8 @@ ปิดแท็บส่วนตัว? + แตะหรือปัดการแจ้งเตือนนี้เพื่อปิดแท็บส่วนตัว + การตลาด @@ -2283,8 +2287,18 @@ ตรวจสอบคุณภาพบทวิจารณ์ ลองใช้คำแนะนำที่เชื่อถือได้ของเราเกี่ยวกับบทวิจารณ์ผลิตภัณฑ์ + + ดูว่าบทวิจารณ์ผลิตภัณฑ์น่าเชื่อถือแค่ไหนใน %1$s ก่อนตัดสินใจซื้อ ตัวตรวจสอบบทวิจารณ์ ซึ่งเป็นคุณลักษณะทดลองจาก %2$s ถูกบรรจุไว้ภายในตัวเบราว์เซอร์โดยตรง ซึ่งสามารถใช้ใน %3$s และ %4$s ได้ด้วย + + ดูว่าบทวิจารณ์ผลิตภัณฑ์น่าเชื่อถือแค่ไหนใน %1$s ก่อนตัดสินใจซื้อ ตัวตรวจสอบบทวิจารณ์ ซึ่งเป็นคุณลักษณะทดลองจาก %2$s ถูกบรรจุไว้ภายในตัวเบราว์เซอร์โดยตรง + + ด้วยการใช้พลังของ %1$s โดย Mozilla เราช่วยให้คุณหลีกเลี่ยงบทวิจารณ์ที่มีอคติและไม่น่าไว้วางใจได้ โมเดล AI ของเราจะปรับปรุงอยู่เสมอเพื่อปกป้องคุณในขณะที่คุณซื้อของ %2$s เรียนรู้เพิ่มเติม + + การเลือก “ใช่ ลองใช้เลย” ถือว่าคุณยอมรับ%2$sและ%3$sของ %1$s โดย Mozilla + + การเลือก “ใช่ ลองใช้เลย” ถือว่าคุณยอมรับข้อตกลงต่อไปนี้จาก %1$s: นโยบายความเป็นส่วนตัว @@ -2297,6 +2311,8 @@ ใช่ลองดู ไม่ใช่ตอนนี้ + + ค้นพบว่าคุณสามารถเชื่อถือบทวิจารณ์ของผลิตภัณฑ์นี้ได้หรือไม่ ก่อนที่คุณจะตัดสินใจซื้อ ลองตัวตรวจสอบบทวิจารณ์ @@ -2357,6 +2373,10 @@ แปลหน้านี้? + + ลองใช้การแปลแบบส่วนตัวใน %1$s + + เพื่อความเป็นส่วนตัวของคุณ ข้อมูลการแปลจะไม่ออกไปนอกอุปกรณ์ของคุณ ภาษาและการปรับปรุงใหม่ๆ จะมาในเร็วๆ นี้! %1$s เรียนรู้เพิ่มเติม @@ -2378,6 +2398,13 @@ เกิดปัญหาในการแปล โปรดลองอีกครั้ง + + ไม่สามารถโหลดภาษาได้ โปรดตรวจสอบการเชื่อมต่ออินเทอร์เน็ตของคุณแล้วลองอีกครั้ง + + ขออภัย เรายังไม่รองรับภาษา%1$s + + เรียนรู้เพิ่มเติม + ตัวเลือกการแปล @@ -2476,11 +2503,30 @@ เลือกแล้ว + + ลบ %1$s (%2$s) หรือไม่? + + หากคุณลบภาษานี้ %1$s จะดาวน์โหลดภาษาบางส่วนลงในแคชของคุณในขณะที่คุณแปล + + ลบทุกภาษา (%1$s) หรือไม่? + + หากคุณลบทุกภาษา %1$s จะดาวน์โหลดภาษาบางส่วนลงในแคชของคุณในขณะที่คุณแปล ลบ ยกเลิก + + ดาวน์โหลดขณะอยู่ในโหมดประหยัดข้อมูล (%1$s) หรือไม่? + + เราดาวน์โหลดภาษาบางส่วนลงในแคชของคุณเพื่อให้การแปลเป็นส่วนตัว ดาวน์โหลดในโหมดประหยัดข้อมูลเสมอ @@ -2495,6 +2541,10 @@ เครื่องมือดีบัก นำทางย้อนกลับ + + เครื่องมือแท็บ + + จำนวนแท็บ ใช้งานอยู่ @@ -2503,6 +2553,10 @@ ส่วนตัว รวมทั้งหมด + + เครื่องมือสร้างแท็บ + + จำนวนแท็บที่จะสร้าง เพิ่มไปยังแท็บที่ใช้งานอยู่ diff --git a/fenix/app/src/main/res/values-uk/strings.xml b/fenix/app/src/main/res/values-uk/strings.xml index fededc1bbf95..90504d5dafd8 100644 --- a/fenix/app/src/main/res/values-uk/strings.xml +++ b/fenix/app/src/main/res/values-uk/strings.xml @@ -244,6 +244,7 @@ Налаштувати домівку + Домашній екран @@ -251,6 +252,9 @@ Стерти історію перегляду + + Перекласти сторінку + Обрана мова @@ -1887,7 +1891,7 @@ Встановіть графічний ключ, PIN-код чи пароль для захисту збережених банківських карток від інших, хто може отримати доступ до вашого пристрою. - Встановіть графічний ключ, PIN-код чи пароль для захисту збережених банківських карток від інших, хто може отримати доступ до вашого пристрою. + Встановіть графічний ключ, PIN-код чи пароль для захисту збережених способів оплати від інших, хто може отримати доступ до вашого пристрою. Встановити @@ -2050,12 +2054,12 @@ Параметри пароля Текстове поле для редагування вебадреси запису. - - Текстове поле для редагування адреси вебсайту. + + Текстове поле для редагування адреси вебсайту. Текстове поле для редагування імені користувача запису. - - Текстове поле для редагування імені користувача. + + Текстове поле для редагування імені користувача. Текстове поле для редагування пароля запису. @@ -2436,6 +2440,8 @@ Виконується переклад + + Вибрати мову Виникла проблема з перекладом. Повторіть спробу. diff --git a/focus-android/app/src/main/res/values-cs/strings.xml b/focus-android/app/src/main/res/values-cs/strings.xml index 2f187689618f..ee0f2eed994c 100644 --- a/focus-android/app/src/main/res/values-cs/strings.xml +++ b/focus-android/app/src/main/res/values-cs/strings.xml @@ -53,7 +53,6 @@ Odebrat ze zkratek - Co je nového Nastavení O nás Nápověda @@ -84,10 +83,9 @@ sharing an URL. --> Sdílet přes - + Vymazat historii prohlížení? + Klepnutím na toto oznámení nebo jeho smazáním bezpečně vymažete svou historii prohlížení. + Vymazat historii prohlížení diff --git a/focus-android/app/src/main/res/values-ja/strings.xml b/focus-android/app/src/main/res/values-ja/strings.xml index c60f9a614598..f4d2d8701d65 100644 --- a/focus-android/app/src/main/res/values-ja/strings.xml +++ b/focus-android/app/src/main/res/values-ja/strings.xml @@ -83,10 +83,9 @@ sharing an URL. --> 共有方法を選択 - + 閲覧履歴を消去しますか? + この通知をタップして閲覧履歴を安全に消去してください。 + 閲覧履歴を消去 From ae8a843ab342729471e572b097733b2ec866bc6f Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Mon, 5 Feb 2024 01:36:54 +0000 Subject: [PATCH 061/586] Update GeckoView (Nightly) to 124.0.20240204213653. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index b0f752026098..47defe5e953b 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240204092554" + const val version = "124.0.20240204213653" /** * GeckoView channel From 80de1d19592331117fba9167413ec1ffc326b6f6 Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Mon, 11 Dec 2023 18:51:12 +0200 Subject: [PATCH 062/586] Bug 1870050 - Upgrade AGP and kotlin dsl version. Also sync lint version. --- android-components/plugins/config/build.gradle | 2 +- android-components/plugins/dependencies/build.gradle | 2 +- .../plugins/dependencies/src/main/java/DependenciesPlugin.kt | 4 ++-- android-components/plugins/github/build.gradle | 2 +- android-components/plugins/publicsuffixlist/build.gradle | 2 +- fenix/plugins/apksize/build.gradle | 2 +- fenix/plugins/fenixdependencies/build.gradle | 2 +- focus-android/plugins/focusdependencies/build.gradle | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/android-components/plugins/config/build.gradle b/android-components/plugins/config/build.gradle index 45fdfa0ad16c..5deaea668389 100644 --- a/android-components/plugins/config/build.gradle +++ b/android-components/plugins/config/build.gradle @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ plugins { - id "org.gradle.kotlin.kotlin-dsl" version "4.1.2" + id "org.gradle.kotlin.kotlin-dsl" version "4.2.1" } repositories { diff --git a/android-components/plugins/dependencies/build.gradle b/android-components/plugins/dependencies/build.gradle index 16baf9b9db49..6a44b0125155 100644 --- a/android-components/plugins/dependencies/build.gradle +++ b/android-components/plugins/dependencies/build.gradle @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ plugins { - id "org.gradle.kotlin.kotlin-dsl" version "4.1.2" + id "org.gradle.kotlin.kotlin-dsl" version "4.2.1" } repositories { diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt index 02c85adc1dfa..b0153388de72 100644 --- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt +++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt @@ -28,11 +28,11 @@ object Versions { const val okio = "3.6.0" const val coil = "2.4.0" - const val android_gradle_plugin = "8.0.2" + const val android_gradle_plugin = "8.2.2" // This has to be synced to the gradlew plugin version. See // http://googlesamples.github.io/android-custom-lint-rules/api-guide/example.md.html#example:samplelintcheckgithubproject/lintversion? - const val lint = "31.0.2" + const val lint = "31.2.2" const val detekt = "1.23.4" const val ktlint = "0.49.1" diff --git a/android-components/plugins/github/build.gradle b/android-components/plugins/github/build.gradle index b8e66d128d6b..ece03e751fc6 100644 --- a/android-components/plugins/github/build.gradle +++ b/android-components/plugins/github/build.gradle @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ plugins { - id "org.gradle.kotlin.kotlin-dsl" version "4.1.2" + id "org.gradle.kotlin.kotlin-dsl" version "4.2.1" } repositories { diff --git a/android-components/plugins/publicsuffixlist/build.gradle b/android-components/plugins/publicsuffixlist/build.gradle index 3a1b0e2110ca..e25a9f21fc11 100644 --- a/android-components/plugins/publicsuffixlist/build.gradle +++ b/android-components/plugins/publicsuffixlist/build.gradle @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ plugins { - id "org.gradle.kotlin.kotlin-dsl" version "4.1.2" + id "org.gradle.kotlin.kotlin-dsl" version "4.2.1" } repositories { diff --git a/fenix/plugins/apksize/build.gradle b/fenix/plugins/apksize/build.gradle index 77b077a8b30c..5a38f6a8b435 100644 --- a/fenix/plugins/apksize/build.gradle +++ b/fenix/plugins/apksize/build.gradle @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ plugins { - id "org.gradle.kotlin.kotlin-dsl" version "4.1.2" + id "org.gradle.kotlin.kotlin-dsl" version "4.2.1" } repositories { diff --git a/fenix/plugins/fenixdependencies/build.gradle b/fenix/plugins/fenixdependencies/build.gradle index 7e8043a2a8f1..f74423c7a6fd 100644 --- a/fenix/plugins/fenixdependencies/build.gradle +++ b/fenix/plugins/fenixdependencies/build.gradle @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ plugins { - id "org.gradle.kotlin.kotlin-dsl" version "4.1.2" + id "org.gradle.kotlin.kotlin-dsl" version "4.2.1" } repositories { diff --git a/focus-android/plugins/focusdependencies/build.gradle b/focus-android/plugins/focusdependencies/build.gradle index 436ef96e4935..9e4d799cf2bf 100644 --- a/focus-android/plugins/focusdependencies/build.gradle +++ b/focus-android/plugins/focusdependencies/build.gradle @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ plugins { - id "org.gradle.kotlin.kotlin-dsl" version "4.1.2" + id "org.gradle.kotlin.kotlin-dsl" version "4.2.1" } repositories { From 923562434b901a92a17e42b86576ef63aedae95d Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Tue, 12 Dec 2023 10:58:48 +0200 Subject: [PATCH 063/586] Bug 1870050 - Suppress RestrictedApi lint --- .../src/main/java/org/mozilla/fenix/components/FenixSnackbar.kt | 2 +- fenix/app/src/main/java/org/mozilla/fenix/ext/Toolbar.kt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/FenixSnackbar.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/FenixSnackbar.kt index 9bbc4d0b6a35..3909a52c0fa8 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/components/FenixSnackbar.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/components/FenixSnackbar.kt @@ -121,7 +121,7 @@ class FenixSnackbar private constructor( * Suppressing ComplexCondition. Yes it's unfortunately complex but that's the nature * of the snackbar handling by Android. It will be simpler once dynamic toolbar is always on. */ - @Suppress("ComplexCondition") + @Suppress("ComplexCondition", "RestrictedApi") fun make( view: View, duration: Int = LENGTH_LONG, diff --git a/fenix/app/src/main/java/org/mozilla/fenix/ext/Toolbar.kt b/fenix/app/src/main/java/org/mozilla/fenix/ext/Toolbar.kt index b7e9b953b64a..c7b6325dbdb2 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/ext/Toolbar.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/ext/Toolbar.kt @@ -33,6 +33,7 @@ fun Toolbar.setToolbarColors(@ColorInt foreground: Int, @ColorInt background: In } } +@Suppress("RestrictedApi") private fun themeActionMenuView(item: ActionMenuView, colorFilter: ColorFilter?) { item.forEach { innerChild -> if (innerChild is ActionMenuItemView) { From a4dbf5ef95f73cd879895ce8ce39f89233e5feeb Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Tue, 12 Dec 2023 10:59:07 +0200 Subject: [PATCH 064/586] Bug 1870050 - Suppress false positive DiffUtilEquals lint --- .../java/org/mozilla/fenix/home/topsites/TopSitesPagerAdapter.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesPagerAdapter.kt b/fenix/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesPagerAdapter.kt index 0a56a0c9cf72..a480f861aff5 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesPagerAdapter.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesPagerAdapter.kt @@ -97,6 +97,7 @@ class TopSitesPagerAdapter( } override fun areContentsTheSame(oldItem: List, newItem: List): Boolean { + @Suppress("DiffUtilEquals") return newItem.zip(oldItem).all { (new, old) -> new == old } } From 7acc6617d028bd182918d7efd9976a22e88d2261 Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:07:53 +0200 Subject: [PATCH 065/586] Bug 1870050 - Remove improper usage of VisibleForTesting annotation --- .../mozilla/components/feature/readerview/ReaderViewFeature.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/android-components/components/feature/readerview/src/main/java/mozilla/components/feature/readerview/ReaderViewFeature.kt b/android-components/components/feature/readerview/src/main/java/mozilla/components/feature/readerview/ReaderViewFeature.kt index 84b7b100687f..51d6083a6cde 100644 --- a/android-components/components/feature/readerview/src/main/java/mozilla/components/feature/readerview/ReaderViewFeature.kt +++ b/android-components/components/feature/readerview/src/main/java/mozilla/components/feature/readerview/ReaderViewFeature.kt @@ -303,7 +303,6 @@ class ReaderViewFeature( return readerBaseUrl?.let { it + "readerview.html?url=$encodedUrl&id=$id&colorScheme=$colorScheme" } } - @VisibleForTesting companion object { private val logger = Logger("ReaderView") From be0862e38b13b64befa6ae91bf708dfd0c90c921 Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:17:39 +0200 Subject: [PATCH 066/586] Bug 1870050 - Add check for proper RegisterReceiverFlags in tests. Skipping this parameter would result in a UnspecifiedRegisterReceiverFlag error. --- .../media/service/MediaSessionServiceDelegateTest.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/android-components/components/feature/media/src/test/java/mozilla/components/feature/media/service/MediaSessionServiceDelegateTest.kt b/android-components/components/feature/media/src/test/java/mozilla/components/feature/media/service/MediaSessionServiceDelegateTest.kt index dbe7a09d8b73..8880f602960a 100644 --- a/android-components/components/feature/media/src/test/java/mozilla/components/feature/media/service/MediaSessionServiceDelegateTest.kt +++ b/android-components/components/feature/media/src/test/java/mozilla/components/feature/media/service/MediaSessionServiceDelegateTest.kt @@ -7,6 +7,7 @@ package mozilla.components.feature.media.service import android.app.ForegroundServiceStartNotAllowedException import android.app.Notification import android.content.BroadcastReceiver +import android.content.Context import android.content.Intent import android.graphics.Bitmap import android.os.Build @@ -440,7 +441,7 @@ class MediaSessionServiceDelegateTest { delegate.registerBecomingNoisyListenerIfNeeded(mock()) - verify(context, never()).registerReceiver(any(), any()) + verify(context, never()).registerReceiver(any(), any(), eq(Context.RECEIVER_NOT_EXPORTED)) } @Test @@ -459,7 +460,11 @@ class MediaSessionServiceDelegateTest { val context = spy(testContext) val delegate = MediaSessionServiceDelegate(context, mock(), mock(), mock(), mock()) delegate.noisyAudioStreamReceiver = mock() - context.registerReceiver(delegate.noisyAudioStreamReceiver, delegate.intentFilter) + context.registerReceiver( + delegate.noisyAudioStreamReceiver, + delegate.intentFilter, + Context.RECEIVER_NOT_EXPORTED, + ) val receiverCaptor = argumentCaptor() delegate.unregisterBecomingNoisyListenerIfNeeded() From bba9a9a5a7a3057960a40b12fcd43b3c72bffa12 Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Thu, 25 Jan 2024 13:41:09 +0200 Subject: [PATCH 067/586] Bug 1870050 - Explicitly add FOREGROUND_SERVICE specific permissions. The permissions already included the merged manifest, but linting shows error if not added directly. --- focus-android/app/src/main/AndroidManifest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/focus-android/app/src/main/AndroidManifest.xml b/focus-android/app/src/main/AndroidManifest.xml index b4ce4e651281..72926930aed8 100644 --- a/focus-android/app/src/main/AndroidManifest.xml +++ b/focus-android/app/src/main/AndroidManifest.xml @@ -15,6 +15,9 @@ + + + Date: Fri, 26 Jan 2024 13:18:23 +0200 Subject: [PATCH 068/586] Bug 1870050 - Add RECEIVER_NOT_EXPORTED flag to receiver. --- .../main/java/org/mozilla/samples/crash/CrashActivity.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/android-components/samples/crash/src/main/java/org/mozilla/samples/crash/CrashActivity.kt b/android-components/samples/crash/src/main/java/org/mozilla/samples/crash/CrashActivity.kt index 26c4a0661ff9..2bcce48acc4c 100644 --- a/android-components/samples/crash/src/main/java/org/mozilla/samples/crash/CrashActivity.kt +++ b/android-components/samples/crash/src/main/java/org/mozilla/samples/crash/CrashActivity.kt @@ -16,6 +16,7 @@ import androidx.core.content.ContextCompat import com.google.android.material.snackbar.Snackbar import mozilla.components.concept.base.crash.Breadcrumb import mozilla.components.lib.crash.Crash +import mozilla.components.support.utils.ext.registerReceiverCompat import org.mozilla.samples.crash.databinding.ActivityCrashBinding class CrashActivity : AppCompatActivity(), View.OnClickListener { @@ -61,7 +62,12 @@ class CrashActivity : AppCompatActivity(), View.OnClickListener { override fun onResume() { super.onResume() - registerReceiver(receiver, IntentFilter(CrashApplication.NON_FATAL_CRASH_BROADCAST)) + + registerReceiverCompat( + receiver, + IntentFilter(CrashApplication.NON_FATAL_CRASH_BROADCAST), + ContextCompat.RECEIVER_NOT_EXPORTED, + ) crashReporter.recordCrashBreadcrumb( Breadcrumb( From 7612d749913c4c15b46a0c258f46dbaf794a124c Mon Sep 17 00:00:00 2001 From: DreVla Date: Fri, 2 Feb 2024 12:22:02 +0200 Subject: [PATCH 069/586] Bug 1840969 - Add title for homepage default browser info card Title for the card info to set Firefox as default browser was missing, "Switch your default browser" is the title now, to match with iOS. --- fenix/app/messaging-evergreen-messages.fml.yaml | 1 + .../src/main/java/org/mozilla/fenix/compose/MessageCard.kt | 4 ++-- fenix/app/src/main/res/values/strings.xml | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/fenix/app/messaging-evergreen-messages.fml.yaml b/fenix/app/messaging-evergreen-messages.fml.yaml index a09773ac5a0c..36e7d2b15ba1 100644 --- a/fenix/app/messaging-evergreen-messages.fml.yaml +++ b/fenix/app/messaging-evergreen-messages.fml.yaml @@ -25,6 +25,7 @@ import: - value: messages: default-browser: + title: default_browser_experiment_card_title text: default_browser_experiment_card_text surface: homescreen action: "MAKE_DEFAULT_BROWSER" diff --git a/fenix/app/src/main/java/org/mozilla/fenix/compose/MessageCard.kt b/fenix/app/src/main/java/org/mozilla/fenix/compose/MessageCard.kt index d5a6cc1d8a18..d3669470c03a 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/compose/MessageCard.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/compose/MessageCard.kt @@ -208,7 +208,7 @@ private fun MessageCardPreview() { ) { MessageCard( messageText = stringResource(id = R.string.default_browser_experiment_card_text), - titleText = stringResource(id = R.string.bookmark_empty_title_error), + titleText = stringResource(id = R.string.default_browser_experiment_card_title), onClick = {}, onCloseButtonClick = {}, ) @@ -245,7 +245,7 @@ private fun MessageCardWithButtonLabelPreview() { ) { MessageCard( messageText = stringResource(id = R.string.default_browser_experiment_card_text), - titleText = stringResource(id = R.string.bookmark_empty_title_error), + titleText = stringResource(id = R.string.default_browser_experiment_card_title), buttonText = stringResource(id = R.string.preferences_set_as_default_browser), onClick = {}, onCloseButtonClick = {}, diff --git a/fenix/app/src/main/res/values/strings.xml b/fenix/app/src/main/res/values/strings.xml index ad5d9588a897..119fb2d1d462 100644 --- a/fenix/app/src/main/res/values/strings.xml +++ b/fenix/app/src/main/res/values/strings.xml @@ -2089,6 +2089,9 @@ %s search + + Switch your default browser + Set links from websites, emails, and messages to open automatically in Firefox. From 3d759e344795e5c8fe536ef511f9c2045f563b73 Mon Sep 17 00:00:00 2001 From: RebecaTudor Date: Wed, 31 Jan 2024 17:25:55 +0200 Subject: [PATCH 070/586] Bug 1809798 - Loads the right wallpaper when changing orientation Because of the android:configChanges from Manifest that disable the automate Activity recreation, the responsibility of handling the configuration changes is transferred to Activity. When configurations changes, onConfigurationChanged() is called. So now when this function called, the correct orientation is sent forward as parameter of applyWallpaper. --- .../org/mozilla/fenix/home/HomeFragment.kt | 23 ++++++++++---- .../fenix/wallpapers/WallpapersUseCases.kt | 21 +++++++------ .../wallpapers/WallpapersUseCasesTest.kt | 30 ++++++++++++++----- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 056677d96e01..588737e35a1b 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -248,7 +248,11 @@ class HomeFragment : Fragment() { val components = requireComponents val currentWallpaperName = requireContext().settings().currentWallpaperName - applyWallpaper(wallpaperName = currentWallpaperName, orientationChange = false) + applyWallpaper( + wallpaperName = currentWallpaperName, + orientationChange = false, + orientation = requireContext().resources.configuration.orientation, + ) components.appStore.dispatch(AppAction.ModeChange(browsingModeManager.mode)) @@ -454,7 +458,11 @@ class HomeFragment : Fragment() { homeMenuView?.dismissMenu() val currentWallpaperName = requireContext().settings().currentWallpaperName - applyWallpaper(wallpaperName = currentWallpaperName, orientationChange = true) + applyWallpaper( + wallpaperName = currentWallpaperName, + orientationChange = true, + orientation = newConfig.orientation, + ) } /** @@ -999,7 +1007,7 @@ class HomeFragment : Fragment() { internal fun shouldEnableWallpaper() = (activity as? HomeActivity)?.themeManager?.currentTheme?.isPrivate?.not() ?: false - private fun applyWallpaper(wallpaperName: String, orientationChange: Boolean) { + private fun applyWallpaper(wallpaperName: String, orientationChange: Boolean, orientation: Int) { when { !shouldEnableWallpaper() || (wallpaperName == lastAppliedWallpaperName && !orientationChange) -> return @@ -1012,8 +1020,7 @@ class HomeFragment : Fragment() { // loadBitmap does file lookups based on name, so we don't need a fully // qualified type to load the image val wallpaper = Wallpaper.Default.copy(name = wallpaperName) - val wallpaperImage = - context?.let { requireComponents.useCases.wallpaperUseCases.loadBitmap(it, wallpaper) } + val wallpaperImage = requireComponents.useCases.wallpaperUseCases.loadBitmap(wallpaper, orientation) wallpaperImage?.let { it.scaleToBottomOfView(binding.wallpaperImageView) binding.wallpaperImageView.isVisible = true @@ -1059,7 +1066,11 @@ class HomeFragment : Fragment() { .distinctUntilChanged() .collect { if (it.name != lastAppliedWallpaperName) { - applyWallpaper(wallpaperName = it.name, orientationChange = false) + applyWallpaper( + wallpaperName = it.name, + orientationChange = false, + orientation = requireContext().resources.configuration.orientation, + ) } } } diff --git a/fenix/app/src/main/java/org/mozilla/fenix/wallpapers/WallpapersUseCases.kt b/fenix/app/src/main/java/org/mozilla/fenix/wallpapers/WallpapersUseCases.kt index 8d9eb70771e0..cdb70c16318c 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/wallpapers/WallpapersUseCases.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/wallpapers/WallpapersUseCases.kt @@ -5,14 +5,13 @@ package org.mozilla.fenix.wallpapers import android.content.Context +import android.content.res.Configuration import android.graphics.Bitmap import android.graphics.BitmapFactory -import androidx.annotation.UiContext import androidx.annotation.VisibleForTesting import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import mozilla.components.concept.fetch.Client -import mozilla.components.support.utils.ext.isLandscape import org.mozilla.fenix.components.AppStore import org.mozilla.fenix.components.appstate.AppAction import org.mozilla.fenix.ext.settings @@ -160,25 +159,25 @@ class WallpapersUseCases( /** * Load the bitmap for a [wallpaper], if available. * - * @param context The context used to get wallpaper orientation. * @param wallpaper The wallpaper to load a bitmap for. + * @param orientation The orientation of wallpaper. */ - suspend operator fun invoke(@UiContext context: Context, wallpaper: Wallpaper): Bitmap? + suspend operator fun invoke(wallpaper: Wallpaper, orientation: Int): Bitmap? } @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal class DefaultLoadBitmapUseCase( private val getFilesDir: suspend () -> File, ) : LoadBitmapUseCase { - override suspend fun invoke(@UiContext context: Context, wallpaper: Wallpaper): Bitmap? = - loadWallpaperFromDisk(context, wallpaper) + override suspend fun invoke(wallpaper: Wallpaper, orientation: Int): Bitmap? = + loadWallpaperFromDisk(wallpaper, orientation) @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal suspend fun loadWallpaperFromDisk( - @UiContext context: Context, wallpaper: Wallpaper, + orientation: Int, ): Bitmap? = Result.runCatching { - val path = wallpaper.getLocalPathFromContext(context) + val path = wallpaper.getLocalPathFromContext(orientation) withContext(Dispatchers.IO) { val file = File(getFilesDir(), path) BitmapFactory.decodeStream(file.inputStream()) @@ -189,13 +188,13 @@ class WallpapersUseCases( * Get the expected local path on disk for a wallpaper. This will differ depending * on orientation and app theme. */ - private fun Wallpaper.getLocalPathFromContext(@UiContext context: Context): String { - val orientation = if (context.isLandscape()) { + private fun Wallpaper.getLocalPathFromContext(orientation: Int): String { + val orientationWallpaper = if (orientation == Configuration.ORIENTATION_LANDSCAPE) { Wallpaper.ImageType.Landscape } else { Wallpaper.ImageType.Portrait } - return Wallpaper.getLocalPath(name, orientation) + return Wallpaper.getLocalPath(name, orientationWallpaper) } } diff --git a/fenix/app/src/test/java/org/mozilla/fenix/wallpapers/WallpapersUseCasesTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/wallpapers/WallpapersUseCasesTest.kt index e2716f30015a..858f2c2dbe84 100644 --- a/fenix/app/src/test/java/org/mozilla/fenix/wallpapers/WallpapersUseCasesTest.kt +++ b/fenix/app/src/test/java/org/mozilla/fenix/wallpapers/WallpapersUseCasesTest.kt @@ -4,7 +4,7 @@ package org.mozilla.fenix.wallpapers -import android.content.Context +import android.content.res.Configuration import io.mockk.Runs import io.mockk.coEvery import io.mockk.coVerify @@ -31,7 +31,8 @@ import org.mozilla.fenix.wallpapers.LegacyWallpaperMigration.Companion.TURNING_R import org.mozilla.fenix.wallpapers.LegacyWallpaperMigration.Companion.TURNING_RED_PANDA_WALLPAPER_NAME import org.mozilla.fenix.wallpapers.LegacyWallpaperMigration.Companion.TURNING_RED_WALLPAPER_TEXT_COLOR import java.io.File -import java.util.* +import java.util.Calendar +import java.util.Date import kotlin.random.Random class WallpapersUseCasesTest { @@ -496,18 +497,33 @@ class WallpapersUseCasesTest { } @Test - fun `GIVEN the context WHEN bitmap is loaded THEN loadWallpaperFromDisk method is called with the correct context and wallpaper`() = + fun `GIVEN the portrait orientation WHEN bitmap is loaded THEN loadWallpaperFromDisk method is called with the correct wallpaper and orientation`() = runTest { val wallpaper: Wallpaper = mockk { every { name } returns "test" } - val context = mockk(relaxed = true) + val orientation = Configuration.ORIENTATION_PORTRAIT val defaultLoadBitmapUseCase = spyk(WallpapersUseCases.DefaultLoadBitmapUseCase { mockFolder }) - coEvery { defaultLoadBitmapUseCase.loadWallpaperFromDisk(context, wallpaper) } returns mockk() + coEvery { defaultLoadBitmapUseCase.loadWallpaperFromDisk(wallpaper, orientation) } returns mockk() - defaultLoadBitmapUseCase.invoke(context, wallpaper) + defaultLoadBitmapUseCase.invoke(wallpaper, orientation) - coVerify { defaultLoadBitmapUseCase.loadWallpaperFromDisk(context, wallpaper) } + coVerify { defaultLoadBitmapUseCase.loadWallpaperFromDisk(wallpaper, orientation) } + } + + @Test + fun `GIVEN the landscape orientation WHEN bitmap is loaded THEN loadWallpaperFromDisk method is called with the correct wallpaper and orientation`() = + runTest { + val wallpaper: Wallpaper = mockk { + every { name } returns "test" + } + val orientation = Configuration.ORIENTATION_LANDSCAPE + val defaultLoadBitmapUseCase = spyk(WallpapersUseCases.DefaultLoadBitmapUseCase { mockFolder }) + coEvery { defaultLoadBitmapUseCase.loadWallpaperFromDisk(wallpaper, orientation) } returns mockk() + + defaultLoadBitmapUseCase.invoke(wallpaper, orientation) + + coVerify { defaultLoadBitmapUseCase.loadWallpaperFromDisk(wallpaper, orientation) } } private enum class TimeRelation { From b2cef5bd5f36f4da241fad9a702eff7bdd863186 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 08:54:24 -0500 Subject: [PATCH 071/586] Update GeckoView (Nightly) to 124.0.20240205094658. (#5456) Co-authored-by: MickeyMoz --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 47defe5e953b..81b89bf9438d 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240204213653" + const val version = "124.0.20240205094658" /** * GeckoView channel From 9aabff678ada90e66610ebbd0ff844d9dc7506ae Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Mon, 5 Feb 2024 05:33:39 +0000 Subject: [PATCH 072/586] Update A-S to 124.20240205050332. --- .../plugins/dependencies/src/main/java/ApplicationServices.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt index b73afcae4026..e23e485381d7 100644 --- a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt +++ b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // These lines are generated by android-components/automation/application-services-nightly-bump.py -val VERSION = "124.20240203050301" +val VERSION = "124.20240205050332" val CHANNEL = ApplicationServicesChannel.NIGHTLY object ApplicationServicesConfig { From 4080770147f114bd0aea9459d94c77acfa337134 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Fri, 2 Feb 2024 15:56:11 -0500 Subject: [PATCH 073/586] Bug 1878409 - Update Gradle to version 8.6 --- .../gradle/wrapper/gradle-wrapper.properties | 2 +- android-components/gradlew.bat | 20 +++++++++---------- .../gradle/wrapper/gradle-wrapper.properties | 2 +- fenix/gradlew.bat | 20 +++++++++---------- .../gradle/wrapper/gradle-wrapper.properties | 2 +- focus-android/gradlew.bat | 20 +++++++++---------- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/android-components/gradle/wrapper/gradle-wrapper.properties b/android-components/gradle/wrapper/gradle-wrapper.properties index 1af9e0930b89..a80b22ce5cff 100644 --- a/android-components/gradle/wrapper/gradle-wrapper.properties +++ b/android-components/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/android-components/gradlew.bat b/android-components/gradlew.bat index 6689b85beecd..7101f8e4676f 100644 --- a/android-components/gradlew.bat +++ b/android-components/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/fenix/gradle/wrapper/gradle-wrapper.properties b/fenix/gradle/wrapper/gradle-wrapper.properties index 1af9e0930b89..a80b22ce5cff 100644 --- a/fenix/gradle/wrapper/gradle-wrapper.properties +++ b/fenix/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/fenix/gradlew.bat b/fenix/gradlew.bat index 6689b85beecd..7101f8e4676f 100644 --- a/fenix/gradlew.bat +++ b/fenix/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/focus-android/gradle/wrapper/gradle-wrapper.properties b/focus-android/gradle/wrapper/gradle-wrapper.properties index 1af9e0930b89..a80b22ce5cff 100644 --- a/focus-android/gradle/wrapper/gradle-wrapper.properties +++ b/focus-android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/focus-android/gradlew.bat b/focus-android/gradlew.bat index 6689b85beecd..7101f8e4676f 100644 --- a/focus-android/gradlew.bat +++ b/focus-android/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail From c5b09786d0cb991abaef94a5be98e44537d67a43 Mon Sep 17 00:00:00 2001 From: ohall-m Date: Fri, 2 Feb 2024 13:07:20 -0500 Subject: [PATCH 074/586] Bug 1878091 - Translations Engine State and Translation Status Sync This bug refines the reducer on a translations engine state change to ensure the Fenix translations state and engine translations state are in sync. --- .../state/reducer/TranslationsStateReducer.kt | 19 ++++++--- .../state/action/TranslationsActionTest.kt | 39 +++++++++++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt index cedc93f756dc..c166fec44d5a 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt @@ -30,18 +30,25 @@ internal object TranslationsStateReducer { } is TranslationsAction.TranslateStateChangeAction -> { - if (action.translationEngineState.requestedTranslationPair != null) { + if (action.translationEngineState.requestedTranslationPair == null || + action.translationEngineState.requestedTranslationPair?.fromLanguage == null || + action.translationEngineState.requestedTranslationPair?.toLanguage == null + ) { + state.copyWithTranslationsState(action.tabId) { + it.copy( + isTranslated = false, + translationEngineState = action.translationEngineState, + ) + } + } else { state.copyWithTranslationsState(action.tabId) { it.copy( isTranslated = true, + translationError = null, + translationEngineState = action.translationEngineState, ) } } - state.copyWithTranslationsState(action.tabId) { - it.copy( - translationEngineState = action.translationEngineState, - ) - } } is TranslationsAction.TranslateAction -> diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt index 5b94d28fc243..c6e2db28bede 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt @@ -9,15 +9,20 @@ import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.concept.engine.translate.DetectedLanguages import mozilla.components.concept.engine.translate.Language +import mozilla.components.concept.engine.translate.TranslationEngineState import mozilla.components.concept.engine.translate.TranslationError import mozilla.components.concept.engine.translate.TranslationOperation import mozilla.components.concept.engine.translate.TranslationPageSettings +import mozilla.components.concept.engine.translate.TranslationPair import mozilla.components.concept.engine.translate.TranslationSupport import mozilla.components.support.test.ext.joinBlocking import mozilla.components.support.test.mock import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import java.lang.Exception @@ -69,6 +74,40 @@ class TranslationsActionTest { assertEquals(true, tabState().translationsState.translationEngineState != null) } + @Test + fun `WHEN a TranslateStateChangeAction is dispatched THEN the translation status updates accordingly`() { + assertNull(tabState().translationsState.translationEngineState) + assertFalse(tabState().translationsState.isTranslated) + + val translatedEngineState = TranslationEngineState( + detectedLanguages = DetectedLanguages(documentLangTag = "es", supportedDocumentLang = true, userPreferredLangTag = "en"), + error = null, + isEngineReady = true, + requestedTranslationPair = TranslationPair(fromLanguage = "es", toLanguage = "en"), + ) + + store.dispatch(TranslationsAction.TranslateStateChangeAction(tabId = tab.id, translationEngineState = translatedEngineState)) + .joinBlocking() + + // Translated state + assertEquals(translatedEngineState, tabState().translationsState.translationEngineState) + assertTrue(tabState().translationsState.isTranslated) + + val nonTranslatedEngineState = TranslationEngineState( + detectedLanguages = DetectedLanguages(documentLangTag = "es", supportedDocumentLang = true, userPreferredLangTag = "en"), + error = null, + isEngineReady = true, + requestedTranslationPair = TranslationPair(fromLanguage = null, toLanguage = null), + ) + + store.dispatch(TranslationsAction.TranslateStateChangeAction(tabId = tab.id, nonTranslatedEngineState)) + .joinBlocking() + + // Non-translated state + assertEquals(nonTranslatedEngineState, tabState().translationsState.translationEngineState) + assertFalse(tabState().translationsState.isTranslated) + } + @Test fun `WHEN a TranslateAction is dispatched AND successful THEN update translation processing status`() { // Initial From c6ed1d76995c7a0946dd8dfd8f089414f075726c Mon Sep 17 00:00:00 2001 From: Titouan Thibaud Date: Mon, 5 Feb 2024 11:36:09 +0100 Subject: [PATCH 075/586] Bug 1807080 - Fix PTR dark theme colors Co-authored-by: Jonathan Almeida --- .../org/mozilla/fenix/browser/BaseBrowserFragment.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index b6fbe9a5270c..ae27629bb8bd 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -942,9 +942,12 @@ abstract class BaseBrowserFragment : binding.swipeRefresh.isEnabled = shouldPullToRefreshBeEnabled(false) if (binding.swipeRefresh.isEnabled) { - val primaryTextColor = - ThemeManager.resolveAttribute(R.attr.textPrimary, context) - binding.swipeRefresh.setColorSchemeColors(primaryTextColor) + val primaryTextColor = ThemeManager.resolveAttribute(R.attr.textPrimary, context) + val primaryBackgroundColor = ThemeManager.resolveAttribute(R.attr.layer2, context) + binding.swipeRefresh.apply { + setColorSchemeResources(primaryTextColor) + setProgressBackgroundColorSchemeResource(primaryBackgroundColor) + } swipeRefreshFeature.set( feature = SwipeRefreshFeature( requireComponents.core.store, From 0a66e9a066e92df9b5cbb8949f6fcd0e5a19a598 Mon Sep 17 00:00:00 2001 From: ohall-m Date: Wed, 31 Jan 2024 10:09:30 -0500 Subject: [PATCH 076/586] Bug 1877712 - Update Mock Translations Languages Bug updates mock display languages to match the current engine support. --- .../TranslationsDialogBottomSheet.kt | 30 +++++------ .../AutomaticTranslationPreference.kt | 8 +-- .../DownloadLanguagesPreference.kt | 51 ++++--------------- 3 files changed, 25 insertions(+), 64 deletions(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBottomSheet.kt b/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBottomSheet.kt index 6934d32d6293..18b1f11cf184 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBottomSheet.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBottomSheet.kt @@ -568,14 +568,14 @@ internal fun getTranslateFromLanguageList(): List { return mutableListOf().apply { add( Language( - code = Locale.CHINA.toLanguageTag(), - localizedDisplayName = Locale.CHINA.displayLanguage, + code = Locale.ENGLISH.toLanguageTag(), + localizedDisplayName = Locale.ENGLISH.displayLanguage, ), ) add( Language( - code = Locale.ENGLISH.toLanguageTag(), - localizedDisplayName = Locale.ENGLISH.displayLanguage, + code = Locale.FRENCH.toLanguageTag(), + localizedDisplayName = Locale.FRENCH.displayLanguage, ), ) add( @@ -586,8 +586,8 @@ internal fun getTranslateFromLanguageList(): List { ) add( Language( - code = Locale.JAPANESE.toLanguageTag(), - localizedDisplayName = Locale.JAPANESE.displayLanguage, + code = Locale.ITALIAN.toLanguageTag(), + localizedDisplayName = Locale.ITALIAN.displayLanguage, ), ) } @@ -598,14 +598,8 @@ internal fun getTranslateToLanguageList(): List { return mutableListOf().apply { add( Language( - code = Locale.KOREAN.toLanguageTag(), - localizedDisplayName = Locale.KOREAN.displayLanguage, - ), - ) - add( - Language( - code = Locale.CANADA.toLanguageTag(), - localizedDisplayName = Locale.CANADA.displayLanguage, + code = Locale.ENGLISH.toLanguageTag(), + localizedDisplayName = Locale.ENGLISH.displayLanguage, ), ) add( @@ -616,14 +610,14 @@ internal fun getTranslateToLanguageList(): List { ) add( Language( - code = Locale.ITALY.toLanguageTag(), - localizedDisplayName = Locale.ITALY.displayLanguage, + code = Locale.GERMAN.toLanguageTag(), + localizedDisplayName = Locale.GERMAN.displayLanguage, ), ) add( Language( - code = Locale.GERMAN.toLanguageTag(), - localizedDisplayName = Locale.GERMAN.displayLanguage, + code = Locale.ITALIAN.toLanguageTag(), + localizedDisplayName = Locale.ITALIAN.displayLanguage, ), ) } diff --git a/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationPreference.kt b/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationPreference.kt index 0cc3ffa2ef33..4ce45c4e2b88 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationPreference.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/automatic/AutomaticTranslationPreference.kt @@ -78,25 +78,25 @@ internal fun getAutomaticTranslationListPreferences(): List().apply { add( AutomaticTranslationItemPreference( - displayName = Locale.CANADA.displayLanguage, + displayName = Locale.ENGLISH.displayLanguage, automaticTranslationOptionPreference = AutomaticTranslationOptionPreference.AlwaysTranslate(), ), ) add( AutomaticTranslationItemPreference( - displayName = Locale.FRANCE.displayLanguage, + displayName = Locale.FRENCH.displayLanguage, automaticTranslationOptionPreference = AutomaticTranslationOptionPreference.OfferToTranslate(), ), ) add( AutomaticTranslationItemPreference( - displayName = Locale.GERMANY.displayLanguage, + displayName = Locale.GERMAN.displayLanguage, automaticTranslationOptionPreference = AutomaticTranslationOptionPreference.NeverTranslate(), ), ) add( AutomaticTranslationItemPreference( - displayName = Locale.CHINA.displayLanguage, + displayName = Locale.ITALIAN.displayLanguage, automaticTranslationOptionPreference = AutomaticTranslationOptionPreference.AlwaysTranslate(), ), ) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/downloadlanguages/DownloadLanguagesPreference.kt b/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/downloadlanguages/DownloadLanguagesPreference.kt index 7089d3d1e2c3..aaf9976e736c 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/downloadlanguages/DownloadLanguagesPreference.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/downloadlanguages/DownloadLanguagesPreference.kt @@ -386,11 +386,11 @@ internal fun getLanguageListPreference(): List { DownloadLanguageItemPreference( languageModel = TranslationsController.RuntimeTranslation.LanguageModel( TranslationsController.Language( - Locale.CHINA.toLanguageTag(), - Locale.CHINA.displayLanguage, + Locale.FRENCH.toLanguageTag(), + Locale.FRENCH.displayLanguage, ), false, - 4000, + 30000000, ), state = DownloadLanguageItemStatePreference( type = DownloadLanguageItemTypePreference.GeneralLanguage, @@ -402,28 +402,11 @@ internal fun getLanguageListPreference(): List { DownloadLanguageItemPreference( languageModel = TranslationsController.RuntimeTranslation.LanguageModel( TranslationsController.Language( - Locale.KOREAN.toLanguageTag(), - Locale.KOREAN.displayLanguage, + Locale.GERMAN.toLanguageTag(), + Locale.GERMAN.displayLanguage, ), false, - 3000, - ), - state = DownloadLanguageItemStatePreference( - type = DownloadLanguageItemTypePreference.GeneralLanguage, - status = DownloadLanguageItemStatusPreference.NotDownloaded, - ), - ), - ) - - add( - DownloadLanguageItemPreference( - languageModel = TranslationsController.RuntimeTranslation.LanguageModel( - TranslationsController.Language( - Locale.FRANCE.toLanguageTag(), - Locale.FRANCE.displayLanguage, - ), - false, - 2000, + 30000000, ), state = DownloadLanguageItemStatePreference( type = DownloadLanguageItemTypePreference.GeneralLanguage, @@ -439,7 +422,7 @@ internal fun getLanguageListPreference(): List { Locale.ITALIAN.displayLanguage, ), false, - 1000, + 30000000, ), state = DownloadLanguageItemStatePreference( type = DownloadLanguageItemTypePreference.GeneralLanguage, @@ -455,7 +438,7 @@ internal fun getLanguageListPreference(): List { Locale.ENGLISH.displayLanguage, ), true, - 3000, + 30000000, ), state = DownloadLanguageItemStatePreference( type = DownloadLanguageItemTypePreference.PivotLanguage, @@ -463,22 +446,6 @@ internal fun getLanguageListPreference(): List { ), ), ) - add( - DownloadLanguageItemPreference( - languageModel = TranslationsController.RuntimeTranslation.LanguageModel( - TranslationsController.Language( - Locale.JAPANESE.toLanguageTag(), - Locale.JAPANESE.displayLanguage, - ), - true, - 3000, - ), - state = DownloadLanguageItemStatePreference( - type = DownloadLanguageItemTypePreference.GeneralLanguage, - status = DownloadLanguageItemStatusPreference.NotDownloaded, - ), - ), - ) add( DownloadLanguageItemPreference( languageModel = TranslationsController.RuntimeTranslation.LanguageModel( @@ -487,7 +454,7 @@ internal fun getLanguageListPreference(): List { stringResource(id = R.string.download_language_all_languages_item_preference), ), true, - 300000, + 90000000, ), state = DownloadLanguageItemStatePreference( type = DownloadLanguageItemTypePreference.AllLanguages, From ea63f1103b5f9bae57b2f017723bfaadf9000323 Mon Sep 17 00:00:00 2001 From: ohall-m Date: Thu, 1 Feb 2024 13:41:29 -0500 Subject: [PATCH 077/586] Bug 1877588 - TranslationsMiddleware Dispatcher Scope Issue This bug is to fix the `Must have a Handler` issue in the TranslationsMiddleware when attempting to call using `Dispatcher.IO`. --- .../middleware/TranslationsMiddleware.kt | 56 +++++++++---------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt index 5062a870f566..dc4abb5102bf 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt @@ -5,9 +5,7 @@ package mozilla.components.browser.state.engine.middleware import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import mozilla.components.browser.state.action.BrowserAction import mozilla.components.browser.state.action.TranslationsAction import mozilla.components.browser.state.action.TranslationsAction.TranslateExpectedAction @@ -80,35 +78,33 @@ class TranslationsMiddleware( * @param context Context to use to dispatch to the store. * @param tabId Tab ID associated with the request. */ - private suspend fun requestSupportedLanguages( + private fun requestSupportedLanguages( context: MiddlewareContext, tabId: String, - ) = withContext(Dispatchers.IO) { - scope.launch { - engine.getSupportedTranslationLanguages( - - onSuccess = { - context.store.dispatch( - TranslationsAction.TranslateSetLanguagesAction( - tabId = tabId, - supportedLanguages = it, - ), - ) - logger.info("Success requesting supported languages.") - }, - - onError = { - context.store.dispatch( - TranslationsAction.TranslateExceptionAction( - tabId = tabId, - operation = TranslationOperation.FETCH_LANGUAGES, - translationError = TranslationError.CouldNotLoadLanguagesError(it), - ), - ) - logger.error("Error requesting supported languages: ", it) - }, - ) - } + ) { + engine.getSupportedTranslationLanguages( + + onSuccess = { + context.store.dispatch( + TranslationsAction.TranslateSetLanguagesAction( + tabId = tabId, + supportedLanguages = it, + ), + ) + logger.info("Success requesting supported languages.") + }, + + onError = { + context.store.dispatch( + TranslationsAction.TranslateExceptionAction( + tabId = tabId, + operation = TranslationOperation.FETCH_LANGUAGES, + translationError = TranslationError.CouldNotLoadLanguagesError(it), + ), + ) + logger.error("Error requesting supported languages: ", it) + }, + ) } /** @@ -122,7 +118,7 @@ class TranslationsMiddleware( private suspend fun requestTranslationPageSettings( context: MiddlewareContext, tabId: String, - ) = withContext(Dispatchers.IO) { + ) { // Always offer setting val alwaysOfferPopup: Boolean = engine.getTranslationsOfferPopup() From 5a584b45db40ba51eb5a247bbd94ea789a136b08 Mon Sep 17 00:00:00 2001 From: jackyzy823 Date: Sun, 4 Feb 2024 08:55:50 +0800 Subject: [PATCH 078/586] Bug 1874522 - Catch OOM, set desired size and disable coil-kt cache in SVG decoder --- .../browser/icons/decoder/SvgIconDecoder.kt | 26 +++++++++++++------ .../images/decoder/AndroidImageDecoder.kt | 1 + 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/android-components/components/browser/icons/src/main/java/mozilla/components/browser/icons/decoder/SvgIconDecoder.kt b/android-components/components/browser/icons/src/main/java/mozilla/components/browser/icons/decoder/SvgIconDecoder.kt index 821b2f98ab31..1b9a9e66fd39 100644 --- a/android-components/components/browser/icons/src/main/java/mozilla/components/browser/icons/decoder/SvgIconDecoder.kt +++ b/android-components/components/browser/icons/src/main/java/mozilla/components/browser/icons/decoder/SvgIconDecoder.kt @@ -10,7 +10,9 @@ import androidx.core.graphics.drawable.toBitmap import coil.ImageLoader import coil.decode.SvgDecoder import coil.executeBlocking +import coil.request.CachePolicy import coil.request.ImageRequest +import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.images.DesiredSize import mozilla.components.support.images.decoder.ImageDecoder @@ -20,14 +22,20 @@ import mozilla.components.support.images.decoder.ImageDecoder * ⚠️ For guidance on use of the Coil library see comment for [ComponentsDependencies.thirdparty_coil_svg]. */ class SvgIconDecoder(val context: Context) : ImageDecoder { - - override fun decode(data: ByteArray, desiredSize: DesiredSize): Bitmap? { - val request = ImageRequest.Builder(context) - .data(data) - .build() - - return SvgImageLoader.getInstance(context).executeBlocking(request).drawable?.toBitmap() - } + private val logger = Logger("SvgIconDecoder") + + override fun decode(data: ByteArray, desiredSize: DesiredSize): Bitmap? = + try { + val request = ImageRequest.Builder(context) + .size(desiredSize.targetSize) + .data(data) + .build() + + SvgImageLoader.getInstance(context).executeBlocking(request).drawable?.toBitmap() + } catch (e: OutOfMemoryError) { + logger.error("Failed to decode the byte data due to OutOfMemoryError") + null + } private object SvgImageLoader { @Volatile @@ -42,6 +50,8 @@ class SvgIconDecoder(val context: Context) : ImageDecoder { synchronized(this) { return ImageLoader.Builder(context) + .memoryCachePolicy(CachePolicy.DISABLED) + .diskCachePolicy(CachePolicy.DISABLED) .components { add(SvgDecoder.Factory()) } .build().also { instance = it } } diff --git a/android-components/components/support/images/src/main/java/mozilla/components/support/images/decoder/AndroidImageDecoder.kt b/android-components/components/support/images/src/main/java/mozilla/components/support/images/decoder/AndroidImageDecoder.kt index 2238f9937a55..5164f938fe0c 100644 --- a/android-components/components/support/images/src/main/java/mozilla/components/support/images/decoder/AndroidImageDecoder.kt +++ b/android-components/components/support/images/src/main/java/mozilla/components/support/images/decoder/AndroidImageDecoder.kt @@ -34,6 +34,7 @@ class AndroidImageDecoder : ImageDecoder { null } } catch (e: OutOfMemoryError) { + logger.error("Failed to decode the byte data due to OutOfMemoryError") null } From 776953afd7b7508ec8903d3a8762f2c13ffcb9e1 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 31 Jan 2024 21:21:12 -0500 Subject: [PATCH 079/586] Bug 1877885 - Update Detekt to version 1.23.5 --- .../plugins/dependencies/src/main/java/DependenciesPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt index b0153388de72..a5bbfff587b4 100644 --- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt +++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt @@ -33,7 +33,7 @@ object Versions { // This has to be synced to the gradlew plugin version. See // http://googlesamples.github.io/android-custom-lint-rules/api-guide/example.md.html#example:samplelintcheckgithubproject/lintversion? const val lint = "31.2.2" - const val detekt = "1.23.4" + const val detekt = "1.23.5" const val ktlint = "0.49.1" const val sentry = "7.2.0" From 9a42de693fc54b83fdbad9fd6640c01821280f6f Mon Sep 17 00:00:00 2001 From: t-p-white Date: Fri, 2 Feb 2024 11:57:30 +0000 Subject: [PATCH 080/586] Bug 1812843 - Maintain aspect ratio when resizing a bitmap for the 'add' button in CustomTabsToolbarFeature --- .../mozac_browser_toolbar_displaytoolbar.xml | 5 +- .../customtabs/CustomTabsToolbarFeature.kt | 17 ++- .../CustomTabsToolbarFeatureTest.kt | 80 +++++++++++- .../components/support/utils/ext/Bitmap.kt | 31 +++++ .../support/utils/ext/BitmapTest.kt | 122 ++++++++++++++++++ 5 files changed, 246 insertions(+), 9 deletions(-) create mode 100644 android-components/components/support/utils/src/main/java/mozilla/components/support/utils/ext/Bitmap.kt create mode 100644 android-components/components/support/utils/src/test/java/mozilla/components/support/utils/ext/BitmapTest.kt diff --git a/android-components/components/browser/toolbar/src/main/res/layout/mozac_browser_toolbar_displaytoolbar.xml b/android-components/components/browser/toolbar/src/main/res/layout/mozac_browser_toolbar_displaytoolbar.xml index a30ca3191138..aa2824bb1043 100644 --- a/android-components/components/browser/toolbar/src/main/res/layout/mozac_browser_toolbar_displaytoolbar.xml +++ b/android-components/components/browser/toolbar/src/main/res/layout/mozac_browser_toolbar_displaytoolbar.xml @@ -29,10 +29,12 @@ android:layout_width="0dp" android:layout_height="40dp" android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" android:importantForAccessibility="no" app:layout_constraintEnd_toStartOf="@+id/mozac_browser_toolbar_browser_actions" app:layout_constraintStart_toEndOf="@+id/mozac_browser_toolbar_navigation_actions" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent" + app:layout_goneMarginEnd="0dp" /> @@ -116,6 +118,7 @@ android:layout_width="wrap_content" android:layout_height="48dp" android:layout_marginTop="4dp" + android:scaleType="center" app:layout_constraintEnd_toEndOf="@+id/mozac_browser_toolbar_background" app:layout_constraintTop_toTopOf="parent" mozac:actionContainerItemSize="48dp" diff --git a/android-components/components/feature/customtabs/src/main/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeature.kt b/android-components/components/feature/customtabs/src/main/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeature.kt index 20d685f7259c..d9ecd5f50c00 100644 --- a/android-components/components/feature/customtabs/src/main/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeature.kt +++ b/android-components/components/feature/customtabs/src/main/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeature.kt @@ -6,6 +6,7 @@ package mozilla.components.feature.customtabs import android.app.PendingIntent import android.graphics.Bitmap +import android.util.Size import android.view.Window import androidx.annotation.ColorInt import androidx.annotation.VisibleForTesting @@ -37,6 +38,7 @@ import mozilla.components.support.ktx.android.view.setNavigationBarTheme import mozilla.components.support.ktx.android.view.setStatusBarTheme import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged import mozilla.components.support.utils.ColorUtils.getReadableTextColor +import mozilla.components.support.utils.ext.resizeMaintainingAspectRatio import mozilla.components.ui.icons.R as iconsR /** @@ -200,13 +202,15 @@ class CustomTabsToolbarFeature( buttonConfig: CustomTabActionButtonConfig?, ) { buttonConfig?.let { config -> + val icon = config.icon + val scaledIconSize = icon.resizeMaintainingAspectRatio(ACTION_BUTTON_MAX_DRAWABLE_DP_SIZE) val drawableIcon = Bitmap.createScaledBitmap( - config.icon, - ACTION_BUTTON_DRAWABLE_WIDTH_DP.dpToPx(context.resources.displayMetrics), - ACTION_BUTTON_DRAWABLE_HEIGHT_DP.dpToPx(context.resources.displayMetrics), + icon, + scaledIconSize.width.dpToPx(context.resources.displayMetrics), + scaledIconSize.height.dpToPx(context.resources.displayMetrics), true, - ) - .toDrawable(context.resources) + ).toDrawable(context.resources) + if (config.tint || forceActionButtonTinting) { drawableIcon.setTint(readableColor) } @@ -302,7 +306,6 @@ class CustomTabsToolbarFeature( } companion object { - private const val ACTION_BUTTON_DRAWABLE_WIDTH_DP = 24 - private const val ACTION_BUTTON_DRAWABLE_HEIGHT_DP = 24 + private val ACTION_BUTTON_MAX_DRAWABLE_DP_SIZE = Size(48, 24) } } diff --git a/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeatureTest.kt b/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeatureTest.kt index 1a849ed51794..1e3cd57cdec2 100644 --- a/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeatureTest.kt +++ b/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/CustomTabsToolbarFeatureTest.kt @@ -404,7 +404,7 @@ class CustomTabsToolbarFeatureTest { } @Test - fun `action button is scaled to 24 width and 24 height`() { + fun `GIVEN a square icon larger than the max drawable size WHEN adding action button to toolbar THEN the icon is scaled to fit`() { val captor = argumentCaptor() val size = 48 val pendingIntent: PendingIntent = mock() @@ -441,6 +441,84 @@ class CustomTabsToolbarFeatureTest { assertEquals(24, button.drawable.intrinsicWidth) } + @Test + fun `GIVEN a wide icon larger than the max drawable size WHEN adding action button to toolbar THEN the icon is scaled to fit`() { + val captor = argumentCaptor() + val width = 96 + val height = 48 + val pendingIntent: PendingIntent = mock() + val tab = createCustomTab( + "https://www.mozilla.org", + id = "mozilla", + config = CustomTabConfig( + actionButtonConfig = CustomTabActionButtonConfig( + description = "Button", + icon = Bitmap.createBitmap(IntArray(width * height), width, height, Bitmap.Config.ARGB_8888), + pendingIntent = pendingIntent, + ), + ), + ) + val store = BrowserStore( + BrowserState( + customTabs = listOf(tab), + ), + ) + val toolbar = spy(BrowserToolbar(testContext)) + val useCases = CustomTabsUseCases( + store = store, + loadUrlUseCase = SessionUseCases(store).loadUrl, + ) + val feature = spy(CustomTabsToolbarFeature(store, toolbar, sessionId = "mozilla", useCases = useCases) {}) + + feature.start() + + verify(feature).addActionButton(anyInt(), any()) + verify(toolbar).addBrowserAction(captor.capture()) + + val button = captor.value.createView(FrameLayout(testContext)) + assertEquals(24, (button as ImageButton).drawable.intrinsicHeight) + assertEquals(48, button.drawable.intrinsicWidth) + } + + @Test + fun `GIVEN a tall icon larger than the max drawable size WHEN adding action button to toolbar THEN the icon is scaled to fit`() { + val captor = argumentCaptor() + val width = 24 + val height = 48 + val pendingIntent: PendingIntent = mock() + val tab = createCustomTab( + "https://www.mozilla.org", + id = "mozilla", + config = CustomTabConfig( + actionButtonConfig = CustomTabActionButtonConfig( + description = "Button", + icon = Bitmap.createBitmap(IntArray(width * height), width, height, Bitmap.Config.ARGB_8888), + pendingIntent = pendingIntent, + ), + ), + ) + val store = BrowserStore( + BrowserState( + customTabs = listOf(tab), + ), + ) + val toolbar = spy(BrowserToolbar(testContext)) + val useCases = CustomTabsUseCases( + store = store, + loadUrlUseCase = SessionUseCases(store).loadUrl, + ) + val feature = spy(CustomTabsToolbarFeature(store, toolbar, sessionId = "mozilla", useCases = useCases) {}) + + feature.start() + + verify(feature).addActionButton(anyInt(), any()) + verify(toolbar).addBrowserAction(captor.capture()) + + val button = captor.value.createView(FrameLayout(testContext)) + assertEquals(24, (button as ImageButton).drawable.intrinsicHeight) + assertEquals(12, button.drawable.intrinsicWidth) + } + @Test fun `action button uses updated url`() { val size = 48 diff --git a/android-components/components/support/utils/src/main/java/mozilla/components/support/utils/ext/Bitmap.kt b/android-components/components/support/utils/src/main/java/mozilla/components/support/utils/ext/Bitmap.kt new file mode 100644 index 000000000000..286afff67727 --- /dev/null +++ b/android-components/components/support/utils/src/main/java/mozilla/components/support/utils/ext/Bitmap.kt @@ -0,0 +1,31 @@ +/* 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 mozilla.components.support.utils.ext + +import android.graphics.Bitmap +import android.util.Size + +/** + * Scales a [Bitmap] to the given [size] while maintaining the aspect ratio. + * + * @param size The new [Size] to scale the [Bitmap] to. + * + * @return the scaled [Size]. + */ +fun Bitmap.resizeMaintainingAspectRatio(size: Size) = if (width > height) { + // Scale a wide bitmap + val newMaxWidth = size.width + val aspectRatio = height.toFloat() / width.toFloat() + val scaledHeight = (newMaxWidth * aspectRatio).toInt() + + Size(newMaxWidth, scaledHeight) +} else { + // Scale square or tall bitmap + val newMaxHeight = size.height + val aspectRatio = width.toFloat() / height.toFloat() + val scaledWidth = (newMaxHeight * aspectRatio).toInt() + + Size(scaledWidth, newMaxHeight) +} diff --git a/android-components/components/support/utils/src/test/java/mozilla/components/support/utils/ext/BitmapTest.kt b/android-components/components/support/utils/src/test/java/mozilla/components/support/utils/ext/BitmapTest.kt new file mode 100644 index 000000000000..7e2313d3d06d --- /dev/null +++ b/android-components/components/support/utils/src/test/java/mozilla/components/support/utils/ext/BitmapTest.kt @@ -0,0 +1,122 @@ +/* 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 mozilla.components.support.utils.ext + +import android.graphics.Bitmap +import android.util.Size +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class BitmapTest { + + @Test + fun `WHEN a square bitmap is smaller than the given max size THEN resizeMaintainingAspectRatio scales the size up maintaining the aspect ratio`() { + val maxSize = Size(48, 48) + val bitmapSize = Size(24, 24) + val bitmap = createBitmap(bitmapSize) + + val scaledBitmapSize = bitmap.resizeMaintainingAspectRatio(maxSize) + + assertEquals(maxSize, scaledBitmapSize) + } + + @Test + fun `WHEN a square bitmap is same as the given max size THEN resizeMaintainingAspectRatio returns the original bitmap size`() { + val maxSize = Size(48, 48) + val bitmap = createBitmap(maxSize) + + val scaledBitmapSize = bitmap.resizeMaintainingAspectRatio(maxSize) + + assertEquals(maxSize, scaledBitmapSize) + } + + @Test + fun `WHEN a square bitmap is larger than the given max size THEN resizeMaintainingAspectRatio scales the size down maintaining the aspect ratio`() { + val maxSize = Size(48, 48) + val bitmapSize = Size(96, 96) + val bitmap = createBitmap(bitmapSize) + + val scaledBitmapSize = bitmap.resizeMaintainingAspectRatio(maxSize) + + assertEquals(maxSize, scaledBitmapSize) + } + + @Test + fun `WHEN a wide bitmap is smaller than the given max size THEN resizeMaintainingAspectRatio scales the size up maintaining the aspect ratio`() { + val maxSize = Size(48, 48) + val bitmapSize = Size(24, 12) + val bitmap = createBitmap(bitmapSize) + + val scaledBitmapSize = bitmap.resizeMaintainingAspectRatio(maxSize) + + val expected = Size(48, 24) + assertEquals(expected, scaledBitmapSize) + } + + @Test + fun `WHEN a wide bitmap is same as the given max size THEN resizeMaintainingAspectRatio returns the bitmap original size`() { + val maxSize = Size(48, 48) + val bitmapSize = Size(48, 24) + val bitmap = createBitmap(bitmapSize) + + val scaledBitmapSize = bitmap.resizeMaintainingAspectRatio(maxSize) + + assertEquals(bitmapSize, scaledBitmapSize) + } + + @Test + fun `WHEN a wide bitmap is larger than the given max size THEN resizeMaintainingAspectRatio scales the size down maintaining the aspect ratio`() { + val maxSize = Size(48, 48) + val bitmapSize = Size(192, 96) + val bitmap = createBitmap(bitmapSize) + + val scaledBitmapSize = bitmap.resizeMaintainingAspectRatio(maxSize) + + val expected = Size(48, 24) + assertEquals(expected, scaledBitmapSize) + } + + @Test + fun `WHEN a tall bitmap is smaller than the given max size THEN resizeMaintainingAspectRatio scales the size up maintaining the aspect ratio`() { + val maxSize = Size(48, 48) + val bitmapSize = Size(12, 24) + val bitmap = createBitmap(bitmapSize) + + val scaledBitmapSize = bitmap.resizeMaintainingAspectRatio(maxSize) + + val expected = Size(24, 48) + assertEquals(expected, scaledBitmapSize) + } + + @Test + fun `WHEN a tall bitmap is same as the given max size THEN resizeMaintainingAspectRatio returns the bitmap original size`() { + val maxSize = Size(48, 48) + val bitmapSize = Size(24, 48) + val bitmap = createBitmap(bitmapSize) + + val scaledBitmapSize = bitmap.resizeMaintainingAspectRatio(maxSize) + + assertEquals(bitmapSize, scaledBitmapSize) + } + + @Test + fun `WHEN a tall bitmap is larger than the given max size THEN resizeMaintainingAspectRatio scales the size down maintaining the aspect ratio`() { + val maxSize = Size(48, 48) + val bitmapSize = Size(96, 192) + val bitmap = createBitmap(bitmapSize) + + val scaledBitmapSize = bitmap.resizeMaintainingAspectRatio(maxSize) + + val expected = Size(24, 48) + assertEquals(expected, scaledBitmapSize) + } + + private fun createBitmap(size: Size) = with(size) { + Bitmap.createBitmap(IntArray(width * height), width, height, Bitmap.Config.ARGB_8888) + } +} From d03309c94457e9dc692499b765ba0e6b285ce295 Mon Sep 17 00:00:00 2001 From: Noah Bond Date: Fri, 2 Feb 2024 09:24:23 -0800 Subject: [PATCH 081/586] Bug 1877123 - Fix number localization in `TabCounter` and `TabTools` --- .../org/mozilla/fenix/compose/TabCounter.kt | 17 ++++++++++---- .../java/org/mozilla/fenix/compose/ext/Int.kt | 15 +++++++++++++ .../fenix/debugsettings/tabs/TabTools.kt | 17 +++++++------- .../org/mozilla/fenix/compose/ext/IntTest.kt | 22 +++++++++++++++++++ 4 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 fenix/app/src/main/java/org/mozilla/fenix/compose/ext/Int.kt create mode 100644 fenix/app/src/test/java/org/mozilla/fenix/compose/ext/IntTest.kt diff --git a/fenix/app/src/main/java/org/mozilla/fenix/compose/TabCounter.kt b/fenix/app/src/main/java/org/mozilla/fenix/compose/TabCounter.kt index a2f2d070973b..b35235f2f703 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/compose/TabCounter.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/compose/TabCounter.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.compose +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding import androidx.compose.material.Icon @@ -21,9 +22,11 @@ import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTag import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import org.mozilla.fenix.R import org.mozilla.fenix.compose.annotation.LightDarkPreview +import org.mozilla.fenix.compose.ext.toLocaleString import org.mozilla.fenix.tabstray.TabsTrayTestTag import org.mozilla.fenix.theme.FirefoxTheme @@ -48,19 +51,20 @@ private const val TAB_TEXT_BOTTOM_PADDING_RATIO = 4 @Composable fun TabCounter(tabCount: Int) { + val formattedTabCount = tabCount.toLocaleString() val normalTabCountText: String val tabCountTextRatio: Float val needsBottomPaddingForInfiniteTabs: Boolean when (tabCount) { in MIN_SINGLE_DIGIT..MAX_SINGLE_DIGIT -> { - normalTabCountText = tabCount.toString() + normalTabCountText = formattedTabCount tabCountTextRatio = ONE_DIGIT_SIZE_RATIO needsBottomPaddingForInfiniteTabs = false } in TWO_DIGIT_THRESHOLD..MAX_VISIBLE_TABS -> { - normalTabCountText = tabCount.toString() + normalTabCountText = formattedTabCount tabCountTextRatio = TWO_DIGITS_SIZE_RATIO needsBottomPaddingForInfiniteTabs = false } @@ -77,7 +81,7 @@ fun TabCounter(tabCount: Int) { } else { stringResource( id = R.string.mozac_tab_counter_open_tab_tray_plural, - tabCount.toString(), + formattedTabCount, ) } @@ -119,9 +123,14 @@ fun TabCounter(tabCount: Int) { } @LightDarkPreview +@Preview(locale = "ar") @Composable private fun TabCounterPreview() { FirefoxTheme { - TabCounter(tabCount = 55) + Box( + modifier = Modifier.background(color = FirefoxTheme.colors.layer1), + ) { + TabCounter(tabCount = 55) + } } } diff --git a/fenix/app/src/main/java/org/mozilla/fenix/compose/ext/Int.kt b/fenix/app/src/main/java/org/mozilla/fenix/compose/ext/Int.kt new file mode 100644 index 000000000000..7d09419cc687 --- /dev/null +++ b/fenix/app/src/main/java/org/mozilla/fenix/compose/ext/Int.kt @@ -0,0 +1,15 @@ +/* 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.compose.ext + +import androidx.compose.ui.text.intl.Locale +import java.text.NumberFormat +import java.util.Locale as JavaLocale + +/** + * Returns a localized string representation of the value. + */ +fun Int.toLocaleString(): String = + NumberFormat.getNumberInstance(JavaLocale(Locale.current.language)).format(this) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/tabs/TabTools.kt b/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/tabs/TabTools.kt index c6daa5d80e7e..5fa97b7c0393 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/tabs/TabTools.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/tabs/TabTools.kt @@ -43,6 +43,7 @@ import org.mozilla.fenix.R import org.mozilla.fenix.compose.Divider import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.compose.button.PrimaryButton +import org.mozilla.fenix.compose.ext.toLocaleString import org.mozilla.fenix.debugsettings.ui.DebugDrawer import org.mozilla.fenix.ext.maxActiveTime import org.mozilla.fenix.tabstray.ext.isNormalTabInactive @@ -152,19 +153,19 @@ private fun TabCounter( TabCountRow( tabType = stringResource(R.string.debug_drawer_tab_tools_tab_count_normal), - count = activeTabCount.toString(), + count = activeTabCount, ) if (inactiveTabsEnabled) { TabCountRow( tabType = stringResource(R.string.debug_drawer_tab_tools_tab_count_inactive), - count = inactiveTabCount.toString(), + count = inactiveTabCount, ) } TabCountRow( tabType = stringResource(R.string.debug_drawer_tab_tools_tab_count_private), - count = privateTabCount.toString(), + count = privateTabCount, ) Spacer(modifier = Modifier.height(8.dp)) @@ -175,7 +176,7 @@ private fun TabCounter( TabCountRow( tabType = stringResource(R.string.debug_drawer_tab_tools_tab_count_total), - count = totalTabCount.toString(), + count = totalTabCount, ) } } @@ -183,7 +184,7 @@ private fun TabCounter( @Composable private fun TabCountRow( tabType: String, - count: String, + count: Int, ) { Row( modifier = Modifier @@ -198,14 +199,14 @@ private fun TabCountRow( ) Text( - text = count, + text = count.toLocaleString(), color = FirefoxTheme.colors.textSecondary, style = FirefoxTheme.typography.headline6, ) } } -private const val DEFAULT_TABS_TO_ADD = "1" +private const val DEFAULT_TABS_TO_ADD = 1 @OptIn(ExperimentalComposeUiApi::class) @Composable @@ -213,7 +214,7 @@ private fun TabCreationTool( inactiveTabsEnabled: Boolean, onCreateTabsClick: ((quantity: Int, isInactive: Boolean, isPrivate: Boolean) -> Unit), ) { - var tabQuantityToCreate by rememberSaveable { mutableStateOf(DEFAULT_TABS_TO_ADD) } + var tabQuantityToCreate by rememberSaveable { mutableStateOf(DEFAULT_TABS_TO_ADD.toLocaleString()) } var hasError by rememberSaveable { mutableStateOf(false) } val keyboardController = LocalSoftwareKeyboardController.current diff --git a/fenix/app/src/test/java/org/mozilla/fenix/compose/ext/IntTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/compose/ext/IntTest.kt new file mode 100644 index 000000000000..c7c68f7ebde3 --- /dev/null +++ b/fenix/app/src/test/java/org/mozilla/fenix/compose/ext/IntTest.kt @@ -0,0 +1,22 @@ +/* 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.compose.ext + +import org.junit.Assert.assertEquals +import org.junit.Test +import java.util.Locale as JavaLocale + +class IntTest { + + @Test + fun `WHEN the language is Arabic THEN translate the number to the proper symbol of that locale`() { + val expected = "٥" + val numberUnderTest = 5 + + JavaLocale.setDefault(JavaLocale("ar")) + + assertEquals(expected, numberUnderTest.toLocaleString()) + } +} From 12d8d630b1c759e6b8bf6f2f4b91c2077b46be08 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Mon, 5 Feb 2024 16:20:37 -0500 Subject: [PATCH 082/586] Bug 1567912 - Add signing-bundle as a dependency for notify-promote --- taskcluster/ci/release-notify-promote/kind.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/taskcluster/ci/release-notify-promote/kind.yml b/taskcluster/ci/release-notify-promote/kind.yml index c80e74af4118..3e59bcdb8461 100644 --- a/taskcluster/ci/release-notify-promote/kind.yml +++ b/taskcluster/ci/release-notify-promote/kind.yml @@ -11,6 +11,7 @@ transforms: kind-dependencies: - signing-apk + - signing-bundle task-defaults: name: notify-release-drivers-promote From db3bbc8ef52479ed6c813458c13487f749165101 Mon Sep 17 00:00:00 2001 From: Matthew Tighe Date: Tue, 19 Dec 2023 16:13:10 -0800 Subject: [PATCH 083/586] Bug 1861459 - Update AppState.mode based on selected tab changes --- .../browser/state/reducer/TabListReducer.kt | 10 +-- .../browser/state/action/TabListActionTest.kt | 59 ++++++++++++-- .../middleware/LastAccessMiddleware.kt | 6 +- .../middleware/LastAccessMiddlewareTest.kt | 26 ------ docs/changelog.md | 3 + .../fenix/bindings/BrowserStoreBinding.kt | 37 +++++++++ .../fenix/components/appstate/AppAction.kt | 8 ++ .../fenix/components/appstate/AppState.kt | 2 + .../components/appstate/AppStoreReducer.kt | 5 ++ .../fenix/bindings/BrowserStoreBindingTest.kt | 79 +++++++++++++++++++ .../appstate/AppStoreReducerTest.kt | 47 +++++++++++ 11 files changed, 239 insertions(+), 43 deletions(-) create mode 100644 fenix/app/src/main/java/org/mozilla/fenix/bindings/BrowserStoreBinding.kt create mode 100644 fenix/app/src/test/java/org/mozilla/fenix/bindings/BrowserStoreBindingTest.kt diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TabListReducer.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TabListReducer.kt index 99ce05b23ab7..74a866a23858 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TabListReducer.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TabListReducer.kt @@ -211,8 +211,9 @@ internal object TabListReducer { state.copy( tabs = normalTabs, selectedTabId = if (selectionAffected) { - // If the selection is affected, select the last normal tab, if available. - normalTabs.lastOrNull()?.id + // If the selection is affected, we'll set it to null as there's no + // normal tab left and NO normal tab should get selected instead. + null } else { state.selectedTabId }, @@ -287,10 +288,7 @@ private fun findNewSelectedTabId( // We found a nearby tab, let's select it. nearbyTab != null -> nearbyTab.id - // If there's no private tab to select anymore then just select the last regular tab - isPrivate -> tabs.last().id - - // Removing the last normal tab should NOT cause a private tab to be selected + // We have run out of tabs of the same type of mode else -> null } } diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TabListActionTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TabListActionTest.kt index 807e72c65dc1..18e644513bdd 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TabListActionTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TabListActionTest.kt @@ -354,11 +354,6 @@ class TabListActionTest { // [a*, b, c, (e*)] -> [(a*), b, c] store.dispatch(TabListAction.RemoveTabAction("e")).joinBlocking() assertEquals("a", store.state.selectedTabId) - - // After removing the last private tab a normal tab will be selected - // [(a*), b, c] -> [b, (c)] - store.dispatch(TabListAction.RemoveTabAction("a")).joinBlocking() - assertEquals("c", store.state.selectedTabId) } @Test @@ -394,6 +389,56 @@ class TabListActionTest { assertNull(store.state.selectedTabId) } + @Test + fun `GIVEN last normal tab WHEN removed THEN no new tab is selected`() { + val normalTab = createTab("normal", private = false) + val privateTab = createTab("private", private = true) + val initialState = BrowserState(tabs = listOf(normalTab, privateTab), selectedTabId = normalTab.id) + val store = BrowserStore(initialState) + + store.dispatch(TabListAction.RemoveTabAction(normalTab.id)).joinBlocking() + + assertNull(store.state.selectedTabId) + assertEquals(1, store.state.tabs.size) + } + + @Test + fun `GIVEN last private tab WHEN removed THEN no new tab is selected`() { + val normalTab = createTab("normal", private = false) + val privateTab = createTab("private", private = true) + val initialState = BrowserState(tabs = listOf(normalTab, privateTab), selectedTabId = privateTab.id) + val store = BrowserStore(initialState) + + store.dispatch(TabListAction.RemoveTabAction(privateTab.id)).joinBlocking() + + assertNull(store.state.selectedTabId) + assertEquals(1, store.state.tabs.size) + } + + @Test + fun `GIVEN normal tabs and one private tab WHEN all normal tabs are removed THEN no new tab is selected`() { + val tabs = List(5) { createTab("$it", private = false) } + createTab("private", private = true) + val initialState = BrowserState(tabs = tabs, selectedTabId = tabs.first().id) + val store = BrowserStore(initialState) + + store.dispatch(TabListAction.RemoveAllNormalTabsAction).joinBlocking() + + assertNull(store.state.selectedTabId) + assertEquals(1, store.state.tabs.size) + } + + @Test + fun `GIVEN one normal tab and private tabs WHEN all private tabs are removed THEN no new tab is selected`() { + val tabs = List(5) { createTab("$it", private = true) } + createTab("normal", private = false) + val initialState = BrowserState(tabs = tabs, selectedTabId = tabs.first().id) + val store = BrowserStore(initialState) + + store.dispatch(TabListAction.RemoveAllPrivateTabsAction).joinBlocking() + + assertNull(store.state.selectedTabId) + assertEquals(1, store.state.tabs.size) + } + @Test fun `RemoveTabAction - Parent will be selected if child is removed and flag is set to true (default)`() { val store = BrowserStore() @@ -1022,7 +1067,7 @@ class TabListActionTest { assertEquals(1, store.state.tabs.size) assertEquals("a", store.state.tabs[0].id) - assertEquals("a", store.state.selectedTabId) + assertEquals(null, store.state.selectedTabId) assertEquals(1, store.state.customTabs.size) assertEquals("a1", store.state.customTabs.last().id) @@ -1281,7 +1326,7 @@ class TabListActionTest { assertEquals(2, store.state.normalTabs.size) assertEquals(0, store.state.privateTabs.size) - assertEquals("c", store.state.selectedTabId) + assertEquals(null, store.state.selectedTabId) } @Test diff --git a/android-components/components/feature/session/src/main/java/mozilla/components/feature/session/middleware/LastAccessMiddleware.kt b/android-components/components/feature/session/src/main/java/mozilla/components/feature/session/middleware/LastAccessMiddleware.kt index b23b0ce5e6f4..c1a90dc0d12c 100644 --- a/android-components/components/feature/session/src/main/java/mozilla/components/feature/session/middleware/LastAccessMiddleware.kt +++ b/android-components/components/feature/session/src/main/java/mozilla/components/feature/session/middleware/LastAccessMiddleware.kt @@ -27,8 +27,7 @@ class LastAccessMiddleware : Middleware { val selectionBeforeRemoval = when (action) { is TabListAction.RemoveTabAction, is TabListAction.RemoveTabsAction, - // NB: RemoveAllNormalTabsAction never updates tab selection - is TabListAction.RemoveAllPrivateTabsAction, + // NB: RemoveAllNormalTabsAction and RemoveAllPrivateTabsAction never update tab selection -> { context.state.selectedTabId } @@ -40,8 +39,7 @@ class LastAccessMiddleware : Middleware { when (action) { is TabListAction.RemoveTabAction, is TabListAction.RemoveTabsAction, - // NB: RemoveAllNormalTabsAction never updates tab selection - is TabListAction.RemoveAllPrivateTabsAction, + // NB: RemoveAllNormalTabsAction and RemoveAllPrivateTabsAction never updates tab selection -> { // If the selected tab changed during removal we make sure to update // the lastAccess state of the newly selected tab. diff --git a/android-components/components/feature/session/src/test/java/mozilla/components/feature/session/middleware/LastAccessMiddlewareTest.kt b/android-components/components/feature/session/src/test/java/mozilla/components/feature/session/middleware/LastAccessMiddlewareTest.kt index d5157fef7af0..9961a8b08403 100644 --- a/android-components/components/feature/session/src/test/java/mozilla/components/feature/session/middleware/LastAccessMiddlewareTest.kt +++ b/android-components/components/feature/session/src/test/java/mozilla/components/feature/session/middleware/LastAccessMiddlewareTest.kt @@ -239,32 +239,6 @@ class LastAccessMiddlewareTest { assertEquals(0L, selectedTab.lastAccess) } - @Test - fun `UpdateLastAction is dispatched when tab is selected during removal of all private tab`() { - val store = BrowserStore( - initialState = BrowserState( - listOf( - createTab("https://mozilla.org", id = "123", private = true), - createTab("https://firefox.com", id = "456", private = true), - createTab("https://getpocket.com", id = "789"), - ), - selectedTabId = "123", - ), - middleware = listOf(LastAccessMiddleware()), - ) - - assertEquals(0L, store.state.tabs[0].lastAccess) - assertEquals(0L, store.state.tabs[1].lastAccess) - assertEquals(0L, store.state.tabs[2].lastAccess) - - store.dispatch(TabListAction.RemoveAllPrivateTabsAction).joinBlocking() - - val selectedTab = store.state.findTab("789") - assertNotNull(selectedTab) - assertEquals(selectedTab!!.id, store.state.selectedTabId) - assertNotEquals(0L, selectedTab.lastAccess) - } - @Test fun `UpdateLastAction is not dispatched when no new tab is selected during removal of all private tab`() { val store = BrowserStore( diff --git a/docs/changelog.md b/docs/changelog.md index 0f52b2882f33..71ab00f69d56 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -14,6 +14,9 @@ permalink: /changelog/ * Added `FileUploadsDirCleaner` deletes temporary stale uploaded files, see [Bug 1860472](https://bugzilla.mozilla.org/show_bug.cgi?id=1860472). * ⚠️ **This is a breaking change**: `PromptFeature` now requires a `FileUploadsDirCleaner` to be constructed +* **browser-state** + * `BrowserStore` and the `TabListReducer` will no longer automatically select a normal tab when all private tabs are removed. [Bug 1861459](https://bugzilla.mozilla.org/show_bug.cgi?id=1861459) + * **all components** * All new usages of the `concept-fetch` component to make fetch requests now have conservative-mode off by default. Current features will continue to use conservative mode until individually updated. diff --git a/fenix/app/src/main/java/org/mozilla/fenix/bindings/BrowserStoreBinding.kt b/fenix/app/src/main/java/org/mozilla/fenix/bindings/BrowserStoreBinding.kt new file mode 100644 index 000000000000..85242e93cc42 --- /dev/null +++ b/fenix/app/src/main/java/org/mozilla/fenix/bindings/BrowserStoreBinding.kt @@ -0,0 +1,37 @@ +/* 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.bindings + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.distinctUntilChangedBy +import mozilla.components.browser.state.selector.selectedTab +import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.lib.state.helpers.AbstractBinding +import org.mozilla.fenix.components.AppStore +import org.mozilla.fenix.components.appstate.AppAction + +/** + * Binding to update the [AppStore] based on changes to [BrowserState]. + */ +class BrowserStoreBinding( + browserStore: BrowserStore, + private val appStore: AppStore, +) : AbstractBinding(browserStore) { + override suspend fun onState(flow: Flow) { + // Update the AppStore with the latest selected tab + flow.distinctUntilChangedBy { it.selectedTabId } + .collectLatest { state -> + state.selectedTab?.let { tab -> + // Ignore re-observations due to lifecycle events, or other pieces of state like + // [mode] may get overwritten + if (appStore.state.selectedTabId != tab.id) { + appStore.dispatch(AppAction.SelectedTabChanged(tab)) + } + } + } + } +} diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppAction.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppAction.kt index eae237c468aa..07eb907e7cb6 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppAction.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppAction.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.components.appstate +import mozilla.components.browser.state.state.TabSessionState import mozilla.components.feature.tab.collections.TabCollection import mozilla.components.feature.top.sites.TopSite import mozilla.components.lib.crash.Crash.NativeCodeCrash @@ -128,6 +129,13 @@ sealed class AppAction : Action { */ data class RemoveRecentSyncedTab(val syncedTab: RecentSyncedTab) : AppAction() + /** + * Action indicating that the selected tab has been changed. + * + * @property tab The tab that has been selected. + */ + data class SelectedTabChanged(val tab: TabSessionState) : AppAction() + /** * [Action]s related to interactions with the Messaging Framework. */ diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppState.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppState.kt index 77edd2d0169b..a056a00e75aa 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppState.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppState.kt @@ -38,6 +38,7 @@ import org.mozilla.fenix.wallpapers.WallpaperState * @property expandedCollections A set containing the ids of the [TabCollection] that are expanded * in the [HomeFragment]. * @property mode Whether the app is in private browsing mode. + * @property selectedTabId The currently selected tab ID. This should be bound to [BrowserStore]. * @property topSites The list of [TopSite] in the [HomeFragment]. * @property showCollectionPlaceholder If true, shows a placeholder when there are no collections. * @property recentTabs The list of recent [RecentTab] in the [HomeFragment]. @@ -64,6 +65,7 @@ data class AppState( val collections: List = emptyList(), val expandedCollections: Set = emptySet(), val mode: BrowsingMode = BrowsingMode.Normal, + val selectedTabId: String? = null, val topSites: List = emptyList(), val showCollectionPlaceholder: Boolean = false, val recentTabs: List = emptyList(), diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppStoreReducer.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppStoreReducer.kt index e175301533db..bf0ab3245ff5 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppStoreReducer.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/components/appstate/AppStoreReducer.kt @@ -8,6 +8,7 @@ import androidx.annotation.VisibleForTesting import mozilla.components.service.pocket.PocketStory.PocketRecommendedStory import mozilla.components.service.pocket.PocketStory.PocketSponsoredStory import mozilla.components.service.pocket.ext.recordNewImpression +import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.components.AppStore import org.mozilla.fenix.components.appstate.shopping.ShoppingStateReducer import org.mozilla.fenix.ext.filterOutTab @@ -100,6 +101,10 @@ internal object AppStoreReducer { else -> state.recentSyncedTabState }, ) + is AppAction.SelectedTabChanged -> state.copy( + selectedTabId = action.tab.id, + mode = BrowsingMode.fromBoolean(action.tab.content.private), + ) is AppAction.DisbandSearchGroupAction -> state.copy( recentHistory = state.recentHistory.filterNot { it is RecentHistoryGroup && it.title.equals(action.searchTerm, true) diff --git a/fenix/app/src/test/java/org/mozilla/fenix/bindings/BrowserStoreBindingTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/bindings/BrowserStoreBindingTest.kt new file mode 100644 index 000000000000..0aaf57ca0f02 --- /dev/null +++ b/fenix/app/src/test/java/org/mozilla/fenix/bindings/BrowserStoreBindingTest.kt @@ -0,0 +1,79 @@ +/* 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.bindings + +import mozilla.components.browser.state.action.TabListAction +import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.createTab +import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.support.test.ext.joinBlocking +import mozilla.components.support.test.rule.MainCoroutineRule +import mozilla.components.support.test.rule.runTestOnMain +import org.junit.Rule +import org.junit.Test +import org.mockito.Mockito.never +import org.mockito.Mockito.spy +import org.mockito.Mockito.verify +import org.mozilla.fenix.components.AppStore +import org.mozilla.fenix.components.appstate.AppAction +import org.mozilla.fenix.components.appstate.AppState + +class BrowserStoreBindingTest { + + @get:Rule + val coroutineRule = MainCoroutineRule() + + lateinit var browserStore: BrowserStore + lateinit var appStore: AppStore + + private val tabId1 = "1" + private val tabId2 = "2" + private val tab1 = createTab(url = tabId1, id = tabId1) + private val tab2 = createTab(url = tabId2, id = tabId2) + + @Test + fun `WHEN selected tab changes THEN app action dispatched with update`() = runTestOnMain { + appStore = spy(AppStore()) + browserStore = BrowserStore( + BrowserState( + tabs = listOf(tab1, tab2), + selectedTabId = tabId1, + ), + ) + + val binding = BrowserStoreBinding(browserStore, appStore) + binding.start() + browserStore.dispatch(TabListAction.SelectTabAction(tabId2)).joinBlocking() + + // consume initial state + verify(appStore).dispatch(AppAction.SelectedTabChanged(tab1)) + // verify response to Browser Store dispatch + verify(appStore).dispatch(AppAction.SelectedTabChanged(tab2)) + } + + @Test + fun `GIVEN selected tab id is set WHEN update is observed with same id THEN update is ignored`() { + appStore = spy( + AppStore( + AppState( + selectedTabId = tabId2, + ), + ), + ) + browserStore = BrowserStore( + BrowserState( + tabs = listOf(tab1, tab2), + selectedTabId = tabId2, + ), + ) + + val binding = BrowserStoreBinding(browserStore, appStore) + binding.start() + browserStore.dispatch(TabListAction.SelectTabAction(tabId2)).joinBlocking() + + // the selected tab should only be dispatched on initialization + verify(appStore, never()).dispatch(AppAction.SelectedTabChanged(tab2)) + } +} diff --git a/fenix/app/src/test/java/org/mozilla/fenix/components/appstate/AppStoreReducerTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/components/appstate/AppStoreReducerTest.kt index 7be038c02bde..2997e14c0640 100644 --- a/fenix/app/src/test/java/org/mozilla/fenix/components/appstate/AppStoreReducerTest.kt +++ b/fenix/app/src/test/java/org/mozilla/fenix/components/appstate/AppStoreReducerTest.kt @@ -5,10 +5,12 @@ package org.mozilla.fenix.components.appstate import io.mockk.mockk +import mozilla.components.browser.state.state.createTab import mozilla.components.lib.crash.Crash.NativeCodeCrash import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test +import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.components.appstate.AppAction.AddNonFatalCrash import org.mozilla.fenix.components.appstate.AppAction.RemoveAllNonFatalCrashes import org.mozilla.fenix.components.appstate.AppAction.RemoveNonFatalCrash @@ -69,4 +71,49 @@ class AppStoreReducerTest { assertTrue(updatedState.nonFatalCrashes.isEmpty()) } + + @Test + fun `GIVEN mode is private WHEN selected tab changes to normal mode THEN state is updated to normal mode`() { + val initialState = AppState( + selectedTabId = null, + mode = BrowsingMode.Private, + ) + + val updatedState = AppStoreReducer.reduce( + initialState, + AppAction.SelectedTabChanged(createTab("", private = false)), + ) + + assertFalse(updatedState.mode.isPrivate) + } + + @Test + fun `GIVEN mode is normal WHEN selected tab changes to private mode THEN state is updated to private mode`() { + val initialState = AppState( + selectedTabId = null, + mode = BrowsingMode.Normal, + ) + + val updatedState = AppStoreReducer.reduce( + initialState, + AppAction.SelectedTabChanged(createTab("", private = true)), + ) + + assertTrue(updatedState.mode.isPrivate) + } + + @Test + fun `WHEN selected tab changes to a tab in the same mode THEN mode is unchanged`() { + val initialState = AppState( + selectedTabId = null, + mode = BrowsingMode.Normal, + ) + + val updatedState = AppStoreReducer.reduce( + initialState, + AppAction.SelectedTabChanged(createTab("", private = false)), + ) + + assertFalse(updatedState.mode.isPrivate) + } } From 52572cc2d439cdca32526e5751c610bae98d80e0 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 6 Feb 2024 00:03:32 +0000 Subject: [PATCH 084/586] Import translations from android-l10n --- .../addons/src/main/res/values-fr/strings.xml | 4 +- .../addons/src/main/res/values-sc/strings.xml | 50 +- .../addons/src/main/res/values-si/strings.xml | 4 +- .../addons/src/main/res/values-tg/strings.xml | 4 +- .../media/src/main/res/values-sc/strings.xml | 21 +- .../media/src/main/res/values-si/strings.xml | 11 +- .../media/src/main/res/values-tg/strings.xml | 11 +- .../src/main/res/values-cs/strings.xml | 4 + .../src/main/res/values-fr/strings.xml | 12 + .../src/main/res/values-sc/strings.xml | 43 +- .../src/main/res/values-si/strings.xml | 36 + .../src/main/res/values-sl/strings.xml | 12 + .../src/main/res/values-tg/strings.xml | 36 + fenix/app/src/main/res/values-azb/strings.xml | 131 ++++ fenix/app/src/main/res/values-sc/strings.xml | 614 +++++++++++++++--- fenix/app/src/main/res/values-si/strings.xml | 52 ++ fenix/app/src/main/res/values-sl/strings.xml | 23 + fenix/app/src/main/res/values-tg/strings.xml | 51 +- 18 files changed, 973 insertions(+), 146 deletions(-) diff --git a/android-components/components/feature/addons/src/main/res/values-fr/strings.xml b/android-components/components/feature/addons/src/main/res/values-fr/strings.xml index 05ddc0ea5057..ab62d4e19074 100644 --- a/android-components/components/feature/addons/src/main/res/values-fr/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-fr/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Accéder aux données de %1$d autres domaines + + %1$s, %2$d sur %3$d Accéder aux onglets du navigateur @@ -75,7 +77,7 @@ Auteur - Auteurs + Auteurs Dernière mise à jour diff --git a/android-components/components/feature/addons/src/main/res/values-sc/strings.xml b/android-components/components/feature/addons/src/main/res/values-sc/strings.xml index 2b8fc9357787..d3dbbca24124 100644 --- a/android-components/components/feature/addons/src/main/res/values-sc/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-sc/strings.xml @@ -1,5 +1,5 @@ - + Lèghere e modificare sa cunfiguratzione de riservadesa @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Atzèdere a is datos tuos in àteros %1$d domìnios + + %1$s, %2$d de %3$d Atzèdere a is ischedas de su navigadore @@ -70,8 +72,10 @@ Abèrrere is ainas de isvilupu pro atzèdere a is datos tuos in is ischedas abertas Versione + + Autoria - Autoria + Autoria Ùrtima atualizatzione @@ -80,6 +84,8 @@ Àteras informatziones subra de is permissos Valutatzione + + Àteru in pitzus de custu cumplementu Cunfiguratzione @@ -108,26 +114,44 @@ Detàllios Permissos - + Boga + + Sinnala Boles agiùnghere %1$s? + + %1$s rechedet permissos agiuntivos. Rechedet su permissu tuo pro: + + Bolet: Agiunghe + + Permite + + Refuda Annulla Installa su cumplementu Annulla + + Retzensiones: %1$s %1$.02f/5 Cumplementos Gestore de cumplementos + + Is cumplementos sunt istados disativados in manera temporànea + + Torra a aviare is cumplementos + + Agata àteros cumplementos Permite @@ -152,6 +176,8 @@ Agiunghe %1$s e %2$s a %3$s Agiunghe·ddos a %1$s + + Iscarrighende e verifichende su cumplementu… Impossìbile otènnere sa lista de cumplementos. @@ -160,6 +186,18 @@ %1$s installadu Faddina in s’installatzione de %1$s + + Faddina in s’installatzione de custu cumplementu. + + Impossìbile iscarrigare custu cumplementu pro more de una faddina in sa connessione. + + Custu cumplementu non si podet installare ca paret corrùmpidu. + + Custu cumplementu non si podet installare ca no est averiguadu. + + %1$s non si podet installare ca no est cumpatìbile cun %2$s %3$s. + + %1$s non si podet installare ca tenet un’arriscu artu de causare problemas de istabilidade o de seguresa. %1$s ativadu @@ -200,4 +238,8 @@ Aberi·ddu dae su menù AB, cumprèndidu - + + Àteras informatziones + + %1$s est istadu disativadu pro more de problemas de seguresa o de istabilidade. + diff --git a/android-components/components/feature/addons/src/main/res/values-si/strings.xml b/android-components/components/feature/addons/src/main/res/values-si/strings.xml index 62cc8201c60f..a98bbc4f23eb 100644 --- a/android-components/components/feature/addons/src/main/res/values-si/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-si/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> අන් වසම් %1$d කට ඔබගේ දත්ත වෙත ප්‍රවේශය + + %3$d න් %1$s, %2$d අතිරික්සුවේ පටිති වෙත ප්‍රවේශය @@ -73,7 +75,7 @@ කර්තෘ - කතුවරු + කතුවරු අවසාන යාවත්කාලය diff --git a/android-components/components/feature/addons/src/main/res/values-tg/strings.xml b/android-components/components/feature/addons/src/main/res/values-tg/strings.xml index 49c9e5fb433c..cce6e4e95177 100644 --- a/android-components/components/feature/addons/src/main/res/values-tg/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-tg/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Дастрас кардани маълумоти шумо дар %1$d домени дигар + + %1$s, %2$d аз %3$d Дастрас кардани варақаҳои браузер @@ -75,7 +77,7 @@ Муаллиф - Муаллифон + Муаллифон Санаи навсозии охирин diff --git a/android-components/components/feature/media/src/main/res/values-sc/strings.xml b/android-components/components/feature/media/src/main/res/values-sc/strings.xml index a217ed041d38..6bce4ac7b382 100644 --- a/android-components/components/feature/media/src/main/res/values-sc/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-sc/strings.xml @@ -1,5 +1,5 @@ - + Cuntenutos multimediales @@ -11,6 +11,25 @@ Sa càmera e su micròfonu sunt ativos + + Toca pro abèrrere s’ischeda chi est impreende sa càmera. + + Toca pro abèrrere s’ischeda chi est impreende su micròfonu. + + Toca pro abèrrere s’ischeda chi est impreende sa càmera e su micròfonu. + + + + Regorda: %1$s est ancora impreende sa càmera. Toca pro abèrrere s’ischeda. + + Regorda: %1$s est ancora impreende su micròfonu. Toca pro abèrrere s’ischeda + + Regorda: %1$s est ancora impreende su micròfonu. Toca pro abèrrere s’ischeda. + + Regorda: %1$s est ancora impreende sa càmera e su micròfonu. Toca pro abèrrere s’ischeda + + Regorda: %1$s est ancora impreende sa càmera e su micròfonu. Toca pro abèrrere s’ischeda. + Reprodue diff --git a/android-components/components/feature/media/src/main/res/values-si/strings.xml b/android-components/components/feature/media/src/main/res/values-si/strings.xml index 57463ce67876..41edbc1ea9cc 100644 --- a/android-components/components/feature/media/src/main/res/values-si/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-si/strings.xml @@ -1,5 +1,5 @@ - + මාධ්‍ය @@ -22,9 +22,14 @@ සටහන: %1$s තවමත් ඔබගේ රූගතය භාවිතා කරයි. පටිත්ත ඇරීමට තට්ටු කරන්න. - සටහන: %1$s තවමත් ඔබගේ ශබ්දවාහිනිය භාවිතා කරයි. පටිත්ත ඇරීමට තට්ටු කරන්න + සටහන: %1$s තවමත් ඔබගේ ශබ්දවාහිනිය භාවිතා කරයි. පටිත්ත ඇරීමට තට්ටු කරන්න + + සටහන: %1$s තවමත් ඔබගේ ශබ්දවාහිනිය භාවිතා කරයි. පටිත්ත ඇරීමට තට්ටු කරන්න. + + සටහන: %1$s තවමත් ඔබගේ ශබ්දවාහිනිය හා රූගතය භාවිතා කරයි. පටිත්ත ඇරීමට තට්ටු කරන්න + - සටහන: %1$s තවමත් ඔබගේ ශබ්දවාහිනිය හා රූගතය භාවිතා කරයි. පටිත්ත ඇරීමට තට්ටු කරන්න + සටහන: %1$s තවමත් ඔබගේ ශබ්දවාහිනිය හා රූගතය භාවිතා කරයි. පටිත්ත ඇරීමට තට්ටු කරන්න. වාදනය diff --git a/android-components/components/feature/media/src/main/res/values-tg/strings.xml b/android-components/components/feature/media/src/main/res/values-tg/strings.xml index 94b0aad8e35e..a725b8155e39 100644 --- a/android-components/components/feature/media/src/main/res/values-tg/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-tg/strings.xml @@ -1,5 +1,5 @@ - + Расона @@ -21,9 +21,14 @@ Ёдоварӣ: %1$s то ҳол аз камераи шумо истифода мебарад. Барои кушодани варақа дар ин ҷой зер кунед. - Ёдоварӣ: %1$s то ҳол аз микрофони шумо истифода мебарад. Барои кушодани варақа дар ин ҷой зер кунед. + Ёдоварӣ: %1$s то ҳол аз микрофони шумо истифода мебарад. Барои кушодани варақа дар ин ҷой зер кунед. + + Ёдоварӣ: %1$s то ҳол аз микрофони шумо истифода мебарад. Барои кушодани варақа дар ин ҷой зер кунед. + + Ёдоварӣ: %1$s то ҳол аз микрофон ва камераи шумо истифода мебарад. Барои кушодани варақа дар ин ҷой зер кунед. + - Ёдоварӣ: %1$s то ҳол аз микрофон ва камераи шумо истифода мебарад. Барои кушодани варақа дар ин ҷой зер кунед. + Ёдоварӣ: %1$s то ҳол аз микрофон ва камераи шумо истифода мебарад. Барои кушодани варақа дар ин ҷой зер кунед. Пахш кардан diff --git a/android-components/components/feature/prompts/src/main/res/values-cs/strings.xml b/android-components/components/feature/prompts/src/main/res/values-cs/strings.xml index 9b47bdb74451..68c9076b00e0 100644 --- a/android-components/components/feature/prompts/src/main/res/values-cs/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-cs/strings.xml @@ -157,8 +157,12 @@ Vyberte adresu Zobrazit navrhované adresy + + Rozbalit uložené adresy Skrýt navrhované adresy + + Sbalit uložené adresy Správa adres diff --git a/android-components/components/feature/prompts/src/main/res/values-fr/strings.xml b/android-components/components/feature/prompts/src/main/res/values-fr/strings.xml index 222a50f1a11c..4dfffcad534f 100644 --- a/android-components/components/feature/prompts/src/main/res/values-fr/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-fr/strings.xml @@ -110,8 +110,12 @@ Gérer les mots de passe Développer les identifiants suggérés + + Développer les mots de passe enregistrés Réduire les identifiants suggérés + + Réduire les mots de passe enregistrés Identifiants suggérés @@ -140,8 +144,12 @@ Utiliser une carte enregistrée Développer les cartes bancaires suggérées + + Développer les cartes enregistrées Réduire les cartes bancaires suggérées + + Réduire les cartes enregistrées Gérer les cartes bancaires @@ -161,8 +169,12 @@ Sélectionner une adresse Développer les adresses suggérées + + Développer les adresses enregistrées Réduire les adresses suggérées + + Réduire les adresses enregistrées Gérer les adresses diff --git a/android-components/components/feature/prompts/src/main/res/values-sc/strings.xml b/android-components/components/feature/prompts/src/main/res/values-sc/strings.xml index 36de00f20149..e4dd91d8c607 100644 --- a/android-components/components/feature/prompts/src/main/res/values-sc/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-sc/strings.xml @@ -18,6 +18,8 @@ Crae Non sarves + + Immoe nono Non sarves mai @@ -26,16 +28,26 @@ Sarva No atualizes + + Immoe nono Atualiza Sa crae non podet èssere bòida + Inserta una crae + Impossìbile sarvare is credentziales + + Impossìbile sarvare sa crae Boles sarvare custa credentziale? + + Boles sarvare sa crae? Boles atualizare custa credentziale? + + Boles atualizare sa crae? Boles agiùnghere su nòmine de utente a sa crae sarvada? @@ -86,6 +98,8 @@ Cunfigura s’ora Gesti is credentziales + + Gesti is craes Ismànnia is credentziales cussigiadas @@ -93,6 +107,16 @@ Credentziales cussigiadas + + Craes sarvadas + + + Cussìgia una crae segura + + Cussìgia una crae segura + + Imprea una crae segura: %1$s + Boles torrare a inviare is datos a su situ? @@ -103,12 +127,16 @@ Seletziona una carta de crèditu + + Imprea una carta sarvada Ismànnia is cartas de crèditu cussigiadas Mìnima is cartas de crèditu cussigiadas Gesti is cartas de crèditu + + Gesti is cartas Boles sarvare custa carta cun seguresa? @@ -117,6 +145,9 @@ Su nùmeru de carta at a èssere tzifradu. Su còdighe de seguresa no at a èssere sarvadu. + + %s tzifrat su nùmeru de sa carta tua. Su còdighe de seguresa no at a èssere sarvadu. + Seletziona un’indiritzu @@ -130,10 +161,14 @@ Immàgine de su contu - + Sèbera unu frunidore de atzessu - - Sèbera unu contu + + Identìfica·ti cun unu contu de %1$s Imprea %1$s comente frunidore de atzessu - + + Sighi + + Annulla + diff --git a/android-components/components/feature/prompts/src/main/res/values-si/strings.xml b/android-components/components/feature/prompts/src/main/res/values-si/strings.xml index ac3be0fd3d21..841bbc61d982 100644 --- a/android-components/components/feature/prompts/src/main/res/values-si/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-si/strings.xml @@ -18,6 +18,8 @@ මුරපදය සුරකින්න එපා + + දැන් නොවේ කිසිවිට නොසුරකින්න @@ -26,16 +28,26 @@ සුරකින්න යාවත්කාල නොකරන්න + + දැන් නොවේ යාවත්කාල මුරපද ක්‍ෂේත්‍රය හිස් නොවිය යුතුය + මුරපදය යොදන්න + පිවිසුම සුරැකීමට නොහැකිය + + මුරපදය සුරැකීමට නොහැකිය මෙම පිවිසුම සුරකින්නද? + + මුරපදය සුරකින්නද? පිවිසුම සංශෝධනයක්ද? + + මුරපදය යාවත්කාල කරන්නද? සුරැකි මුරපදයට පරි. නාමය එක් කරන්නද? @@ -86,13 +98,22 @@ කාලය සකසන්න පිවිසුම් කළමනාකරණය + + මුරපද කළමනාකරණය යෝජිත පිවිසුම් විහිදන්න + + සුරැකි මුරපද විහිදන්න යෝජිත පිවිසුම් හකුලන්න + + සුරැකි මුරපද හකුළන්න යෝජිත පිවිසුම් + + සුරැකි මුරපද + ශක්තිමත් මුරපදයක් යෝජනා කරන්න @@ -112,12 +133,20 @@ ණයපතක් තෝරන්න + + සුරැකි පත යොදාගන්න යෝජිත ණයපත් විහිදන්න + + සුරැකි පත් විහිදන්න යෝජිත ණයපත් හකුලන්න + + සුරැකි පත් හකුළන්න ණයපත් කළමනාකරණය + + පත් කළමනාකරණය මෙම පත ආරක්‍ෂිතව සුරකින්නද? @@ -125,13 +154,20 @@ පතෙහි අංකය සංකේතනය වනු ඇත. ආරක්‍ෂණ කේතය සුරැකෙන්නේ නැත. + + %s ඔබගේ පතෙහි අංකය සංකේතනය කරයි. ඔබගේ ආරක්‍ෂණ කේතය සුරැකෙන්නේ නැත. + ලිපිනය තෝරන්න යෝජිත ලිපින විහිදන්න + + සුරැකි ලිපින විහිදන්න යෝජිත ලිපින හකුලන්න + + සුරැකි ලිපින හකුළන්න ලිපින කළමනාකරණය diff --git a/android-components/components/feature/prompts/src/main/res/values-sl/strings.xml b/android-components/components/feature/prompts/src/main/res/values-sl/strings.xml index 948040aa9823..e77ba5c0e4ac 100644 --- a/android-components/components/feature/prompts/src/main/res/values-sl/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-sl/strings.xml @@ -95,8 +95,12 @@ Upravljanje prijav Razširi predlagane prijave + + Prikaži shranjena gesla Strni predlagane prijave + + Skrij shranjena gesla Predlagane prijave @@ -125,8 +129,12 @@ Uporabi shranjeno kartico Razširi predlagane kreditne kartice + + Prikaži shranjene kartice Strni predlagane kreditne kartice + + Skrij shranjene kartice Upravljanje kreditnih kartic @@ -146,8 +154,12 @@ Izbira naslova Razširi predlagane naslove + + Prikaži shranjene naslove Strni predlagane naslove + + Skrij shranjene naslove Upravljanje naslovov diff --git a/android-components/components/feature/prompts/src/main/res/values-tg/strings.xml b/android-components/components/feature/prompts/src/main/res/values-tg/strings.xml index 43d2bcf8667f..58703d132cce 100644 --- a/android-components/components/feature/prompts/src/main/res/values-tg/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-tg/strings.xml @@ -18,6 +18,8 @@ Ниҳонвожа Нигоҳ дошта нашавад + + Ҳоло не Ҳеҷ гоҳ нигоҳ дошта нашавад @@ -26,16 +28,26 @@ Нигоҳ доштан Навсозӣ карда нашавад + + Ҳоло не Навсозӣ кардан Ҷойи ниҳонвожа бояд холӣ набошад + Ниҳонвожаеро ворид намоед + Нигоҳ доштани маълумоти воридшавӣ ғайриимкон аст + + Ниҳонвожа нигоҳ дошта нашуд Маълумоти воридшавии ҷориро нигоҳ медоред? + + Ниҳонвожаро нигоҳ медоред? Маълумоти воридшавии ҷориро аз нав нигоҳ медоред? + + Ниҳонвожаро аз нав нигоҳ медоред? Номи корбарро ба ниҳонвожаи нигоҳдошташуда илова мекунед? @@ -85,13 +97,22 @@ Танзими вақт Идоракунии воридшавӣ + + Идоракунии ниҳонвожаҳо Намоиш додани воридшавиҳои пешниҳодшуда + + Баркушодани ниҳонвожаҳои нигоҳдошташуда Пинҳон кардани воридшавиҳои пешниҳодшуда + + Пинҳон кардани ниҳонвожаҳои нигоҳдошташуда Воридшавиҳои пешниҳодшуда + + Ниҳонвожаҳои нигоҳдошташуда + Пешниҳод кардани ниҳонвожаи боқувват @@ -111,12 +132,20 @@ Корти кредитиро интихоб кунед + + Истифодаи корти нигоҳдошташуда Кортҳои кредитии пешниҳодшударо нишон диҳед + + Баркушодани кортҳои нигоҳдошташуда Кортҳои кредитии пешниҳодшударо пинҳон кунед + + Пинҳон кардани кортҳои нигоҳдошташуда Идоракунии кортҳои кредитӣ + + Идоракунии кортҳо Ин кортро ба таври бехатар нигоҳ медоред? @@ -124,13 +153,20 @@ Рақами корт рамзгузорӣ карда мешавад. Рамзи амниятӣ нигоҳ дошта намешавад. + + «%s» рақами корти шуморо рамзгузорӣ мекунад. Рамзи амниятии шумо нигоҳ дошта намешавад. + Интихоб кардани нишонӣ Намоиш додани нишониҳои пешниҳодшуда + + Баркушодани нишониҳои нигоҳдошташуда Пинҳон кардани нишониҳои пешниҳодшуда + + Пинҳон кардани нишониҳои нигоҳдошташуда Идоракунии нишониҳо diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml index eee28262ea11..b375ebffee70 100644 --- a/fenix/app/src/main/res/values-azb/strings.xml +++ b/fenix/app/src/main/res/values-azb/strings.xml @@ -61,6 +61,137 @@ سون ساخلانان‌لار + + بوتون ساخلانمیش بوکمارک‌لاری گؤستر + + قالدیر + + + %1$s موزیلا طرفیندن دوزه‌دیلمیش. + + + + + %1$s گیزلی تاغلاری باغلادیغینیز زامان ویا اپ‌دن چیخدیغینیز زامان آختاریش و مورور گئچمیشی پوزولار. بو سیزی سایتلارا ویا اینترنت خیدمت وئرنلره گیزلی ائتمه‌سه‌ده، بو جهازدان ایستیفاده ائدن هرکسدن آنلاین اولاراق نه ائتدیگینیزی گیزلی ساخلاماغی آسانلاشدیریر. + + گیزلی مورور حاقیندا یایقین اینانجلار + + + + + بو جهازدا هئچ بیر ایز قویمایین. + + + + %1$s بوتون گیزلی تاغ‌لارینیزی باغلادیغینیز زامان، کوکی‌لری، گئچمیش‌لری و سایت بیلگی‌لرینیزی سیلیر. %2$s + + منیم فعالیتلریمی کیم گؤره بیلر؟ + + + + + سونراکی گیزلی تاغلاریزی بیر توخونوشلا باشلادین. + + آناصفحه‌یه آرتیر + + یوخ ممنون + + + + سیز %1$s اپ‌لرده باغلانتی‌لاری اوتوماتیک آچماغی تنظیم ائلیه بیلرسیز. + + تنظیم‌لره گئدین + + باغلا + + + + + ایندیه قدر لاب گوجلو گیزلیلیک اؤزللیگیمیز، سایتلار آراسی ایزله‌ییجی‌لرین قاباغینی آلار. + + بوتون کوکی قوروما حاقیندا بیلگی آلین + + + + یئنی بیر گیزلی اوتورم باشلادماق اوچون بورایا توخونون. گئچمیشینیزی، کوکی‌لرینیزی، هرشئیی سیلین. + + + + کامئرا ال چاتماسی لازیم.اندروید تنظیم‌لرینه گئدین، ایجازه‌لره توخونون و ایجازه وئرین. + + تنظیم‌لره گئدین + + باغلا + + + گئچن گون، هفته و یا آی ایچینده باخیلمامیش آچیق تاغ‌لاری اوتوماتیک باغلاماغا قویون. + + سئچه‌نک‌لره باخ + + باغلا + + + + ایکی هفته‌ده باخمادیغینیز تاغلار بورایا داشینیر. + + تنظیم‌لردن باغلا + + + + بیر آیدان سونرا اوتوماتیک باغلانسین؟ + + %1$s سون بر آی ایچینده باخدیغینیز تاغلاری باغلایا بیلر. + + باغلا + + + اتوماتیک باغلامانی آچ + + + + + یئنی تاغ + + یئنی گیزلی تاغ + + + + رمزلر شورتکاتی + + + + دالیا قاییت + + هامیسینی گؤستر + + بوتون سون تاغلاری گؤستر دویمه‌سی + + بوتون دؤنگل اولموش تاغلارا باخین + + دؤنگل ائدیلمیش جهاز + + قالدیر + + قالدیر + + + + + سون باخیلان‌لار + + قالدیر + + diff --git a/fenix/app/src/main/res/values-sc/strings.xml b/fenix/app/src/main/res/values-sc/strings.xml index 989794579b00..8b93e08ae965 100644 --- a/fenix/app/src/main/res/values-sc/strings.xml +++ b/fenix/app/src/main/res/values-sc/strings.xml @@ -61,6 +61,19 @@ Mitos fitianos subra de sa navigatzione privada
+ + + Non lasses rastros in custu dispositivu + + %1$s cantzellat testimòngios, cronologia e datos de is sitos cando serras totu is ventanas privadas. %2$s + + Chie diat pòdere bìdere s’atividade mia? + Aberi s’ischeda privada imbeniente cun unu tocu ebbia. @@ -80,6 +93,7 @@ Leghe àteru subra de s’amparu totale contra is testimòngios + Atzessu rechestu a sa fotocàmera. Bae a sa cunfiguratzione de Android, toca is permissos e sèbera permite. @@ -169,6 +183,8 @@ Biblioteca Situ de iscrivania + + Aberi in un’ischeda normale Agiunghe a s’ischermu printzipale @@ -177,6 +193,8 @@ Torra a sincronizare Chirca in sa pàgina + + Tradue sa pàgina Sarva in una colletzione @@ -210,6 +228,12 @@ Ischermu printzipale + + Cantzella sa cronologia de navigatzione + + Tradue sa pàgina + Lìngua seletzionada @@ -221,8 +245,6 @@ Iscansiona - - Motore de chirca Cunfiguratzione de su motore de chirca @@ -254,6 +276,8 @@ Ti donamus su benebènnidu a un’internet mègius Prus colores. Una mègius riservadesa. Su matessi impinnu de pònnere is persones prima de is profitos. + + Passare de un’ischermu a s’àteru est fàtzile comente mai Cumintza @@ -266,23 +290,47 @@ Serra - Sighi + Sighi - Immoe nono + Immoe nono + + + Avisu de riservadesa de Firefox + + + Nos praghet a t’amparare + + Su navigadore nostru isvilupadu chena iscopu de lucru agiudat a blocare is aziendas chi iscrocant is fainas tuas in su web. + + Su navigadore nostru isvilupadu chena iscopu de lucru agiudat a blocare is aziendas chi iscrocant is fainas tuas in su web.\n\nÀteras informatziones in s’avisu de riservadesa nostru. + + avisu de riservadesa Cunfigura comente navigadore predefinidu Immoe nono + + Abarra amparadu cun su tzifradu cando passas dae unu dispositivu a s’àteru Identìfica·ti Immoe nono + + Is notìficas t’agiudant a èssere prus amparadu cun Firefox + + Imbia in manera segura ischedas intre is dispositivos tuos e iscoberi àteras optziones de riservadesa in Firefox. Ativa is notìficas Immoe nono + + Immoe nono + Aberi in un’ischeda de %1$s noa @@ -303,7 +351,7 @@ Seletziona·nde unu - Gesti is curtzadòrgios de chirca + Gesti motores de chirca alternativos Modìfica is motores visìbiles in su menù de chirca @@ -312,8 +360,16 @@ Motore de chirca predefinidu Chirca - - Barra de indiritzos + + Motores de chirca + + Cussìgios dae àteros motores de chirca + + Preferèntzias de sa barra de indiritzos + + Barra de indiritzos - Cussìgios de Firefox + + Àteras informatziones in pitzus de is cussìgios de Firefox Avalora in Google Play Modalidade «isceti HTTPS» - - Ismenguada de is avisos de testimòngios - - Ismèngua is avisos de testimòngios - - Disativadu - - Ativu + + Blocu de is avisos de testimòngios + + Blocu de is avisos de testimòngios in sa navigatzione privada Disativadu pro custu situ Annulla + + Imbia una rechesta + + Boles preguntare agiudu pro custu situ? + + Rechesta imbiada Ativu pro custu situ + + Rechesta de agiudu imbiada Situ non cumpatìbile + - Boles ativare s’ismèngua de is avisos de testimòngios pro %1$s? + Boles ativare su blocu de is avisos de testimòngios pro %1$s? - Boles disativare s’ismèngua de is avisos de testimòngios pro %1$s? - - %1$s at a limpiare is testimòngios de custu situ e at a atualizare sa pàgina. Sa limpiesa de totu is testimòngios ti diat pòdere serrare sa sessione o isboidare is carrellos de s’ispesa. - - Immoe nono + Boles disativare su blocu de is avisos de testimòngios pro %1$s? + + %1$s at refudadu testimòngios + + Prus pagas distratziones, prus pagos testimòngios sighende·ti in custu situ. Disativadu @@ -382,8 +443,8 @@ Est probàbile chi su situ web non siat cumpatìbile cun HTTPS. Atzessibilidade - - Serbidore de contos de Firefox personalizadu + + Serbidore de contos de Mozilla personalizadu Serbidore de Sync personalizadu @@ -401,7 +462,7 @@ Intra pro sincronizare ischedas, sinnalibros, craes e àteru. - Contu de Firefox + Contu de Mozilla Torra a connètere pro sighire cun sa sincronizatzione @@ -412,8 +473,6 @@ Còllida de datos Curretzione de faddinas pro mèdiu de USB - - Ammustra is motores de chirca Ammustra cussìgios de chirca @@ -432,13 +491,33 @@ Cunfiguratzione de su contu Cumpletamentu de URL in automàticu + + Cussìgios dae is ispònsors + + Cussìgios dae %1$s + + Otene cussìgios de sa rete acapiados a sa chirca tua Aberi is ligòngios in is aplicatziones + + Semper + + Pregunta prima de abèrrere + + Mai Gestore de iscarrigamentos esternu + + Ativa is registros de Gecko + + Serrende s’aplicatzione pro aplicare is modìficas… + Cumplementos + + Installa unu cumplementu dae un’archìviu Notìficas @@ -492,12 +571,10 @@ Àteras informatziones %s clàssicu - - Editzione limitada - - Sa colletzione noa de boghes indipendentes. %s - - Sa colletzione noa de boghes indipendentes. + + Sa colletzione Boghes indipendentes. %s + + Sa colletzione Boghes indipendentes. Proa un’istrichiddu de colore @@ -507,12 +584,27 @@ Iscoberi àteros isfundos de ischermu - - - Cumplementu non cumpatìbile - - Su cumplementu est giai installadu - + + + Cumplementos noos a disponimentu + + Controlla is prus de chentu estensiones noas chi ti permitint de personalizare Firefox. + + Esplora cumplementos + + + + Is cumplementos sunt istados disativados in manera temporànea + + Proa torrende a aviare is cumplementos + + Sighi cun is cumplementos disativados + + + + Gesti su contu + + Modìfica sa crae tua, gesti sa colletzione de datos o cantzella su contu Sincroniza immoe @@ -523,6 +615,8 @@ Sinnalibros Credentziales + + Craes Ischedas abertas @@ -549,6 +643,8 @@ %1$s in %2$s %3$s Cartas de crèditu + + Mètodos de pagamentu Indiritzos @@ -786,10 +882,10 @@ Aberi is ischedas Nòmine de sa colletzione - - Torra a nominare - - Boga + + Torra a nominare + + Boga Cantzella dae sa cronologia @@ -1032,6 +1128,12 @@ Sarva comente PDF Impossìbile generare su PDF + + Iscarta + + Impossìbile imprentare custa pàgina + + Imprenta Imbia a su dispositivu @@ -1054,8 +1156,12 @@ In foras de lìnia Connete un’àteru dispositivu + + Pro imbiare un’ischeda, identìfica·ti in Firefox in un’àteru dispositivu, a su mancu. Apo cumprèndidu + + Impossìbile cumpartzire in custa aplicatzione Imbia a su dispositivu @@ -1068,12 +1174,28 @@ Serra is ischedas privadas + + + Boles serrare is ischedas privadas? + Toca o iscurre in custa notìfica pro serrare is ischedas privadas. + + + Firefox est lestru e privadu + + Imprea Firefox comente navigadore predefinidu Prova sa navigatzione privada + + Nàviga chene sighiduras Faghe sa prima chirca + + No, gràtzias + Colletzione cantzellada @@ -1091,6 +1213,8 @@ Ischeda privada serrada Ischedas privadas serradas + + Datos de sa navigatzione privada cantzellados ISCONTZA @@ -1112,6 +1236,8 @@ Boles cantzellare %1$s? Cantzella + + Intrende a sa modalidade de ischermu cumpletu URL copiadu @@ -1127,12 +1253,15 @@ %d ischedas - Cronologia de navigatzione e datos de is sitos + + Cronologia de navigatzione %d indiritzos - - Testimòngios + + Testimòngios e datos de is sitos + + Immàgines e archìvios in sa memòria temporànea Permissos de is sitos @@ -1145,6 +1274,8 @@ Essi + + Perìodu de tempus pro cantzellare Ùrtima ora @@ -1173,35 +1304,10 @@ Grupu cantzelladu - - Ti donamus su benebènnidu a un’internet mègius - - Identìfica·ti Sincronizatzione ativa - - Amparu de riservadesa predefinidu - - Istàndard (predefinidu) - - Echilìbriu intre amparu e rendimentu. Is pàginas s’ant a carrigare cun normalidade. - - Restrinta - - Controllas is datos tuos - - Cumintza a navigare - - Sèbera unu tema - - Automàticu - - Tema iscuru - - Tema craru - Ischedas imbiadas. @@ -1334,10 +1440,17 @@ Sighi a su situ + + Nòmine de su curtzadòrgiu + Credentziales e craes + + Craes Sarva credentziales e craes + + Sarva is craes Pregunta·mi·ddu @@ -1353,16 +1466,27 @@ Agiunghe credentziale + + Agiunghe crae + Sincronizatzione de credentziales + + Sincroniza is craes Sincronizatzione de credentziales intre dispositivos + + Sincroniza is craes intre dispositivos Credentziales sarvadas + + Craes sarvadas Is credentziales chi as a sarvare o sincronizare cun %s ant a èssere ammustradas inoghe. Leghe àteru subra de Sync. + + Àteras informatziones in pitzus de sa sincronizatzione Etzetziones @@ -1373,6 +1497,8 @@ Cantzella totu is etzetziones Chirca credentziales + + Chirca craes Situ @@ -1421,18 +1547,28 @@ Indiritzos Cartas de crèditu + + Mètodos de pagamentu Sarva e cumpleta in automàticu is cartas + + Sarva e cumpleta cun is mètodos de pagamentu Is datos sunt tzifrados + + %s tzifrat totu is mètodos de pagamentu chi sarves Sincronizatzione de cartas intre dispositivos Sincronizatzione de cartas Agiunghe una carta de crèditu + + Agiunghe una carta Gesti is cartas + + Gesti is cartas Agiunghe un’indiritzu @@ -1440,9 +1576,14 @@ Sarva e cumpleta in automàticu is indiritzos + + Sarva e cumpleta cun is indiritzos Include datos comente nùmeros, indiritzos eletrònicos e indiritzos de ispeditzione + + Includet nùmeros de telèfonu e indiritzos eletrònicos + Agiunghe una carta @@ -1463,6 +1604,8 @@ Cantzella sa carta Seguru chi boles cantzellare custa carta de crèditu? + + Boles cantzellare sa carta? Cantzella @@ -1475,16 +1618,32 @@ Cartas sarvadas Inserta unu nùmeru de carta vàlidu + + Inserta unu nùmeru de carta vàlidu Cumpila custu campu + + Agiunghe unu nòmine Isbloca pro bìdere is cartas sarvadas tuas + + Ampara is cartas de crèditu tuas + + Ampara is mètodos de pagamentu sarvados + + Cunfigura una secuèntzia de blocu, PIN o crae pro amparare is cartas de crèditu sarvadas tuas de s’atzessu de àtera gente chi tèngiat su dispositivu tuo. + + Cunfigura una secuèntzia de blocu, PIN o crae pro amparare is mètodos de pagamentu sarvados de s’atzessu de àtera gente chi tèngiat su dispositivu tuo. Cunfigura immoe A pustis Isbloca su disposivitu tuo + + Isbloca pro impreare informatzione sarvada de una carta de crèditu + + Isbloca pro impreare is mètodos de pagamentu sarvados Agiunghe un’indiritzu @@ -1521,6 +1680,8 @@ Cantzella s’indiritzu Seguru chi boles cantzellare custu indiritzu? + + Boles cantzellare custu indiritzu? Cantzella @@ -1536,26 +1697,16 @@ Agiunghe unu motore de chirca nou Modìfica motore de chirca - - Agiunghe - - Sarva Modìfica Cantzella - - Àteru Nòmine - - Nòmine Nòmine de su motore de chirca - Cadena de chirca - URL de impreare in sa chirca Sostitui sa chirca cun «%s». Esempru: \nhttps://www.google.com/search?q=%s @@ -1567,8 +1718,7 @@ URL de s’API pro is cussìgios de chirca - Sostitui sa chirca cun “%s”. -Esempru: \nhttp://suggestqueries.google.com/complete/search?client=firefox&q=%s + Sostitui sa chirca cun “%s”. Pro esempru:\nhttps://suggestqueries.google.com/complete/search?client=firefox&q=%s Sarva @@ -1628,22 +1778,38 @@ Esempru: \nhttp://suggestqueries.google.com/complete/search?client=firefox&q Modìfica Seguru chi boles cantzellare custa credentziale? + + Seguru chi boles cantzellare custa crae? Cantzella Annulla Optziones de credentziales + + Optziones de is craes Sarva is modìficas a sa credentziale. + + Sarva is modìficas. Modìfica + + Modìfica sa crae Agiunghe una credentziale noa + + Agiunghe una crae Crae rechesta + + Inserta una crae Nòmine de utente rechestu + + Inserta unu nòmine de utente + + Inserta un’indiritzu web Chirca cun sa boghe @@ -1658,23 +1824,36 @@ Esempru: \nhttp://suggestqueries.google.com/complete/search?client=firefox&q Connete un’àteru dispositivu. + + Autèntica·ti torra. + + Ativa sa sincronizatzione de ischedas. + + Nissuna ischeda aberta in su Firefox de is àteros dispositivos. + + Ammustra una lista de ischedas abertas in àteros dispositivos tuos. Identìfica·ti a sync Nissuna ischeda aberta + + + Lìmite de curtzadòrgios barigadu + + Pro agiùnghere unu curtzadòrgiu nou, boga·nde unu. Toca e mantene su situ, pustis seletziona boga. AB, apo cumprèndidu Curtzadòrgios - - Nòmine + + Nòmine Nòmine de su curtzadòrgiu - - AB - - Annulla + + AB + + Annulla Cunfiguratzione @@ -1725,6 +1904,8 @@ Esempru: \nhttp://suggestqueries.google.com/complete/search?client=firefox&q Artìculos pro tema Iscoberi·nde àteros + + Funtzionat gràtzias a %s. Parte de sa famìlia de Firefox. %s @@ -1735,11 +1916,268 @@ Esempru: \nhttp://suggestqueries.google.com/complete/search?client=firefox&q Bae a sa cunfiguratzione + + + Verificadore de retzensiones + + Retzensiones fidadas + + Misturu de retzensiones fidadas e non fidadas + + Retzensiones non fidadas + + Canto sunt fidadas custas retzensiones? + + Valutatzione assentada + + Retzensiones non fidadas bogadas + + In evidèntzia dae retzensiones reghentes + + Comente istabilimus sa calidade de is retzensiones + + Impreamus tecnologias de inteligèntzia artifitziale (IA) dae %s in Mozilla pro controllare sa calidade de is retzensiones de produtos. Custu t’at a agiudare a verificare sa calidade sa retzensione, non de su produtu. + + votu alfabèticu dae A a F.]]> + + Retzensiones fidadas. Pensamus chi is retzensiones est probàbile chi bèngiant dae clientes reales chi ant lassadu retzensiones sintzeras e ogetivas. + + Pensamus chi ddoe at unu misturu de retzensiones fidadas e non fidadas. + + Retzensiones non fidadas. Pensamus chi is retzensiones est probàbile chi siant farsas o bèngiant dae utentes no ogetivos. + + valutatzione assentada si basat isceti subra de retzensiones chi cunsideramus fidadas.]]> + + + in evidèntzia benent dae is retzensiones in %s de is ùrtimas 80 dies chi cunsideramus fidadas.]]> + + Àteras informatziones in pitzus de %s. + + comente %s istabilit sa calidade de is retzensiones + + Cunfiguratzione + + Ammustra publitzidade in su verificadore de retzensiones + + Àteras informatziones + + Disativa su verificadore de retzensiones + + Àteru de cunsiderare + + %s dae Mozilla + + Informatziones noas de verificare + + Controlla immoe + + Ancora no ddoe at bastantes retzensiones + + Su produtu no est a disponimentu + + Su produtu sinnaladu est a disponimentu + + Controllende sa calidade de sa retzensione + + Controllende sa calidade de sa retzensione + + Controllende sa calidade de sa retzensione (%s) + + Custu podet trigare finas a 60 segundos. + + Gràtzias de sa sinnalatzione. + + Non podimus verificare custas retzensiones + + Àteras informatziones luego + + S’anàlisi est atualizada + + Apo cumprèndidu + + Nissuna informatzione a disponimentu immoe + + Semus traballende pro risòlvere su problema. Torra luego. + + Nissuna connessione de rete + + Àteras informatziones + + polìtica de riservadesa + + Polìtica de riservadesa + + cunditziones de su servìtziu + + Cunditziones de su servìtziu + + Eja, dd’apo a proare + + Immoe nono + + Proa su verificadore de retzensiones + + Aberi su verificadore de retzensiones + + Beta + + Aberi su verificadore de retzensiones + + Serra su verificadore de retzensiones + + %1$s de 5 isteddos + + Ammustra·nde prus pagu + + Ammustra àteru + + Calidade + + Prètziu + + Imbiu + + Cumpetitividade + + “%s” + mìnima + + minimadu ismànnia + + ismanniadu + + aberi su ligòngiu pro àteras informatziones in pitzus de custa colletzione leghe s’artìculu + + + aberi su ligòngiu pro nde lèghere àteras informatziones + + Ligòngios + + Ligòngios a disponimentu + + + + + + Boles tradùere custa pàgina? + + Proa is tradutziones privadas in %1$s + + Àteras informatziones + + Tradue dae + + Tradue in + + Immoe nono + + Fatu + + Tradue + + Torra a nce proare + + Traduende + + Tradutzione in cursu + + Sèbera una lìngua + + Custa lìngua no est ancora atzetada: %1$s. + + Àteras informatziones + + + + Optziones de tradutzione + + Cunfiguratzione de sa tradutzione + + + In pitzus de is tradutziones de %1$s + + + + Tradutziones + + Preferèntzias de sa tradutzione + + Tradutzione automàtica + + Non traduas mai custos sitos + + Iscàrriga lìnguas + + + + Tradutzione automàtica + + + Tradue semper + + Non traduas mai + + + + Non traduas mai custos sitos + + Boga %1$s + + Boles cantzellare %1$s? + + Cantzella + + Annulla + + + + Iscàrriga lìnguas + + Àteras informatziones + + Lìnguas a disponimentu + + rechestu + + %1$s (%2$s) + + Iscàrriga lìnguas + + Totu is lìnguas + + Cantzella + + In cursu + + Iscàrriga + + Seletzionada + + + Boles cantzellare %1$s (%2$s)? + + Cantzella + + Annulla + + + Iscàrriga + + Iscàrriga e tradue + + Annulla + diff --git a/fenix/app/src/main/res/values-si/strings.xml b/fenix/app/src/main/res/values-si/strings.xml index 4cc16dd0fe7b..07e0127c332e 100644 --- a/fenix/app/src/main/res/values-si/strings.xml +++ b/fenix/app/src/main/res/values-si/strings.xml @@ -245,6 +245,9 @@ history and go back to the home screen. --> පිරික්සුම් ඉතිහාසය මකන්න + + පිටුව පරිවර්තනය + තෝරාගත් භාෂාව @@ -320,10 +323,15 @@ දැන් නොවේ + + + ෆයර්ෆොක්ස් රහස්‍යතා දැන්වීම ඔබට ආරක්‍ෂාව සලසන්නෙමු + අපගේ ලාභ නොලබන පිටුබලයක් සහිත අතිරික්සුව අන්තර්ජාලය පුරා ඔබව රහසින් ලුහුබඳින සමාගම් ස්වයංක්‍රීයව නවත්වයි. + සමාගම් රහසින් අන්තර්ජාලය පුරා ඔබව ලුහුබැඳීම නැවැත්වීමට අපගේ ලාභ නොලබන පිටුබලයක් සහිත අතිරික්සුව සැමවිට උදව් කරයි.\n\nඅපගේ රහස්‍යතා දැන්වීමෙන් තව දැන ගන්න. @@ -427,6 +435,8 @@ දත්තකඩ පතාක අවහිරය + + පෞද්. පිරික්සීමෙහි දත්තකඩ පතාක අවහිරය මෙම අඩවියට අක්‍රියයි @@ -443,9 +453,23 @@ සහාය ඉල්ලීම යැවිණි අඩවියට සහාය නොදක්වයි + + %1$s සඳහා දත්තකඩ පතාක අවහිරය සක්‍රිය කරන්නද? + + %1$s සඳහා දත්තකඩ පතාක අවහිරය අක්‍රිය කරන්නද? %1$s මඟින් මෙම අඩවියේ දත්තකඩ ඉල්ලීම් ස්වයංක්‍රීයව ඉවතලීමට නොහැක. ඉදිරියේ දී මෙම අඩවිය සඳහා සහාය දැක්වීමට ඉල්ලීමක් යැවීමට හැකිය. + + අක්‍රිය කරන්න සහ %1$s දත්තකඩ මකා මෙම අඩවිය නැවත පූරණය කරනු ඇත. මෙය ඔබව නික්මවීමට හෝ බඩු කරත්ත හිස් කිරීමට ඉඩ ඇත. + + සක්‍රිය කළහොත් %1$s මෙම අඩවියේ දත්තකඩ පතාක ස්වයංක්‍රීයව ඉවතලීමට උත්සාහ කරයි. + + %1$s ඔබ වෙනුවෙන් දත්තකඩ ඉවතලිණි + + + බාධා අවමයි, මෙම අඩවියේ ඔබව ලුහුබඳින දත්තකඩ අවමයි. + ඉහළ ආරක්‍ෂාවක් සඳහා HTTPS සංකේතන කෙටුම්පත භාවිතයෙන් අඩවි වෙත ස්වයංක්‍රීයව සම්බන්ධ වීමට තැත් කරයි. @@ -1506,6 +1530,8 @@ සමස්ත දත්තකඩ (අඩවි කැඩීමට හේතු වේ) හරස්-අඩවි දත්තකඩ හුදකලාව + + දත්ත බෙදා විකිණීමෙන් වළකින ලෙස අඩවි වලට දන්වන්න ලුහුබැඳීමේ අන්තර්ගතය @@ -1646,6 +1672,8 @@ මුරපද සමමුහූර්තය උපාංගවල පිවිසුම් සමමුහූර්තය + + උපාංග අතර මුරපද සමමුහූර්තය සුරැකි පිවිසුම් @@ -1948,16 +1976,28 @@ පිවිසීමේ මුරපදය සඳහා සංස්කරණය කළ හැකි පෙළ ක්‍ෂේත්‍රය. පිවිසීමට වෙනස්කම් සුරකින්න. + + වෙනස්කම් සුරකින්න සංස්කරණය + + මුරපදය සංස්කරණය නව පිවිසුමක් යොදන්න + + මුරපදය එක් කරන්න මුරපදයක් අවශ්‍යයි + + මුරපදයක් යොදන්න පරිශීලක නාමය අවශ්‍යයි + + පරිශ්‍රීලක නාමයක් යොදන්න සත්කාරක නාමය අවශ්‍යයි + + වියමන ලිපිනයක් යොදන්න හඬ සෙවුම @@ -2200,6 +2240,9 @@ තව දැන ගැනීමට සබැඳිය අරින්න + + සබැඳි + @@ -2298,6 +2341,15 @@ අවලංගු + + දත්ත ඉතිරි කරන ප්‍රකාරයේ දී බාගන්න ද (%1$s)? + + පරිවර්තන පෞද්ගලිකව රැඳවීමට ඔබගේ නිහිතයට අර්ධව භාෂා බාගැනෙයි. + + සෑමවිට දත්ත ඉතිරි කරන ප්‍රකාරයේ දී බාගන්න බාගන්න diff --git a/fenix/app/src/main/res/values-sl/strings.xml b/fenix/app/src/main/res/values-sl/strings.xml index 403d88a38763..1376022d9b7a 100644 --- a/fenix/app/src/main/res/values-sl/strings.xml +++ b/fenix/app/src/main/res/values-sl/strings.xml @@ -1314,6 +1314,8 @@ Zapri zasebne zavihke + Tapnite to obvestilo ali ga povlecite vstran, da zaprete zasebne zavihke. + Trženje @@ -1722,8 +1724,12 @@ Izjeme Tu bodo prikazane prijave in gesla, ki niso shranjena. + + Za tukaj navedena mesta %s ne bo shranjeval gesel. Prijave in gesla za te strani ne bodo shranjene. + + Za ta spletna mesta %s ne bo shranjeval gesel. Izbriši vse izjeme @@ -1758,8 +1764,12 @@ Odklenite za ogled shranjenih prijav Zavarujte svoje prijave in gesla + + Zavarujte shranjena gesla Nastavite vzorec za zaklepanje naprave, PIN ali geslo za zaščito pred dostopom do shranjenih prijav in gesel, če vašo napravo uporablja še kdo. + + Nastavite vzorec za zaklepanje naprave, PIN ali geslo za zaščito pred dostopom do shranjenih gesel, če vašo napravo uporablja še kdo. Pozneje @@ -1794,6 +1804,8 @@ Shranjuj in izpolnjuj načine plačila Podatki so šifrirani + + %s šifrira vse načine plačila, ki jih shranite Sinhroniziraj kartice med napravami @@ -2025,8 +2037,12 @@ Možnosti gesel Besedilno polje za urejanje spletnega naslova prijave. + + Besedilno polje za urejanje spletnega naslova. Besedilno polje za urejanje uporabniškega imena prijave. + + Besedilno polje za urejanje uporabniškega imena. Besedilno polje za urejanje gesla prijave. @@ -2430,6 +2446,8 @@ Nikoli ne prevajaj jezika %1$s Nikoli ne prevajaj tega spletnega mesta + + Preglasi vse druge nastavitve Nastavitve prevajanja @@ -2479,6 +2497,9 @@ Prekliči + + + Prenesi jezike Več o tem @@ -2500,6 +2521,8 @@ Izbrano + + Če izbrišete vse jezike, bo %1$s pri prevajanju v predpomnilnik naložil delne jezike. Izbriši diff --git a/fenix/app/src/main/res/values-tg/strings.xml b/fenix/app/src/main/res/values-tg/strings.xml index 00441626da65..4eaf14fdb39c 100644 --- a/fenix/app/src/main/res/values-tg/strings.xml +++ b/fenix/app/src/main/res/values-tg/strings.xml @@ -246,6 +246,7 @@ Танзимоти саҳифаи асосӣ + Экрани асосӣ @@ -253,6 +254,9 @@ Пок кардани таърихи тамошо + + Тарҷума кардани саҳифа + Забони интихобшуда @@ -264,8 +268,6 @@ Ҷустуҷӯ - - Низоми ҷустуҷӯӣ Танзимоти низоми ҷустуҷӯӣ @@ -320,14 +322,14 @@ - Огоҳиҳо барои кори бештар бо «%s» ба шумо кумак мекунанд + Огоҳиҳо барои кори бештар бо «%s» ба шумо кумак мекунанд - Варақаҳои худро байни дастгоҳҳо ҳамоҳанг созед, боргириҳоро идора кунед, барои беҳтар танзим кардани муҳофизати махфияти «%s» маслиҳатҳо гиред ва аз чизҳои бештар истифода баред. + Варақаҳои худро байни дастгоҳҳо ҳамоҳанг созед, боргириҳоро идора кунед, барои беҳтар танзим кардани муҳофизати махфияти «%s» маслиҳатҳо гиред ва аз чизҳои бештар истифода баред. - Идома додан + Идома додан - Ҳоло не + Ҳоло не @@ -444,21 +446,11 @@ Реҷаи «Танҳо HTTPS» - - Маҳдудкунии баннери куки Манъкунандаи баннери куки Манъкунандаи баннери куки дар тамошокунии хусусӣ - - Маҳдуд кардани баннерҳои куки - - Ғайрифаъол - - Фаъол - - - «%1$s» ба таври худкор кушиш мекунад, ки дархостҳои кукиҳоро дар баннерҳои кукиҳо рад кунад. + Барои ин сомона хомӯш аст @@ -476,36 +468,17 @@ Ин сомона дар айни замон дастгирӣ намешавад - «Маҳдудкунии баннери куки»-ро барои %1$s фаъол месозед? - Манъкунандаи баннери кукиро барои %1$s фаъол мекунед? - - «Маҳдудкунии баннери куки»-ро барои %1$s хомӯш месозед? Манъкунандаи баннери кукиро барои %1$s хомӯш мекунед? «%1$s» наметавонад, ки дархостҳои кукиро барои ин сомона ба таври худкор рад кунад. Шумо метавонед барои дастгирӣ кардани ин сомона дар оянда дархостеро фиристонед. - - %1$s кукиҳои ин сомонаро тоза мекунад ва саҳифаро аз нав бор мекунад. Амали тозакунии ҳамаи кукиҳо метавонад шуморо аз сомона хориҷ кунад ва сабадҳои харидории шуморо холӣ намояд. Хомӯш кунед ва «%1$s» кукиҳоро тоза намуда, ин сомонаро аз нав бор мекунад. Ин амал метавонад шуморо аз сомона хориҷ кунад ва сабадҳои харидории шуморо холӣ намояд. - «%1$s» кӯшиш мекунад, ки ҳамаи дархостҳои кукиҳоро дар сомонаҳои дастгиришаванда ба таври худкор рад кунад. - Фаъол созед, ва «%1$s» кӯшиш мекунад, ки ҳамаи баннерҳои кукиро дар ин сомона ба таври худкор рад кунад. - - Ба «%1$s» иҷозат медиҳед, ки баннерҳои кукиро рад кунад? - - «%1$s» метавонад бисёр дархостҳои баннерҳои кукиро ба таври худкор рад кунад. - - Ҳоло не - - Шумо бояд камтар дархостҳои кукиҳоро бинед - - - Иҷозат додан «%1$s» дар ҳоли ҳозир барои шумо кукиҳоро рад кард @@ -1294,8 +1267,6 @@ Нодида гузарондан - Чоп ғайриимкон аст - Ин саҳифа чоп карда намешавад Чоп кардан @@ -1746,6 +1717,8 @@ Воридшавиҳое, ки шумо дар %s нигоҳ медоред ё ҳамоҳанг мекунед, дар ин ҷо нишон дода мешаванд. Маълумоти бештар дар бораи ҳамоҳангсозӣ + + Маълумоти бештар дар бораи ҳамоҳангсозӣ Истисноҳо @@ -2223,8 +2196,6 @@ Нуқтаҳои асосӣ аз тақризҳои «%s» ба хулоса омаданд, ки дар давоми 80 рӯзи охир ҷамъ карда шудаанд ва онҳо ба умеди мо боэътимод мебошанд.]]> Маълумоти бештар дар бораи «%s». - - чӣ тавр «%s» аз ҷониби «Mozilla» сифати тақризҳоро муайян мекунад чӣ тавр «%s» сифати тақризҳоро муайян мекунад From 0b05908da4e526e2e4e7491e4e81e26653dec9b4 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 6 Feb 2024 01:25:31 +0000 Subject: [PATCH 085/586] Update GeckoView (Nightly) to 124.0.20240205205906. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 81b89bf9438d..73972e4e0d0f 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240205094658" + const val version = "124.0.20240205205906" /** * GeckoView channel From ceaeadd72752bd794eeeb3e2dfda58204c7eecd2 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 6 Feb 2024 05:33:40 +0000 Subject: [PATCH 086/586] Update A-S to 124.20240206050329. --- .../plugins/dependencies/src/main/java/ApplicationServices.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt index e23e485381d7..5eec4af99a60 100644 --- a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt +++ b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // These lines are generated by android-components/automation/application-services-nightly-bump.py -val VERSION = "124.20240205050332" +val VERSION = "124.20240206050329" val CHANNEL = ApplicationServicesChannel.NIGHTLY object ApplicationServicesConfig { From 11d4fe7af135c5b74e97619d75a3893174b0770e Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Thu, 1 Feb 2024 11:47:03 +0200 Subject: [PATCH 087/586] Bug 1877939 - Remove redundant assertion functions from EnhancedTrackingProtectionRobot --- .../robots/EnhancedTrackingProtectionRobot.kt | 61 ++++++++----------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt index 29e2a25abcef..a56bab508090 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt @@ -38,10 +38,29 @@ import org.mozilla.fenix.helpers.isChecked * Implementation of Robot Pattern for Enhanced Tracking Protection UI. */ class EnhancedTrackingProtectionRobot { - fun verifyEnhancedTrackingProtectionSheetStatus(status: String, state: Boolean) = - assertEnhancedTrackingProtectionSheetStatus(status, state) + fun verifyEnhancedTrackingProtectionSheetStatus(status: String, state: Boolean) { + mDevice.waitNotNull(Until.findObjects(By.text("Protections are $status for this site"))) + onView(ViewMatchers.withResourceName("switch_widget")).check( + matches( + isChecked( + state, + ), + ), + ) + Log.i(TAG, "verifyEnhancedTrackingProtectionSheetStatus: Verified ETP toggle is checked: $state") + } - fun verifyETPSwitchVisibility(visible: Boolean) = assertETPSwitchVisibility(visible) + fun verifyETPSwitchVisibility(visible: Boolean) { + if (visible) { + enhancedTrackingProtectionSwitch() + .check(matches(isDisplayed())) + Log.i(TAG, "verifyETPSwitchVisibility: Verified ETP toggle is displayed") + } else { + enhancedTrackingProtectionSwitch() + .check(matches(not(isDisplayed()))) + Log.i(TAG, "verifyETPSwitchVisibility: Verified ETP toggle is not displayed") + } + } fun verifyCrossSiteCookiesBlocked(isBlocked: Boolean) { assertUIObjectExists(itemWithResId("$packageName:id/cross_site_tracking")) @@ -184,7 +203,10 @@ class EnhancedTrackingProtectionRobot { pageSecurityIndicator().waitForExists(waitingTime) pageSecurityIndicator().click() Log.i(TAG, "openEnhancedTrackingProtectionSheet: Clicked site security button") - assertSecuritySheetIsCompletelyDisplayed() + Log.i(TAG, "openEnhancedTrackingProtectionSheet: Looking for quick actions sheet") + mDevice.findObject(UiSelector().description(getStringResource(R.string.quick_settings_sheet))) + .waitForExists(waitingTime) + assertUIObjectExists(itemWithResId("$packageName:id/quick_action_sheet")) EnhancedTrackingProtectionRobot().interact() return Transition() @@ -236,30 +258,6 @@ fun enhancedTrackingProtection(interact: EnhancedTrackingProtectionRobot.() -> U return EnhancedTrackingProtectionRobot.Transition() } -private fun assertETPSwitchVisibility(visible: Boolean) { - if (visible) { - enhancedTrackingProtectionSwitch() - .check(matches(isDisplayed())) - Log.i(TAG, "assertETPSwitchVisibility: Verified ETP toggle is displayed") - } else { - enhancedTrackingProtectionSwitch() - .check(matches(not(isDisplayed()))) - Log.i(TAG, "assertETPSwitchVisibility: Verified ETP toggle is not displayed") - } -} - -private fun assertEnhancedTrackingProtectionSheetStatus(status: String, state: Boolean) { - mDevice.waitNotNull(Until.findObjects(By.text("Protections are $status for this site"))) - onView(ViewMatchers.withResourceName("switch_widget")).check( - matches( - isChecked( - state, - ), - ), - ) - Log.i(TAG, "assertEnhancedTrackingProtectionSheetStatus: Verified ETP toggle is checked: $state") -} - private fun pageSecurityIndicator() = mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_security_indicator")) @@ -315,10 +313,3 @@ private fun fingerprintersBlockListButton() = withText("Fingerprinters"), ), ) - -private fun assertSecuritySheetIsCompletelyDisplayed() { - Log.i(TAG, "assertSecuritySheetIsCompletelyDisplayed: Looking for quick actions sheet") - mDevice.findObject(UiSelector().description(getStringResource(R.string.quick_settings_sheet))) - .waitForExists(waitingTime) - assertUIObjectExists(itemWithResId("$packageName:id/quick_action_sheet")) -} From f98206c3a10fba0106bc1cb27052b64fc643c385 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Thu, 1 Feb 2024 20:43:41 +0200 Subject: [PATCH 088/586] Bug 1877939 - Add pairs of test logs to EnhancedTrackingProtectionRobot --- .../robots/EnhancedTrackingProtectionRobot.kt | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt index a56bab508090..365b30c9829c 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt @@ -40,6 +40,7 @@ import org.mozilla.fenix.helpers.isChecked class EnhancedTrackingProtectionRobot { fun verifyEnhancedTrackingProtectionSheetStatus(status: String, state: Boolean) { mDevice.waitNotNull(Until.findObjects(By.text("Protections are $status for this site"))) + Log.i(TAG, "verifyEnhancedTrackingProtectionSheetStatus: Trying to check ETP toggle is checked: $state") onView(ViewMatchers.withResourceName("switch_widget")).check( matches( isChecked( @@ -52,10 +53,12 @@ class EnhancedTrackingProtectionRobot { fun verifyETPSwitchVisibility(visible: Boolean) { if (visible) { + Log.i(TAG, "verifyETPSwitchVisibility: Trying to verify ETP toggle is displayed") enhancedTrackingProtectionSwitch() .check(matches(isDisplayed())) Log.i(TAG, "verifyETPSwitchVisibility: Verified ETP toggle is displayed") } else { + Log.i(TAG, "verifyETPSwitchVisibility: Trying to verify ETP toggle is not displayed") enhancedTrackingProtectionSwitch() .check(matches(not(isDisplayed()))) Log.i(TAG, "verifyETPSwitchVisibility: Verified ETP toggle is not displayed") @@ -64,9 +67,11 @@ class EnhancedTrackingProtectionRobot { fun verifyCrossSiteCookiesBlocked(isBlocked: Boolean) { assertUIObjectExists(itemWithResId("$packageName:id/cross_site_tracking")) + Log.i(TAG, "verifyCrossSiteCookiesBlocked: Trying to click cross site cookies block list button") crossSiteCookiesBlockListButton().click() Log.i(TAG, "verifyCrossSiteCookiesBlocked: Clicked cross site cookies block list button") // Verifies the trackers block/allow list + Log.i(TAG, "verifyCrossSiteCookiesBlocked: Trying to verify cross site cookies are blocked: $isBlocked") onView(withId(R.id.details_blocking_header)) .check( matches( @@ -84,9 +89,11 @@ class EnhancedTrackingProtectionRobot { fun verifySocialMediaTrackersBlocked(isBlocked: Boolean) { assertUIObjectExists(itemWithResId("$packageName:id/social_media_trackers")) + Log.i(TAG, "verifySocialMediaTrackersBlocked: Trying to click social trackers block list button") socialTrackersBlockListButton().click() Log.i(TAG, "verifySocialMediaTrackersBlocked: Clicked social trackers block list button") // Verifies the trackers block/allow list + Log.i(TAG, "verifySocialMediaTrackersBlocked: Trying to verify social trackers are blocked: $isBlocked") onView(withId(R.id.details_blocking_header)) .check( matches( @@ -100,15 +107,18 @@ class EnhancedTrackingProtectionRobot { ), ) Log.i(TAG, "verifySocialMediaTrackersBlocked: Verified social trackers are blocked: $isBlocked") + Log.i(TAG, "verifySocialMediaTrackersBlocked: Trying to verify blocked social trackers list is displayed") onView(withId(R.id.blocking_text_list)).check(matches(isDisplayed())) Log.i(TAG, "verifySocialMediaTrackersBlocked: Verified blocked social trackers list is displayed") } fun verifyFingerprintersBlocked(isBlocked: Boolean) { assertUIObjectExists(itemWithResId("$packageName:id/fingerprinters")) + Log.i(TAG, "verifyFingerprintersBlocked: Trying to click fingerprinters block list button") fingerprintersBlockListButton().click() Log.i(TAG, "verifyFingerprintersBlocked: Clicked fingerprinters block list button") // Verifies the trackers block/allow list + Log.i(TAG, "verifyFingerprintersBlocked: Trying to verify fingerprinters are blocked: $isBlocked") onView(withId(R.id.details_blocking_header)) .check( matches( @@ -122,15 +132,18 @@ class EnhancedTrackingProtectionRobot { ), ) Log.i(TAG, "verifyFingerprintersBlocked: Verified fingerprinters are blocked: $isBlocked") + Log.i(TAG, "verifyFingerprintersBlocked: Trying to verify blocked fingerprinter trackers list is displayed") onView(withId(R.id.blocking_text_list)).check(matches(isDisplayed())) Log.i(TAG, "verifyFingerprintersBlocked: Verified blocked fingerprinter trackers list is displayed") } fun verifyCryptominersBlocked(isBlocked: Boolean) { assertUIObjectExists(itemWithResId("$packageName:id/cryptominers")) + Log.i(TAG, "verifyCryptominersBlocked: Trying to click cryptominers block list button") cryptominersBlockListButton().click() Log.i(TAG, "verifyCryptominersBlocked: Clicked cryptominers block list button") // Verifies the trackers block/allow list + Log.i(TAG, "verifyCryptominersBlocked: Trying to verify cryptominers are blocked: $isBlocked") onView(withId(R.id.details_blocking_header)) .check( matches( @@ -144,15 +157,18 @@ class EnhancedTrackingProtectionRobot { ), ) Log.i(TAG, "verifyCryptominersBlocked: Verified cryptominers are blocked: $isBlocked") + Log.i(TAG, "verifyCryptominersBlocked: Trying to verify blocked cryptominers trackers list is displayed") onView(withId(R.id.blocking_text_list)).check(matches(isDisplayed())) Log.i(TAG, "verifyCryptominersBlocked: Verified blocked cryptominers trackers list is displayed") } fun verifyTrackingContentBlocked(isBlocked: Boolean) { assertUIObjectExists(itemWithText("Tracking Content")) + Log.i(TAG, "verifyTrackingContentBlocked: Trying to click tracking content block list button") trackingContentBlockListButton().click() Log.i(TAG, "verifyTrackingContentBlocked: Clicked tracking content block list button") // Verifies the trackers block/allow list + Log.i(TAG, "verifyTrackingContentBlocked: Trying to verify tracking content is blocked: $isBlocked") onView(withId(R.id.details_blocking_header)) .check( matches( @@ -166,11 +182,13 @@ class EnhancedTrackingProtectionRobot { ), ) Log.i(TAG, "verifyTrackingContentBlocked: Verified tracking content is blocked: $isBlocked") + Log.i(TAG, "verifyTrackingContentBlocked: Trying to verify blocked tracking content trackers list is displayed") onView(withId(R.id.blocking_text_list)).check(matches(isDisplayed())) Log.i(TAG, "verifyTrackingContentBlocked: Verified blocked tracking content trackers list is displayed") } fun viewTrackingContentBlockList() { + Log.i(TAG, "viewTrackingContentBlockList: Trying to verify blocked tracking content trackers") onView(withId(R.id.blocking_text_list)) .check( matches( @@ -193,19 +211,23 @@ class EnhancedTrackingProtectionRobot { ) fun navigateBackToDetails() { + Log.i(TAG, "navigateBackToDetails: Trying to click details list back button") onView(withId(R.id.details_back)).click() Log.i(TAG, "navigateBackToDetails: Clicked details list back button") } class Transition { fun openEnhancedTrackingProtectionSheet(interact: EnhancedTrackingProtectionRobot.() -> Unit): Transition { - Log.i(TAG, "openEnhancedTrackingProtectionSheet: Looking for site security button") + Log.i(TAG, "openEnhancedTrackingProtectionSheet: Waiting for $waitingTime ms for site security button to exist") pageSecurityIndicator().waitForExists(waitingTime) + Log.i(TAG, "openEnhancedTrackingProtectionSheet: Waited for $waitingTime ms for site security button to exist") + Log.i(TAG, "openEnhancedTrackingProtectionSheet: Trying to click site security button") pageSecurityIndicator().click() Log.i(TAG, "openEnhancedTrackingProtectionSheet: Clicked site security button") - Log.i(TAG, "openEnhancedTrackingProtectionSheet: Looking for quick actions sheet") + Log.i(TAG, "openEnhancedTrackingProtectionSheet: Waiting for $waitingTime ms for quick actions sheet to exits") mDevice.findObject(UiSelector().description(getStringResource(R.string.quick_settings_sheet))) .waitForExists(waitingTime) + Log.i(TAG, "openEnhancedTrackingProtectionSheet: Waited for $waitingTime ms for quick actions sheet to exits") assertUIObjectExists(itemWithResId("$packageName:id/quick_action_sheet")) EnhancedTrackingProtectionRobot().interact() @@ -214,6 +236,7 @@ class EnhancedTrackingProtectionRobot { fun closeEnhancedTrackingProtectionSheet(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { // Back out of the Enhanced Tracking Protection sheet + Log.i(TAG, "closeEnhancedTrackingProtectionSheet: Trying to click device back button") mDevice.pressBack() Log.i(TAG, "closeEnhancedTrackingProtectionSheet: Clicked device back button") @@ -222,6 +245,7 @@ class EnhancedTrackingProtectionRobot { } fun toggleEnhancedTrackingProtectionFromSheet(interact: EnhancedTrackingProtectionRobot.() -> Unit): Transition { + Log.i(TAG, "toggleEnhancedTrackingProtectionFromSheet: Trying to click ETP switch") enhancedTrackingProtectionSwitch().click() Log.i(TAG, "toggleEnhancedTrackingProtectionFromSheet: Clicked ETP switch") @@ -230,10 +254,13 @@ class EnhancedTrackingProtectionRobot { } fun openProtectionSettings(interact: SettingsSubMenuEnhancedTrackingProtectionRobot.() -> Unit): SettingsSubMenuEnhancedTrackingProtectionRobot.Transition { - Log.i(TAG, "openProtectionSettings: Looking for ETP sheet \"Details\" button") + Log.i(TAG, "openProtectionSettings: Waiting for $waitingTime ms for ETP sheet \"Details\" button to exist") openEnhancedTrackingProtectionDetails().waitForExists(waitingTime) + Log.i(TAG, "openProtectionSettings: Waited for $waitingTime ms for ETP sheet \"Details\" button to exist") + Log.i(TAG, "openProtectionSettings: Trying to click ETP sheet \"Details\" button") openEnhancedTrackingProtectionDetails().click() Log.i(TAG, "openProtectionSettings: Clicked ETP sheet \"Details\" button") + Log.i(TAG, "openProtectionSettings: Trying to click \"Protection Settings\" button") trackingProtectionSettingsButton().click() Log.i(TAG, "openProtectionSettings: Clicked \"Protection Settings\" button") @@ -242,8 +269,10 @@ class EnhancedTrackingProtectionRobot { } fun openDetails(interact: EnhancedTrackingProtectionRobot.() -> Unit): Transition { - Log.i(TAG, "openDetails: Looking for ETP sheet \"Details\" button") + Log.i(TAG, "openDetails: Waiting for $waitingTime ms for ETP sheet \"Details\" button to exist") openEnhancedTrackingProtectionDetails().waitForExists(waitingTime) + Log.i(TAG, "openDetails: Waited for $waitingTime ms for ETP sheet \"Details\" button to exist") + Log.i(TAG, "openDetails: Trying to click ETP sheet \"Details\" button") openEnhancedTrackingProtectionDetails().click() Log.i(TAG, "openDetails: Clicked ETP sheet \"Details\" button") From 76202746beaf1dd2237afaebe97ae072a9cac196 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Thu, 1 Feb 2024 12:09:13 +0200 Subject: [PATCH 089/586] Bug 1877945 - Remove redundant assertion functions from FindInPageRobot --- .../fenix/ui/robots/FindInPageRobot.kt | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt index ed459189ba81..1b43737caa6b 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt @@ -27,9 +27,21 @@ import org.mozilla.fenix.helpers.ext.waitNotNull * Implementation of Robot Pattern for the find in page UI. */ class FindInPageRobot { - fun verifyFindInPageNextButton() = assertFindInPageNextButton() - fun verifyFindInPagePrevButton() = assertFindInPagePrevButton() - fun verifyFindInPageCloseButton() = assertFindInPageCloseButton() + fun verifyFindInPageNextButton() { + findInPageNextButton() + .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + Log.i(TAG, "verifyFindInPageNextButton: Verified find in page next result button is visible") + } + fun verifyFindInPagePrevButton() { + findInPagePrevButton() + .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + Log.i(TAG, "verifyFindInPagePrevButton: Verified find in page previous result button is visible") + } + fun verifyFindInPageCloseButton() { + findInPageCloseButton() + .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + Log.i(TAG, "verifyFindInPageCloseButton: Verified find in page close button is visible") + } fun clickFindInPageNextButton() { findInPageNextButton().click() Log.i(TAG, "clickFindInPageNextButton: Clicked next result button") @@ -84,21 +96,3 @@ private fun findInPageResult() = onView(withId(R.id.find_in_page_result_text)) private fun findInPageNextButton() = onView(withId(R.id.find_in_page_next_btn)) private fun findInPagePrevButton() = onView(withId(R.id.find_in_page_prev_btn)) private fun findInPageCloseButton() = onView(withId(R.id.find_in_page_close_btn)) - -private fun assertFindInPageNextButton() { - findInPageNextButton() - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) - Log.i(TAG, "assertFindInPageNextButton: Verified find in page next result button is visible") -} - -private fun assertFindInPagePrevButton() { - findInPagePrevButton() - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) - Log.i(TAG, "assertFindInPagePrevButton: Verified find in page previous result button is visible") -} - -private fun assertFindInPageCloseButton() { - findInPageCloseButton() - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) - Log.i(TAG, "assertFindInPageCloseButton: Verified find in page close button is visible") -} From d5051b60a8e09816ede70a3f1f3f1d859796facc Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Thu, 1 Feb 2024 20:49:39 +0200 Subject: [PATCH 090/586] Bug 1877945 - Add pairs of test logs to FindInPageRobot --- .../mozilla/fenix/ui/robots/FindInPageRobot.kt | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt index 1b43737caa6b..7f0789c227e7 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt @@ -28,48 +28,59 @@ import org.mozilla.fenix.helpers.ext.waitNotNull */ class FindInPageRobot { fun verifyFindInPageNextButton() { + Log.i(TAG, "verifyFindInPageNextButton: Trying to verify find in page next result button is visible") findInPageNextButton() .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) Log.i(TAG, "verifyFindInPageNextButton: Verified find in page next result button is visible") } fun verifyFindInPagePrevButton() { + Log.i(TAG, "verifyFindInPagePrevButton: Trying to verify find in page previous result button is visible") findInPagePrevButton() .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) Log.i(TAG, "verifyFindInPagePrevButton: Verified find in page previous result button is visible") } fun verifyFindInPageCloseButton() { + Log.i(TAG, "verifyFindInPageCloseButton: Trying to verify find in page close button is visible") findInPageCloseButton() .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) Log.i(TAG, "verifyFindInPageCloseButton: Verified find in page close button is visible") } fun clickFindInPageNextButton() { + Log.i(TAG, "clickFindInPageNextButton: Trying to click next result button") findInPageNextButton().click() Log.i(TAG, "clickFindInPageNextButton: Clicked next result button") } fun clickFindInPagePrevButton() { + Log.i(TAG, "clickFindInPagePrevButton: Trying to click previous result button") findInPagePrevButton().click() Log.i(TAG, "clickFindInPagePrevButton: Clicked previous result button") } fun enterFindInPageQuery(expectedText: String) { mDevice.waitNotNull(Until.findObject(By.res("org.mozilla.fenix.debug:id/find_in_page_query_text")), waitingTime) + Log.i(TAG, "enterFindInPageQuery: Trying to clear find in page bar text") findInPageQuery().perform(clearText()) Log.i(TAG, "enterFindInPageQuery: Cleared find in page bar text") mDevice.waitNotNull(Until.gone(By.res("org.mozilla.fenix.debug:id/find_in_page_result_text")), waitingTime) + Log.i(TAG, "enterFindInPageQuery: Trying to type $expectedText in find in page bar") findInPageQuery().perform(typeText(expectedText)) - Log.i(TAG, "enterFindInPageQuery: Typed $expectedText to find in page bar") + Log.i(TAG, "enterFindInPageQuery: Typed $expectedText in find page bar") mDevice.waitNotNull(Until.findObject(By.res("org.mozilla.fenix.debug:id/find_in_page_result_text")), waitingTime) } fun verifyFindInPageResult(ratioCounter: String) { mDevice.waitNotNull(Until.findObject(By.text(ratioCounter)), waitingTime) + Log.i(TAG, "verifyFindInPageResult: Trying to verify $ratioCounter results") findInPageResult().check(matches(withText((ratioCounter)))) Log.i(TAG, "verifyFindInPageResult: Verified $ratioCounter results") } class Transition { fun closeFindInPageWithCloseButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "closeFindInPageWithCloseButton: Waiting for device to be idle") mDevice.waitForIdle() + Log.i(TAG, "closeFindInPageWithCloseButton: Device was idle") + Log.i(TAG, "closeFindInPageWithCloseButton: Trying to close find in page button") findInPageCloseButton().click() Log.i(TAG, "closeFindInPageWithCloseButton: Clicked close find in page button") BrowserRobot().interact() @@ -77,11 +88,15 @@ class FindInPageRobot { } fun closeFindInPageWithBackButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "closeFindInPageWithBackButton: Waiting for device to be idle") mDevice.waitForIdle() + Log.i(TAG, "closeFindInPageWithBackButton: Device was idle") // Will need to press back 2x, the first will only dismiss the keyboard + Log.i(TAG, "closeFindInPageWithBackButton: Trying to press 1x the device back button") mDevice.pressBack() Log.i(TAG, "closeFindInPageWithBackButton: Pressed 1x the device back button") + Log.i(TAG, "closeFindInPageWithBackButton: Trying to press 2x the device back button") mDevice.pressBack() Log.i(TAG, "closeFindInPageWithBackButton: Pressed 2x the device back button") From a7a9305a4fa1ce69325de7cdc469d6f99fbc0e51 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Thu, 1 Feb 2024 14:17:38 +0200 Subject: [PATCH 091/586] Bug 1878028 - Remove redundant assertion functions from HistoryRobot --- .../mozilla/fenix/ui/ComposeHistoryTest.kt | 5 +- .../org/mozilla/fenix/ui/ComposeSearchTest.kt | 3 +- .../java/org/mozilla/fenix/ui/HistoryTest.kt | 5 +- .../java/org/mozilla/fenix/ui/SearchTest.kt | 3 +- .../mozilla/fenix/ui/robots/HistoryRobot.kt | 87 ++++++------------- 5 files changed, 37 insertions(+), 66 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHistoryTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHistoryTest.kt index 5a2fed714d78..138ffa7c300a 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHistoryTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHistoryTest.kt @@ -28,6 +28,7 @@ import org.mozilla.fenix.helpers.RecyclerViewIdlingResource import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem +import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.historyMenu import org.mozilla.fenix.ui.robots.homeScreen @@ -128,7 +129,7 @@ class ComposeHistoryTest { ) { clickDeleteHistoryButton(firstWebPage.url.toString()) } - verifyDeleteSnackbarText("Deleted") + verifySnackBarText(expectedText = "Deleted") verifyEmptyHistoryView() } } @@ -153,7 +154,7 @@ class ComposeHistoryTest { verifyDeleteConfirmationMessage() selectEverythingOption() confirmDeleteAllHistory() - verifyDeleteSnackbarText("Browsing data deleted") + verifySnackBarText(expectedText = "Browsing data deleted") verifyEmptyHistoryView() } } diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSearchTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSearchTest.kt index 71391b52284c..27f46d84fd63 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSearchTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSearchTest.kt @@ -31,6 +31,7 @@ import org.mozilla.fenix.helpers.SearchDispatcher import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper import org.mozilla.fenix.helpers.TestHelper.exitMenu +import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.ui.robots.clickContextMenuItem import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen @@ -472,7 +473,7 @@ class ComposeSearchTest { }.openRecentlyVisitedSearchGroupHistoryList(queryString) { clickDeleteAllHistoryButton() confirmDeleteAllHistory() - verifyDeleteSnackbarText("Group deleted") + verifySnackBarText(expectedText = "Group deleted") verifyHistoryItemExists(shouldExist = false, firstPageUrl.toString()) }.goBack {} homeScreen { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HistoryTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HistoryTest.kt index ec76f441985b..f29372c637e8 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HistoryTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HistoryTest.kt @@ -29,6 +29,7 @@ import org.mozilla.fenix.helpers.RecyclerViewIdlingResource import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem +import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.historyMenu import org.mozilla.fenix.ui.robots.homeScreen @@ -131,7 +132,7 @@ class HistoryTest { clickUndoDeleteButton() verifyHistoryItemExists(true, firstWebPage.url.toString()) clickDeleteHistoryButton(firstWebPage.url.toString()) - verifyDeleteSnackbarText("Deleted") + verifySnackBarText(expectedText = "Deleted") verifyEmptyHistoryView() } } @@ -161,7 +162,7 @@ class HistoryTest { verifyDeleteConfirmationMessage() selectEverythingOption() confirmDeleteAllHistory() - verifyDeleteSnackbarText("Browsing data deleted") + verifySnackBarText(expectedText = "Browsing data deleted") verifyEmptyHistoryView() } } diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt index 0a5686c03d78..d1d0076cd16f 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt @@ -44,6 +44,7 @@ import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem import org.mozilla.fenix.helpers.TestHelper.mDevice +import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.ui.robots.clickContextMenuItem import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen @@ -487,7 +488,7 @@ class SearchTest { }.openRecentlyVisitedSearchGroupHistoryList(queryString) { clickDeleteAllHistoryButton() confirmDeleteAllHistory() - verifyDeleteSnackbarText("Group deleted") + verifySnackBarText("Group deleted") verifyHistoryItemExists(shouldExist = false, firstPageUrl.toString()) }.goBack {} homeScreen { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt index 768121d45164..b38920e0de01 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt @@ -19,7 +19,6 @@ import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.uiautomator.By import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until -import org.hamcrest.Matchers import org.hamcrest.Matchers.allOf import org.mozilla.fenix.R import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource @@ -38,17 +37,26 @@ import org.mozilla.fenix.helpers.ext.waitNotNull */ class HistoryRobot { - fun verifyHistoryMenuView() = assertHistoryMenuView() + fun verifyHistoryMenuView() { + onView( + allOf(withText("History"), withParent(withId(R.id.navigationToolbar))), + ).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + } fun verifyEmptyHistoryView() { mDevice.findObject( UiSelector().text("No history here"), ).waitForExists(waitingTime) - assertEmptyHistoryView() + onView( + allOf( + withId(R.id.history_empty_view), + withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE), + ), + ).check(matches(withText("No history here"))) } - fun verifyHistoryListExists() = assertHistoryListExists() + fun verifyHistoryListExists() = assertUIObjectExists(itemWithResId("$packageName:id/history_list")) fun verifyVisitedTimeTitle() { mDevice.waitNotNull( @@ -57,21 +65,24 @@ class HistoryRobot { ), waitingTime, ) - assertVisitedTimeTitle() + onView(withId(R.id.header_title)).check(matches(withText("Today"))) } fun verifyHistoryItemExists(shouldExist: Boolean, item: String) = assertUIObjectExists(itemContainingText(item), exists = shouldExist) - fun verifyFirstTestPageTitle(title: String) = assertTestPageTitle(title) + fun verifyFirstTestPageTitle(title: String) = + testPageTitle() + .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + .check(matches(withText(title))) fun verifyTestPageUrl(expectedUrl: Uri) = pageUrl(expectedUrl.toString()).check(matches(isDisplayed())) - fun verifyCopySnackBarText() = assertCopySnackBarText() - - fun verifyDeleteConfirmationMessage() = assertDeleteConfirmationMessage() - - fun verifyHomeScreen() = HomeScreenRobot().verifyHomeScreen() + fun verifyDeleteConfirmationMessage() = + assertUIObjectExists( + itemWithResIdContainingText("$packageName:id/title", getStringResource(R.string.delete_history_prompt_title)), + itemWithResIdContainingText("$packageName:id/body", getStringResource(R.string.delete_history_prompt_body_2)), + ) fun clickDeleteHistoryButton(item: String) { deleteButton(item).click() @@ -98,9 +109,7 @@ class HistoryRobot { .textContains(getStringResource(R.string.delete_browsing_data_prompt_cancel)), ).click() - fun verifyDeleteSnackbarText(text: String) = assertSnackBarText(text) - - fun verifyUndoDeleteSnackBarButton() = assertUndoDeleteSnackBarButton() + fun verifyUndoDeleteSnackBarButton() = snackBarUndoButton().check(matches(withText("UNDO"))) fun clickUndoDeleteButton() { snackBarUndoButton().click() @@ -130,7 +139,7 @@ class HistoryRobot { } fun openWebsite(url: Uri, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - assertHistoryListExists() + assertUIObjectExists(itemWithResId("$packageName:id/history_list")) onView(withText(url.toString())).click() BrowserRobot().interact() @@ -138,8 +147,8 @@ class HistoryRobot { } fun openRecentlyClosedTabs(interact: RecentlyClosedTabsRobot.() -> Unit): RecentlyClosedTabsRobot.Transition { - recentlyClosedTabsListButton.waitForExists(waitingTime) - recentlyClosedTabsListButton.click() + recentlyClosedTabsListButton().waitForExists(waitingTime) + recentlyClosedTabsListButton().click() RecentlyClosedTabsRobot().interact() return RecentlyClosedTabsRobot.Transition() @@ -168,50 +177,8 @@ private fun deleteButton(title: String) = private fun deleteButton() = onView(withId(R.id.history_delete)) -private fun snackBarText() = onView(withId(R.id.snackbar_text)) - -private fun assertHistoryMenuView() { - onView( - allOf(withText("History"), withParent(withId(R.id.navigationToolbar))), - ) - .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) -} - -private fun assertEmptyHistoryView() = - onView( - allOf( - withId(R.id.history_empty_view), - withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE), - ), - ) - .check(matches(withText("No history here"))) - -private fun assertHistoryListExists() = - mDevice.findObject(UiSelector().resourceId("$packageName:id/history_list")).waitForExists(waitingTime) - -private fun assertVisitedTimeTitle() = - onView(withId(R.id.header_title)).check(matches(withText("Today"))) - -private fun assertTestPageTitle(title: String) = testPageTitle() - .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) - .check(matches(withText(title))) - -private fun assertDeleteConfirmationMessage() = - assertUIObjectExists( - itemWithResIdContainingText("$packageName:id/title", getStringResource(R.string.delete_history_prompt_title)), - itemWithResIdContainingText("$packageName:id/body", getStringResource(R.string.delete_history_prompt_body_2)), - ) - -private fun assertCopySnackBarText() = snackBarText().check(matches(withText("URL copied"))) - -private fun assertSnackBarText(text: String) = - snackBarText().check(matches(withText(Matchers.containsString(text)))) - private fun snackBarUndoButton() = onView(withId(R.id.snackbar_btn)) -private fun assertUndoDeleteSnackBarButton() = - snackBarUndoButton().check(matches(withText("UNDO"))) - private fun deleteHistoryEverythingOption() = mDevice .findObject( @@ -220,5 +187,5 @@ private fun deleteHistoryEverythingOption() = .resourceId("$packageName:id/everything_button"), ) -private val recentlyClosedTabsListButton = +private fun recentlyClosedTabsListButton() = mDevice.findObject(UiSelector().resourceId("$packageName:id/recently_closed_tabs_header")) From 04c111d2c94cdcb64ca1968db9da0c119ad0df00 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Thu, 1 Feb 2024 16:49:42 +0200 Subject: [PATCH 092/586] Bug 1878028 - Add more test logs to HistoryRobot --- .../mozilla/fenix/ui/robots/HistoryRobot.kt | 69 +++++++++++++++++-- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt index b38920e0de01..fc6ee4d1ad2f 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.ui.robots import android.net.Uri +import android.util.Log import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.RootMatchers.isDialog @@ -21,6 +22,7 @@ import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import org.hamcrest.Matchers.allOf import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText @@ -38,22 +40,28 @@ import org.mozilla.fenix.helpers.ext.waitNotNull class HistoryRobot { fun verifyHistoryMenuView() { + Log.i(TAG, "verifyHistoryMenuView: Trying to verify that history menu view is visible") onView( allOf(withText("History"), withParent(withId(R.id.navigationToolbar))), ).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + Log.i(TAG, "verifyHistoryMenuView: Verified that history menu view is visible") } fun verifyEmptyHistoryView() { + Log.i(TAG, "verifyEmptyHistoryView: Waiting for $waitingTime ms for empty history list view to exist") mDevice.findObject( UiSelector().text("No history here"), ).waitForExists(waitingTime) + Log.i(TAG, "verifyEmptyHistoryView: Waited for $waitingTime ms for empty history list view to exist") + Log.i(TAG, "verifyEmptyHistoryView: Trying to verify empty history list view") onView( allOf( withId(R.id.history_empty_view), withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE), ), ).check(matches(withText("No history here"))) + Log.i(TAG, "verifyEmptyHistoryView: Verified empty history list view") } fun verifyHistoryListExists() = assertUIObjectExists(itemWithResId("$packageName:id/history_list")) @@ -65,18 +73,27 @@ class HistoryRobot { ), waitingTime, ) + Log.i(TAG, "verifyVisitedTimeTitle: Trying to verify \"Today\" chronological timeline title") onView(withId(R.id.header_title)).check(matches(withText("Today"))) + Log.i(TAG, "verifyVisitedTimeTitle: Verified \"Today\" chronological timeline title") } fun verifyHistoryItemExists(shouldExist: Boolean, item: String) = assertUIObjectExists(itemContainingText(item), exists = shouldExist) - fun verifyFirstTestPageTitle(title: String) = + fun verifyFirstTestPageTitle(title: String) { + Log.i(TAG, "verifyFirstTestPageTitle: Trying to verify $title page title is visible") testPageTitle() .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) .check(matches(withText(title))) + Log.i(TAG, "verifyFirstTestPageTitle: Verified $title page title is visible") + } - fun verifyTestPageUrl(expectedUrl: Uri) = pageUrl(expectedUrl.toString()).check(matches(isDisplayed())) + fun verifyTestPageUrl(expectedUrl: Uri) { + Log.i(TAG, "verifyTestPageUrl: Trying to verify page url: $expectedUrl is displayed") + pageUrl(expectedUrl.toString()).check(matches(isDisplayed())) + Log.i(TAG, "verifyTestPageUrl: Verified page url: $expectedUrl is displayed") + } fun verifyDeleteConfirmationMessage() = assertUIObjectExists( @@ -85,34 +102,58 @@ class HistoryRobot { ) fun clickDeleteHistoryButton(item: String) { + Log.i(TAG, "clickDeleteHistoryButton: Trying to click delete history button for item: $item") deleteButton(item).click() + Log.i(TAG, "clickDeleteHistoryButton: Clicked delete history button for item: $item") } - fun verifyDeleteHistoryItemButton(historyItemTitle: String) = + fun verifyDeleteHistoryItemButton(historyItemTitle: String) { + Log.i(TAG, "verifyDeleteHistoryItemButton: Trying to verify delete history button for item: $historyItemTitle is visible") deleteButton(historyItemTitle).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + Log.i(TAG, "verifyDeleteHistoryItemButton: Verified delete history button for item: $historyItemTitle is visible") + } - fun clickDeleteAllHistoryButton() = deleteButton().click() + fun clickDeleteAllHistoryButton() { + Log.i(TAG, "clickDeleteAllHistoryButton: Trying to click delete all history button") + deleteButton().click() + Log.i(TAG, "clickDeleteAllHistoryButton: Clicked delete all history button") + } - fun selectEverythingOption() = deleteHistoryEverythingOption().click() + fun selectEverythingOption() { + Log.i(TAG, "selectEverythingOption: Trying to click \"Everything\" dialog option") + deleteHistoryEverythingOption().click() + Log.i(TAG, "selectEverythingOption: Clicked \"Everything\" dialog option") + } fun confirmDeleteAllHistory() { + Log.i(TAG, "confirmDeleteAllHistory: Trying to click \"Delete\" dialog button") onView(withText("Delete")) .inRoot(isDialog()) .check(matches(isDisplayed())) .click() + Log.i(TAG, "confirmDeleteAllHistory: Clicked \"Delete\" dialog button") } - fun cancelDeleteHistory() = + fun cancelDeleteHistory() { + Log.i(TAG, "cancelDeleteHistory: Trying to click \"Cancel\" dialog button") mDevice .findObject( UiSelector() .textContains(getStringResource(R.string.delete_browsing_data_prompt_cancel)), ).click() + Log.i(TAG, "cancelDeleteHistory: Clicked \"Cancel\" dialog button") + } - fun verifyUndoDeleteSnackBarButton() = snackBarUndoButton().check(matches(withText("UNDO"))) + fun verifyUndoDeleteSnackBarButton() { + Log.i(TAG, "verifyUndoDeleteSnackBarButton: Trying to verify \"Undo\" snackbar button") + snackBarUndoButton().check(matches(withText("UNDO"))) + Log.i(TAG, "verifyUndoDeleteSnackBarButton: Verified \"Undo\" snackbar button") + } fun clickUndoDeleteButton() { + Log.i(TAG, "verifyUndoDeleteSnackBarButton: Trying to click \"Undo\" snackbar button") snackBarUndoButton().click() + Log.i(TAG, "verifyUndoDeleteSnackBarButton: Clicked \"Undo\" snackbar button") } fun verifySearchGroupDisplayed(shouldBeDisplayed: Boolean, searchTerm: String, groupSize: Int) = @@ -126,13 +167,19 @@ class HistoryRobot { ) fun openSearchGroup(searchTerm: String) { + Log.i(TAG, "openSearchGroup: Waiting for $waitingTime ms for search group: $searchTerm to exist") mDevice.findObject(UiSelector().text(searchTerm)).waitForExists(waitingTime) + Log.i(TAG, "openSearchGroup: Waited for $waitingTime ms for search group: $searchTerm to exist") + Log.i(TAG, "openSearchGroup: Trying to click search group: $searchTerm") mDevice.findObject(UiSelector().text(searchTerm)).click() + Log.i(TAG, "openSearchGroup: Clicked search group: $searchTerm") } class Transition { fun goBack(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "goBack: Trying to click go back menu button") onView(withContentDescription("Navigate up")).click() + Log.i(TAG, "goBack: Clicked go back menu button") BrowserRobot().interact() return BrowserRobot.Transition() @@ -140,22 +187,30 @@ class HistoryRobot { fun openWebsite(url: Uri, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { assertUIObjectExists(itemWithResId("$packageName:id/history_list")) + Log.i(TAG, "openWebsite: Trying to click history item with url: $url") onView(withText(url.toString())).click() + Log.i(TAG, "openWebsite: Clicked history item with url: $url") BrowserRobot().interact() return BrowserRobot.Transition() } fun openRecentlyClosedTabs(interact: RecentlyClosedTabsRobot.() -> Unit): RecentlyClosedTabsRobot.Transition { + Log.i(TAG, "openRecentlyClosedTabs: Waiting for $waitingTime ms for \"Recently closed tabs\" button to exist") recentlyClosedTabsListButton().waitForExists(waitingTime) + Log.i(TAG, "openRecentlyClosedTabs: Waited for $waitingTime ms for \"Recently closed tabs\" button to exist") + Log.i(TAG, "openRecentlyClosedTabs: Trying to click \"Recently closed tabs\" button") recentlyClosedTabsListButton().click() + Log.i(TAG, "openRecentlyClosedTabs: Clicked \"Recently closed tabs\" button") RecentlyClosedTabsRobot().interact() return RecentlyClosedTabsRobot.Transition() } fun clickSearchButton(interact: SearchRobot.() -> Unit): SearchRobot.Transition { + Log.i(TAG, "clickSearchButton: Trying to click search history button") itemWithResId("$packageName:id/history_search").click() + Log.i(TAG, "clickSearchButton: Clicked search history button") SearchRobot().interact() return SearchRobot.Transition() From de5db98e7ade9170c28b475773f2aa43ad074d23 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 13:58:44 +0000 Subject: [PATCH 093/586] Bump nokogiri from 1.14.3 to 1.16.2 in /docs Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.14.3 to 1.16.2. - [Release notes](https://github.com/sparklemotion/nokogiri/releases) - [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md) - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.14.3...v1.16.2) --- updated-dependencies: - dependency-name: nokogiri dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index f60684d34992..e43ff644b956 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -210,7 +210,7 @@ GEM jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) minitest (5.19.0) - nokogiri (1.14.3-x86_64-linux) + nokogiri (1.16.2-x86_64-linux) racc (~> 1.4) octokit (4.25.1) faraday (>= 1, < 3) @@ -218,7 +218,7 @@ GEM pathutil (0.16.2) forwardable-extended (~> 2.6) public_suffix (4.0.7) - racc (1.6.2) + racc (1.7.3) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) From 21b8a3b3dfb066a1d32287bafdbf815df6a1482f Mon Sep 17 00:00:00 2001 From: jackyzy823 Date: Sun, 4 Feb 2024 09:33:06 +0800 Subject: [PATCH 094/586] Bug 1878524 - Return immediately when tab found --- .../main/java/org/mozilla/fenix/tabstray/TabsTrayTabLayouts.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayTabLayouts.kt b/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayTabLayouts.kt index 9d8e32404d43..2ad8485760a8 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayTabLayouts.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayTabLayouts.kt @@ -94,6 +94,7 @@ fun TabLayout( tabs.forEachIndexed { index, tab -> if (tab.id == selectedTabId) { selectedTabIndex = index + return@forEachIndexed } } } From a1f24fffc970a95be76c2e06ed75061989b6f417 Mon Sep 17 00:00:00 2001 From: Arturo Mejia Date: Mon, 5 Feb 2024 15:03:58 -0500 Subject: [PATCH 095/586] Bug 1876806 - Do not remove downloaded files in private tabs after deleting browsing data --- .../downloads/AbstractFetchDownloadService.kt | 5 +++- .../AbstractFetchDownloadServiceTest.kt | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/AbstractFetchDownloadService.kt b/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/AbstractFetchDownloadService.kt index 03476445ece2..fb8411352aec 100644 --- a/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/AbstractFetchDownloadService.kt +++ b/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/AbstractFetchDownloadService.kt @@ -271,7 +271,10 @@ abstract class AbstractFetchDownloadService : Service() { internal fun handleRemovePrivateDownloadIntent(download: DownloadState) { if (download.private) { downloadJobs[download.id]?.let { - cancelDownloadJob(it) + // Do not cancel already completed downloads. + if (it.status != COMPLETED) { + cancelDownloadJob(it) + } removeDownloadJob(it) } store.dispatch(DownloadAction.RemoveDownloadAction(download.id)) diff --git a/android-components/components/feature/downloads/src/test/java/mozilla/components/feature/downloads/AbstractFetchDownloadServiceTest.kt b/android-components/components/feature/downloads/src/test/java/mozilla/components/feature/downloads/AbstractFetchDownloadServiceTest.kt index a601e863cf7a..504354e185fc 100644 --- a/android-components/components/feature/downloads/src/test/java/mozilla/components/feature/downloads/AbstractFetchDownloadServiceTest.kt +++ b/android-components/components/feature/downloads/src/test/java/mozilla/components/feature/downloads/AbstractFetchDownloadServiceTest.kt @@ -271,6 +271,30 @@ class AbstractFetchDownloadServiceTest { service.handleRemovePrivateDownloadIntent(downloadState) + verify(service, times(0)).cancelDownloadJob(downloadJobState) + verify(service).removeDownloadJob(downloadJobState) + verify(browserStore).dispatch(DownloadAction.RemoveDownloadAction(downloadState.id)) + } + + @Test + fun `WHEN handleRemovePrivateDownloadIntent is called with a private download AND not COMPLETED status THEN removeDownloadJob and cancelDownloadJob must be called`() { + val downloadState = DownloadState(url = "mozilla.org/mozilla.txt", private = true) + val downloadJobState = DownloadJobState(state = downloadState, status = DOWNLOADING) + val browserStore = mock() + val service = spy( + object : AbstractFetchDownloadService() { + override val httpClient = client + override val store = browserStore + override val notificationsDelegate = this@AbstractFetchDownloadServiceTest.notificationsDelegate + }, + ) + + doAnswer { Unit }.`when`(service).removeDownloadJob(any()) + + service.downloadJobs[downloadState.id] = downloadJobState + + service.handleRemovePrivateDownloadIntent(downloadState) + verify(service).cancelDownloadJob(downloadJobState) verify(service).removeDownloadJob(downloadJobState) verify(browserStore).dispatch(DownloadAction.RemoveDownloadAction(downloadState.id)) From 14eccacb38b44d3fcf0a0b6e46170bd34f718b9a Mon Sep 17 00:00:00 2001 From: William Durand Date: Tue, 6 Feb 2024 12:54:41 +0100 Subject: [PATCH 096/586] Bug 1870312 - Avoid overlap between add-on item and install button --- .../feature/addons/ui/AddonsManagerAdapter.kt | 5 +- .../feature/addons/ui/CustomViewHolder.kt | 1 + .../res/layout/mozac_feature_addons_item.xml | 189 +++++++++--------- .../addons/ui/AddonsManagerAdapterTest.kt | 11 +- 4 files changed, 113 insertions(+), 93 deletions(-) diff --git a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt index 136d0b60e7c4..5eede548e3bd 100644 --- a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt +++ b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt @@ -144,6 +144,7 @@ class AddonsManagerAdapter( val context = parent.context val inflater = LayoutInflater.from(context) val view = inflater.inflate(R.layout.mozac_feature_addons_item, parent, false) + val contentWrapperView = view.findViewById(R.id.add_on_content_wrapper) val iconView = view.findViewById(R.id.add_on_icon) val titleView = view.findViewById(R.id.add_on_name) val summaryView = view.findViewById(R.id.add_on_description) @@ -155,6 +156,7 @@ class AddonsManagerAdapter( val statusErrorView = view.findViewById(R.id.add_on_status_error) return AddonViewHolder( view, + contentWrapperView, iconView, titleView, summaryView, @@ -281,7 +283,8 @@ class AddonsManagerAdapter( } holder.itemView.tag = addon - holder.itemView.setOnClickListener { + // Attach the on click listener to the content wrapper so that it doesn't overlap with the install button. + holder.contentWrapperView.setOnClickListener { addonsManagerDelegate.onAddonItemClicked(addon) } diff --git a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/CustomViewHolder.kt b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/CustomViewHolder.kt index 9f7220bc7caa..7268d53d312c 100644 --- a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/CustomViewHolder.kt +++ b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/CustomViewHolder.kt @@ -38,6 +38,7 @@ sealed class CustomViewHolder(view: View) : RecyclerView.ViewHolder(view) { @Suppress("LongParameterList") class AddonViewHolder( view: View, + val contentWrapperView: View, val iconView: ImageView, val titleView: TextView, val summaryView: TextView, diff --git a/android-components/components/feature/addons/src/main/res/layout/mozac_feature_addons_item.xml b/android-components/components/feature/addons/src/main/res/layout/mozac_feature_addons_item.xml index 4497d92dea1e..24b066ad25d1 100644 --- a/android-components/components/feature/addons/src/main/res/layout/mozac_feature_addons_item.xml +++ b/android-components/components/feature/addons/src/main/res/layout/mozac_feature_addons_item.xml @@ -11,125 +11,132 @@ android:layout_height="wrap_content" android:background="?android:attr/selectableItemBackground" android:orientation="horizontal" - android:paddingStart="16dp" + android:paddingStart="0dp" android:paddingEnd="0dp"> - - + android:orientation="horizontal"> + + + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + android:orientation="vertical" + android:paddingStart="8dp" + android:paddingTop="8dp" + android:paddingEnd="4dp" + android:paddingBottom="8dp"> - - - + android:layout_marginBottom="@dimen/add_on_name_container_margin_bottom" + android:orientation="horizontal"> - + + + - + - + - + android:layout_marginTop="6dp" + android:orientation="horizontal"> - - - + + + + + - + - + - - + + + diff --git a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonsManagerAdapterTest.kt b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonsManagerAdapterTest.kt index 5a8f5307d109..41b8370cd0e1 100644 --- a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonsManagerAdapterTest.kt +++ b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonsManagerAdapterTest.kt @@ -121,6 +121,7 @@ class AddonsManagerAdapterTest { @Test fun `bind add-on`() { + val contentWrapperView = View(testContext) val titleView: TextView = mock() val summaryView: TextView = mock() val ratingAccessibleView: TextView = mock() @@ -133,6 +134,7 @@ class AddonsManagerAdapterTest { whenever(iconView.context).thenReturn(testContext) val addonViewHolder = CustomViewHolder.AddonViewHolder( view = view, + contentWrapperView = contentWrapperView, iconView = iconView, titleView = titleView, summaryView = summaryView, @@ -175,7 +177,7 @@ class AddonsManagerAdapterTest { verify(summaryView).setTextColor(ContextCompat.getColor(testContext, style.addonSummaryTextColor!!)) assertNotNull(addonViewHolder.itemView.tag) - addonViewHolder.itemView.performClick() + addonViewHolder.contentWrapperView.performClick() verify(addonsManagerAdapterDelegate).onAddonItemClicked(addon) addButton.performClick() verify(addonsManagerAdapterDelegate).onInstallAddonButtonClicked(addon) @@ -307,6 +309,7 @@ class AddonsManagerAdapterTest { whenever(iconView.context).thenReturn(testContext) val addonViewHolder = CustomViewHolder.AddonViewHolder( view = view, + contentWrapperView = mock(), iconView = iconView, titleView = titleView, summaryView = summaryView, @@ -560,6 +563,7 @@ class AddonsManagerAdapterTest { whenever(iconView.context).thenReturn(testContext) val addonViewHolder = CustomViewHolder.AddonViewHolder( view = View(testContext), + contentWrapperView = mock(), iconView = iconView, titleView = titleView, summaryView = summaryView, @@ -606,6 +610,7 @@ class AddonsManagerAdapterTest { whenever(iconView.context).thenReturn(testContext) val addonViewHolder = CustomViewHolder.AddonViewHolder( view = View(testContext), + contentWrapperView = mock(), iconView = iconView, titleView = titleView, summaryView = summaryView, @@ -645,6 +650,7 @@ class AddonsManagerAdapterTest { whenever(iconView.context).thenReturn(testContext) val addonViewHolder = CustomViewHolder.AddonViewHolder( view = View(testContext), + contentWrapperView = mock(), iconView = iconView, titleView = titleView, summaryView = summaryView, @@ -693,6 +699,7 @@ class AddonsManagerAdapterTest { val addonViewHolder = CustomViewHolder.AddonViewHolder( view = View(testContext), + contentWrapperView = mock(), iconView = iconView, titleView = titleView, summaryView = summaryView, @@ -734,6 +741,7 @@ class AddonsManagerAdapterTest { val addonViewHolder = CustomViewHolder.AddonViewHolder( view = View(testContext), + contentWrapperView = mock(), iconView = iconView, titleView = titleView, summaryView = summaryView, @@ -776,6 +784,7 @@ class AddonsManagerAdapterTest { val addonViewHolder = CustomViewHolder.AddonViewHolder( view = View(testContext), + contentWrapperView = mock(), iconView = iconView, titleView = titleView, summaryView = summaryView, From c7fefbf4dcded336cee128615770101626b7324c Mon Sep 17 00:00:00 2001 From: Jackie Johnson <107960801+jjSDET@users.noreply.github.com> Date: Fri, 2 Feb 2024 02:02:59 -0600 Subject: [PATCH 097/586] Bug 1873897 - Update Testrail Milestone Release Trigger and Slack Message --- .../taskcluster/androidTest/testrail.py | 180 ------------------ .../taskcluster/androidTest/ui-test.sh | 9 - .../androidTest/lib/testrail_conn.py | 104 ---------- .../taskcluster/androidTest/testrail.py | 180 ------------------ .../taskcluster/androidTest/ui-test.sh | 9 - .../ci/release-notify-testrail/kind.yml | 71 +++++++ taskcluster/scripts/lib/testrail_api.py | 130 +++++++++++++ .../scripts}/lib/testrail_conn.py | 0 taskcluster/scripts/lib/testrail_utils.py | 74 +++++++ taskcluster/scripts/slack_notifier.py | 169 ++++++++++++++++ taskcluster/scripts/testrail_main.py | 97 ++++++++++ 11 files changed, 541 insertions(+), 482 deletions(-) delete mode 100644 fenix/automation/taskcluster/androidTest/testrail.py delete mode 100644 focus-android/automation/taskcluster/androidTest/lib/testrail_conn.py delete mode 100644 focus-android/automation/taskcluster/androidTest/testrail.py create mode 100644 taskcluster/ci/release-notify-testrail/kind.yml create mode 100644 taskcluster/scripts/lib/testrail_api.py rename {fenix/automation/taskcluster/androidTest => taskcluster/scripts}/lib/testrail_conn.py (100%) create mode 100644 taskcluster/scripts/lib/testrail_utils.py create mode 100644 taskcluster/scripts/slack_notifier.py create mode 100644 taskcluster/scripts/testrail_main.py diff --git a/fenix/automation/taskcluster/androidTest/testrail.py b/fenix/automation/taskcluster/androidTest/testrail.py deleted file mode 100644 index e735e417a0c5..000000000000 --- a/fenix/automation/taskcluster/androidTest/testrail.py +++ /dev/null @@ -1,180 +0,0 @@ -""" -This Python script is designed to automate the process of creating milestones -and test runs in TestRail, and updating test cases based on the results of -automated smoke tests for different product releases. - -Below is a summary of its functionality in order of execution: - -1. Environment and Credentials Setup: - - Imports necessary libraries and modules. - - Loads environmental variables from "execution_metadata.env". - - Reads and processes TestRail credentials from '.testrail_credentials.json'. - -2. Environment Variables Validation: - - Retrieves and validates several environment variables like `PRODUCT_TYPE`, - `RELEASE_TYPE`, `VERSION_NUMBER`, and `TEST_STATUS`. - - Ensures `TEST_STATUS` is either 'PASS' or 'FAIL'. - -3. Utility Functions: - - `parse_release_number()`: Parses the version number to extract a specific part. - - `build_milestone_name()`: Constructs a milestone name based on product type, - release type, and version number. - - `build_milestone_description()`: Creates a detailed description for the milestone - including the current date and placeholders for various testing statuses. - -4. TestRail Integration: - - Defines a `TestRail` class that handles interactions with the TestRail API. - - Includes methods to create milestones, create test runs, and update test cases. - -5. Main Execution: - - Checks if `TEST_STATUS` is 'PASS'. If not, it raises an error to trigger a Slack notification. - - Sets parameters for a demo TestRail project. - - Instantiates the `TestRail` class. - - Creates a milestone in TestRail and retrieves its ID. - - Creates test runs for each device/API combination (currently hardcoded for phase 1 testing) - and updates test cases to 'passed' status. - -6. Phase 1 and Phase 2 Notes: - - The script is currently in Phase 1, where certain values are hardcoded for testing. - - In Phase 2, these hardcoded values will be parameterized for broader usage. -""" - - -import json -import os -import textwrap -from lib.testrail_conn import APIClient -from dotenv import load_dotenv -from datetime import datetime - -try: - load_dotenv("execution_metadata.env") # Attempt to load .env file -except FileNotFoundError: - raise FileNotFoundError("The .env file was not found.") -except Exception as e: - raise Exception(f"An error occurred while loading the .env file: {e}") - -try: - with open(".testrail_credentials.json", "r") as file: - secret = json.load(file) - TESTRAIL_HOST = secret["host"] - TESTRAIL_USERNAME = secret["username"] - TESTRAIL_PASSWORD = secret["password"] -except json.JSONDecodeError as e: - raise ValueError(f"Failed to load testrail credentials : {e}") - -try: - PRODUCT_TYPE = os.environ["PRODUCT_TYPE"] - RELEASE_TYPE = os.environ["RELEASE_TYPE"] - VERSION_NUMBER = os.environ["MOBILE_HEAD_REF"] - TEST_STATUS = os.environ["TEST_STATUS"] - - if TEST_STATUS not in ("PASS", "FAIL"): - raise ValueError(f"ERROR: Invalid TEST_STATUS value: {TEST_STATUS}") -except KeyError as e: - raise ValueError(f"ERROR: Missing Environment Variable: {e}") - - -def parse_release_number(VERSION_NUMBER): - parts = VERSION_NUMBER.split("_") - return parts[1] - - -def build_milestone_name(product_type, release_type, version_number): - return f"Automated smoke testing sign-off - {product_type} {release_type} {version_number}" - - -def build_milestone_description(milestone_name): - current_date = datetime.now() - formatted_date = current_date = current_date.strftime("%B %d, %Y") - return textwrap.dedent( - f""" - RELEASE: {milestone_name}\n\n\ - RELEASE_TAG_URL: https://github.com/mozilla-mobile/firefox-android/releases\n\n\ - RELEASE_DATE: {formatted_date}\n\n\ - TESTING_STATUS: [ TBD ]\n\n\ - QA_RECOMMENDATION:[ TBD ]\n\n\ - QA_RECOMENTATION_VERBOSE: \n\n\ - TESTING_SUMMARY\n\n\ - Known issues: n/a\n\ - New issue: n/a\n\ - Verified issue: - """ - ) - - -class TestRail: - def __init__(self): - try: - self.client = APIClient(TESTRAIL_HOST) - self.client.user = TESTRAIL_USERNAME - self.client.password = TESTRAIL_PASSWORD - except KeyError as e: - raise ValueError(f"ERROR: Missing Testrail Env Var: {e}") - - # Public Methods - - def create_milestone(self, testrail_project_id, title, description): - data = {"name": title, "description": description} - return self.client.send_post(f"add_milestone/{testrail_project_id}", data) - - def create_test_run( - self, testrail_project_id, testrail_milestone_id, name_run, testrail_suite_id - ): - data = { - "name": name_run, - "milestone_id": testrail_milestone_id, - "suite_id": testrail_suite_id, - } - return self.client.send_post(f"add_run/{testrail_project_id}", data) - - def update_test_cases_to_passed( - self, testrail_project_id, testrail_run_id, testrail_suite_id - ): - test_cases = self._get_test_cases(testrail_project_id, testrail_suite_id) - data = { - "results": [ - {"case_id": test_case["id"], "status_id": 1} for test_case in test_cases - ] - } - return testrail._update_test_run_results(testrail_run_id, data) - - # Private Methods - - def _get_test_cases(self, testrail_project_id, testrail_test_suite_id): - return self.client.send_get( - f"get_cases/{testrail_project_id}&suite_id={testrail_test_suite_id}" - ) - - def _update_test_run_results(self, testrail_run_id, data): - return self.client.send_post(f"add_results_for_cases/{testrail_run_id}", data) - - -if __name__ == "__main__": - if TEST_STATUS != "PASS": - raise ValueError("Tests failed. Sending Slack Notification....") - - # There are for a dummy Testrail project used for Phase 1 testing of this script - # They will be parameterized during Phase 2 of script hardening - PROJECT_ID = 53 # Firefox for FireTV - TEST_SUITE_ID = 45442 # Demo Test Suite - - testrail = TestRail() - milestone_name = build_milestone_name( - PRODUCT_TYPE, RELEASE_TYPE, parse_release_number(VERSION_NUMBER) - ) - milestone_description = build_milestone_description(milestone_name) - - # Create milestone for 'Firefox for FireTV' and store the ID - milestone_id = testrail.create_milestone( - PROJECT_ID, milestone_name, milestone_description - )["id"] - - # Create test run for each Device/API and update test cases to 'passed' - # The Firebase Test devices are temporarily hard-coded during testing - # and will be parameterized in Phase 2 of hardening - for test_run_name in ["Google Pixel 32(Android11)", "Google Pixel2(Android9)"]: - test_run_id = testrail.create_test_run( - PROJECT_ID, milestone_id, test_run_name, TEST_SUITE_ID - )["id"] - testrail.update_test_cases_to_passed(PROJECT_ID, test_run_id, TEST_SUITE_ID) diff --git a/fenix/automation/taskcluster/androidTest/ui-test.sh b/fenix/automation/taskcluster/androidTest/ui-test.sh index a4df3971b968..3c5b29c172d3 100755 --- a/fenix/automation/taskcluster/androidTest/ui-test.sh +++ b/fenix/automation/taskcluster/androidTest/ui-test.sh @@ -102,18 +102,9 @@ function failure_check() { echo if [[ $exitcode -ne 0 ]]; then echo "FAILURE: UI test run failed, please check above URL" - TEST_STATUS="FAIL" else echo "All UI test(s) have passed!" - TEST_STATUS="PASS" fi - - { - echo "TEST_STATUS=${TEST_STATUS}" - echo "PRODUCT_TYPE=${PRODUCT_TYPE}" - echo "RELEASE_TYPE=${RELEASE_TYPE}" - } >> execution_metadata.env - echo echo "RESULTS" echo diff --git a/focus-android/automation/taskcluster/androidTest/lib/testrail_conn.py b/focus-android/automation/taskcluster/androidTest/lib/testrail_conn.py deleted file mode 100644 index e2e18dd9f736..000000000000 --- a/focus-android/automation/taskcluster/androidTest/lib/testrail_conn.py +++ /dev/null @@ -1,104 +0,0 @@ -# flake8: noqa -"""TestRail API binding for Python 3.x. - -(API v2, available since TestRail 3.0) - -Compatible with TestRail 3.0 and later. - -Learn more: - -http://docs.gurock.com/testrail-api2/start -http://docs.gurock.com/testrail-api2/accessing - -Copyright Gurock Software GmbH. See license.md for details. -""" - -import base64 -import json - -import requests - - -class APIClient: - def __init__(self, base_url): - self.user = "" - self.password = "" - if not base_url.endswith("/"): - base_url += "/" - self.__url = base_url + "index.php?/api/v2/" - - def send_get(self, uri, filepath=None): - """Issue a GET request (read) against the API. - - Args: - uri: The API method to call including parameters, e.g. get_case/1. - filepath: The path and file name for attachment download; used only - for 'get_attachment/:attachment_id'. - - Returns: - A dict containing the result of the request. - """ - return self.__send_request("GET", uri, filepath) - - def send_post(self, uri, data): - """Issue a POST request (write) against the API. - - Args: - uri: The API method to call, including parameters, e.g. add_case/1. - data: The data to submit as part of the request as a dict; strings - must be UTF-8 encoded. If adding an attachment, must be the - path to the file. - - Returns: - A dict containing the result of the request. - """ - return self.__send_request("POST", uri, data) - - def __send_request(self, method, uri, data): - url = self.__url + uri - - auth = str( - base64.b64encode(bytes("%s:%s" % (self.user, self.password), "utf-8")), - "ascii", - ).strip() - headers = {"Authorization": "Basic " + auth} - - if method == "POST": - if uri[:14] == "add_attachment": # add_attachment API method - files = {"attachment": (open(data, "rb"))} - response = requests.post(url, headers=headers, files=files) - files["attachment"].close() - else: - headers["Content-Type"] = "application/json" - payload = bytes(json.dumps(data), "utf-8") - response = requests.post(url, headers=headers, data=payload) - else: - headers["Content-Type"] = "application/json" - response = requests.get(url, headers=headers) - - if response.status_code > 201: - try: - error = response.json() - except ( - requests.exceptions.HTTPError - ): # response.content not formatted as JSON - error = str(response.content) - raise APIError( - "TestRail API returned HTTP %s (%s)" % (response.status_code, error) - ) - else: - if uri[:15] == "get_attachment/": # Expecting file, not JSON - try: - open(data, "wb").write(response.content) - return data - except FileNotFoundError: - return "Error saving attachment." - else: - try: - return response.json() - except requests.exceptions.HTTPError: - return {} - - -class APIError(Exception): - pass diff --git a/focus-android/automation/taskcluster/androidTest/testrail.py b/focus-android/automation/taskcluster/androidTest/testrail.py deleted file mode 100644 index e735e417a0c5..000000000000 --- a/focus-android/automation/taskcluster/androidTest/testrail.py +++ /dev/null @@ -1,180 +0,0 @@ -""" -This Python script is designed to automate the process of creating milestones -and test runs in TestRail, and updating test cases based on the results of -automated smoke tests for different product releases. - -Below is a summary of its functionality in order of execution: - -1. Environment and Credentials Setup: - - Imports necessary libraries and modules. - - Loads environmental variables from "execution_metadata.env". - - Reads and processes TestRail credentials from '.testrail_credentials.json'. - -2. Environment Variables Validation: - - Retrieves and validates several environment variables like `PRODUCT_TYPE`, - `RELEASE_TYPE`, `VERSION_NUMBER`, and `TEST_STATUS`. - - Ensures `TEST_STATUS` is either 'PASS' or 'FAIL'. - -3. Utility Functions: - - `parse_release_number()`: Parses the version number to extract a specific part. - - `build_milestone_name()`: Constructs a milestone name based on product type, - release type, and version number. - - `build_milestone_description()`: Creates a detailed description for the milestone - including the current date and placeholders for various testing statuses. - -4. TestRail Integration: - - Defines a `TestRail` class that handles interactions with the TestRail API. - - Includes methods to create milestones, create test runs, and update test cases. - -5. Main Execution: - - Checks if `TEST_STATUS` is 'PASS'. If not, it raises an error to trigger a Slack notification. - - Sets parameters for a demo TestRail project. - - Instantiates the `TestRail` class. - - Creates a milestone in TestRail and retrieves its ID. - - Creates test runs for each device/API combination (currently hardcoded for phase 1 testing) - and updates test cases to 'passed' status. - -6. Phase 1 and Phase 2 Notes: - - The script is currently in Phase 1, where certain values are hardcoded for testing. - - In Phase 2, these hardcoded values will be parameterized for broader usage. -""" - - -import json -import os -import textwrap -from lib.testrail_conn import APIClient -from dotenv import load_dotenv -from datetime import datetime - -try: - load_dotenv("execution_metadata.env") # Attempt to load .env file -except FileNotFoundError: - raise FileNotFoundError("The .env file was not found.") -except Exception as e: - raise Exception(f"An error occurred while loading the .env file: {e}") - -try: - with open(".testrail_credentials.json", "r") as file: - secret = json.load(file) - TESTRAIL_HOST = secret["host"] - TESTRAIL_USERNAME = secret["username"] - TESTRAIL_PASSWORD = secret["password"] -except json.JSONDecodeError as e: - raise ValueError(f"Failed to load testrail credentials : {e}") - -try: - PRODUCT_TYPE = os.environ["PRODUCT_TYPE"] - RELEASE_TYPE = os.environ["RELEASE_TYPE"] - VERSION_NUMBER = os.environ["MOBILE_HEAD_REF"] - TEST_STATUS = os.environ["TEST_STATUS"] - - if TEST_STATUS not in ("PASS", "FAIL"): - raise ValueError(f"ERROR: Invalid TEST_STATUS value: {TEST_STATUS}") -except KeyError as e: - raise ValueError(f"ERROR: Missing Environment Variable: {e}") - - -def parse_release_number(VERSION_NUMBER): - parts = VERSION_NUMBER.split("_") - return parts[1] - - -def build_milestone_name(product_type, release_type, version_number): - return f"Automated smoke testing sign-off - {product_type} {release_type} {version_number}" - - -def build_milestone_description(milestone_name): - current_date = datetime.now() - formatted_date = current_date = current_date.strftime("%B %d, %Y") - return textwrap.dedent( - f""" - RELEASE: {milestone_name}\n\n\ - RELEASE_TAG_URL: https://github.com/mozilla-mobile/firefox-android/releases\n\n\ - RELEASE_DATE: {formatted_date}\n\n\ - TESTING_STATUS: [ TBD ]\n\n\ - QA_RECOMMENDATION:[ TBD ]\n\n\ - QA_RECOMENTATION_VERBOSE: \n\n\ - TESTING_SUMMARY\n\n\ - Known issues: n/a\n\ - New issue: n/a\n\ - Verified issue: - """ - ) - - -class TestRail: - def __init__(self): - try: - self.client = APIClient(TESTRAIL_HOST) - self.client.user = TESTRAIL_USERNAME - self.client.password = TESTRAIL_PASSWORD - except KeyError as e: - raise ValueError(f"ERROR: Missing Testrail Env Var: {e}") - - # Public Methods - - def create_milestone(self, testrail_project_id, title, description): - data = {"name": title, "description": description} - return self.client.send_post(f"add_milestone/{testrail_project_id}", data) - - def create_test_run( - self, testrail_project_id, testrail_milestone_id, name_run, testrail_suite_id - ): - data = { - "name": name_run, - "milestone_id": testrail_milestone_id, - "suite_id": testrail_suite_id, - } - return self.client.send_post(f"add_run/{testrail_project_id}", data) - - def update_test_cases_to_passed( - self, testrail_project_id, testrail_run_id, testrail_suite_id - ): - test_cases = self._get_test_cases(testrail_project_id, testrail_suite_id) - data = { - "results": [ - {"case_id": test_case["id"], "status_id": 1} for test_case in test_cases - ] - } - return testrail._update_test_run_results(testrail_run_id, data) - - # Private Methods - - def _get_test_cases(self, testrail_project_id, testrail_test_suite_id): - return self.client.send_get( - f"get_cases/{testrail_project_id}&suite_id={testrail_test_suite_id}" - ) - - def _update_test_run_results(self, testrail_run_id, data): - return self.client.send_post(f"add_results_for_cases/{testrail_run_id}", data) - - -if __name__ == "__main__": - if TEST_STATUS != "PASS": - raise ValueError("Tests failed. Sending Slack Notification....") - - # There are for a dummy Testrail project used for Phase 1 testing of this script - # They will be parameterized during Phase 2 of script hardening - PROJECT_ID = 53 # Firefox for FireTV - TEST_SUITE_ID = 45442 # Demo Test Suite - - testrail = TestRail() - milestone_name = build_milestone_name( - PRODUCT_TYPE, RELEASE_TYPE, parse_release_number(VERSION_NUMBER) - ) - milestone_description = build_milestone_description(milestone_name) - - # Create milestone for 'Firefox for FireTV' and store the ID - milestone_id = testrail.create_milestone( - PROJECT_ID, milestone_name, milestone_description - )["id"] - - # Create test run for each Device/API and update test cases to 'passed' - # The Firebase Test devices are temporarily hard-coded during testing - # and will be parameterized in Phase 2 of hardening - for test_run_name in ["Google Pixel 32(Android11)", "Google Pixel2(Android9)"]: - test_run_id = testrail.create_test_run( - PROJECT_ID, milestone_id, test_run_name, TEST_SUITE_ID - )["id"] - testrail.update_test_cases_to_passed(PROJECT_ID, test_run_id, TEST_SUITE_ID) diff --git a/focus-android/automation/taskcluster/androidTest/ui-test.sh b/focus-android/automation/taskcluster/androidTest/ui-test.sh index 285d377f8d70..362d528b3df4 100755 --- a/focus-android/automation/taskcluster/androidTest/ui-test.sh +++ b/focus-android/automation/taskcluster/androidTest/ui-test.sh @@ -98,18 +98,9 @@ function failure_check() { echo if [[ $exitcode -ne 0 ]]; then echo "FAILURE: UI test run failed, please check above URL" - TEST_STATUS="FAIL" else echo "All UI test(s) have passed!" - TEST_STATUS="PASS" fi - - { - echo "TEST_STATUS=${TEST_STATUS}" - echo "PRODUCT_TYPE=${PRODUCT_TYPE}" - echo "RELEASE_TYPE=${RELEASE_TYPE}" - } >> execution_metadata.env - echo echo "RESULTS" echo diff --git a/taskcluster/ci/release-notify-testrail/kind.yml b/taskcluster/ci/release-notify-testrail/kind.yml new file mode 100644 index 000000000000..ab47faa8a7e3 --- /dev/null +++ b/taskcluster/ci/release-notify-testrail/kind.yml @@ -0,0 +1,71 @@ +# 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/. +--- +loader: taskgraph.loader.transform:loader + +transforms: + - taskgraph.transforms.job:transforms + - taskgraph.transforms.task:transforms + +task-defaults: + description: Sends Slack message to release testers that Testrail Milestone was created. + worker-type: b-android + worker: + docker-image: {in-tree: ui-tests} + max-run-time: 120 + env: + TESTRAIL_PROJECT_ID: '59' # Fenix Browser + TESTRAIL_TEST_SUITE_ID: '49319' # Test Automation Release Milestone + run: + use-caches: false + using: run-commands + secrets: + - name: project/mobile/ci/testrail + key: testrailCredentials + path: .testrail_credentials.json + json: true + routes: + - notify.slack-channel.G016BC5FUHJ.on-failed + scopes: + - queue:route:notify.slack-channel.G016BC5FUHJ # notify mobile-alerts-sandbox on failure + - notify:slack-channel:G016BC5FUHJ + - queue:route:notify.slack-channel.C02KDDS9QM9 # notify mobile-testeng on success + - notify:slack-channel:C02KDDS9QM9 + +tasks: + create-milestone-focus: + dependencies: + ui-test-apk: ui-test-apk-focus-arm-beta + description: Create Testrail Milestone for Focus + run-on-tasks-for: [github-push] + run-on-git-branches: [releases_v] + run: + pre-commands: + # get-secrets is called from '..' directory so we need to cd into any directory to make it work + - ["cd", "focus-android"] + commands: + - [python3, "../taskcluster/scripts/testrail_main.py"] + + worker: + env: + SHIPPING_PRODUCT: focus + TESTRAIL_PRODUCT_TYPE: Focus + + create-milestone-fenix: + dependencies: + ui-test-apk: ui-test-apk-fenix-arm-beta + description: Create Testrail Milestone for Fenix + run-on-tasks-for: [github-push] + run-on-git-branches: [releases_v] + run: + pre-commands: + # get-secrets is called from '..' directory so we need to cd into any directory to make it work + - ["cd", "fenix"] + commands: + - [python3, "../taskcluster/scripts/testrail_main.py"] + worker: + env: + SHIPPING_PRODUCT: fenix + TESTRAIL_PRODUCT_TYPE: Firefox + \ No newline at end of file diff --git a/taskcluster/scripts/lib/testrail_api.py b/taskcluster/scripts/lib/testrail_api.py new file mode 100644 index 000000000000..ace0a2ddacec --- /dev/null +++ b/taskcluster/scripts/lib/testrail_api.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 + +# 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/. +""" +This module provides a TestRail class for interfacing with the TestRail API, enabling the creation and management of test milestones, test runs, and updating test cases. It facilitates automation and integration of TestRail functionalities into testing workflows, particularly for projects requiring automated test management and reporting. + +The TestRail class encapsulates methods to interact with TestRail's API, including creating milestones and test runs, updating test cases, and checking the existence of milestones. It also features a method to retry API calls, enhancing the robustness of network interactions. + +Key Components: +- TestRail Class: A class providing methods for interacting with TestRail's API. + - create_milestone: Create a new milestone in a TestRail project. + - create_milestone_and_test_runs: Create a milestone and associated test runs for multiple devices in a project. + - create_test_run: Create a test run within a TestRail project. + - does_milestone_exist: Check if a milestone already exists in a TestRail project. + - update_test_cases_to_passed: Update the status of test cases to 'passed' in a test run. +- Private Methods: Utility methods for internal use to fetch test cases, update test run results, and retrieve milestones. +- Retry Mechanism: A method to retry API calls with a specified number of attempts and delay, improving reliability in case of intermittent network issues. + +Usage: +This module is intended to be used as part of a larger automated testing system, where integration with TestRail is required for test management and reporting. + +""" + +import os +import sys +import time + +# Ensure the directory containing this script is in Python's search path +script_directory = os.path.dirname(os.path.abspath(__file__)) +if script_directory not in sys.path: + sys.path.append(script_directory) + +from testrail_conn import APIClient + + +class TestRail: + def __init__(self, host, username, password): + self.client = APIClient(host) + self.client.user = username + self.client.password = password + + # Public Methods + + def create_milestone(self, testrail_project_id, title, description): + data = {"name": title, "description": description} + return self.client.send_post(f"add_milestone/{testrail_project_id}", data) + + def create_milestone_and_test_runs( + self, project_id, milestone_name, milestone_description, devices, test_suite_id + ): + # Create milestone + milestone_id = self._retry_api_call( + self.create_milestone, project_id, milestone_name, milestone_description + )["id"] + + # Create test runs for each device + for device in devices: + test_run_id = self._retry_api_call( + self.create_test_run, project_id, milestone_id, device, test_suite_id + )["id"] + self._retry_api_call( + self.update_test_cases_to_passed, project_id, test_run_id, test_suite_id + ) + + return milestone_id + + def create_test_run( + self, testrail_project_id, testrail_milestone_id, name_run, testrail_suite_id + ): + data = { + "name": name_run, + "milestone_id": testrail_milestone_id, + "suite_id": testrail_suite_id, + } + return self.client.send_post(f"add_run/{testrail_project_id}", data) + + def does_milestone_exist(self, testrail_project_id, milestone_name): + num_of_milestones_to_check = 10 # check last 10 milestones + milestones = self._get_milestones( + testrail_project_id + ) # returns reverse chronological order + for milestone in milestones[ + -num_of_milestones_to_check: + ]: # check last 10 api responses + if milestone_name == milestone["name"]: + return True + + def update_test_cases_to_passed( + self, testrail_project_id, testrail_run_id, testrail_suite_id + ): + test_cases = self._get_test_cases(testrail_project_id, testrail_suite_id) + data = { + "results": [ + {"case_id": test_case["id"], "status_id": 1} for test_case in test_cases + ] + } + return self._update_test_run_results(testrail_run_id, data) + return False + + # Private Methods + + def _get_test_cases(self, testrail_project_id, testrail_test_suite_id): + return self.client.send_get( + f"get_cases/{testrail_project_id}&suite_id={testrail_test_suite_id}" + ) + + def _update_test_run_results(self, testrail_run_id, data): + return self.client.send_post(f"add_results_for_cases/{testrail_run_id}", data) + + def _get_milestones(self, testrail_project_id): + return self.client.send_get(f"get_milestones/{testrail_project_id}") + + def _retry_api_call(self, api_call, *args, max_retries=3, delay=5): + """ + Retries the given API call up to max_retries times with a delay between attempts. + + :param api_call: The API call method to retry. + :param args: Arguments to pass to the API call. + :param max_retries: Maximum number of retries. + :param delay: Delay between retries in seconds. + """ + for attempt in range(max_retries): + try: + return api_call(*args) + except Exception as e: + if attempt == max_retries - 1: + raise # Reraise the last exception + time.sleep(delay) diff --git a/fenix/automation/taskcluster/androidTest/lib/testrail_conn.py b/taskcluster/scripts/lib/testrail_conn.py similarity index 100% rename from fenix/automation/taskcluster/androidTest/lib/testrail_conn.py rename to taskcluster/scripts/lib/testrail_conn.py diff --git a/taskcluster/scripts/lib/testrail_utils.py b/taskcluster/scripts/lib/testrail_utils.py new file mode 100644 index 000000000000..6a379ea82a80 --- /dev/null +++ b/taskcluster/scripts/lib/testrail_utils.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 + +# 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/. +""" +This script contains utility functions designed to support the integration of automated +testing processes with TestRail, a test case management tool. The primary focus is on +creating and managing milestones in TestRail based on automated smoke tests for product +releases. It includes functions for building milestone names and descriptions, determining +release types, and loading TestRail credentials. + +Functions: +- build_milestone_name(product_type, release_type, version_number): Constructs a formatted + milestone name based on the product type, release type, and version number. +- build_milestone_description(milestone_name): Generates a detailed description for the + milestone, including the release date and placeholders for testing status and QA recommendations. +- get_release_version(): Reads and returns the release version number from a 'version.txt' file. +- get_release_type(version): Determines the release type (e.g., Alpha, Beta, RC) based on + the version string. +- load_testrail_credentials(json_file_path): Loads TestRail credentials from a JSON file + and handles potential errors during the loading process. +""" + +from datetime import datetime +import json +import textwrap + + +def build_milestone_name(product_type, release_type, version_number): + return f"Automated smoke testing sign-off - {product_type} {release_type} {version_number}" + + +def build_milestone_description(milestone_name): + current_date = datetime.now() + formatted_date = current_date = current_date.strftime("%B %d, %Y") + return textwrap.dedent( + f""" + RELEASE: {milestone_name}\n\n\ + RELEASE_TAG_URL: https://github.com/mozilla-mobile/firefox-android/releases\n\n\ + RELEASE_DATE: {formatted_date}\n\n\ + TESTING_STATUS: [ TBD ]\n\n\ + QA_RECOMMENDATION:[ TBD ]\n\n\ + QA_RECOMENTATION_VERBOSE: \n\n\ + TESTING_SUMMARY\n\n\ + Known issues: n/a\n\ + New issue: n/a\n\ + Verified issue: + """ + ) + + +def get_release_version(): + with open("version.txt", "r") as file: + version = file.readline().strip() + return version + + +def get_release_type(version): + release_map = {"a": "Alpha", "b": "Beta"} + # use generator expression to check each char for key else default to 'RC' + product_type = next( + (release_map[char] for char in version if char in release_map), "RC" + ) + return product_type + + +def load_testrail_credentials(json_file_path): + try: + with open(json_file_path, "r") as file: + credentials = json.load(file) + return credentials + except json.JSONDecodeError as e: + raise ValueError(f"Failed to load TestRail credentials: {e}") diff --git a/taskcluster/scripts/slack_notifier.py b/taskcluster/scripts/slack_notifier.py new file mode 100644 index 000000000000..7dd7328c7837 --- /dev/null +++ b/taskcluster/scripts/slack_notifier.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 + +# 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/. +""" +This module provides functionalities for sending notifications to Slack channels, specifically designed for use in automated testing and release processes. It includes capabilities for sending both success and error notifications with customizable message templates. The module leverages Taskcluster for notification services and integrates with Slack's API to deliver real-time updates. + +Key Features: +- SLACK_SUCCESS_MESSAGE_TEMPLATE: A predefined template for formatting success messages to be sent to Slack. This template includes placeholders for dynamic content such as product version and release details. +- SLACK_ERROR_MESSAGE_TEMPLATE: A template for error messages, used to notify about failures or issues in automated processes, particularly with TestRail API interactions. +- send_slack_notification: A function that sends a Slack notification based on a provided template and value dictionary. It handles the construction of the message payload and interfaces with Taskcluster's Slack notification service. +- get_taskcluster_options: Retrieves configuration options for Taskcluster based on the current runtime environment, ensuring appropriate setup for notification delivery. +- send_error_notification: A higher-level function that formats and sends error notifications to a specified Slack channel. +- send_success_notification: Similarly, this function sends success notifications to a specified Slack channel, using the success message template. + +Usage: +The module is intended to be integrated into automated testing and release workflows, where Slack notifications are required to report the status of various processes, such as test executions or release milestones. + +Example: +To send a success notification: + success_values = {'RELEASE_VERSION': '1.0', 'SHIPPING_PRODUCT': 'ExampleProduct'} + send_success_notification(success_values, 'channel_id', taskcluster_options) + +To send an error notification: + send_error_notification('Error details', 'channel_id', taskcluster_options) +""" + +import json +import os +from string import Template +import time +import traceback + +import taskcluster + +SLACK_SUCCESS_MESSAGE_TEMPLATE = Template( + """ +[ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "New Release: :firefox: $SHIPPING_PRODUCT-v$RELEASE_VERSION :star:" + } + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*Testrail Release*: $TESTRAIL_PRODUCT_TYPE $RELEASE_TYPE $RELEASE_VERSION has been created:testrail:" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*UI Automated Tests*:" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": " :white_check_mark: Automated smoke test - Google Pixel 3a(Android 11)" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": ":white_check_mark: Automated smoke test - Google Pixel 2(Android 9)" + } + }, + { + "type": "divider" + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": ":testops-notify: created by " + } + ] + } +] +""" +) + +SLACK_ERROR_MESSAGE_TEMPLATE = Template( + """ +[ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "Failed to call TestRail API at $timestamp with error: $error_message" + } + } +] +""" +) + + +def send_slack_notification(template, values, channel_id, options): + """ + Sends a Slack notification based on the provided template and values. + + :param template: Template object for the Slack message. + :param values: Dictionary containing values to substitute in the template. + :param channel_id: Slack channel ID to send the message to. + :param options: Taskcluster options for the notification service. + """ + slack_message = json.loads(template.safe_substitute(**values)) + # workaround for https://github.com/taskcluster/taskcluster/issues/6801 + duplicate_message_workaround = str(int(time.time())) + payload = { + "channelId": channel_id, + "text": duplicate_message_workaround, + "blocks": slack_message, + } + + try: + response = taskcluster.Notify(options).slack(payload) + print("Response from API:", response) + except Exception as e: + print(f"Error sending Slack message: {e}") + traceback.print_exc() + + if hasattr(e, "response"): + print("Response content:", e.response.text) + + +def get_taskcluster_options(): + """ + Retrieves the Taskcluster setup options according to the current environment. + + :return: A dictionary of Taskcluster options. + """ + options = taskcluster.optionsFromEnvironment() + proxy_url = os.environ.get("TASKCLUSTER_PROXY_URL") + + if proxy_url is not None: + # Always use proxy url when available + options["rootUrl"] = proxy_url + + if "rootUrl" not in options: + # Always have a value in root url + options["rootUrl"] = "https://community-tc.services.mozilla.com" + + return options + + +def send_error_notification(error_message, channel_id, options): + values = { + "timestamp": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), + "error_message": error_message, + } + send_slack_notification(SLACK_ERROR_MESSAGE_TEMPLATE, values, channel_id, options) + + +def send_success_notification(success_values, channel_id, options): + send_slack_notification( + SLACK_SUCCESS_MESSAGE_TEMPLATE, success_values, channel_id, options + ) diff --git a/taskcluster/scripts/testrail_main.py b/taskcluster/scripts/testrail_main.py new file mode 100644 index 000000000000..44113279271d --- /dev/null +++ b/taskcluster/scripts/testrail_main.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 + +# 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/. +""" +This Python script automates creating milestones and test runs in TestRail and updating +test cases based on the results of automated smoke tests for different product releases. + +Functionality includes: +- Reading TestRail credentials and environment variables. +- Building milestone names and descriptions. +- Interacting with the TestRail API to create milestones, test runs, and update test cases. +- Sending notifications to a specified Slack channel. +""" + +import os +import sys +from lib.testrail_api import TestRail +from slack_notifier import ( + get_taskcluster_options, + send_error_notification, + send_success_notification, +) +from lib.testrail_utils import ( + build_milestone_name, + build_milestone_description, + get_release_version, + get_release_type, + load_testrail_credentials, +) + +# Constants +SUCCESS_CHANNEL_ID = "C02KDDS9QM9" # mobile-testeng +ERROR_CHANNEL_ID = "G016BC5FUHJ" # mobile-alerts-sandbox + + +def main(): + # Load TestRail credentials + credentials = load_testrail_credentials(".testrail_credentials.json") + testrail = TestRail( + credentials["host"], credentials["username"], credentials["password"] + ) + + # Read task environment variables + try: + shipping_product = os.environ["SHIPPING_PRODUCT"] + testrail_product_type = os.environ["TESTRAIL_PRODUCT_TYPE"] + testrail_project_id = os.environ["TESTRAIL_PROJECT_ID"] + testrail_test_suite_id = os.environ["TESTRAIL_TEST_SUITE_ID"] + except KeyError as e: + raise ValueError(f"ERROR: Missing Environment Variable: {e}") + + # Release information + release_version = get_release_version() + release_type = get_release_type(release_version) + + # Build milestone information + milestone_name = build_milestone_name( + testrail_product_type, release_type, release_version + ) + milestone_description = build_milestone_description(milestone_name) + + # Configure Taskcluster API + options = get_taskcluster_options() + + try: + # Check if milestone exists + if testrail.does_milestone_exist(testrail_project_id, milestone_name): + print(f"Milestone for {milestone_name} already exists. Exiting script...") + sys.exit() + + # Create milestone and test runs + devices = ["Google Pixel 32(Android11)", "Google Pixel2(Android9)"] + testrail.create_milestone_and_test_runs( + testrail_project_id, + milestone_name, + milestone_description, + devices, + testrail_test_suite_id, + ) + + # Send success notification + success_values = { + "RELEASE_VERSION": release_version, + "RELEASE_TYPE": release_type, + "SHIPPING_PRODUCT": shipping_product, + "TESTRAIL_PRODUCT_TYPE": testrail_product_type, + } + send_success_notification(success_values, SUCCESS_CHANNEL_ID, options) + + except Exception as error_message: + send_error_notification(str(error_message), ERROR_CHANNEL_ID, options) + + +if __name__ == "__main__": + main() From a01aa2756df7c3b47c3afec9b2d43edb0e1ca06b Mon Sep 17 00:00:00 2001 From: Jackie Johnson <107960801+jjSDET@users.noreply.github.com> Date: Tue, 6 Feb 2024 06:39:20 -0600 Subject: [PATCH 098/586] Bug 1873897 - update devices for testing --- taskcluster/scripts/lib/testrail_api.py | 2 +- taskcluster/scripts/testrail_main.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/taskcluster/scripts/lib/testrail_api.py b/taskcluster/scripts/lib/testrail_api.py index ace0a2ddacec..cc699b53bc85 100644 --- a/taskcluster/scripts/lib/testrail_api.py +++ b/taskcluster/scripts/lib/testrail_api.py @@ -86,6 +86,7 @@ def does_milestone_exist(self, testrail_project_id, milestone_name): ]: # check last 10 api responses if milestone_name == milestone["name"]: return True + return False def update_test_cases_to_passed( self, testrail_project_id, testrail_run_id, testrail_suite_id @@ -97,7 +98,6 @@ def update_test_cases_to_passed( ] } return self._update_test_run_results(testrail_run_id, data) - return False # Private Methods diff --git a/taskcluster/scripts/testrail_main.py b/taskcluster/scripts/testrail_main.py index 44113279271d..4324393f8fc9 100644 --- a/taskcluster/scripts/testrail_main.py +++ b/taskcluster/scripts/testrail_main.py @@ -71,7 +71,7 @@ def main(): sys.exit() # Create milestone and test runs - devices = ["Google Pixel 32(Android11)", "Google Pixel2(Android9)"] + devices = ["Google Pixel 3(Android11)", "Google Pixel 2(Android11)"] testrail.create_milestone_and_test_runs( testrail_project_id, milestone_name, From ed535ba157a81b40d68c0700ba47c0c2536163f5 Mon Sep 17 00:00:00 2001 From: Jackie Johnson <107960801+jjSDET@users.noreply.github.com> Date: Tue, 6 Feb 2024 06:58:01 -0600 Subject: [PATCH 099/586] Bug 1873897 - add Focus project and suite --- .../ci/release-notify-testrail/kind.yml | 31 +++++++++++-------- taskcluster/scripts/testrail_main.py | 7 +++-- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/taskcluster/ci/release-notify-testrail/kind.yml b/taskcluster/ci/release-notify-testrail/kind.yml index ab47faa8a7e3..7ce767454530 100644 --- a/taskcluster/ci/release-notify-testrail/kind.yml +++ b/taskcluster/ci/release-notify-testrail/kind.yml @@ -14,9 +14,6 @@ task-defaults: worker: docker-image: {in-tree: ui-tests} max-run-time: 120 - env: - TESTRAIL_PROJECT_ID: '59' # Fenix Browser - TESTRAIL_TEST_SUITE_ID: '49319' # Test Automation Release Milestone run: use-caches: false using: run-commands @@ -35,29 +32,36 @@ task-defaults: tasks: create-milestone-focus: - dependencies: - ui-test-apk: ui-test-apk-focus-arm-beta + # disable for testing + # dependencies: + # ui-test-apk: ui-test-apk-focus-arm-beta description: Create Testrail Milestone for Focus - run-on-tasks-for: [github-push] - run-on-git-branches: [releases_v] + # run-on-tasks-for: [github-push] + # run-on-git-branches: [releases_v] + run-on-tasks-for: [github-pull-request] # use this for testing + run-on-git-branches: [mte-2053] run: pre-commands: # get-secrets is called from '..' directory so we need to cd into any directory to make it work - ["cd", "focus-android"] commands: - [python3, "../taskcluster/scripts/testrail_main.py"] - worker: env: SHIPPING_PRODUCT: focus TESTRAIL_PRODUCT_TYPE: Focus + TESTRAIL_PROJECT_ID: '48' # Fenix Browser + TESTRAIL_TEST_SUITE_ID: '49386' # Test Automation Release Milestone - Focus create-milestone-fenix: - dependencies: - ui-test-apk: ui-test-apk-fenix-arm-beta + # disable for testing + # dependencies: + # ui-test-apk: ui-test-apk-fenix-arm-beta description: Create Testrail Milestone for Fenix - run-on-tasks-for: [github-push] - run-on-git-branches: [releases_v] + # run-on-tasks-for: [github-push] + # run-on-git-branches: [releases_v] + run-on-tasks-for: [github-pull-request] # use this for testing + run-on-git-branches: [mte-2053] run: pre-commands: # get-secrets is called from '..' directory so we need to cd into any directory to make it work @@ -68,4 +72,5 @@ tasks: env: SHIPPING_PRODUCT: fenix TESTRAIL_PRODUCT_TYPE: Firefox - \ No newline at end of file + TESTRAIL_PROJECT_ID: '59' # Fenix Browser + TESTRAIL_TEST_SUITE_ID: '49319' # Test Automation Release Milestone - Fenix \ No newline at end of file diff --git a/taskcluster/scripts/testrail_main.py b/taskcluster/scripts/testrail_main.py index 4324393f8fc9..93dcaa021f99 100644 --- a/taskcluster/scripts/testrail_main.py +++ b/taskcluster/scripts/testrail_main.py @@ -52,7 +52,8 @@ def main(): raise ValueError(f"ERROR: Missing Environment Variable: {e}") # Release information - release_version = get_release_version() + # release_version = get_release_version() # disable for testing + release_version = "125.0b3" release_type = get_release_type(release_version) # Build milestone information @@ -87,7 +88,9 @@ def main(): "SHIPPING_PRODUCT": shipping_product, "TESTRAIL_PRODUCT_TYPE": testrail_product_type, } - send_success_notification(success_values, SUCCESS_CHANNEL_ID, options) + # disable for testing + # send_success_notification(success_values, SUCCESS_CHANNEL_ID, options) + send_success_notification(success_values, ERROR_CHANNEL_ID, options) except Exception as error_message: send_error_notification(str(error_message), ERROR_CHANNEL_ID, options) From 8ed350ce5797586bdaa81557ba9b0e234dc341f4 Mon Sep 17 00:00:00 2001 From: Jackie Johnson <107960801+jjSDET@users.noreply.github.com> Date: Tue, 6 Feb 2024 07:16:02 -0600 Subject: [PATCH 100/586] Bug 1873897 - update Milestone name --- taskcluster/scripts/lib/testrail_utils.py | 2 +- taskcluster/scripts/testrail_main.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/taskcluster/scripts/lib/testrail_utils.py b/taskcluster/scripts/lib/testrail_utils.py index 6a379ea82a80..c51fbd348b18 100644 --- a/taskcluster/scripts/lib/testrail_utils.py +++ b/taskcluster/scripts/lib/testrail_utils.py @@ -28,7 +28,7 @@ def build_milestone_name(product_type, release_type, version_number): - return f"Automated smoke testing sign-off - {product_type} {release_type} {version_number}" + return f"Build Validation sign-off - {product_type} {release_type} {version_number}" def build_milestone_description(milestone_name): diff --git a/taskcluster/scripts/testrail_main.py b/taskcluster/scripts/testrail_main.py index 93dcaa021f99..02805406a34e 100644 --- a/taskcluster/scripts/testrail_main.py +++ b/taskcluster/scripts/testrail_main.py @@ -53,7 +53,7 @@ def main(): # Release information # release_version = get_release_version() # disable for testing - release_version = "125.0b3" + release_version = "125.0b4" release_type = get_release_type(release_version) # Build milestone information From cf08a94ad11eaa405899003dc8b63deff2a83e5a Mon Sep 17 00:00:00 2001 From: Jackie Johnson <107960801+jjSDET@users.noreply.github.com> Date: Tue, 6 Feb 2024 07:52:37 -0600 Subject: [PATCH 101/586] Bug 1873897 - add testrail_project_id to slack_notify values dict --- taskcluster/scripts/slack_notifier.py | 41 +++++++++++++++++++++------ taskcluster/scripts/testrail_main.py | 3 +- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/taskcluster/scripts/slack_notifier.py b/taskcluster/scripts/slack_notifier.py index 7dd7328c7837..4446b93bf902 100644 --- a/taskcluster/scripts/slack_notifier.py +++ b/taskcluster/scripts/slack_notifier.py @@ -17,13 +17,38 @@ Usage: The module is intended to be integrated into automated testing and release workflows, where Slack notifications are required to report the status of various processes, such as test executions or release milestones. -Example: -To send a success notification: - success_values = {'RELEASE_VERSION': '1.0', 'SHIPPING_PRODUCT': 'ExampleProduct'} - send_success_notification(success_values, 'channel_id', taskcluster_options) +Required Values for Notifications: -To send an error notification: - send_error_notification('Error details', 'channel_id', taskcluster_options) +These values are required when calling the `send_success_notification` and `send_slack_notification` functions. +They must be passed as an object with the following keys and their respective values. + +Required Keys and Expected Values: +- RELEASE_TYPE: Release Type or Stage (e.g., Alpha, Beta, RC). +- RELEASE_VERSION: Release Version from versions.txt (e.g., '124.0b5'). +- SHIPPING_PRODUCT: Release Tag Name (e.g., fennec, focus). +- TESTRAIL_PROJECT_ID: Project ID for TestRail Project (e.g., Fenix Browser). +- TESTRAIL_PRODUCT_TYPE: Name for the official release product (e.g., Firefox, not fennec). + +These values are used as arguments for `success_values` and `values` when calling the respective functions. + +Example Usage: + +success_values = { + "RELEASE_TYPE": "Beta", + "RELEASE_VERSION": "124.0b5", + "SHIPPING_PRODUCT": "fennec", + "TESTRAIL_PROJECT_ID": 59, # Fenix Browser + "TESTRAIL_PRODUCT_TYPE": "Firefox" +} + +send_success_notification(success_values, 'channel_id', taskcluster_options) + +values = { + "timestamp": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), + "error_message": error_message, +} + +send_error_notification(values, 'channel_id', taskcluster_options) """ import json @@ -51,7 +76,7 @@ "type": "section", "text": { "type": "mrkdwn", - "text": "*Testrail Release*: $TESTRAIL_PRODUCT_TYPE $RELEASE_TYPE $RELEASE_VERSION has been created:testrail:" + "text": "*Testrail Release*: $TESTRAIL_PRODUCT_TYPE $RELEASE_TYPE $RELEASE_VERSION has been created:testrail:" } }, { @@ -65,7 +90,7 @@ "type": "section", "text": { "type": "mrkdwn", - "text": " :white_check_mark: Automated smoke test - Google Pixel 3a(Android 11)" + "text": " :white_check_mark: Automated smoke test - Google Pixel 3(Android 11)" } }, { diff --git a/taskcluster/scripts/testrail_main.py b/taskcluster/scripts/testrail_main.py index 02805406a34e..3b05d5fa8b63 100644 --- a/taskcluster/scripts/testrail_main.py +++ b/taskcluster/scripts/testrail_main.py @@ -83,9 +83,10 @@ def main(): # Send success notification success_values = { - "RELEASE_VERSION": release_version, "RELEASE_TYPE": release_type, + "RELEASE_VERSION": release_version, "SHIPPING_PRODUCT": shipping_product, + "TESTRAIL_PROJECT_ID": testrail_project_id, "TESTRAIL_PRODUCT_TYPE": testrail_product_type, } # disable for testing From a98f3f8332389064ef3dbdc044c891ad8853ceb1 Mon Sep 17 00:00:00 2001 From: Jackie Johnson <107960801+jjSDET@users.noreply.github.com> Date: Tue, 6 Feb 2024 07:58:31 -0600 Subject: [PATCH 102/586] Bug 1873897 - update project id for testing --- taskcluster/scripts/testrail_main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taskcluster/scripts/testrail_main.py b/taskcluster/scripts/testrail_main.py index 3b05d5fa8b63..397b7df98a9a 100644 --- a/taskcluster/scripts/testrail_main.py +++ b/taskcluster/scripts/testrail_main.py @@ -53,7 +53,7 @@ def main(): # Release information # release_version = get_release_version() # disable for testing - release_version = "125.0b4" + release_version = "125.0b6" release_type = get_release_type(release_version) # Build milestone information From d5fa3936506bdf5ab8e72579d5f16cc0d8edb207 Mon Sep 17 00:00:00 2001 From: Jackie Johnson <107960801+jjSDET@users.noreply.github.com> Date: Tue, 6 Feb 2024 09:13:11 -0600 Subject: [PATCH 103/586] Bug 1873897 - remove testing values --- .../ci/release-notify-testrail/kind.yml | 22 +++++++------------ taskcluster/scripts/testrail_main.py | 7 ++---- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/taskcluster/ci/release-notify-testrail/kind.yml b/taskcluster/ci/release-notify-testrail/kind.yml index 7ce767454530..29f25779d411 100644 --- a/taskcluster/ci/release-notify-testrail/kind.yml +++ b/taskcluster/ci/release-notify-testrail/kind.yml @@ -32,14 +32,11 @@ task-defaults: tasks: create-milestone-focus: - # disable for testing - # dependencies: - # ui-test-apk: ui-test-apk-focus-arm-beta + dependencies: + ui-test-apk: ui-test-apk-focus-arm-beta description: Create Testrail Milestone for Focus - # run-on-tasks-for: [github-push] - # run-on-git-branches: [releases_v] - run-on-tasks-for: [github-pull-request] # use this for testing - run-on-git-branches: [mte-2053] + run-on-tasks-for: [github-push] + run-on-git-branches: [releases_v] run: pre-commands: # get-secrets is called from '..' directory so we need to cd into any directory to make it work @@ -54,14 +51,11 @@ tasks: TESTRAIL_TEST_SUITE_ID: '49386' # Test Automation Release Milestone - Focus create-milestone-fenix: - # disable for testing - # dependencies: - # ui-test-apk: ui-test-apk-fenix-arm-beta + dependencies: + ui-test-apk: ui-test-apk-fenix-arm-beta description: Create Testrail Milestone for Fenix - # run-on-tasks-for: [github-push] - # run-on-git-branches: [releases_v] - run-on-tasks-for: [github-pull-request] # use this for testing - run-on-git-branches: [mte-2053] + run-on-tasks-for: [github-push] + run-on-git-branches: [releases_v] run: pre-commands: # get-secrets is called from '..' directory so we need to cd into any directory to make it work diff --git a/taskcluster/scripts/testrail_main.py b/taskcluster/scripts/testrail_main.py index 397b7df98a9a..0feca07f5255 100644 --- a/taskcluster/scripts/testrail_main.py +++ b/taskcluster/scripts/testrail_main.py @@ -52,8 +52,7 @@ def main(): raise ValueError(f"ERROR: Missing Environment Variable: {e}") # Release information - # release_version = get_release_version() # disable for testing - release_version = "125.0b6" + release_version = get_release_version() release_type = get_release_type(release_version) # Build milestone information @@ -89,9 +88,7 @@ def main(): "TESTRAIL_PROJECT_ID": testrail_project_id, "TESTRAIL_PRODUCT_TYPE": testrail_product_type, } - # disable for testing - # send_success_notification(success_values, SUCCESS_CHANNEL_ID, options) - send_success_notification(success_values, ERROR_CHANNEL_ID, options) + send_success_notification(success_values, SUCCESS_CHANNEL_ID, options) except Exception as error_message: send_error_notification(str(error_message), ERROR_CHANNEL_ID, options) From 0945489ae31fa7ada078d95b6bee8147b360679b Mon Sep 17 00:00:00 2001 From: ohall-m Date: Wed, 31 Jan 2024 15:28:25 -0500 Subject: [PATCH 104/586] Bug 1877205 - Translations Fetch Supported Languages Refactor This patch refactors a few things for fetching supported languages: * `TranslateExpectedAction` is decoupled from fetching languages * Now use `OperationRequestedAction` w/ `FETCH_SUPPORTED_LANGUAGES` * Refactors the Fenix fragment to send `OperationRequestedAction` as a placeholder for data initialization * `TranslateSetLanguagesAction` is now `SetSupportedLanguagesAction` --- .../browser/state/action/BrowserAction.kt | 2 +- .../middleware/TranslationsMiddleware.kt | 17 ++---- .../state/reducer/TranslationsStateReducer.kt | 31 +++++++--- .../state/action/TranslationsActionTest.kt | 41 +++++++++++-- .../middleware/TranslationsMiddlewareTest.kt | 59 ++++++++++++------- .../engine/translate/TranslationOperation.kt | 2 +- .../TranslationsDialogFragment.kt | 10 +++- 7 files changed, 112 insertions(+), 50 deletions(-) diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt index 1074c65a2b42..0d6bd1a892f6 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt @@ -954,7 +954,7 @@ sealed class TranslationsAction : BrowserAction() { * @property tabId The ID of the tab the [EngineSession] that requested the list. * @property supportedLanguages The languages the engine supports for translation. */ - data class TranslateSetLanguagesAction( + data class SetSupportedLanguagesAction( override val tabId: String, val supportedLanguages: TranslationSupport?, ) : TranslationsAction(), ActionWithTab diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt index dc4abb5102bf..13c0098d118d 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt @@ -8,7 +8,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import mozilla.components.browser.state.action.BrowserAction import mozilla.components.browser.state.action.TranslationsAction -import mozilla.components.browser.state.action.TranslationsAction.TranslateExpectedAction import mozilla.components.browser.state.selector.findTab import mozilla.components.browser.state.state.BrowserState import mozilla.components.concept.engine.Engine @@ -40,16 +39,12 @@ class TranslationsMiddleware( ) { // Pre process actions when (action) { - is TranslateExpectedAction -> { - scope.launch { - requestSupportedLanguages(context, action.tabId) - } - } - is TranslationsAction.OperationRequestedAction -> { when (action.operation) { - TranslationOperation.FETCH_LANGUAGES -> { - // Bug 1877205 + TranslationOperation.FETCH_SUPPORTED_LANGUAGES -> { + scope.launch { + requestSupportedLanguages(context, action.tabId) + } } TranslationOperation.FETCH_PAGE_SETTINGS -> { scope.launch { @@ -86,7 +81,7 @@ class TranslationsMiddleware( onSuccess = { context.store.dispatch( - TranslationsAction.TranslateSetLanguagesAction( + TranslationsAction.SetSupportedLanguagesAction( tabId = tabId, supportedLanguages = it, ), @@ -98,7 +93,7 @@ class TranslationsMiddleware( context.store.dispatch( TranslationsAction.TranslateExceptionAction( tabId = tabId, - operation = TranslationOperation.FETCH_LANGUAGES, + operation = TranslationOperation.FETCH_SUPPORTED_LANGUAGES, translationError = TranslationError.CouldNotLoadLanguagesError(it), ), ) diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt index c166fec44d5a..e00e04e1f8de 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt @@ -83,9 +83,9 @@ internal object TranslationsStateReducer { } } - TranslationOperation.FETCH_LANGUAGES -> { + TranslationOperation.FETCH_SUPPORTED_LANGUAGES -> { // Reset the error state, and then generally expect - // [TranslationsAction.TranslateSetLanguagesAction] to update state in the + // [TranslationsAction.SetSupportedLanguagesAction] to update state in the // success case. state.copyWithTranslationsState(action.tabId) { it.copy( @@ -127,7 +127,7 @@ internal object TranslationsStateReducer { } } - TranslationOperation.FETCH_LANGUAGES -> { + TranslationOperation.FETCH_SUPPORTED_LANGUAGES -> { state.copyWithTranslationsState(action.tabId) { it.copy( supportedLanguages = null, @@ -147,7 +147,7 @@ internal object TranslationsStateReducer { } } - is TranslationsAction.TranslateSetLanguagesAction -> + is TranslationsAction.SetSupportedLanguagesAction -> state.copyWithTranslationsState(action.tabId) { it.copy( supportedLanguages = action.supportedLanguages, @@ -163,10 +163,25 @@ internal object TranslationsStateReducer { } is TranslationsAction.OperationRequestedAction -> - state.copyWithTranslationsState(action.tabId) { - it.copy( - pageSettings = null, - ) + when (action.operation) { + TranslationOperation.FETCH_SUPPORTED_LANGUAGES -> { + state.copyWithTranslationsState(action.tabId) { + it.copy( + supportedLanguages = null, + ) + } + } + TranslationOperation.FETCH_PAGE_SETTINGS -> { + state.copyWithTranslationsState(action.tabId) { + it.copy( + pageSettings = null, + ) + } + } + TranslationOperation.TRANSLATE, TranslationOperation.RESTORE -> { + // No state change for these operations + state + } } } diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt index c6e2db28bede..91d6d5370768 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt @@ -183,7 +183,7 @@ class TranslationsActionTest { } @Test - fun `WHEN a TranslateSetLanguagesAction is dispatched AND successful THEN update supportedLanguages`() { + fun `WHEN a SetSupportedLanguagesAction is dispatched AND successful THEN update supportedLanguages`() { // Initial assertEquals(null, tabState().translationsState.supportedLanguages) @@ -192,7 +192,7 @@ class TranslationsActionTest { val fromLanguage = Language("es", "Spanish") val supportedLanguages = TranslationSupport(listOf(fromLanguage), listOf(toLanguage)) store.dispatch( - TranslationsAction.TranslateSetLanguagesAction( + TranslationsAction.SetSupportedLanguagesAction( tabId = tab.id, supportedLanguages = supportedLanguages, ), @@ -235,7 +235,7 @@ class TranslationsActionTest { store.dispatch( TranslationsAction.TranslateExceptionAction( tabId = tab.id, - operation = TranslationOperation.FETCH_LANGUAGES, + operation = TranslationOperation.FETCH_SUPPORTED_LANGUAGES, translationError = fetchError, ), ).joinBlocking() @@ -275,7 +275,7 @@ class TranslationsActionTest { store.dispatch( TranslationsAction.TranslateSuccessAction( tabId = tab.id, - operation = TranslationOperation.FETCH_LANGUAGES, + operation = TranslationOperation.FETCH_SUPPORTED_LANGUAGES, ), ).joinBlocking() assertEquals(null, tabState().translationsState.translationError) @@ -306,7 +306,7 @@ class TranslationsActionTest { } @Test - fun `WHEN a OperationRequestedAction is dispatched THEN clear pageSettings`() { + fun `WHEN a OperationRequestedAction is dispatched for FETCH_PAGE_SETTINGS THEN clear pageSettings`() { // Setting first to have a more robust initial state assertNull(tabState().translationsState.pageSettings) @@ -337,4 +337,35 @@ class TranslationsActionTest { // Action success assertNull(tabState().translationsState.pageSettings) } + + @Test + fun `WHEN a OperationRequestedAction is dispatched for FETCH_SUPPORTED_LANGUAGES THEN clear supportLanguages`() { + // Setting first to have a more robust initial state + assertNull(tabState().translationsState.supportedLanguages) + + val supportLanguages = TranslationSupport( + fromLanguages = listOf(Language("en", "English")), + toLanguages = listOf(Language("en", "English")), + ) + + store.dispatch( + TranslationsAction.SetSupportedLanguagesAction( + tabId = tab.id, + supportedLanguages = supportLanguages, + ), + ).joinBlocking() + + assertEquals(supportLanguages, tabState().translationsState.supportedLanguages) + + // Action started + store.dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_SUPPORTED_LANGUAGES, + ), + ).joinBlocking() + + // Action success + assertNull(tabState().translationsState.supportedLanguages) + } } diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt index 0b4721b660cc..6cefd586783d 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt @@ -4,7 +4,6 @@ package mozilla.components.browser.state.engine.middleware -import kotlinx.coroutines.launch import kotlinx.coroutines.test.runTest import mozilla.components.browser.state.action.BrowserAction import mozilla.components.browser.state.action.TranslationsAction @@ -17,6 +16,7 @@ import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.Engine import mozilla.components.concept.engine.EngineSession import mozilla.components.concept.engine.translate.DetectedLanguages +import mozilla.components.concept.engine.translate.Language import mozilla.components.concept.engine.translate.LanguageSetting import mozilla.components.concept.engine.translate.TranslationEngineState import mozilla.components.concept.engine.translate.TranslationError @@ -30,6 +30,7 @@ import mozilla.components.support.test.libstate.ext.waitUntilIdle import mozilla.components.support.test.mock import mozilla.components.support.test.rule.MainCoroutineRule import mozilla.components.support.test.whenever +import org.junit.Before import org.junit.Rule import org.junit.Test import org.mockito.Mockito.spy @@ -54,6 +55,13 @@ class TranslationsMiddlewareTest { private val tabs = spy(listOf(tab)) private val state = spy(BrowserState(tabs = tabs)) private val store = spy(BrowserStore(middleware = listOf(translationsMiddleware), initialState = state)) + private val context = mock>() + + @Before + fun setup() { + whenever(context.store).thenReturn(store) + whenever(context.state).thenReturn(state) + } private fun waitForIdle() { scope.testScheduler.runCurrent() @@ -63,43 +71,50 @@ class TranslationsMiddlewareTest { } @Test - fun `WHEN TranslateExpectedAction is dispatched AND fetching languages is successful THEN TranslateSetLanguagesAction is dispatched`() { - val supportedLanguages = TranslationSupport(null, null) - val callbackCaptor = argumentCaptor<((TranslationSupport) -> Unit)>() - val action = TranslationsAction.TranslateExpectedAction(tabId = tab.id) - val middlewareContext = mock>() + fun `WHEN OperationRequestedAction is dispatched to fetch languages AND succeeds THEN SetSupportedLanguagesAction is dispatched`() = runTest { + val supportedLanguages = TranslationSupport( + fromLanguages = listOf(Language("en", "English")), + toLanguages = listOf(Language("en", "English")), + ) + val languageCallback = argumentCaptor<((TranslationSupport) -> Unit)>() - // Important for ensuring that the tests verify on the same store - whenever(middlewareContext.store).thenReturn(store) - whenever(engine.getSupportedTranslationLanguages(callbackCaptor.capture(), any())) - .thenAnswer { callbackCaptor.value(supportedLanguages) } + val action = + TranslationsAction.OperationRequestedAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_SUPPORTED_LANGUAGES, + ) - translationsMiddleware.invoke(middlewareContext, {}, action) + translationsMiddleware.invoke(context, {}, action) + verify(engine).getSupportedTranslationLanguages(onSuccess = languageCallback.capture(), onError = any()) + languageCallback.value.invoke(supportedLanguages) waitForIdle() - scope.launch { - verify(store).dispatch( - TranslationsAction.TranslateSetLanguagesAction( - tabId = tab.id, - supportedLanguages = supportedLanguages, - ), - ) - } + verify(context.store).dispatch( + TranslationsAction.SetSupportedLanguagesAction( + tabId = tab.id, + supportedLanguages = supportedLanguages, + ), + ) waitForIdle() } @Test - fun `WHEN TranslateExpectedAction is dispatched AND fetching languages fails THEN TranslateExceptionAction is dispatched`() { - store.dispatch(TranslationsAction.TranslateExpectedAction(tabId = tab.id)).joinBlocking() + fun `WHEN OperationRequestedAction is dispatched with FETCH_SUPPORTED_LANGUAGES AND fails THEN TranslateExceptionAction is dispatched`() = runTest { + store.dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_SUPPORTED_LANGUAGES, + ), + ).joinBlocking() waitForIdle() verify(store).dispatch( TranslationsAction.TranslateExceptionAction( tabId = tab.id, - operation = TranslationOperation.FETCH_LANGUAGES, + operation = TranslationOperation.FETCH_SUPPORTED_LANGUAGES, translationError = TranslationError.CouldNotLoadLanguagesError(any()), ), ) diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationOperation.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationOperation.kt index 711aef827d22..4ad17b0f2a15 100644 --- a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationOperation.kt +++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationOperation.kt @@ -23,7 +23,7 @@ enum class TranslationOperation { * the languages supported for translating both "to" and "from" with their BCP-47 language tag * and localized name. */ - FETCH_LANGUAGES, + FETCH_SUPPORTED_LANGUAGES, /** * The page related settings the translation engine should fetch. diff --git a/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt index 24bd845e326f..e94bc22ce172 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt @@ -26,6 +26,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment import mozilla.components.browser.state.action.TranslationsAction import mozilla.components.browser.state.selector.findTab import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.concept.engine.translate.TranslationOperation import mozilla.components.concept.engine.translate.initialFromLanguage import mozilla.components.concept.engine.translate.initialToLanguage import mozilla.components.lib.state.ext.observeAsComposableState @@ -69,8 +70,13 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() { container: ViewGroup?, savedInstanceState: Bundle?, ): View = ComposeView(requireContext()).apply { - // Signalling user intention to translate - browserStore.dispatch(TranslationsAction.TranslateExpectedAction(args.sessionId)) + // Signalling need to fetch languages + browserStore.dispatch( + TranslationsAction.OperationRequestedAction( + tabId = args.sessionId, + operation = TranslationOperation.FETCH_SUPPORTED_LANGUAGES, + ), + ) setContent { val translationsState = browserStore.observeAsComposableState { From 5010d526c901422c4b3ff5b87302e7805df466f1 Mon Sep 17 00:00:00 2001 From: Cathy Lu Date: Mon, 5 Feb 2024 15:20:48 -0600 Subject: [PATCH 105/586] Bug 1876823 - Add action to fetch sites that should not be translated --- .../browser/state/action/BrowserAction.kt | 11 +++++ .../middleware/TranslationsMiddleware.kt | 41 ++++++++++++++++++ .../state/reducer/TranslationsStateReducer.kt | 34 +++++++++++++++ .../browser/state/state/TranslationsState.kt | 4 +- .../state/action/TranslationsActionTest.kt | 18 ++++++++ .../middleware/TranslationsMiddlewareTest.kt | 43 +++++++++++++++++++ .../engine/translate/TranslationError.kt | 8 ++++ .../engine/translate/TranslationOperation.kt | 5 +++ 8 files changed, 163 insertions(+), 1 deletion(-) diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt index 0d6bd1a892f6..53b72ac3b5ff 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt @@ -969,6 +969,17 @@ sealed class TranslationsAction : BrowserAction() { override val tabId: String, val pageSettings: TranslationPageSettings?, ) : TranslationsAction(), ActionWithTab + + /** + * Sets the list of sites that the user has opted to never translate. + * + * @property tabId The ID of the tab the [EngineSession] that requested the list. + * @property neverTranslateSites The never translate sites. + */ + data class SetNeverTranslateSitesAction( + override val tabId: String, + val neverTranslateSites: List, + ) : TranslationsAction(), ActionWithTab } /** diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt index 13c0098d118d..0dcae6f3d964 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt @@ -51,6 +51,11 @@ class TranslationsMiddleware( requestTranslationPageSettings(context, action.tabId) } } + TranslationOperation.FETCH_NEVER_TRANSLATE_SITES -> { + scope.launch { + getNeverTranslateSites(context, action.tabId) + } + } TranslationOperation.TRANSLATE, TranslationOperation.RESTORE, -> Unit @@ -102,6 +107,42 @@ class TranslationsMiddleware( ) } + /** + * Retrieves the list of never translate sites using [scope] and dispatches the result to the + * store via [TranslationsAction.SetNeverTranslateSitesAction] or else dispatches the failure + * [TranslationsAction.TranslateExceptionAction]. + * + * @param context Context to use to dispatch to the store. + * @param tabId Tab ID associated with the request. + */ + private fun getNeverTranslateSites( + context: MiddlewareContext, + tabId: String, + ) { + engine.getNeverTranslateSiteList( + onSuccess = { + context.store.dispatch( + TranslationsAction.SetNeverTranslateSitesAction( + tabId = tabId, + neverTranslateSites = it, + ), + ) + logger.info("Success requesting never translate sites.") + }, + + onError = { + context.store.dispatch( + TranslationsAction.TranslateExceptionAction( + tabId = tabId, + operation = TranslationOperation.FETCH_NEVER_TRANSLATE_SITES, + translationError = TranslationError.CouldNotLoadNeverTranslateSites(it), + ), + ) + logger.error("Error requesting never translate sites: ", it) + }, + ) + } + /** * Retrieves the page settings using [scope] and dispatches the result to the * store via [TranslationsAction.SetPageSettingsAction] or else dispatches the failure diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt index e00e04e1f8de..3930578a5d83 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt @@ -104,6 +104,17 @@ internal object TranslationsStateReducer { ) } } + + TranslationOperation.FETCH_NEVER_TRANSLATE_SITES -> { + // Reset the error state, and then generally expect + // [TranslationsAction.SetNeverTranslateSitesAction] to update + // state in the success case. + state.copyWithTranslationsState(action.tabId) { + it.copy( + neverTranslateSites = null, + ) + } + } } } @@ -144,6 +155,15 @@ internal object TranslationsStateReducer { ) } } + + TranslationOperation.FETCH_NEVER_TRANSLATE_SITES -> { + state.copyWithTranslationsState(action.tabId) { + it.copy( + neverTranslateSites = null, + settingsError = action.translationError, + ) + } + } } } @@ -162,6 +182,13 @@ internal object TranslationsStateReducer { ) } + is TranslationsAction.SetNeverTranslateSitesAction -> + state.copyWithTranslationsState(action.tabId) { + it.copy( + neverTranslateSites = action.neverTranslateSites, + ) + } + is TranslationsAction.OperationRequestedAction -> when (action.operation) { TranslationOperation.FETCH_SUPPORTED_LANGUAGES -> { @@ -178,6 +205,13 @@ internal object TranslationsStateReducer { ) } } + TranslationOperation.FETCH_NEVER_TRANSLATE_SITES -> { + state.copyWithTranslationsState(action.tabId) { + it.copy( + neverTranslateSites = null, + ) + } + } TranslationOperation.TRANSLATE, TranslationOperation.RESTORE -> { // No state change for these operations state diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/TranslationsState.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/TranslationsState.kt index 2f99cdd084b1..3bc7b288da0a 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/TranslationsState.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/state/TranslationsState.kt @@ -19,8 +19,9 @@ import mozilla.components.concept.engine.translate.TranslationSupport * @property isTranslated The page is currently translated. * @property isTranslateProcessing The page is currently attempting a translation. * @property isRestoreProcessing The page is currently attempting a restoration. - * @property pageSettings The translation engine settings that relate to the current page. * @property supportedLanguages Set of languages the translation engine supports. + * @property pageSettings The translation engine settings that relate to the current page. + * @property neverTranslateSites List of sites the user has opted to never translate. * @property translationError Type of error that occurred when acquiring resources, translating, or * restoring a translation. * @property settingsError Type of error that occurred when acquiring resources or setting preferences. @@ -34,6 +35,7 @@ data class TranslationsState( val isRestoreProcessing: Boolean = false, val supportedLanguages: TranslationSupport? = null, val pageSettings: TranslationPageSettings? = null, + val neverTranslateSites: List? = null, val translationError: TranslationError? = null, val settingsError: TranslationError? = null, ) diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt index 91d6d5370768..4e0dc165bc19 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt @@ -203,6 +203,24 @@ class TranslationsActionTest { assertEquals(supportedLanguages, tabState().translationsState.supportedLanguages) } + @Test + fun `WHEN a SetNeverTranslateSitesAction is dispatched AND successful THEN update neverTranslateSites`() { + // Initial + assertEquals(null, tabState().translationsState.neverTranslateSites) + + // Action started + val neverTranslateSites = listOf("google.com") + store.dispatch( + TranslationsAction.SetNeverTranslateSitesAction( + tabId = tab.id, + neverTranslateSites = neverTranslateSites, + ), + ).joinBlocking() + + // Action success + assertEquals(neverTranslateSites, tabState().translationsState.neverTranslateSites) + } + @Test fun `WHEN a TranslateExceptionAction is dispatched due to an error THEN update the error condition according to the operation`() { // Initial state diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt index 6cefd586783d..011ab19a4731 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt @@ -206,4 +206,47 @@ class TranslationsMiddlewareTest { waitForIdle() } + + @Test + fun `WHEN OperationRequestedAction is dispatched to fetch never translate sites AND succeeds THEN SetNeverTranslateSitesAction is dispatched`() = runTest { + val neverTranslateSites = listOf("google.com") + val sitesCallback = argumentCaptor<((List) -> Unit)>() + val action = + TranslationsAction.OperationRequestedAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_NEVER_TRANSLATE_SITES, + ) + translationsMiddleware.invoke(context, {}, action) + verify(engine).getNeverTranslateSiteList(onSuccess = sitesCallback.capture(), onError = any()) + sitesCallback.value.invoke(neverTranslateSites) + + verify(context.store).dispatch( + TranslationsAction.SetNeverTranslateSitesAction( + tabId = tab.id, + neverTranslateSites = neverTranslateSites, + ), + ) + + waitForIdle() + } + + @Test + fun `WHEN OperationRequestedAction is dispatched to fetch never translate sites AND fails THEN TranslateExceptionAction is dispatched`() = runTest { + store.dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_NEVER_TRANSLATE_SITES, + ), + ).joinBlocking() + waitForIdle() + + verify(store).dispatch( + TranslationsAction.TranslateExceptionAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_NEVER_TRANSLATE_SITES, + translationError = TranslationError.CouldNotLoadNeverTranslateSites(any()), + ), + ) + waitForIdle() + } } diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationError.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationError.kt index 313744478668..812ffe88f563 100644 --- a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationError.kt +++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationError.kt @@ -80,6 +80,14 @@ sealed class TranslationError( class CouldNotLoadPageSettingsError(override val cause: Throwable?) : TranslationError(errorName = "could-not-load-settings", displayError = false, cause = cause) + /** + * Could not load never translate sites error. + * + * @param cause The original throwable before it was converted into this error state. + */ + class CouldNotLoadNeverTranslateSites(override val cause: Throwable?) : + TranslationError(errorName = "could-not-load-never-translate-sites", displayError = false, cause = cause) + /** * The language is not supported for translation. * diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationOperation.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationOperation.kt index 4ad17b0f2a15..7de131a7a8b0 100644 --- a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationOperation.kt +++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationOperation.kt @@ -29,4 +29,9 @@ enum class TranslationOperation { * The page related settings the translation engine should fetch. */ FETCH_PAGE_SETTINGS, + + /** + * The list of never translate sites the translation engine should fetch. + */ + FETCH_NEVER_TRANSLATE_SITES, } From 32bfcff0fd05c150d514144324c76d319fc1746b Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 7 Feb 2024 00:03:12 +0000 Subject: [PATCH 106/586] Import translations from android-l10n --- .../addons/src/main/res/values-da/strings.xml | 2 + .../addons/src/main/res/values-sk/strings.xml | 2 +- .../media/src/main/res/values-da/strings.xml | 11 +- .../src/main/res/values-da/strings.xml | 36 +++++ fenix/app/src/main/res/values-azb/strings.xml | 134 ++++++++++++++++++ fenix/app/src/main/res/values-da/strings.xml | 102 +++++++++++++ fenix/app/src/main/res/values-kab/strings.xml | 4 + fenix/app/src/main/res/values-si/strings.xml | 2 + .../app/src/main/res/values-da/strings.xml | 9 +- .../app/src/main/res/values-eu/strings.xml | 8 +- 10 files changed, 296 insertions(+), 14 deletions(-) diff --git a/android-components/components/feature/addons/src/main/res/values-da/strings.xml b/android-components/components/feature/addons/src/main/res/values-da/strings.xml index 5b2e832f2db7..ff1dc3cfe6e9 100644 --- a/android-components/components/feature/addons/src/main/res/values-da/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-da/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Tilgå dine data på %1$d andre domæner + + %1$s, %2$d af %3$d Tilgå faneblade diff --git a/android-components/components/feature/addons/src/main/res/values-sk/strings.xml b/android-components/components/feature/addons/src/main/res/values-sk/strings.xml index 38b7631e06c2..572330224a76 100644 --- a/android-components/components/feature/addons/src/main/res/values-sk/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-sk/strings.xml @@ -245,7 +245,7 @@ Doplnok %1$s bol pridaný do aplikácie %2$s - Otvorte ho v ponuke + Nájdete ho v ponuke Ok, rozumiem diff --git a/android-components/components/feature/media/src/main/res/values-da/strings.xml b/android-components/components/feature/media/src/main/res/values-da/strings.xml index c1f331a2c4cb..28a62989b39d 100644 --- a/android-components/components/feature/media/src/main/res/values-da/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-da/strings.xml @@ -1,5 +1,5 @@ - + Medieindhold @@ -22,9 +22,14 @@ Påmindelse: %1$s bruger stadig dit kamera. Tryk for at åbne fanebladet. - Påmindelse: %1$s bruger stadig din mikrofon. Tryk for at åbne fanebladet. + Påmindelse: %1$s bruger stadig din mikrofon. Tryk for at åbne fanebladet. + + Påmindelse: %1$s bruger stadig din mikrofon. Tryk for at åbne fanebladet. + + Påmindelse: %1$s bruger stadig din mikrofon og dit kamera. Tryk for at åbne fanebladet + - Påmindelse: %1$s bruger stadig din mikrofon og dit kamera. Tryk for at åbne fanebladet + Påmindelse: %1$s bruger stadig din mikrofon og dit kamera. Tryk for at åbne fanebladet. Afspil diff --git a/android-components/components/feature/prompts/src/main/res/values-da/strings.xml b/android-components/components/feature/prompts/src/main/res/values-da/strings.xml index 81291e1d9038..df13afc653e3 100644 --- a/android-components/components/feature/prompts/src/main/res/values-da/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-da/strings.xml @@ -18,6 +18,8 @@ Adgangskode Gem ikke + + Ikke nu Gem aldrig @@ -26,16 +28,26 @@ Gem Opdater ikke + + Ikke nu Opdater Feltet Adgangskode må ikke være tomt + Indtast en adgangskode + Kunne ikke gemme login + + Kan ikke gemme adgangskode Gem dette login? + + Gem adgangskode? Opdater dette login? + + Opdater adgangskode? Føj brugernavn til gemt adgangskode? @@ -85,13 +97,22 @@ Vælg tidspunkt Håndter logins + + Håndter adgangskoder Udvid foreslåede logins + + Udvid gemte adgangskoder Sammenfold foreslåede logins + + Sammenfold gemte adgangskoder Foreslåede logins + + Gemte adgangskoder + Foreslå stærk adgangskode @@ -110,12 +131,20 @@ Vælg betalingskort + + Brug gemt kort Udvid foreslåede betalingskort + + Udvid gemte kort Sammenfold foreslåede betalingskort + + Sammenfold gemte kort Håndter betalingskort + + Håndter kort Gem dette kort sikkert? @@ -123,13 +152,20 @@ Kortnummeret vil blive krypteret. Sikkerhedskoden vil ikke blive gemt. + + %s krypterer dit kortnummer. Din sikkerhedskode bliver ikke gemt. + Vælg adresse Udvid foreslåede adresser + + Udvid gemte adresser Sammenfold foreslåede adresser + + Sammenfold gemte adresser Håndter adresser diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml index b375ebffee70..d3b9fa55415a 100644 --- a/fenix/app/src/main/res/values-azb/strings.xml +++ b/fenix/app/src/main/res/values-azb/strings.xml @@ -192,6 +192,140 @@ قالدیر + + بوتون گئچمیش آراشدیرمالاری گؤستر + + + + دالیا + + قاباغا + + رفرش + + دوردور + + تاخیلان‌لار + + حساب بیلگی‌لری + + بوردا هئچ تاخیلان یوخ + + + + ال‌توتما + + یئنی نه وار + + تنظیم‌‎لر + + کیتابخانا + + دسکتاپ سایت + + معمولی تاغدا آچ + + آناصفحه‌یه آرتیر + + قوْش + + گئنه دؤنگل + + صفحه‌ده تاپ + + + + صفحه‌نی ترجومه ائله + + مجموعه‌ده ساخلا + + پایلاش + + %1$s ایله آچ + + %1$s طرفیندن گوج آلیر + + %1$s گوجو ایله + + + + اوخوجو گؤرونوشو + + اوخوجو گؤرونوشو باغلا + + اپده آچ + + اوخوجو گؤرونوشو اؤزللشدیر + + اکله + + دوزه‌لیش + + آنایارپاغی اؤزللشدیر + + + + باش صفحه + + + + مورور گئچمیشینی پوز + + + + صفحه‌نی ترجومه ائله + + + + سئچیلمیش دیل + + + + جهاز دیلینی ایشه آل + + دیل آختار + + + + + اسکن + + آختاریش موتورونون تنظیم‌لری + + ایجازه وئر + + ایجازه وئرمه + + اؤزل اوتورم‌لاردا آختاریش تکلیف‌لرینه ایجازه وئریلسین؟ + + + + %s ایله آختار + + + ایندی یوخ + + + + یئنی بیر %1$s تاغی آچین + + آختاریش + + وب‌ده آختارین + + سس‌لی آختاریش + + + + تنظیم‌‎لر + + عمومی + + diff --git a/fenix/app/src/main/res/values-da/strings.xml b/fenix/app/src/main/res/values-da/strings.xml index 7e983ecc98c1..6c206ff7bb78 100644 --- a/fenix/app/src/main/res/values-da/strings.xml +++ b/fenix/app/src/main/res/values-da/strings.xml @@ -252,6 +252,9 @@ history and go back to the home screen. --> Slet browser-historik + + Oversæt side + Valgt sprog @@ -325,10 +328,15 @@ Ikke nu + + + Privatlivserklæring for Firefox Vi elsker at holde dig sikker + Vores browser er støttet af en nonprofit-organisation og forhindrer virksomheder i at følge dig rundt på nettet i det skjulte. + Vores non-profit-støttede browser hjælper med at forhindre virksomheder i at følge dig rundt på nettet i hemmelighed.\n\nLæs mere i vores privatlivserklæring. @@ -682,6 +690,8 @@ Bogmærker Logins + + Adgangskoder Åbne faneblade @@ -708,6 +718,8 @@ Betalingskort + + Betalingsmetoder Adresser @@ -1643,8 +1655,12 @@ Logins og adgangskoder + + Adgangskoder Gem logins og adgangskoder + + Gem adgangskoder Bed om at gemme @@ -1661,26 +1677,46 @@ Tilføj login + + Tilføj adgangskode + Synkroniser logins + + Synkroniser adgangskoder Synkroniser logins på tværs af enheder + + Synkroniser adgangskoder på tværs af enheder Gemte logins + + Gemte adgangskoder De logins, du gemmer eller synkroniserer til %s, vises her. + + Adgangskoderne, du gemmer i eller synkroniserer med %s vil blive vist her. Alle dine gemte adgangskoder bliver krypteret. + Læs mere om Sync. + + Læs mere om synkronisering Undtagelser Logins og adgangskoder, der ikke er gemt, vises her. + + %s gemmer ikke adgangskoder til websteder vist her. Logins og adgangskoder vil ikke blive gemt for disse websteder. + + %s gemmer ikke adgangskoder til disse websteder. Slet alle undtagelser Søg efter logins + + Søg efter adgangskoder Websted @@ -1709,10 +1745,16 @@ Skjul adgangskode Lås op for at se dine gemte logins + + Lås op for at se dine gemte adgangskoder Gør dine logins og adgangskoder sikre + + Gør dine gemte adgangskoder sikre Indstil en pinkode, en adgangskode eller et låsemønster på din enhed for at forhindre, at andre mennesker får adgang til dine gemte logins og adgangskoder, hvis de har adgang til din enhed. + + Indstil en pinkode, en adgangskode eller et låsemønster på din enhed for at forhindre, at andre mennesker får adgang til dine gemte adgangskoder, hvis de har adgang til din enhed. Senere @@ -1732,6 +1774,9 @@ Sortér menuen logins + + Menuen sorter adgangskoder + Autofyld @@ -1739,27 +1784,42 @@ Adresser Betalingskort + + Betalingsmetoder Gem og autofyld betalingskort + + Gem og udfyld betalingsmetoder Data er krypteret + + %s krypterer alle betalingsmetoder, du gemmer Synkroniser kort på tværs af enheder Synkroniser kort Tilføj betalingskort + + Tilføj kort Håndter gemte kort + + Håndter kort Tilføj adresse Håndter adresser Gem og autofyld adresser + + Gem og udfyld adresser Inkluderer oplysninger såsom telefonnumre, mail- og forsendelsesadresser + + Inkluderer telefonnumre og mailadresser + Tilføj kort @@ -1780,6 +1840,8 @@ Slet kort Er du sikker på, at du vil slette dette betalingskort? + + Slet kort? Slet @@ -1795,14 +1857,22 @@ Indtast et gyldigt betalingskortnummer + + Indtast et gyldigt kortnummer Udfyld dette felt + + Tilføj navn Lås op for at se dine gemte betalingskort Beskyt dine betalingskort + + Gør dine gemte betalingsmetoder sikre Indstil en pinkode, en adgangskode eller et låsemønster på din enhed for at forhindre, at andre mennesker får adgang til dine gemte betalingskort, hvis de har adgang til din enhed. + + Indstil en pinkode, en adgangskode eller et låsemønster på din enhed for at forhindre, at andre mennesker får adgang til dine gemte betalingsmetoder, hvis de har adgang til din enhed. Indstil nu @@ -1812,6 +1882,8 @@ Lås op for at anvende gemte informationer om betalingskort + + Lås op for at bruge gemte betalingsmetoder Tilføj adresse @@ -1848,6 +1920,8 @@ Slet adresse Er du sikker på, at du vil slette denne adresse? + + Slet denne adresse? Slet @@ -1947,30 +2021,52 @@ Rediger Er du sikker på, at du vil slette dette login? + + Er du sikker på, at du vil slette denne adgangskode? Slet Annuller Login-indstillinger + + Adgangskode-indstillinger Det redigerbare tekstfelt for login’ets webadresse. + + Det redigerbare tekstfelt for webadressen. Det redigerbare tekstfelt for login’ets brugernavn. + + Det redigerbare tekstfelt for brugernavnet. Det redigerbare tekstfelt for login’ets adgangskode. + + Det redigerbare tekstfelt for adgangskoden. Gem ændringer til login. + + Gem ændringer. Rediger + + Rediger adgangskode Tilføj nyt login + + Tilføj adgangskode Adgangskode påkrævet + + Indtast en adgangskode Brugernavn påkrævet + + Indtast et brugernavn Værtsnavn påkrævet + + Indtast en webadresse Stemme-søgning @@ -2325,6 +2421,8 @@ Oversættelse i gang + + Vælg et sprog Der opstod et problem med at oversætte. Prøv igen. @@ -2345,6 +2443,10 @@ Oversæt aldrig %1$s Oversæt aldrig dette websted + + Tilsidesætter alle andre indstillinger + + Tilsidesætter tilbud om oversættelse Oversættelses-indstillinger diff --git a/fenix/app/src/main/res/values-kab/strings.xml b/fenix/app/src/main/res/values-kab/strings.xml index 780162870679..bdb13932b350 100644 --- a/fenix/app/src/main/res/values-kab/strings.xml +++ b/fenix/app/src/main/res/values-kab/strings.xml @@ -1558,6 +1558,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Akk inagan n tuqqna (ad rẓen isaml web) Ɛzel inagan n tuqqna gar yismal + + Ssuter i yismal web ur snuzuyen, ur beṭṭun isefka-w Agbur n uḍfaṛ @@ -1759,6 +1761,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Serreḥ akken ad tsekneḍ inekcam-ik yettwaskelsen Mmesten inekcam d wawalen uffiren + + Seɣles awalen-ik·im uffiren i yettwaskelsen Sbadu azenziɣ n usekkeṛ, tangal PIN, neɣ awal uffir akken ad temmesteneḍ inekcam-ik akked wawlen-ik uffiren yettwaskelsen ticki yella win ikecmen ɣer yibenk-ik. diff --git a/fenix/app/src/main/res/values-si/strings.xml b/fenix/app/src/main/res/values-si/strings.xml index 07e0127c332e..b986ea293dc4 100644 --- a/fenix/app/src/main/res/values-si/strings.xml +++ b/fenix/app/src/main/res/values-si/strings.xml @@ -1289,6 +1289,8 @@ පෞද්. පටිති වසන්නද? + පෞද්. පටිති වැසීමට දැනුම්දීම මත තට්ටු හෝ තල්ලු කරන්න. + අළෙවිකරණය diff --git a/focus-android/app/src/main/res/values-da/strings.xml b/focus-android/app/src/main/res/values-da/strings.xml index f064becc7045..feb002061516 100644 --- a/focus-android/app/src/main/res/values-da/strings.xml +++ b/focus-android/app/src/main/res/values-da/strings.xml @@ -54,7 +54,6 @@ Fjern fra genveje - Nyheder Indstillinger Om Hjælp @@ -85,10 +84,10 @@ sharing an URL. --> Del via - + Slet browser-historik? + + Tryk på eller ryd denne meddelelse for at slette din browser-historik på en sikker måde. + Slet browser-historik diff --git a/focus-android/app/src/main/res/values-eu/strings.xml b/focus-android/app/src/main/res/values-eu/strings.xml index 8639fde0cdc1..cfd4e8294fde 100644 --- a/focus-android/app/src/main/res/values-eu/strings.xml +++ b/focus-android/app/src/main/res/values-eu/strings.xml @@ -53,7 +53,6 @@ Kendu lasterbideetatik - Nobedadeak Ezarpenak Honi buruz Laguntza @@ -84,10 +83,9 @@ sharing an URL. --> Partekatu - + Ezabatu nabigatze-historia? + Sakatu edo garbitu jakinarazpen hau zure nabigatze-historia ezabatzeko. + Ezabatu nabigatze-historia From 6cf415808d84c11117ffc2aca6035e779945fede Mon Sep 17 00:00:00 2001 From: Lina Butler Date: Sat, 3 Feb 2024 11:49:05 -0800 Subject: [PATCH 107/586] Bug 1878434 - Record an awesomebar abandonment for cancelled toolbar edits. We were missing instrumentation for the case where the user cancels editing. This commit adds that instrumentation. --- .../java/org/mozilla/fenix/search/SearchDialogController.kt | 1 + .../org/mozilla/fenix/search/SearchDialogControllerTest.kt | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/search/SearchDialogController.kt b/fenix/app/src/main/java/org/mozilla/fenix/search/SearchDialogController.kt index 74e830fce94b..4ab17e66a97c 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/search/SearchDialogController.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/search/SearchDialogController.kt @@ -143,6 +143,7 @@ class SearchDialogController( override fun handleEditingCancelled() { clearToolbarFocus() dismissDialogAndGoBack() + store.dispatch(AwesomeBarAction.EngagementFinished(abandoned = true)) } override fun handleTextChanged(text: String) { diff --git a/fenix/app/src/test/java/org/mozilla/fenix/search/SearchDialogControllerTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/search/SearchDialogControllerTest.kt index fcb7fb6f80d7..d1e10dcfea6d 100644 --- a/fenix/app/src/test/java/org/mozilla/fenix/search/SearchDialogControllerTest.kt +++ b/fenix/app/src/test/java/org/mozilla/fenix/search/SearchDialogControllerTest.kt @@ -313,6 +313,10 @@ class SearchDialogControllerTest { assertTrue(clearToolbarFocusInvoked) assertTrue(dismissAndGoBack) + + middleware.assertLastAction(AwesomeBarAction.EngagementFinished::class) { action -> + assertTrue(action.abandoned) + } } @Test From 89dca41708afabcf25b3e7a737238001183c280c Mon Sep 17 00:00:00 2001 From: Lina Butler Date: Fri, 2 Feb 2024 16:11:14 -0800 Subject: [PATCH 108/586] Bug 1878434 - Add the `awesomebar.{engagement, abandonment}` events. This commit: * Sends the new `awesomebar.{engagement, abandonment}` events when the user finishes interacting with the awesomebar. These events match iOS's events of the same name, and Desktop's `urlbar.{engagement, abandonment}` events. * Removes the `engagement_abandoned` extra key for the `awesomebar.{sponsored, non_sponsored}_suggestion_impressed` events, since they're specific to AMP and Wikipedia suggestions, and are subsumed by the new events. This is the first step toward unifying our awesomebar search telemetry on all our platforms. --- fenix/app/metrics.yaml | 51 ++++++++++++++++--- .../components/metrics/MetricController.kt | 2 - .../fenix/telemetry/TelemetryMiddleware.kt | 11 +++- 3 files changed, 54 insertions(+), 10 deletions(-) diff --git a/fenix/app/metrics.yaml b/fenix/app/metrics.yaml index fe36185ed84c..636f46ff28c4 100644 --- a/fenix/app/metrics.yaml +++ b/fenix/app/metrics.yaml @@ -9204,8 +9204,10 @@ awesomebar: A sponsored suggestion was visible when the user finished interacting with the awesomebar. bugs: - https://bugzilla.mozilla.org/show_bug.cgi?id=1871156 + - https://bugzilla.mozilla.org/show_bug.cgi?id=1878434 data_reviews: - https://github.com/mozilla-mobile/firefox-android/pull/4914#issuecomment-1874271848 + - https://github.com/mozilla-mobile/firefox-android/pull/5438#issuecomment-1930970336 data_sensitivity: - interaction notification_emails: @@ -9216,12 +9218,6 @@ awesomebar: expires: never extra_keys: provider: *sponsored_suggestion_provider - engagement_abandoned: &awesomebar_engagement_abandoned - description: | - If `true`, the user dismissed the awesomebar without navigating to a destination. If - `false`, the user finished engaging with the awesomebar by navigating to a destination, - like a URL, a search results page, or a suggestion. - type: boolean metadata: tags: - Search @@ -9231,8 +9227,10 @@ awesomebar: A non-sponsored suggestion was visible when the user finished interacting with the awesomebar. bugs: - https://bugzilla.mozilla.org/show_bug.cgi?id=1871156 + - https://bugzilla.mozilla.org/show_bug.cgi?id=1878434 data_reviews: - https://github.com/mozilla-mobile/firefox-android/pull/4914#issuecomment-1874271848 + - https://github.com/mozilla-mobile/firefox-android/pull/5438#issuecomment-1930970336 data_sensitivity: - interaction notification_emails: @@ -9243,10 +9241,49 @@ awesomebar: expires: never extra_keys: provider: *non_sponsored_suggestion_provider - engagement_abandoned: *awesomebar_engagement_abandoned metadata: tags: - Search + engagement: + type: event + description: | + The user completed their search session by tapping a search result, + or entering a URL or a search term. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1878434 + data_reviews: + - https://github.com/mozilla-mobile/firefox-android/pull/5438#issuecomment-1930970336 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + - lina@mozilla.com + - ttran@mozilla.com + - najiang@mozilla.com + expires: never + metadata: + tags: + - Search + abandonment: + type: event + description: | + The user dismissed the awesomebar without completing their search. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1878434 + data_reviews: + - https://github.com/mozilla-mobile/firefox-android/pull/5438#issuecomment-1930970336 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + - lina@mozilla.com + - ttran@mozilla.com + - najiang@mozilla.com + expires: never + metadata: + tags: + - Search + android_autofill: supported: type: boolean diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt index 453ff4750a44..6e43803f460b 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt @@ -339,7 +339,6 @@ internal class ReleaseMetricController( Awesomebar.sponsoredSuggestionImpressed.record( Awesomebar.SponsoredSuggestionImpressedExtra( provider = "amp", - engagementAbandoned = engagementAbandoned, ), ) } @@ -347,7 +346,6 @@ internal class ReleaseMetricController( Awesomebar.nonSponsoredSuggestionImpressed.record( Awesomebar.NonSponsoredSuggestionImpressedExtra( provider = "wikipedia", - engagementAbandoned = engagementAbandoned, ), ) } diff --git a/fenix/app/src/main/java/org/mozilla/fenix/telemetry/TelemetryMiddleware.kt b/fenix/app/src/main/java/org/mozilla/fenix/telemetry/TelemetryMiddleware.kt index 3b448bdb42dd..53c1fc8fef9a 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/telemetry/TelemetryMiddleware.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/telemetry/TelemetryMiddleware.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.telemetry import android.content.Context +import mozilla.components.browser.state.action.AwesomeBarAction import mozilla.components.browser.state.action.BrowserAction import mozilla.components.browser.state.action.ContentAction import mozilla.components.browser.state.action.DownloadAction @@ -25,6 +26,7 @@ import mozilla.telemetry.glean.internal.TimerId import mozilla.telemetry.glean.private.NoExtras import org.mozilla.fenix.Config import org.mozilla.fenix.GleanMetrics.Addons +import org.mozilla.fenix.GleanMetrics.Awesomebar import org.mozilla.fenix.GleanMetrics.Events import org.mozilla.fenix.GleanMetrics.Metrics import org.mozilla.fenix.components.metrics.Event @@ -59,7 +61,7 @@ class TelemetryMiddleware( private val logger = Logger("TelemetryMiddleware") - @Suppress("TooGenericExceptionCaught", "ComplexMethod", "NestedBlockDepth") + @Suppress("TooGenericExceptionCaught", "ComplexMethod", "NestedBlockDepth", "LongMethod") override fun invoke( context: MiddlewareContext, next: (BrowserAction) -> Unit, @@ -144,6 +146,13 @@ class TelemetryMiddleware( is ExtensionsProcessAction.DisabledAction -> { Addons.extensionsProcessUiDisable.add() } + is AwesomeBarAction.EngagementFinished -> { + if (action.abandoned) { + Awesomebar.abandonment.record() + } else { + Awesomebar.engagement.record() + } + } else -> { // no-op } From c9739f1c661bef8ef269a9dbfdc885742f9983c9 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 7 Feb 2024 05:33:36 +0000 Subject: [PATCH 109/586] Update A-S to 124.20240207050252. --- .../plugins/dependencies/src/main/java/ApplicationServices.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt index 5eec4af99a60..036f32d9b7e4 100644 --- a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt +++ b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // These lines are generated by android-components/automation/application-services-nightly-bump.py -val VERSION = "124.20240206050329" +val VERSION = "124.20240207050252" val CHANNEL = ApplicationServicesChannel.NIGHTLY object ApplicationServicesConfig { From 8801d0dfc0591df1ebb08423b2369dafb98ea6c3 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 6 Feb 2024 14:32:54 +0200 Subject: [PATCH 110/586] Bug 1878866 - Add missing pairs of logs to AddToHomeScreenRobot --- .../fenix/ui/robots/AddToHomeScreenRobot.kt | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt index 5d1bd8338c15..f42941bbca9f 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt @@ -30,21 +30,25 @@ import java.util.regex.Pattern class AddToHomeScreenRobot { fun verifyAddPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) { + Log.i(TAG, "verifyAddPrivateBrowsingShortcutButton: Trying to verify \"Add to Home screen\" private browsing shortcut dialog button is displayed") composeTestRule.onNodeWithTag("private.add").assertIsDisplayed() Log.i(TAG, "verifyAddPrivateBrowsingShortcutButton: Verified \"Add to Home screen\" private browsing shortcut dialog button is displayed") } fun verifyNoThanksPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) { + Log.i(TAG, "verifyNoThanksPrivateBrowsingShortcutButton: Trying to verify \"No thanks\" private browsing shortcut dialog button is displayed") composeTestRule.onNodeWithTag("private.cancel").assertIsDisplayed() Log.i(TAG, "verifyNoThanksPrivateBrowsingShortcutButton: Verified \"No thanks\" private browsing shortcut dialog button is displayed") } fun clickAddPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) { + Log.i(TAG, "clickAddPrivateBrowsingShortcutButton: Trying to click \"Add to Home screen\" private browsing shortcut dialog button") composeTestRule.onNodeWithTag("private.add").performClick() Log.i(TAG, "clickAddPrivateBrowsingShortcutButton: Clicked \"Add to Home screen\" private browsing shortcut dialog button") } fun addShortcutName(title: String) { + Log.i(TAG, "addShortcutName: Trying to set shortcut name to: $title") shortcutTextField().setText(title) Log.i(TAG, "addShortcutName: Set shortcut name to: $title") } @@ -52,17 +56,20 @@ class AddToHomeScreenRobot { fun verifyShortcutTextFieldTitle(title: String) = assertUIObjectExists(shortcutTitle(title)) fun clickAddShortcutButton() { + Log.i(TAG, "clickAddShortcutButton: Trying to click \"Add\" button from \"Add to home screen\" dialog and wait for $waitingTime ms for a new window") confirmAddToHomeScreenButton().clickAndWaitForNewWindow(waitingTime) - Log.i(TAG, "clickAddShortcutButton: Clicked \"Add\" button from \"Add to home screen\" dialog") + Log.i(TAG, "clickAddShortcutButton: Clicked \"Add\" button from \"Add to home screen\" dialog and waited for $waitingTime ms for a new window") } fun clickCancelShortcutButton() { + Log.i(TAG, "clickCancelShortcutButton: Trying to click \"Cancel\" button from \"Add to home screen\" dialog") cancelAddToHomeScreenButton().click() Log.i(TAG, "clickCancelShortcutButton: Clicked \"Cancel\" button from \"Add to home screen\" dialog") } fun clickAddAutomaticallyButton() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Log.i(TAG, "clickAddAutomaticallyButton: Waiting for $waitingTime ms until finding \"Add automatically\" system dialog button") mDevice.wait( Until.findObject( By.text( @@ -71,7 +78,8 @@ class AddToHomeScreenRobot { ), waitingTime, ) - Log.i(TAG, "clickAddAutomaticallyButton: Waited for \"Add automatically\" system dialog button") + Log.i(TAG, "clickAddAutomaticallyButton: Waited for $waitingTime ms until \"Add automatically\" system dialog button was found") + Log.i(TAG, "clickAddAutomaticallyButton: Trying to click \"Add automatically\" system dialog button") addAutomaticallyButton().click() Log.i(TAG, "clickAddAutomaticallyButton: Clicked \"Add automatically\" system dialog button") } @@ -82,32 +90,37 @@ class AddToHomeScreenRobot { class Transition { fun openHomeScreenShortcut(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "openHomeScreenShortcut: Waiting for $waitingTime ms until finding $title home screen shortcut") mDevice.wait( Until.findObject(By.text(title)), waitingTime, ) - Log.i(TAG, "openHomeScreenShortcut: Waited for $title home screen shortcut") + Log.i(TAG, "openHomeScreenShortcut: Waited for $waitingTime ms until $title home screen shortcut was found") + Log.i(TAG, "openHomeScreenShortcut: Trying to click $title home screen shortcut and wait for $waitingTime ms for a new window") mDevice.findObject((UiSelector().text(title))).clickAndWaitForNewWindow(waitingTime) - Log.i(TAG, "openHomeScreenShortcut: Clicked $title home screen shortcut") + Log.i(TAG, "openHomeScreenShortcut: Clicked $title home screen shortcut and waited for $waitingTime ms for a new window") BrowserRobot().interact() return BrowserRobot.Transition() } fun searchAndOpenHomeScreenShortcut(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "searchAndOpenHomeScreenShortcut: Trying to press device home button") mDevice.pressHome() Log.i(TAG, "searchAndOpenHomeScreenShortcut: Pressed device home button") fun homeScreenView() = UiScrollable(UiSelector().scrollable(true)) + Log.i(TAG, "searchAndOpenHomeScreenShortcut: Waiting for $waitingTime ms for home screen view to exist") homeScreenView().waitForExists(waitingTime) - Log.i(TAG, "searchAndOpenHomeScreenShortcut: Waiting for home screen view") + Log.i(TAG, "searchAndOpenHomeScreenShortcut: Waited for $waitingTime ms for home screen view to exist") fun shortcut() = homeScreenView() .setAsHorizontalList() .getChildByText(UiSelector().textContains(title), title, true) + Log.i(TAG, "searchAndOpenHomeScreenShortcut: Trying to click home screen shortcut: $title and wait for a new window") shortcut().clickAndWaitForNewWindow() - Log.i(TAG, "searchAndOpenHomeScreenShortcut: Clicked home screen shortcut: $title") + Log.i(TAG, "searchAndOpenHomeScreenShortcut: Clicked home screen shortcut: $title and waited for a new window") BrowserRobot().interact() return BrowserRobot.Transition() From cbbe88e2915a5a80398e3c9bc1a828a27dd9320b Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 6 Feb 2024 15:08:59 +0200 Subject: [PATCH 111/586] Bug 1878878 - Add missing pairs of logs to BookmarksRobot --- .../mozilla/fenix/ui/robots/BookmarksRobot.kt | 109 +++++++++++++----- 1 file changed, 81 insertions(+), 28 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt index 0176f326ce15..48b73ced86be 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt @@ -55,11 +55,12 @@ import org.mozilla.fenix.helpers.ext.waitNotNull class BookmarksRobot { fun verifyBookmarksMenuView() { - Log.i(TAG, "verifyBookmarksMenuView: Looking for bookmarks view") + Log.i(TAG, "verifyBookmarksMenuView: Waiting for $waitingTime ms for bookmarks view to exist") mDevice.findObject( UiSelector().text("Bookmarks"), ).waitForExists(waitingTime) - + Log.i(TAG, "verifyBookmarksMenuView: Waited for $waitingTime ms for bookmarks view to exist") + Log.i(TAG, "verifyBookmarksMenuView: Trying to verify bookmarks view is displayed") onView( allOf( withText("Bookmarks"), @@ -70,16 +71,19 @@ class BookmarksRobot { } fun verifyAddFolderButton() { + Log.i(TAG, "verifyAddFolderButton: Trying to verify add bookmarks folder button is visible") addFolderButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) Log.i(TAG, "verifyAddFolderButton: Verified add bookmarks folder button is visible") } fun verifyCloseButton() { + Log.i(TAG, "verifyCloseButton: Trying to verify close bookmarks section button is visible") closeButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) Log.i(TAG, "verifyCloseButton: Verified close bookmarks section button is visible") } fun verifyBookmarkFavicon(forUrl: Uri) { + Log.i(TAG, "verifyBookmarkFavicon: Trying to verify bookmarks favicon for $forUrl is visible") bookmarkFavicon(forUrl.toString()).check( matches( withEffectiveVisibility( @@ -91,41 +95,47 @@ class BookmarksRobot { } fun verifyBookmarkedURL(url: String) { + Log.i(TAG, "verifyBookmarkedURL: Trying to verify bookmarks url: $url is displayed") bookmarkURL(url).check(matches(isDisplayed())) Log.i(TAG, "verifyBookmarkedURL: Verified bookmarks url: $url is displayed") } fun verifyFolderTitle(title: String) { - Log.i(TAG, "verifyFolderTitle: Looking for bookmarks folder with title: $title") + Log.i(TAG, "verifyFolderTitle: Waiting for $waitingTime ms for bookmarks folder with title: $title to exist") mDevice.findObject(UiSelector().text(title)).waitForExists(waitingTime) + Log.i(TAG, "verifyFolderTitle: Waited for $waitingTime ms for bookmarks folder with title: $title to exist") + Log.i(TAG, "verifyFolderTitle: Trying to verify bookmarks folder with title: $title is displayed") onView(withText(title)).check(matches(isDisplayed())) Log.i(TAG, "verifyFolderTitle: Verified bookmarks folder with title: $title is displayed") } fun verifyBookmarkFolderIsNotCreated(title: String) { - Log.i(TAG, "verifyBookmarkFolderIsNotCreated: Looking for bookmarks view") + Log.i(TAG, "verifyBookmarkFolderIsNotCreated: Waiting for $waitingTime ms for bookmarks folder with title: $title to exist") mDevice.findObject( UiSelector() .resourceId("$packageName:id/bookmarks_wrapper"), ).waitForExists(waitingTime) + Log.i(TAG, "verifyBookmarkFolderIsNotCreated: Waited for $waitingTime ms for bookmarks folder with title: $title to exist") assertUIObjectExists(itemContainingText(title), exists = false) } fun verifyBookmarkTitle(title: String) { - Log.i(TAG, "verifyBookmarkTitle: Looking for bookmark with title: $title") + Log.i(TAG, "verifyBookmarkTitle: Waiting for $waitingTime ms for bookmark with title: $title to exist") mDevice.findObject(UiSelector().text(title)).waitForExists(waitingTime) + Log.i(TAG, "verifyBookmarkTitle: Waited for $waitingTime ms for bookmark with title: $title to exist") + Log.i(TAG, "verifyBookmarkTitle: Trying to verify bookmark with title: $title is displayed") onView(withText(title)).check(matches(isDisplayed())) Log.i(TAG, "verifyBookmarkTitle: Verified bookmark with title: $title is displayed") } fun verifyBookmarkIsDeleted(expectedTitle: String) { - Log.i(TAG, "verifyBookmarkIsDeleted: Looking for bookmarks view") + Log.i(TAG, "verifyBookmarkIsDeleted: Waiting for $waitingTime ms for bookmarks view to exist") mDevice.findObject( UiSelector() .resourceId("$packageName:id/bookmarks_wrapper"), ).waitForExists(waitingTime) - + Log.i(TAG, "verifyBookmarkIsDeleted: Waited for $waitingTime ms for bookmarks view to exist") assertUIObjectExists( itemWithResIdContainingText( "$packageName:id/title", @@ -136,16 +146,19 @@ class BookmarksRobot { } fun verifyUndoDeleteSnackBarButton() { + Log.i(TAG, "verifyUndoDeleteSnackBarButton: Trying to verify bookmark deletion undo snack bar button") snackBarUndoButton().check(matches(withText("UNDO"))) Log.i(TAG, "verifyUndoDeleteSnackBarButton: Verified bookmark deletion undo snack bar button") } fun verifySnackBarHidden() { + Log.i(TAG, "verifySnackBarHidden: Waiting until undo snack bar button is gone") mDevice.waitNotNull( Until.gone(By.text("UNDO")), waitingTime, ) - Log.i(TAG, "verifySnackBarHidden: Waited until undo snack bar button is gone") + Log.i(TAG, "verifySnackBarHidden: Waited until undo snack bar button was gone") + Log.i(TAG, "verifySnackBarHidden: Trying to verify bookmark snack bar does not exist") onView(withId(R.id.snackbar_layout)).check(doesNotExist()) Log.i(TAG, "verifySnackBarHidden: Verified bookmark snack bar does not exist") } @@ -162,6 +175,7 @@ class BookmarksRobot { ) fun verifyKeyboardHidden(isExpectedToBeVisible: Boolean) { + Log.i(TAG, "assertKeyboardVisibility: Trying to verify that the keyboard is visible: $isExpectedToBeVisible") assertEquals( isExpectedToBeVisible, mDevice @@ -172,33 +186,38 @@ class BookmarksRobot { } fun verifyShareOverlay() { + Log.i(TAG, "verifyShareOverlay: Trying to verify bookmarks sharing overlay is displayed") onView(withId(R.id.shareWrapper)).check(matches(isDisplayed())) Log.i(TAG, "verifyShareOverlay: Verified bookmarks sharing overlay is displayed") } fun verifyShareBookmarkFavicon() { + Log.i(TAG, "verifyShareBookmarkFavicon: Trying to verify shared bookmarks favicon is displayed") onView(withId(R.id.share_tab_favicon)).check(matches(isDisplayed())) Log.i(TAG, "verifyShareBookmarkFavicon: Verified shared bookmarks favicon is displayed") } fun verifyShareBookmarkTitle() { + Log.i(TAG, "verifyShareBookmarkTitle: Trying to verify shared bookmarks title is displayed") onView(withId(R.id.share_tab_title)).check(matches(isDisplayed())) Log.i(TAG, "verifyShareBookmarkTitle: Verified shared bookmarks title is displayed") } fun verifyShareBookmarkUrl() { + Log.i(TAG, "verifyShareBookmarkUrl: Trying to verify shared bookmarks url is displayed") onView(withId(R.id.share_tab_url)).check(matches(isDisplayed())) Log.i(TAG, "verifyShareBookmarkUrl: Verified shared bookmarks url is displayed") } fun verifyCurrentFolderTitle(title: String) { - Log.i(TAG, "verifyCurrentFolderTitle: Looking for bookmark with title: $title") + Log.i(TAG, "verifyCurrentFolderTitle: Waiting for $waitingTime ms for bookmark with title: $title to exist") mDevice.findObject( UiSelector().resourceId("$packageName:id/navigationToolbar") .textContains(title), ) .waitForExists(waitingTime) - + Log.i(TAG, "verifyCurrentFolderTitle: Waited for $waitingTime ms for bookmark with title: $title to exist") + Log.i(TAG, "verifyCurrentFolderTitle: Trying to verify bookmark with title: $title is displayed") onView( allOf( withText(title), @@ -210,22 +229,25 @@ class BookmarksRobot { } fun waitForBookmarksFolderContentToExist(parentFolderName: String, childFolderName: String) { - Log.i(TAG, "waitForBookmarksFolderContentToExist: Looking for navigation toolbar containing bookmark folder with title: $parentFolderName") + Log.i(TAG, "waitForBookmarksFolderContentToExist: Waiting for $waitingTime ms for navigation toolbar containing bookmark folder with title: $parentFolderName to exist") mDevice.findObject( UiSelector().resourceId("$packageName:id/navigationToolbar") .textContains(parentFolderName), ) .waitForExists(waitingTime) + Log.i(TAG, "waitForBookmarksFolderContentToExist: Waited for $waitingTime ms for navigation toolbar containing bookmark folder with title: $parentFolderName to exist") mDevice.waitNotNull(Until.findObject(By.text(childFolderName)), waitingTime) } fun verifySyncSignInButton() { + Log.i(TAG, "verifySyncSignInButton: Trying to verify sign in to sync button is visible") syncSignInButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) Log.i(TAG, "verifySyncSignInButton: Verified sign in to sync button is visible") } fun cancelFolderDeletion() { + Log.i(TAG, "cancelFolderDeletion: Trying to click \"Cancel\" bookmarks folder deletion dialog button") onView(withText("CANCEL")) .inRoot(RootMatchers.isDialog()) .check(matches(isDisplayed())) @@ -253,6 +275,7 @@ class BookmarksRobot { Until.findObject(By.desc("Add folder")), waitingTime, ) + Log.i(TAG, "clickAddFolderButton: Trying to click add bookmarks folder button") addFolderButton().click() Log.i(TAG, "clickAddFolderButton: Clicked add bookmarks folder button") } @@ -260,79 +283,99 @@ class BookmarksRobot { fun clickAddNewFolderButtonFromSelectFolderView() { itemWithResId("$packageName:id/add_folder_button") .also { + Log.i(TAG, "clickAddNewFolderButtonFromSelectFolderView: Waiting for $waitingTime ms for add bookmarks folder button from folder selection view to exist") it.waitForExists(waitingTime) + Log.i(TAG, "clickAddNewFolderButtonFromSelectFolderView: Waited for $waitingTime ms for add bookmarks folder button from folder selection view to exist") + Log.i(TAG, "clickAddNewFolderButtonFromSelectFolderView: Trying to click add bookmarks folder button from folder selection view") it.click() + Log.i(TAG, "clickAddNewFolderButtonFromSelectFolderView: Clicked add bookmarks folder button from folder selection view") } - Log.i(TAG, "clickAddNewFolderButtonFromSelectFolderView: Clicked add bookmarks folder button from folder selection view") } fun addNewFolderName(name: String) { - addFolderTitleField() - .click() - .perform(replaceText(name)) + Log.i(TAG, "addNewFolderName: Trying to click add folder name field") + addFolderTitleField().click() + Log.i(TAG, "addNewFolderName: Clicked to click add folder name field") + Log.i(TAG, "addNewFolderName: Trying to set bookmarks folder name to: $name") + addFolderTitleField().perform(replaceText(name)) Log.i(TAG, "addNewFolderName: Bookmarks folder name was set to: $name") } fun saveNewFolder() { + Log.i(TAG, "saveNewFolder: Trying to click save folder button") saveFolderButton().click() Log.i(TAG, "saveNewFolder: Clicked save folder button") } fun navigateUp() { + Log.i(TAG, "navigateUp: Trying to click navigate up toolbar button") goBackButton().click() Log.i(TAG, "navigateUp: Clicked navigate up toolbar button") } fun clickUndoDeleteButton() { + Log.i(TAG, "clickUndoDeleteButton: Trying to click undo snack bar button") snackBarUndoButton().click() Log.i(TAG, "clickUndoDeleteButton: Clicked undo snack bar button") } fun changeBookmarkTitle(newTitle: String) { - bookmarkNameEditBox() - .perform(clearText()) - .perform(typeText(newTitle)) + Log.i(TAG, "changeBookmarkTitle: Trying to clear bookmark name text box") + bookmarkNameEditBox().perform(clearText()) + Log.i(TAG, "changeBookmarkTitle: Cleared bookmark name text box") + Log.i(TAG, "changeBookmarkTitle: Trying to set bookmark title to: $newTitle") + bookmarkNameEditBox().perform(typeText(newTitle)) Log.i(TAG, "changeBookmarkTitle: Bookmark title was set to: $newTitle") } fun changeBookmarkUrl(newUrl: String) { - bookmarkURLEditBox() - .perform(clearText()) - .perform(typeText(newUrl)) + Log.i(TAG, "changeBookmarkUrl: Trying to clear bookmark url text box") + bookmarkURLEditBox().perform(clearText()) + Log.i(TAG, "changeBookmarkUrl: Cleared bookmark url text box") + Log.i(TAG, "changeBookmarkUrl: Trying to set bookmark url to: $newUrl") + bookmarkURLEditBox().perform(typeText(newUrl)) Log.i(TAG, "changeBookmarkUrl: Bookmark url was set to: $newUrl") } fun saveEditBookmark() { + Log.i(TAG, "saveEditBookmark: Trying to click save bookmark button") saveBookmarkButton().click() Log.i(TAG, "saveEditBookmark: Clicked save bookmark button") - Log.i(TAG, "saveEditBookmark: Looking for bookmarks list") + Log.i(TAG, "saveEditBookmark: Waiting for $waitingTime ms for bookmarks list to exist") mDevice.findObject(UiSelector().resourceId("org.mozilla.fenix.debug:id/bookmark_list")).waitForExists(waitingTime) + Log.i(TAG, "saveEditBookmark: Waited for $waitingTime ms for bookmarks list to exist") } fun clickParentFolderSelector() { + Log.i(TAG, "clickParentFolderSelector: Trying to click folder selector") bookmarkFolderSelector().click() Log.i(TAG, "clickParentFolderSelector: Clicked folder selector") } fun selectFolder(title: String) { + Log.i(TAG, "selectFolder: Trying to click folder with title: $title") onView(withText(title)).click() - Log.i(TAG, "selectFolder: Selected folder: $title") + Log.i(TAG, "selectFolder: Clicked folder with title: $title") } fun longTapDesktopFolder(title: String) { + Log.i(TAG, "longTapDesktopFolder: Trying to long tap folder with title: $title") onView(withText(title)).perform(longClick()) - Log.i(TAG, "longTapDesktopFolder: Log tapped folder with title: $title") + Log.i(TAG, "longTapDesktopFolder: Long tapped folder with title: $title") } fun cancelDeletion() { val cancelButton = mDevice.findObject(UiSelector().textContains("CANCEL")) - Log.i(TAG, "saveEditBookmark: Looking for \"Cancel\" bookmarks deletion button") + Log.i(TAG, "cancelDeletion: Waiting for $waitingTime ms for \"Cancel\" bookmarks deletion button to exist") cancelButton.waitForExists(waitingTime) + Log.i(TAG, "cancelDeletion: Waited for $waitingTime ms for \"Cancel\" bookmarks deletion button to exist") + Log.i(TAG, "cancelDeletion: Trying to click \"Cancel\" bookmarks deletion button") cancelButton.click() - Log.i(TAG, "saveEditBookmark: Clicked \"Cancel\" bookmarks deletion button") + Log.i(TAG, "cancelDeletion: Clicked \"Cancel\" bookmarks deletion button") } fun confirmDeletion() { + Log.i(TAG, "confirmDeletion: Trying to click \"Delete\" bookmarks deletion button") onView(withText(R.string.delete_browsing_data_prompt_allow)) .inRoot(RootMatchers.isDialog()) .check(matches(isDisplayed())) @@ -341,12 +384,14 @@ class BookmarksRobot { } fun clickDeleteInEditModeButton() { + Log.i(TAG, "clickDeleteInEditModeButton: Trying to click delete bookmarks button while in edit mode") deleteInEditModeButton().click() Log.i(TAG, "clickDeleteInEditModeButton: Clicked delete bookmarks button while in edit mode") } class Transition { fun closeMenu(interact: HomeScreenRobot.() -> Unit): Transition { + Log.i(TAG, "closeMenu: Trying to click close bookmarks section button") closeButton().click() Log.i(TAG, "closeMenu: Clicked close bookmarks section button") @@ -356,6 +401,7 @@ class BookmarksRobot { fun openThreeDotMenu(bookmark: String, interact: ThreeDotMenuBookmarksRobot.() -> Unit): ThreeDotMenuBookmarksRobot.Transition { mDevice.waitNotNull(Until.findObject(res("$packageName:id/overflow_menu"))) + Log.i(TAG, "openThreeDotMenu: Trying to click three dot button for bookmark item: $bookmark") threeDotMenu(bookmark).click() Log.i(TAG, "openThreeDotMenu: Clicked three dot button for bookmark item: $bookmark") @@ -364,6 +410,7 @@ class BookmarksRobot { } fun clickSingInToSyncButton(interact: SettingsTurnOnSyncRobot.() -> Unit): SettingsTurnOnSyncRobot.Transition { + Log.i(TAG, "clickSingInToSyncButton: Trying to click sign in to sync button") syncSignInButton().click() Log.i(TAG, "clickSingInToSyncButton: Clicked sign in to sync button") @@ -372,6 +419,7 @@ class BookmarksRobot { } fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + Log.i(TAG, "goBack: Trying to click go back button") goBackButton().click() Log.i(TAG, "goBack: Clicked go back button") @@ -380,6 +428,7 @@ class BookmarksRobot { } fun goBackToBrowserScreen(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "goBackToBrowserScreen: Trying to click go back button") goBackButton().click() Log.i(TAG, "goBackToBrowserScreen: Clicked go back button") @@ -388,6 +437,7 @@ class BookmarksRobot { } fun closeEditBookmarkSection(interact: BookmarksRobot.() -> Unit): Transition { + Log.i(TAG, "goBackToBrowserScreen: Trying to click go back button") goBackButton().click() Log.i(TAG, "goBackToBrowserScreen: Clicked go back button") @@ -396,19 +446,22 @@ class BookmarksRobot { } fun openBookmarkWithTitle(bookmarkTitle: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "openBookmarkWithTitle: Looking for bookmark with title: $bookmarkTitle") itemWithResIdAndText("$packageName:id/title", bookmarkTitle) .also { + Log.i(TAG, "openBookmarkWithTitle: Waiting for $waitingTime ms for bookmark with title: $bookmarkTitle") it.waitForExists(waitingTime) + Log.i(TAG, "openBookmarkWithTitle: Waited for $waitingTime ms for bookmark with title: $bookmarkTitle") + Log.i(TAG, "openBookmarkWithTitle: Trying to click bookmark with title: $bookmarkTitle and wait for $waitingTimeShort ms for a new window") it.clickAndWaitForNewWindow(waitingTimeShort) + Log.i(TAG, "openBookmarkWithTitle: Clicked bookmark with title: $bookmarkTitle and waited for $waitingTimeShort ms for a new window") } - Log.i(TAG, "openBookmarkWithTitle: Clicked bookmark with title: $bookmarkTitle") BrowserRobot().interact() return BrowserRobot.Transition() } fun clickSearchButton(interact: SearchRobot.() -> Unit): SearchRobot.Transition { + Log.i(TAG, "clickSearchButton: Trying to click search bookmarks button") itemWithResId("$packageName:id/bookmark_search").click() Log.i(TAG, "clickSearchButton: Clicked search bookmarks button") From 08c308a6fbfc4c242a624c4223f7187fe756c148 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 6 Feb 2024 17:52:27 +0200 Subject: [PATCH 112/586] Bug 1879027 - Add missing pairs of logs to CollectionRobot --- .../fenix/ui/robots/CollectionRobot.kt | 81 ++++++++++++++----- 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt index 94626a88e5c8..1dc74bb38a1f 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt @@ -48,6 +48,7 @@ class CollectionRobot { ) fun clickAddNewCollection() { + Log.i(TAG, "clickAddNewCollection: Trying to click the add new collection button") addNewCollectionButton().click() Log.i(TAG, "clickAddNewCollection: Clicked the add new collection button") } @@ -56,25 +57,33 @@ class CollectionRobot { // names a collection saved from tab drawer fun typeCollectionNameAndSave(collectionName: String) { + Log.i(TAG, "typeCollectionNameAndSave: Trying to set collection name text field to: $collectionName") collectionNameTextField().text = collectionName Log.i(TAG, "typeCollectionNameAndSave: Collection name text field set to: $collectionName") + Log.i(TAG, "typeCollectionNameAndSave: Waiting for $waitingTime ms for add collection button panel to exist") addCollectionButtonPanel().waitForExists(waitingTime) + Log.i(TAG, "typeCollectionNameAndSave: Waited for $waitingTime ms for add collection button panel to exist") + Log.i(TAG, "typeCollectionNameAndSave: Trying to click \"OK\" panel button") addCollectionOkButton().click() Log.i(TAG, "typeCollectionNameAndSave: Clicked \"OK\" panel button") } fun verifyTabsSelectedCounterText(numOfTabs: Int) { - Log.i(TAG, "verifyTabsSelectedCounterText: Waiting for \"Select tabs to save\" prompt to be gone") + Log.i(TAG, "verifyTabsSelectedCounterText: Waiting for $waitingTime ms for \"Select tabs to save\" prompt to be gone") itemWithText("Select tabs to save").waitUntilGone(waitingTime) + Log.i(TAG, "verifyTabsSelectedCounterText: Waited for $waitingTime ms for \"Select tabs to save\" prompt to be gone") val tabsCounter = mDevice.findObject(UiSelector().resourceId("$packageName:id/bottom_bar_text")) + Log.i(TAG, "verifyTabsSelectedCounterText: Trying to assert that number of tabs selected is: $numOfTabs") when (numOfTabs) { 1 -> assertItemTextEquals(tabsCounter, expectedText = "$numOfTabs tab selected") 2 -> assertItemTextEquals(tabsCounter, expectedText = "$numOfTabs tabs selected") } + Log.i(TAG, "verifyTabsSelectedCounterText: Asserted number of tabs selected is: $numOfTabs") } fun saveTabsSelectedForCollection() { + Log.i(TAG, "saveTabsSelectedForCollection: Trying to click \"Save\" button") itemWithResId("$packageName:id/save_button").click() Log.i(TAG, "saveTabsSelectedForCollection: Clicked \"Save\" button") } @@ -96,11 +105,14 @@ class CollectionRobot { fun verifyCollectionMenuIsVisible(visible: Boolean, rule: ComposeTestRule) { if (visible) { - collectionThreeDotButton(rule) - .assertExists() - .assertIsDisplayed() + Log.i(TAG, "verifyCollectionMenuIsVisible: Trying to verify collection three dot button exists") + collectionThreeDotButton(rule).assertExists() Log.i(TAG, "verifyCollectionMenuIsVisible: Verified collection three dot button exists") + Log.i(TAG, "verifyCollectionMenuIsVisible: Trying to verify collection three dot button is displayed") + collectionThreeDotButton(rule).assertIsDisplayed() + Log.i(TAG, "verifyCollectionMenuIsVisible: Verified collection three dot button is displayed") } else { + Log.i(TAG, "verifyCollectionMenuIsVisible: Trying to verify collection three dot button does not exist") collectionThreeDotButton(rule) .assertDoesNotExist() Log.i(TAG, "verifyCollectionMenuIsVisible: Verified collection three dot button does not exist") @@ -108,40 +120,52 @@ class CollectionRobot { } fun clickCollectionThreeDotButton(rule: ComposeTestRule) { - collectionThreeDotButton(rule) - .assertIsDisplayed() - .performClick() + Log.i(TAG, "clickCollectionThreeDotButton: Trying to verify three dot button is displayed") + collectionThreeDotButton(rule).assertIsDisplayed() + Log.i(TAG, "clickCollectionThreeDotButton: Verified three dot button is displayed") + Log.i(TAG, "clickCollectionThreeDotButton: Trying to click three dot button") + collectionThreeDotButton(rule).performClick() Log.i(TAG, "clickCollectionThreeDotButton: Clicked three dot button") } fun selectOpenTabs(rule: ComposeTestRule) { - rule.onNode(hasText("Open tabs")) - .assertIsDisplayed() - .performClick() + Log.i(TAG, "selectOpenTabs: Trying to verify \"Open tabs\" menu option is displayed") + rule.onNode(hasText("Open tabs")).assertIsDisplayed() + Log.i(TAG, "selectOpenTabs: Verified \"Open tabs\" menu option is displayed") + Log.i(TAG, "selectOpenTabs: Trying to click \"Open tabs\" menu option") + rule.onNode(hasText("Open tabs")).performClick() Log.i(TAG, "selectOpenTabs: Clicked \"Open tabs\" menu option") } fun selectRenameCollection(rule: ComposeTestRule) { - rule.onNode(hasText("Rename collection")) - .assertIsDisplayed() - .performClick() + Log.i(TAG, "selectRenameCollection: Trying to verify \"Rename collection\" menu option is displayed") + rule.onNode(hasText("Rename collection")).assertIsDisplayed() + Log.i(TAG, "selectRenameCollection: Verified \"Rename collection\" menu option is displayed") + Log.i(TAG, "selectRenameCollection: Trying to click \"Rename collection\" menu option") + rule.onNode(hasText("Rename collection")).performClick() Log.i(TAG, "selectRenameCollection: Clicked \"Rename collection\" menu option") + Log.i(TAG, "selectRenameCollection: Waiting for $waitingTime ms for collection name text field to exist") mainMenuEditCollectionNameField().waitForExists(waitingTime) + Log.i(TAG, "selectRenameCollection: Waited for $waitingTime ms for collection name text field to exist") } fun selectAddTabToCollection(rule: ComposeTestRule) { - rule.onNode(hasText("Add tab")) - .assertIsDisplayed() - .performClick() + Log.i(TAG, "selectAddTabToCollection: Trying to verify \"Add tab\" menu option is displayed") + rule.onNode(hasText("Add tab")).assertIsDisplayed() + Log.i(TAG, "selectAddTabToCollection: Verified \"Add tab\" menu option is displayed") + Log.i(TAG, "selectAddTabToCollection: Trying to click \"Add tab\" menu option") + rule.onNode(hasText("Add tab")).performClick() Log.i(TAG, "selectAddTabToCollection: Clicked \"Add tab\" menu option") mDevice.waitNotNull(Until.findObject(By.text("Select Tabs"))) } fun selectDeleteCollection(rule: ComposeTestRule) { - rule.onNode(hasText("Delete collection")) - .assertIsDisplayed() - .performClick() + Log.i(TAG, "selectDeleteCollection: Trying to verify \"Delete collection\" menu option is displayed") + rule.onNode(hasText("Delete collection")).assertIsDisplayed() + Log.i(TAG, "selectDeleteCollection: Verified \"Delete collection\" menu option is displayed") + Log.i(TAG, "selectDeleteCollection: Trying to click \"Delete collection\" menu option") + rule.onNode(hasText("Delete collection")).performClick() Log.i(TAG, "selectDeleteCollection: Clicked \"Delete collection\" menu option") } @@ -149,27 +173,33 @@ class CollectionRobot { assertUIObjectExists(removeTabFromCollectionButton(title), exists = visible) fun removeTabFromCollection(title: String) { + Log.i(TAG, "removeTabFromCollection: Trying to click remove button for tab: $title") removeTabFromCollectionButton(title).click() Log.i(TAG, "removeTabFromCollection: Clicked remove button for tab: $title") } fun swipeTabLeft(title: String, rule: ComposeTestRule) { + Log.i(TAG, "swipeTabLeft: Trying to remove tab: $title using swipe left action") rule.onNode(hasText(title), useUnmergedTree = true) .performTouchInput { swipeLeft() } Log.i(TAG, "swipeTabLeft: Removed tab: $title using swipe left action") + Log.i(TAG, "swipeTabLeft: Waiting for rule to be idle") rule.waitForIdle() Log.i(TAG, "swipeTabLeft: Waited for rule to be idle") } fun swipeTabRight(title: String, rule: ComposeTestRule) { + Log.i(TAG, "swipeTabRight: Trying to remove tab: $title using swipe right action") rule.onNode(hasText(title), useUnmergedTree = true) .performTouchInput { swipeRight() } Log.i(TAG, "swipeTabRight: Removed tab: $title using swipe right action") + Log.i(TAG, "swipeTabRight: Waiting for rule to be idle") rule.waitForIdle() Log.i(TAG, "swipeTabRight: Waited for rule to be idle") } fun goBackInCollectionFlow() { + Log.i(TAG, "goBackInCollectionFlow: Trying to click collection creation flow back button") backButton().click() Log.i(TAG, "goBackInCollectionFlow: Clicked collection creation flow back button") } @@ -180,8 +210,9 @@ class CollectionRobot { interact: HomeScreenRobot.() -> Unit, ): HomeScreenRobot.Transition { assertUIObjectExists(itemContainingText(title)) + Log.i(TAG, "collapseCollection: Trying to click collection $title and wait for $waitingTimeShort ms for a new window") itemContainingText(title).clickAndWaitForNewWindow(waitingTimeShort) - Log.i(TAG, "collapseCollection: Clicked collection $title") + Log.i(TAG, "collapseCollection: Clicked collection $title and waited for $waitingTimeShort ms for a new window") assertUIObjectExists(itemWithDescription(getStringResource(R.string.remove_tab_from_collection)), exists = false) HomeScreenRobot().interact() @@ -193,9 +224,13 @@ class CollectionRobot { name: String, interact: BrowserRobot.() -> Unit, ): BrowserRobot.Transition { + Log.i(TAG, "typeCollectionNameAndSave: Waiting for $waitingTime ms for collection name text field to exist") mainMenuEditCollectionNameField().waitForExists(waitingTime) + Log.i(TAG, "typeCollectionNameAndSave: Waited for $waitingTime ms for collection name text field to exist") + Log.i(TAG, "typeCollectionNameAndSave: Trying to set collection name text field to: $name") mainMenuEditCollectionNameField().text = name Log.i(TAG, "typeCollectionNameAndSave: Collection name text field set to: $name") + Log.i(TAG, "typeCollectionNameAndSave: Trying to press done action button") onView(withId(R.id.name_collection_edittext)).perform(pressImeActionButton()) Log.i(TAG, "typeCollectionNameAndSave: Pressed done action button") @@ -210,7 +245,10 @@ class CollectionRobot { title: String, interact: BrowserRobot.() -> Unit, ): BrowserRobot.Transition { + Log.i(TAG, "selectExistingCollection: Waiting for $waitingTime ms for collection with title: $title to exist") collectionTitle(title).waitForExists(waitingTime) + Log.i(TAG, "selectExistingCollection: Waited for $waitingTime ms for collection with title: $title to exist") + Log.i(TAG, "selectExistingCollection: Trying to click collection with title: $title") collectionTitle(title).click() Log.i(TAG, "selectExistingCollection: Clicked collection with title: $title") @@ -219,7 +257,10 @@ class CollectionRobot { } fun clickShareCollectionButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { + Log.i(TAG, "clickShareCollectionButton: Waiting for $waitingTime ms for share collection button to exist") shareCollectionButton().waitForExists(waitingTime) + Log.i(TAG, "clickShareCollectionButton: Waited for $waitingTime ms for share collection button to exist") + Log.i(TAG, "clickShareCollectionButton: Trying to click share collection button") shareCollectionButton().click() Log.i(TAG, "clickShareCollectionButton: Clicked share collection button") From 625fee0944075d2675190a7c55219eab96627c13 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Mon, 5 Feb 2024 12:20:42 +0200 Subject: [PATCH 113/586] Bug 1879072 - Remove redundant assertion functions from HomeScreenRobot --- .../fenix/ui/robots/HomeScreenRobot.kt | 212 +++++++----------- 1 file changed, 85 insertions(+), 127 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt index 5c7bfd4cb859..71cff2971add 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt @@ -104,14 +104,27 @@ class HomeScreenRobot { fun verifyHomePrivateBrowsingButton() = assertUIObjectExists(privateBrowsingButton()) fun verifyHomeMenuButton() = assertUIObjectExists(menuButton) - fun verifyTabButton() = assertTabButton() - fun verifyCollectionsHeader() = assertCollectionsHeader() - fun verifyNoCollectionsText() = assertNoCollectionsText() + fun verifyTabButton() = + onView(allOf(withId(R.id.tab_button), isDisplayed())).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + fun verifyCollectionsHeader() = + onView(allOf(withText("Collections"))).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + fun verifyNoCollectionsText() = + onView( + withText( + containsString( + "Collect the things that matter to you.\n" + + "Group together similar searches, sites, and tabs for quick access later.", + ), + ), + ).check(matches(isDisplayed())) + fun verifyHomeWordmark() { homeScreenList().scrollToBeginning(3) assertUIObjectExists(homepageWordmark()) } - fun verifyHomeComponent() = assertHomeComponent() + fun verifyHomeComponent() = + onView(ViewMatchers.withResourceName("sessionControlRecyclerView")) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) fun verifyTabCounter(numberOfOpenTabs: String) = assertUIObjectExists(tabCounter(numberOfOpenTabs)) @@ -218,7 +231,16 @@ class HomeScreenRobot { fun verifyExistingTopSitesList() = assertUIObjectExists(itemWithResId("$packageName:id/top_sites_list")) - fun verifyNotExistingTopSitesList(title: String) = assertNotExistingTopSitesList(title) + fun verifyNotExistingTopSitesList(title: String) { + mDevice.findObject(UiSelector().text(title)).waitUntilGone(waitingTime) + assertUIObjectExists( + itemWithResIdContainingText( + "$packageName:id/top_site_title", + title, + ), + exists = false, + ) + } fun verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle: String, position: Int) = assertUIObjectExists( itemWithResIdAndIndex("$packageName:id/top_site_item", index = position - 1) @@ -228,17 +250,60 @@ class HomeScreenRobot { ), exists = false, ) - fun verifyNotExistingSponsoredTopSitesList() = assertSponsoredTopSitesNotDisplayed() + fun verifyNotExistingSponsoredTopSitesList() = + assertUIObjectExists( + itemWithResIdContainingText( + "$packageName:id/top_site_subtitle", + getStringResource(R.string.top_sites_sponsored_label), + ), + exists = false, + ) + fun verifyExistingTopSitesTabs(title: String) { homeScreenList().scrollIntoView(itemWithResId("$packageName:id/top_sites_list")) - assertExistingTopSitesTabs(title) + mDevice.findObject( + UiSelector() + .resourceId("$packageName:id/top_site_title") + .textContains(title), + ).waitForExists(waitingTime) + + onView(allOf(withId(R.id.top_sites_list))) + .check(matches(hasDescendant(withText(title)))) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) } fun verifySponsoredShortcutDetails(sponsoredShortcutTitle: String, position: Int) { - assertSponsoredShortcutLogoIsDisplayed(position) - assertSponsoredShortcutTitle(sponsoredShortcutTitle, position) - assertSponsoredSubtitleIsDisplayed(position) + assertUIObjectExists( + itemWithResIdAndIndex(resourceId = "$packageName:id/top_site_item", index = position - 1) + .getChild( + UiSelector() + .resourceId("$packageName:id/favicon_card"), + ), + ) + assertUIObjectExists( + itemWithResIdAndIndex(resourceId = "$packageName:id/top_site_item", index = position - 1) + .getChild( + UiSelector() + .textContains(sponsoredShortcutTitle), + ), + ) + assertUIObjectExists( + itemWithResIdAndIndex(resourceId = "$packageName:id/top_site_item", index = position - 1) + .getChild( + UiSelector() + .resourceId("$packageName:id/top_site_subtitle"), + ), + ) + } + fun verifyTopSiteContextMenuItems() { + mDevice.waitNotNull( + findObject(By.text("Open in private tab")), + waitingTime, + ) + mDevice.waitNotNull( + findObject(By.text("Remove")), + waitingTime, + ) } - fun verifyTopSiteContextMenuItems() = assertTopSiteContextMenuItems() fun verifyJumpBackInSectionIsDisplayed() { scrollToElementByText(getStringResource(R.string.recent_tabs_header)) @@ -247,13 +312,16 @@ class HomeScreenRobot { fun verifyJumpBackInSectionIsNotDisplayed() = assertUIObjectExists(itemContainingText(getStringResource(R.string.recent_tabs_header)), exists = false) fun verifyJumpBackInItemTitle(testRule: ComposeTestRule, itemTitle: String) = - assertJumpBackInItemTitle(testRule, itemTitle) + testRule.onNodeWithTag("recent.tab.title", useUnmergedTree = true).assert(hasText(itemTitle)) fun verifyJumpBackInItemWithUrl(testRule: ComposeTestRule, itemUrl: String) = - assertJumpBackInItemWithUrl(testRule, itemUrl) - fun verifyJumpBackInShowAllButton() = assertJumpBackInShowAllButton() - fun verifyRecentlyVisitedSectionIsDisplayed(exists: Boolean) = assertRecentlyVisitedSectionIsDisplayed(exists) - fun verifyRecentBookmarksSectionIsDisplayed(exists: Boolean) = assertRecentBookmarksSectionIsDisplayed(exists) - fun verifyPocketSectionIsDisplayed(exists: Boolean) = assertPocketSectionIsDisplayed(exists) + testRule.onNodeWithTag("recent.tab.url", useUnmergedTree = true).assert(hasText(itemUrl)) + fun verifyJumpBackInShowAllButton() = assertUIObjectExists(itemContainingText(getStringResource(R.string.recent_tabs_show_all))) + fun verifyRecentlyVisitedSectionIsDisplayed(exists: Boolean) = + assertUIObjectExists(itemContainingText(getStringResource(R.string.history_metadata_header_2)), exists = exists) + fun verifyRecentBookmarksSectionIsDisplayed(exists: Boolean) = + assertUIObjectExists(itemContainingText(getStringResource(R.string.recently_saved_title)), exists = exists) + fun verifyPocketSectionIsDisplayed(exists: Boolean) = + assertUIObjectExists(itemContainingText(getStringResource(R.string.pocket_stories_header_1)), exists = exists) fun verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed: Boolean, searchTerm: String, groupSize: Int) { // checks if the search group exists in the Recently visited section @@ -820,118 +888,8 @@ private fun assertKeyboardVisibility(isExpectedToBeVisible: Boolean) = .contains("mInputShown=true"), ) -private fun assertTabButton() = - onView(allOf(withId(R.id.tab_button), isDisplayed())) - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - -private fun assertCollectionsHeader() = - onView(allOf(withText("Collections"))) - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - -private fun assertNoCollectionsText() = - onView( - withText( - containsString( - "Collect the things that matter to you.\n" + - "Group together similar searches, sites, and tabs for quick access later.", - ), - ), - ).check(matches(isDisplayed())) - -private fun assertHomeComponent() = - onView(ViewMatchers.withResourceName("sessionControlRecyclerView")) - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - private fun threeDotButton() = onView(allOf(withId(R.id.menuButton))) -private fun assertExistingTopSitesTabs(title: String) { - mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/top_site_title") - .textContains(title), - ).waitForExists(waitingTime) - - onView(allOf(withId(R.id.top_sites_list))) - .check(matches(hasDescendant(withText(title)))) - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) -} - -private fun assertSponsoredShortcutLogoIsDisplayed(position: Int) = - assertUIObjectExists( - itemWithResIdAndIndex(resourceId = "$packageName:id/top_site_item", index = position - 1) - .getChild( - UiSelector() - .resourceId("$packageName:id/favicon_card"), - ), - ) - -private fun assertSponsoredSubtitleIsDisplayed(position: Int) = - assertUIObjectExists( - itemWithResIdAndIndex(resourceId = "$packageName:id/top_site_item", index = position - 1) - .getChild( - UiSelector() - .resourceId("$packageName:id/top_site_subtitle"), - ), - ) - -private fun assertSponsoredShortcutTitle(sponsoredShortcutTitle: String, position: Int) = - assertUIObjectExists( - itemWithResIdAndIndex(resourceId = "$packageName:id/top_site_item", index = position - 1) - .getChild( - UiSelector() - .textContains(sponsoredShortcutTitle), - ), - ) - -private fun assertNotExistingTopSitesList(title: String) { - mDevice.findObject(UiSelector().text(title)).waitUntilGone(waitingTime) - assertUIObjectExists( - itemWithResIdContainingText( - "$packageName:id/top_site_title", - title, - ), - exists = false, - ) -} - -private fun assertSponsoredTopSitesNotDisplayed() = - assertUIObjectExists( - itemWithResIdContainingText( - "$packageName:id/top_site_subtitle", - getStringResource(R.string.top_sites_sponsored_label), - ), - exists = false, - ) - -private fun assertTopSiteContextMenuItems() { - mDevice.waitNotNull( - findObject(By.text("Open in private tab")), - waitingTime, - ) - mDevice.waitNotNull( - findObject(By.text("Remove")), - waitingTime, - ) -} - -private fun assertJumpBackInItemTitle(testRule: ComposeTestRule, itemTitle: String) = - testRule.onNodeWithTag("recent.tab.title", useUnmergedTree = true).assert(hasText(itemTitle)) - -private fun assertJumpBackInItemWithUrl(testRule: ComposeTestRule, itemUrl: String) = - testRule.onNodeWithTag("recent.tab.url", useUnmergedTree = true).assert(hasText(itemUrl)) - -private fun assertJumpBackInShowAllButton() = - assertUIObjectExists(itemContainingText(getStringResource(R.string.recent_tabs_show_all))) - -private fun assertRecentlyVisitedSectionIsDisplayed(exists: Boolean) = - assertUIObjectExists(itemContainingText(getStringResource(R.string.history_metadata_header_2)), exists = exists) - -private fun assertRecentBookmarksSectionIsDisplayed(exists: Boolean) = - assertUIObjectExists(itemContainingText(getStringResource(R.string.recently_saved_title)), exists = exists) - -private fun assertPocketSectionIsDisplayed(exists: Boolean) = - assertUIObjectExists(itemContainingText(getStringResource(R.string.pocket_stories_header_1)), exists = exists) - private fun saveTabsToCollectionButton() = onView(withId(R.id.add_tabs_to_collections_button)) private fun tabsCounter() = onView(withId(R.id.tab_button)) From 3136eebb099a6439979a620d00f20758ca77b85d Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Mon, 5 Feb 2024 12:40:15 +0200 Subject: [PATCH 114/586] Bug 1879072 - Remove unused functions from HomeScreenRobot --- .../fenix/ui/robots/HomeScreenRobot.kt | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt index 71cff2971add..3364da18dd82 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt @@ -48,7 +48,6 @@ import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.containsString import org.hamcrest.CoreMatchers.instanceOf import org.hamcrest.Matchers -import org.junit.Assert import org.junit.Assert.assertTrue import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants.LISTS_MAXSWIPES @@ -99,9 +98,6 @@ class HomeScreenRobot { fun verifyHomeScreenAppBarItems() = assertUIObjectExists(homeScreen(), privateBrowsingButton(), homepageWordmark()) - fun verifyNavigationToolbarItems(numberOfOpenTabs: String = "0") = - assertUIObjectExists(navigationToolbar(), menuButton, tabCounter(numberOfOpenTabs)) - fun verifyHomePrivateBrowsingButton() = assertUIObjectExists(privateBrowsingButton()) fun verifyHomeMenuButton() = assertUIObjectExists(menuButton) fun verifyTabButton() = @@ -320,8 +316,6 @@ class HomeScreenRobot { assertUIObjectExists(itemContainingText(getStringResource(R.string.history_metadata_header_2)), exists = exists) fun verifyRecentBookmarksSectionIsDisplayed(exists: Boolean) = assertUIObjectExists(itemContainingText(getStringResource(R.string.recently_saved_title)), exists = exists) - fun verifyPocketSectionIsDisplayed(exists: Boolean) = - assertUIObjectExists(itemContainingText(getStringResource(R.string.pocket_stories_header_1)), exists = exists) fun verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed: Boolean, searchTerm: String, groupSize: Int) { // checks if the search group exists in the Recently visited section @@ -353,13 +347,6 @@ class HomeScreenRobot { .perform(click()) } - fun swipeToBottom() = onView(withId(R.id.homeLayout)).perform(ViewActions.swipeUp()) - - fun swipeToTop() = - onView(withId(R.id.sessionControlRecyclerView)).perform(ViewActions.swipeDown()) - - fun clickFirefoxLogo() = homepageWordmark().click() - fun verifyThoughtProvokingStories(enabled: Boolean) { if (enabled) { scrollToElementByText(getStringResource(R.string.pocket_stories_header_1)) @@ -789,18 +776,6 @@ class HomeScreenRobot { return ComposeTabDrawerRobot.Transition(composeTestRule) } - fun clickJumpBackInItemWithTitle(itemTitle: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - mDevice - .findObject( - UiSelector() - .resourceId("recent.tab.title") - .textContains(itemTitle), - ).clickAndWaitForNewWindow(waitingTime) - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - fun clickPocketStoryItem(publisher: String, position: Int, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { mDevice.findObject( UiSelector() @@ -880,14 +855,6 @@ private fun homeScreenList() = .scrollable(true), ).setAsVerticalList() -private fun assertKeyboardVisibility(isExpectedToBeVisible: Boolean) = - Assert.assertEquals( - isExpectedToBeVisible, - mDevice - .executeShellCommand("dumpsys input_method | grep mInputShown") - .contains("mInputShown=true"), - ) - private fun threeDotButton() = onView(allOf(withId(R.id.menuButton))) private fun saveTabsToCollectionButton() = onView(withId(R.id.add_tabs_to_collections_button)) @@ -934,12 +901,6 @@ val deleteFromHistory = ), ).inRoot(RootMatchers.isPlatformPopup()) -private val recentlyVisitedList = - UiScrollable( - UiSelector() - .className("android.widget.HorizontalScrollView"), - ).setAsHorizontalList() - private val sponsoredShortcutsSettingsButton = mDevice .findObject( From 7b9171780287fe30410e77bf7f26f0b1e8e0d83d Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Mon, 5 Feb 2024 12:50:51 +0200 Subject: [PATCH 115/586] Bug 1879072 - Convert private variables to functions so they don't get initialized --- .../fenix/ui/robots/HomeScreenRobot.kt | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt index 3364da18dd82..e47f9ef46073 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt @@ -79,19 +79,20 @@ import org.mozilla.fenix.tabstray.TabsTrayTestTag * Implementation of Robot Pattern for the home screen menu. */ class HomeScreenRobot { - val privateSessionMessage = - "$appName clears your search and browsing history from private tabs when you close them" + - " or quit the app. While this doesn’t make you anonymous to websites or your internet" + - " service provider, it makes it easier to keep what you do online private from anyone" + - " else who uses this device." - fun verifyNavigationToolbar() = assertUIObjectExists(navigationToolbar()) fun verifyHomeScreen() = assertUIObjectExists(homeScreen()) fun verifyPrivateBrowsingHomeScreenItems() { verifyHomeScreenAppBarItems() - assertUIObjectExists(itemContainingText(privateSessionMessage)) + assertUIObjectExists( + itemContainingText( + "$appName clears your search and browsing history from private tabs when you close them" + + " or quit the app. While this doesn’t make you anonymous to websites or your internet" + + " service provider, it makes it easier to keep what you do online private from anyone" + + " else who uses this device.", + ), + ) verifyCommonMythsLink() } @@ -99,7 +100,7 @@ class HomeScreenRobot { assertUIObjectExists(homeScreen(), privateBrowsingButton(), homepageWordmark()) fun verifyHomePrivateBrowsingButton() = assertUIObjectExists(privateBrowsingButton()) - fun verifyHomeMenuButton() = assertUIObjectExists(menuButton) + fun verifyHomeMenuButton() = assertUIObjectExists(menuButton()) fun verifyTabButton() = onView(allOf(withId(R.id.tab_button), isDisplayed())).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) fun verifyCollectionsHeader() = @@ -365,8 +366,7 @@ class HomeScreenRobot { fun verifyPocketRecommendedStoriesItems() { for (position in 0..8) { - pocketStoriesList - .scrollIntoView(UiSelector().index(position)) + pocketStoriesList().scrollIntoView(UiSelector().index(position)) assertUIObjectExists(itemWithIndex(position)) } } @@ -387,8 +387,7 @@ class HomeScreenRobot { // } fun verifyDiscoverMoreStoriesButton() { - pocketStoriesList - .scrollIntoView(UiSelector().text("Discover more")) + pocketStoriesList().scrollIntoView(UiSelector().text("Discover more")) assertUIObjectExists(itemWithText("Discover more")) } @@ -661,7 +660,7 @@ class HomeScreenRobot { mDevice.findObject( UiSelector().resourceId("$packageName:id/simple_text"), ).waitForExists(waitingTime) - deleteFromHistory.click() + deleteFromHistory().click() HomeScreenRobot().interact() return Transition() @@ -677,18 +676,18 @@ class HomeScreenRobot { } fun clickSponsorsAndPrivacyButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - sponsorsAndPrivacyButton.waitForExists(waitingTime) - sponsorsAndPrivacyButton.clickAndWaitForNewWindow(waitingTime) + sponsorsAndPrivacyButton().waitForExists(waitingTime) + sponsorsAndPrivacyButton().clickAndWaitForNewWindow(waitingTime) BrowserRobot().interact() return BrowserRobot.Transition() } fun clickSponsoredShortcutsSettingsButton(interact: SettingsSubMenuHomepageRobot.() -> Unit): SettingsSubMenuHomepageRobot.Transition { - Log.i(TAG, "clickSponsoredShortcutsSettingsButton: Looking for: ${sponsoredShortcutsSettingsButton.selector}") - sponsoredShortcutsSettingsButton.waitForExists(waitingTime) - sponsoredShortcutsSettingsButton.clickAndWaitForNewWindow(waitingTime) - Log.i(TAG, "clickSponsoredShortcutsSettingsButton: Clicked ${sponsoredShortcutsSettingsButton.selector} and waiting for $waitingTime for a new window") + Log.i(TAG, "clickSponsoredShortcutsSettingsButton: Looking for: ${sponsoredShortcutsSettingsButton().selector}") + sponsoredShortcutsSettingsButton().waitForExists(waitingTime) + sponsoredShortcutsSettingsButton().clickAndWaitForNewWindow(waitingTime) + Log.i(TAG, "clickSponsoredShortcutsSettingsButton: Clicked ${sponsoredShortcutsSettingsButton().selector} and waiting for $waitingTime for a new window") SettingsSubMenuHomepageRobot().interact() return SettingsSubMenuHomepageRobot.Transition() @@ -793,7 +792,7 @@ class HomeScreenRobot { } fun clickPocketDiscoverMoreButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - pocketStoriesList + pocketStoriesList() .scrollIntoView(UiSelector().text("Discover more")) mDevice.findObject(UiSelector().text("Discover more")).also { @@ -888,12 +887,12 @@ private fun homepageWordmark() = private fun navigationToolbar() = itemWithResId("$packageName:id/toolbar") -private val menuButton = +private fun menuButton() = itemWithResId("$packageName:id/menuButton") private fun tabCounter(numberOfOpenTabs: String) = itemWithResIdAndText("$packageName:id/counter_text", numberOfOpenTabs) -val deleteFromHistory = +fun deleteFromHistory() = onView( allOf( withId(R.id.simple_text), @@ -901,7 +900,7 @@ val deleteFromHistory = ), ).inRoot(RootMatchers.isPlatformPopup()) -private val sponsoredShortcutsSettingsButton = +private fun sponsoredShortcutsSettingsButton() = mDevice .findObject( UiSelector() @@ -909,7 +908,7 @@ private val sponsoredShortcutsSettingsButton = .resourceId("$packageName:id/simple_text"), ) -private val sponsorsAndPrivacyButton = +private fun sponsorsAndPrivacyButton() = mDevice .findObject( UiSelector() @@ -917,5 +916,5 @@ private val sponsorsAndPrivacyButton = .resourceId("$packageName:id/simple_text"), ) -private val pocketStoriesList = +private fun pocketStoriesList() = UiScrollable(UiSelector().resourceId("pocket.stories")).setAsHorizontalList() From e3381b389600e1b47a5f0e09d3d22c25b12e63b9 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Mon, 5 Feb 2024 13:55:33 +0200 Subject: [PATCH 116/586] Bug 1879072 - Add test logs to HomeScreenRobot --- .../fenix/ui/robots/HomeScreenRobot.kt | 277 +++++++++++++++--- 1 file changed, 241 insertions(+), 36 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt index e47f9ef46073..62842aa21c75 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt @@ -101,11 +101,24 @@ class HomeScreenRobot { fun verifyHomePrivateBrowsingButton() = assertUIObjectExists(privateBrowsingButton()) fun verifyHomeMenuButton() = assertUIObjectExists(menuButton()) - fun verifyTabButton() = - onView(allOf(withId(R.id.tab_button), isDisplayed())).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - fun verifyCollectionsHeader() = + fun verifyTabButton() { + Log.i(TAG, "verifyTabButton: Trying to verify tab counter button is visible") + onView(allOf(withId(R.id.tab_button), isDisplayed())).check( + matches( + withEffectiveVisibility( + Visibility.VISIBLE, + ), + ), + ) + Log.i(TAG, "verifyTabButton: Verified tab counter button is visible") + } + fun verifyCollectionsHeader() { + Log.i(TAG, "verifyCollectionsHeader: Trying to verify collections header is visible") onView(allOf(withText("Collections"))).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - fun verifyNoCollectionsText() = + Log.i(TAG, "verifyCollectionsHeader: Verified collections header is visible") + } + fun verifyNoCollectionsText() { + Log.i(TAG, "verifyNoCollectionsText: Trying to verify empty collections placeholder text is displayed") onView( withText( containsString( @@ -114,14 +127,21 @@ class HomeScreenRobot { ), ), ).check(matches(isDisplayed())) + Log.i(TAG, "verifyNoCollectionsText: Verified empty collections placeholder text is displayed") + } fun verifyHomeWordmark() { + Log.i(TAG, "verifyHomeWordmark: Trying to scroll 3x to the beginning of the home screen") homeScreenList().scrollToBeginning(3) + Log.i(TAG, "verifyHomeWordmark: Scrolled 3x to the beginning of the home screen") assertUIObjectExists(homepageWordmark()) } - fun verifyHomeComponent() = + fun verifyHomeComponent() { + Log.i(TAG, "verifyHomeComponent: Trying to verify home screen view is visible") onView(ViewMatchers.withResourceName("sessionControlRecyclerView")) .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + Log.i(TAG, "verifyHomeComponent: Verified home screen view is visible") + } fun verifyTabCounter(numberOfOpenTabs: String) = assertUIObjectExists(tabCounter(numberOfOpenTabs)) @@ -132,95 +152,130 @@ class HomeScreenRobot { // Upgrading users onboarding dialog fun verifyUpgradingUserOnboardingFirstScreen(testRule: ComposeTestRule) { testRule.also { + Log.i(TAG, "verifyUpgradingUserOnboardingFirstScreen: Trying to verify that the upgrading user first onboarding screen title is displayed") it.onNodeWithText(getStringResource(R.string.onboarding_home_welcome_title_2)) .assertIsDisplayed() - + Log.i(TAG, "verifyUpgradingUserOnboardingFirstScreen: Verified that the upgrading user first onboarding screen title is displayed") + Log.i(TAG, "verifyUpgradingUserOnboardingFirstScreen: Trying to verify that the upgrading user first onboarding screen description is displayed") it.onNodeWithText(getStringResource(R.string.onboarding_home_welcome_description)) .assertIsDisplayed() - + Log.i(TAG, "verifyUpgradingUserOnboardingFirstScreen: Verified that the upgrading user first onboarding screen description is displayed") + Log.i(TAG, "verifyUpgradingUserOnboardingFirstScreen: Trying to verify that the upgrading user first onboarding \"Get started\" button is displayed") it.onNodeWithText(getStringResource(R.string.onboarding_home_get_started_button)) .assertIsDisplayed() + Log.i(TAG, "verifyUpgradingUserOnboardingFirstScreen: Verified that the upgrading user first onboarding \"Get started\" button is displayed") } } fun verifyFirstOnboardingCard(composeTestRule: ComposeTestRule) { composeTestRule.also { + Log.i(TAG, "verifyFirstOnboardingCard: Trying to verify that the first onboarding screen title exists") it.onNodeWithText( getStringResource(R.string.juno_onboarding_default_browser_title_nimbus_2), ).assertExists() - + Log.i(TAG, "verifyFirstOnboardingCard: Verified that the first onboarding screen title exists") + Log.i(TAG, "verifyFirstOnboardingCard: Trying to verify that the first onboarding screen description exists") it.onNodeWithText( getStringResource(R.string.juno_onboarding_default_browser_description_nimbus_3), ).assertExists() - + Log.i(TAG, "verifyFirstOnboardingCard: Verified that the first onboarding screen description exists") + Log.i(TAG, "verifyFirstOnboardingCard: Trying to verify that the first onboarding \"Set as default browser\" button exists") it.onNodeWithText( getStringResource(R.string.juno_onboarding_default_browser_positive_button), ).assertExists() - + Log.i(TAG, "verifyFirstOnboardingCard: Verified that the first onboarding \"Set as default browser\" button exists") + Log.i(TAG, "verifyFirstOnboardingCard: Trying to verify that the first onboarding \"Not now\" button exists") it.onNodeWithText( getStringResource(R.string.juno_onboarding_default_browser_negative_button), ).assertExists() + Log.i(TAG, "verifyFirstOnboardingCard: Verified that the first onboarding \"Not now\" button exists") } } fun verifySecondOnboardingCard(composeTestRule: ComposeTestRule) { composeTestRule.also { + Log.i(TAG, "verifySecondOnboardingCard: Trying to verify that the second onboarding screen title exists") it.onNodeWithText( getStringResource(R.string.juno_onboarding_sign_in_title_2), ).assertExists() - + Log.i(TAG, "verifySecondOnboardingCard: Verified that the second onboarding screen title exists") + Log.i(TAG, "verifySecondOnboardingCard: Trying to verify that the second onboarding screen description exists") it.onNodeWithText( getStringResource(R.string.juno_onboarding_sign_in_description_2), ).assertExists() - + Log.i(TAG, "verifySecondOnboardingCard: Verified that the second onboarding screen description exists") + Log.i(TAG, "verifySecondOnboardingCard: Trying to verify that the first onboarding \"Sign in\" button exists") it.onNodeWithText( getStringResource(R.string.juno_onboarding_sign_in_positive_button), ).assertExists() - + Log.i(TAG, "verifySecondOnboardingCard: Verified that the first onboarding \"Sign in\" button exists") + Log.i(TAG, "verifySecondOnboardingCard: Trying to verify that the first onboarding \"Not now\" button exists") it.onNodeWithText( getStringResource(R.string.juno_onboarding_sign_in_negative_button), ).assertExists() + Log.i(TAG, "verifySecondOnboardingCard: Verified that the first onboarding \"Not now\" button exists") } } - fun clickNotNowOnboardingButton(composeTestRule: ComposeTestRule) = + fun clickNotNowOnboardingButton(composeTestRule: ComposeTestRule) { + Log.i(TAG, "clickNotNowOnboardingButton: Trying to click \"Not now\" onboarding button") composeTestRule.onNodeWithText( getStringResource(R.string.juno_onboarding_default_browser_negative_button), ).performClick() + Log.i(TAG, "clickNotNowOnboardingButton: Clicked \"Not now\" onboarding button") + } - fun swipeSecondOnboardingCardToRight() = + fun swipeSecondOnboardingCardToRight() { + Log.i(TAG, "swipeSecondOnboardingCardToRight: Trying to perform swipe right action on second onboarding card") mDevice.findObject( UiSelector().textContains( getStringResource(R.string.juno_onboarding_sign_in_title_2), ), ).swipeRight(3) + Log.i(TAG, "swipeSecondOnboardingCardToRight: Performed swipe right action on second onboarding card") + } - fun clickGetStartedButton(testRule: ComposeTestRule) = - testRule.onNodeWithText(getStringResource(R.string.onboarding_home_get_started_button)).performClick() + fun clickGetStartedButton(testRule: ComposeTestRule) { + Log.i(TAG, "clickGetStartedButton: Trying to click \"Get started\" onboarding button") + testRule.onNodeWithText(getStringResource(R.string.onboarding_home_get_started_button)) + .performClick() + Log.i(TAG, "clickGetStartedButton: Clicked \"Get started\" onboarding button") + } - fun clickCloseButton(testRule: ComposeTestRule) = + fun clickCloseButton(testRule: ComposeTestRule) { + Log.i(TAG, "clickCloseButton: Trying to click close onboarding button") testRule.onNode(hasContentDescription("Close")).performClick() + Log.i(TAG, "clickCloseButton: Clicked close onboarding button") + } fun verifyUpgradingUserOnboardingSecondScreen(testRule: ComposeTestRule) { testRule.also { + Log.i(TAG, "verifyUpgradingUserOnboardingSecondScreen: Trying to verify that the upgrading user second onboarding screen title is displayed") it.onNodeWithText(getStringResource(R.string.onboarding_home_sync_title_3)) .assertIsDisplayed() - + Log.i(TAG, "verifyUpgradingUserOnboardingSecondScreen: Verified that the upgrading user second onboarding screen title is displayed") + Log.i(TAG, "verifyUpgradingUserOnboardingSecondScreen: Trying to verify that the upgrading user second onboarding screen description is displayed") it.onNodeWithText(getStringResource(R.string.onboarding_home_sync_description)) .assertIsDisplayed() - + Log.i(TAG, "verifyUpgradingUserOnboardingSecondScreen: Verified that the upgrading user second onboarding screen description is displayed") + Log.i(TAG, "verifyUpgradingUserOnboardingSecondScreen: Trying to verify that the upgrading user second onboarding \"Sign in\" button is displayed") it.onNodeWithText(getStringResource(R.string.onboarding_home_sign_in_button)) .assertIsDisplayed() - + Log.i(TAG, "verifyUpgradingUserOnboardingSecondScreen: Verified that the upgrading user second onboarding \"Sign in\" button is displayed") + Log.i(TAG, "verifyUpgradingUserOnboardingSecondScreen: Trying to that the verify upgrading user second onboarding \"Skip\" button is displayed") it.onNodeWithText(getStringResource(R.string.onboarding_home_skip_button)) .assertIsDisplayed() + Log.i(TAG, "verifyUpgradingUserOnboardingSecondScreen: Verified that the upgrading user second onboarding \"Skip\" button is displayed") } } - fun clickSkipButton(testRule: ComposeTestRule) = + fun clickSkipButton(testRule: ComposeTestRule) { + Log.i(TAG, "clickSkipButton: Trying to click \"Skip\" onboarding button") testRule .onNodeWithText(getStringResource(R.string.onboarding_home_skip_button)) .performClick() + Log.i(TAG, "clickSkipButton: Clicked \"Skip\" onboarding button") + } fun verifyCommonMythsLink() = assertUIObjectExists(itemContainingText(getStringResource(R.string.private_browsing_common_myths))) @@ -229,7 +284,9 @@ class HomeScreenRobot { assertUIObjectExists(itemWithResId("$packageName:id/top_sites_list")) fun verifyNotExistingTopSitesList(title: String) { + Log.i(TAG, "verifyNotExistingTopSitesList: Waiting for $waitingTime ms for top site: $title to be gone") mDevice.findObject(UiSelector().text(title)).waitUntilGone(waitingTime) + Log.i(TAG, "verifyNotExistingTopSitesList: Waited for $waitingTime ms for top site: $title to be gone") assertUIObjectExists( itemWithResIdContainingText( "$packageName:id/top_site_title", @@ -257,16 +314,21 @@ class HomeScreenRobot { ) fun verifyExistingTopSitesTabs(title: String) { + Log.i(TAG, "verifyExistingTopSitesTabs: Trying to scroll into view the top sites list") homeScreenList().scrollIntoView(itemWithResId("$packageName:id/top_sites_list")) + Log.i(TAG, "verifyExistingTopSitesTabs: Scrolled into view the top sites list") + Log.i(TAG, "verifyExistingTopSitesTabs: Waiting for $waitingTime ms for top site: $title to exist") mDevice.findObject( UiSelector() .resourceId("$packageName:id/top_site_title") .textContains(title), ).waitForExists(waitingTime) - + Log.i(TAG, "verifyExistingTopSitesTabs: Waited for $waitingTime ms for top site: $title to exist") + Log.i(TAG, "verifyExistingTopSitesTabs: Trying to verify top site: $title is visible") onView(allOf(withId(R.id.top_sites_list))) .check(matches(hasDescendant(withText(title)))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + Log.i(TAG, "verifyExistingTopSitesTabs: Verified top site: $title is visible") } fun verifySponsoredShortcutDetails(sponsoredShortcutTitle: String, position: Int) { assertUIObjectExists( @@ -308,10 +370,17 @@ class HomeScreenRobot { } fun verifyJumpBackInSectionIsNotDisplayed() = assertUIObjectExists(itemContainingText(getStringResource(R.string.recent_tabs_header)), exists = false) - fun verifyJumpBackInItemTitle(testRule: ComposeTestRule, itemTitle: String) = - testRule.onNodeWithTag("recent.tab.title", useUnmergedTree = true).assert(hasText(itemTitle)) - fun verifyJumpBackInItemWithUrl(testRule: ComposeTestRule, itemUrl: String) = + fun verifyJumpBackInItemTitle(testRule: ComposeTestRule, itemTitle: String) { + Log.i(TAG, "verifyJumpBackInItemTitle: Trying to verify jump back in item with title: $itemTitle") + testRule.onNodeWithTag("recent.tab.title", useUnmergedTree = true) + .assert(hasText(itemTitle)) + Log.i(TAG, "verifyJumpBackInItemTitle: Verified jump back in item with title: $itemTitle") + } + fun verifyJumpBackInItemWithUrl(testRule: ComposeTestRule, itemUrl: String) { + Log.i(TAG, "verifyJumpBackInItemWithUrl: Trying to verify jump back in item with URL: $itemUrl") testRule.onNodeWithTag("recent.tab.url", useUnmergedTree = true).assert(hasText(itemUrl)) + Log.i(TAG, "verifyJumpBackInItemWithUrl: Verified jump back in item with URL: $itemUrl") + } fun verifyJumpBackInShowAllButton() = assertUIObjectExists(itemContainingText(getStringResource(R.string.recent_tabs_show_all))) fun verifyRecentlyVisitedSectionIsDisplayed(exists: Boolean) = assertUIObjectExists(itemContainingText(getStringResource(R.string.history_metadata_header_2)), exists = exists) @@ -344,8 +413,10 @@ class HomeScreenRobot { } fun togglePrivateBrowsingModeOnOff() { + Log.i(TAG, "togglePrivateBrowsingModeOnOff: Trying to click private browsing home screen button") onView(ViewMatchers.withResourceName("privateBrowsingButton")) .perform(click()) + Log.i(TAG, "togglePrivateBrowsingModeOnOff: Clicked private browsing home screen button") } fun verifyThoughtProvokingStories(enabled: Boolean) { @@ -353,20 +424,26 @@ class HomeScreenRobot { scrollToElementByText(getStringResource(R.string.pocket_stories_header_1)) assertUIObjectExists(itemContainingText(getStringResource(R.string.pocket_stories_header_1))) } else { + Log.i(TAG, "verifyThoughtProvokingStories: Trying to perform ${LISTS_MAXSWIPES}x a scroll action to the end of the home screen") homeScreenList().scrollToEnd(LISTS_MAXSWIPES) + Log.i(TAG, "verifyThoughtProvokingStories: Performed ${LISTS_MAXSWIPES}x a scroll action to the end of the home screen") assertUIObjectExists(itemContainingText(getStringResource(R.string.pocket_stories_header_1)), exists = false) } } fun scrollToPocketProvokingStories() { + Log.i(TAG, "scrollToPocketProvokingStories: Trying to scroll into view the featured pocket stories") homeScreenList().scrollIntoView( mDevice.findObject(UiSelector().resourceId("pocket.recommended.story").index(2)), ) + Log.i(TAG, "scrollToPocketProvokingStories: Scrolled into view the featured pocket stories") } fun verifyPocketRecommendedStoriesItems() { for (position in 0..8) { + Log.i(TAG, "verifyPocketRecommendedStoriesItems: Trying to scroll into view the featured pocket story from position: $position") pocketStoriesList().scrollIntoView(UiSelector().index(position)) + Log.i(TAG, "verifyPocketRecommendedStoriesItems: Scrolled into view the featured pocket story from position: $position") assertUIObjectExists(itemWithIndex(position)) } } @@ -387,7 +464,9 @@ class HomeScreenRobot { // } fun verifyDiscoverMoreStoriesButton() { + Log.i(TAG, "verifyDiscoverMoreStoriesButton: Trying to scroll into view the Pocket \"Discover more\" button") pocketStoriesList().scrollIntoView(UiSelector().text("Discover more")) + Log.i(TAG, "verifyDiscoverMoreStoriesButton: Scrolled into view the Pocket \"Discover more\" button") assertUIObjectExists(itemWithText("Discover more")) } @@ -396,33 +475,54 @@ class HomeScreenRobot { scrollToElementByText(getStringResource(R.string.pocket_stories_categories_header)) assertUIObjectExists(itemContainingText(getStringResource(R.string.pocket_stories_categories_header))) } else { + Log.i(TAG, "verifyStoriesByTopic: Trying to perform ${LISTS_MAXSWIPES}x a scroll action to the end of the home screen") homeScreenList().scrollToEnd(LISTS_MAXSWIPES) + Log.i(TAG, "verifyStoriesByTopic: Performed ${LISTS_MAXSWIPES}x a scroll action to the end of the home screen") assertUIObjectExists(itemContainingText(getStringResource(R.string.pocket_stories_categories_header)), exists = false) } } fun verifyStoriesByTopicItems() { + Log.i(TAG, "verifyStoriesByTopicItems: Trying to scroll into view the stories by topic home screen section") homeScreenList().scrollIntoView(UiSelector().resourceId("pocket.categories")) + Log.i(TAG, "verifyStoriesByTopicItems: Scrolled into view the stories by topic home screen section") + Log.i(TAG, "verifyStoriesByTopicItems: Trying to verify that there are more than 1 \"Stories by topic\" categories") assertTrue(mDevice.findObject(UiSelector().resourceId("pocket.categories")).childCount > 1) + Log.i(TAG, "verifyStoriesByTopicItems: Verified that there are more than 1 \"Stories by topic\" categories") } fun verifyStoriesByTopicItemState(composeTestRule: ComposeTestRule, isSelected: Boolean, position: Int) { + Log.i(TAG, "verifyStoriesByTopicItemState: Trying to scroll into view \"Powered By Pocket\" home screen section") homeScreenList().scrollIntoView(mDevice.findObject(UiSelector().resourceId("pocket.header"))) + Log.i(TAG, "verifyStoriesByTopicItemState: Scrolled into view \"Powered By Pocket\" home screen section") if (isSelected) { + Log.i(TAG, "verifyStoriesByTopicItemState: Trying verify that the stories by topic home screen section is displayed") composeTestRule.onNodeWithTag("pocket.categories").assertIsDisplayed() + Log.i(TAG, "verifyStoriesByTopicItemState: Verified that the stories by topic home screen section is displayed") + Log.i(TAG, "verifyStoriesByTopicItemState: Trying verify that the stories by topic item at position: $position is selected") storyByTopicItem(composeTestRule, position).assertIsSelected() + Log.i(TAG, "verifyStoriesByTopicItemState: Verified that the stories by topic item at position: $position is selected") } else { + Log.i(TAG, "verifyStoriesByTopicItemState: Trying verify that the stories by topic home screen section is displayed") composeTestRule.onNodeWithTag("pocket.categories").assertIsDisplayed() + Log.i(TAG, "verifyStoriesByTopicItemState: Verified that the stories by topic home screen section is displayed") + Log.i(TAG, "verifyStoriesByTopicItemState: Trying to verify that the stories by topic item at position: $position is not selected") storyByTopicItem(composeTestRule, position).assertIsNotSelected() + Log.i(TAG, "verifyStoriesByTopicItemState: Verified that the stories by topic item at position: $position is not selected") } } - fun clickStoriesByTopicItem(composeTestRule: ComposeTestRule, position: Int) = + fun clickStoriesByTopicItem(composeTestRule: ComposeTestRule, position: Int) { + Log.i(TAG, "clickStoriesByTopicItem: Trying to click stories by topic item from position: $position") storyByTopicItem(composeTestRule, position).performClick() + Log.i(TAG, "clickStoriesByTopicItem: Clicked stories by topic item from position: $position") + } fun verifyPoweredByPocket() { + Log.i(TAG, "verifyPoweredByPocket: Trying to scroll into view \"Powered By Pocket\" home screen section") homeScreenList().scrollIntoView(mDevice.findObject(UiSelector().resourceId("pocket.header"))) + Log.i(TAG, "verifyPoweredByPocket: Scrolled into view \"Powered By Pocket\" home screen section") assertUIObjectExists(itemWithResId("pocket.header.title")) } @@ -431,16 +531,21 @@ class HomeScreenRobot { scrollToElementByText(getStringResource(R.string.browser_menu_customize_home_1)) assertUIObjectExists(itemContainingText("Customize homepage")) } else { + Log.i(TAG, "verifyCustomizeHomepageButton: Trying to perform ${LISTS_MAXSWIPES}x a scroll action to the end of the home screen") homeScreenList().scrollToEnd(LISTS_MAXSWIPES) + Log.i(TAG, "verifyCustomizeHomepageButton: Performed ${LISTS_MAXSWIPES}x a scroll action to the end of the home screen") assertUIObjectExists(itemContainingText("Customize homepage"), exists = false) } } - fun verifyJumpBackInMessage(composeTestRule: ComposeTestRule) = + fun verifyJumpBackInMessage(composeTestRule: ComposeTestRule) { + Log.i(TAG, "verifyJumpBackInMessage: Trying to verify jump back in contextual message") composeTestRule .onNodeWithText( getStringResource(R.string.onboarding_home_screen_jump_back_contextual_hint_2), ).assertExists() + Log.i(TAG, "verifyJumpBackInMessage: Verified jump back in contextual message") + } fun getProvokingStoryPublisher(position: Int): String { val publisher = mDevice.findObject( @@ -457,6 +562,7 @@ class HomeScreenRobot { } fun verifyToolbarPosition(defaultPosition: Boolean) { + Log.i(TAG, "verifyToolbarPosition: Trying to verify toolbar is set to top: $defaultPosition") onView(withId(R.id.toolbarLayout)) .check( if (defaultPosition) { @@ -465,6 +571,7 @@ class HomeScreenRobot { isCompletelyAbove(withId(R.id.homeAppBar)) }, ) + Log.i(TAG, "verifyToolbarPosition: Verified toolbar position is set to top: $defaultPosition") } fun verifyNimbusMessageCard(title: String, text: String, action: String) { val textView = UiSelector() @@ -483,17 +590,22 @@ class HomeScreenRobot { } fun verifyIfInPrivateOrNormalMode(privateBrowsingEnabled: Boolean) { + Log.i(TAG, "verifyIfInPrivateOrNormalMode: Trying to verify private browsing mode is enabled") assert(isPrivateModeEnabled() == privateBrowsingEnabled) + Log.i(TAG, "verifyIfInPrivateOrNormalMode: Verified private browsing mode is enabled: $privateBrowsingEnabled") } class Transition { fun openTabDrawer(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + Log.i(TAG, "openTabDrawer: Waiting for $waitingTime ms for tab counter button to exist") mDevice.findObject( UiSelector().descriptionContains("open tab. Tap to switch tabs."), ).waitForExists(waitingTime) - + Log.i(TAG, "openTabDrawer: Waited for $waitingTime ms for tab counter button to exist") + Log.i(TAG, "openTabDrawer: Trying to click tab counter button") tabsCounter().click() + Log.i(TAG, "openTabDrawer: Clicked tab counter button") mDevice.waitNotNull(Until.findObject(By.res("$packageName:id/tab_layout"))) TabDrawerRobot().interact() @@ -501,9 +613,15 @@ class HomeScreenRobot { } fun openComposeTabDrawer(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition { + Log.i(TAG, "openComposeTabDrawer: Waiting for device to be idle for $waitingTime ms") mDevice.waitForIdle(waitingTime) + Log.i(TAG, "openComposeTabDrawer: Device was idle for $waitingTime ms") + Log.i(TAG, "openComposeTabDrawer: Trying to click tab counter button") onView(withId(R.id.tab_button)).click() + Log.i(TAG, "openComposeTabDrawer: Clicked tab counter button") + Log.i(TAG, "openComposeTabDrawer: Trying to verify the tabs tray exists") composeTestRule.onNodeWithTag(TabsTrayTestTag.tabsTray).assertExists() + Log.i(TAG, "openComposeTabDrawer: Verified the tabs tray exists") ComposeTabDrawerRobot(composeTestRule).interact() return ComposeTabDrawerRobot.Transition(composeTestRule) @@ -513,17 +631,18 @@ class HomeScreenRobot { // Issue: https://github.com/mozilla-mobile/fenix/issues/21578 try { Log.i(TAG, "openThreeDotMenu: Try block") - Log.i(TAG, "openThreeDotMenu: Looking for main menu button") mDevice.waitNotNull( Until.findObject(By.res("$packageName:id/menuButton")), waitingTime, ) } catch (e: AssertionError) { Log.i(TAG, "openThreeDotMenu: Catch block") + Log.i(TAG, "openThreeDotMenu: Trying to click device back button") mDevice.pressBack() - Log.i(TAG, "openThreeDotMenu: Pressed device back button") + Log.i(TAG, "openThreeDotMenu: Clicked device back button") } finally { Log.i(TAG, "openThreeDotMenu: Finally block") + Log.i(TAG, "openThreeDotMenu: Trying to click main menu button") threeDotButton().perform(click()) Log.i(TAG, "openThreeDotMenu: Clicked main menu button") } @@ -533,9 +652,15 @@ class HomeScreenRobot { } fun openSearch(interact: SearchRobot.() -> Unit): SearchRobot.Transition { + Log.i(TAG, "openSearch: Waiting for $waitingTime ms for the navigation toolbar to exist") navigationToolbar().waitForExists(waitingTime) + Log.i(TAG, "openSearch: Waited for $waitingTime ms for the navigation toolbar to exist") + Log.i(TAG, "openSearch: Trying to click navigation toolbar") navigationToolbar().click() + Log.i(TAG, "openSearch: Clicked navigation toolbar") + Log.i(TAG, "openSearch: Waiting for device to be idle") mDevice.waitForIdle() + Log.i(TAG, "openSearch: Device was idle") SearchRobot().interact() return SearchRobot.Transition() @@ -545,7 +670,9 @@ class HomeScreenRobot { testRule: ComposeTestRule, interact: SyncSignInRobot.() -> Unit, ): SyncSignInRobot.Transition { + Log.i(TAG, "clickUpgradingUserOnboardingSignInButton: Trying to click the upgrading user onboarding \"Sign in\" button") testRule.onNodeWithText("Sign in").performClick() + Log.i(TAG, "clickUpgradingUserOnboardingSignInButton: Clicked the upgrading user onboarding \"Sign in\" button") SyncSignInRobot().interact() return SyncSignInRobot.Transition() @@ -554,26 +681,38 @@ class HomeScreenRobot { fun togglePrivateBrowsingMode(switchPBModeOn: Boolean = true) { // Switch to private browsing homescreen if (switchPBModeOn && !isPrivateModeEnabled()) { + Log.i(TAG, "togglePrivateBrowsingMode: Waiting for $waitingTime ms for private browsing button to exist") privateBrowsingButton().waitForExists(waitingTime) + Log.i(TAG, "togglePrivateBrowsingMode: Waited for $waitingTime ms for private browsing button to exist") + Log.i(TAG, "togglePrivateBrowsingMode: Trying to click private browsing button") privateBrowsingButton().click() + Log.i(TAG, "togglePrivateBrowsingMode: Clicked private browsing button") } // Switch to normal browsing homescreen if (!switchPBModeOn && isPrivateModeEnabled()) { + Log.i(TAG, "togglePrivateBrowsingMode: Waiting for $waitingTime ms for private browsing button to exist") privateBrowsingButton().waitForExists(waitingTime) + Log.i(TAG, "togglePrivateBrowsingMode: Waited for $waitingTime ms for private browsing button to exist") + Log.i(TAG, "togglePrivateBrowsingMode: Trying to click private browsing button") + privateBrowsingButton().click() privateBrowsingButton().click() + Log.i(TAG, "togglePrivateBrowsingMode: Clicked private browsing button") } } fun triggerPrivateBrowsingShortcutPrompt(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenRobot.Transition { // Loop to press the PB icon for 5 times to display the Add the Private Browsing Shortcut CFR for (i in 1..5) { + Log.i(TAG, "triggerPrivateBrowsingShortcutPrompt: Waiting for $waitingTime ms for private browsing button to exist") mDevice.findObject(UiSelector().resourceId("$packageName:id/privateBrowsingButton")) .waitForExists( waitingTime, ) - + Log.i(TAG, "triggerPrivateBrowsingShortcutPrompt: Waited for $waitingTime ms for private browsing button to exist") + Log.i(TAG, "triggerPrivateBrowsingShortcutPrompt: Trying to click private browsing button") privateBrowsingButton().click() + Log.i(TAG, "triggerPrivateBrowsingShortcutPrompt: Clicked private browsing button") } AddToHomeScreenRobot().interact() @@ -581,13 +720,19 @@ class HomeScreenRobot { } fun pressBack() { + Log.i(TAG, "pressBack: Trying to click device back button") onView(ViewMatchers.isRoot()).perform(ViewActions.pressBack()) + Log.i(TAG, "pressBack: Clicked device back button") } fun openNavigationToolbar(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition { + Log.i(TAG, "openNavigationToolbar: Waiting for $waitingTime ms for navigation the toolbar to exist") mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar")) .waitForExists(waitingTime) + Log.i(TAG, "openNavigationToolbar: Waited for $waitingTime ms for the navigation toolbar to exist") + Log.i(TAG, "openNavigationToolbar: Trying to click the navigation toolbar") navigationToolbar().click() + Log.i(TAG, "openNavigationToolbar: Clicked the navigation toolbar") NavigationToolbarRobot().interact() return NavigationToolbarRobot.Transition() @@ -597,20 +742,23 @@ class HomeScreenRobot { title: String, interact: HomeScreenRobot.() -> Unit, ): Transition { + Log.i(TAG, "openContextMenuOnTopSitesWithTitle: Trying to long click top site with title: $title") onView(withId(R.id.top_sites_list)).perform( actionOnItem( hasDescendant(withText(title)), ViewActions.longClick(), ), ) + Log.i(TAG, "openContextMenuOnTopSitesWithTitle: Long clicked top site with title: $title") HomeScreenRobot().interact() return Transition() } fun openContextMenuOnSponsoredShortcut(sponsoredShortcutTitle: String, interact: HomeScreenRobot.() -> Unit): Transition { + Log.i(TAG, "openContextMenuOnSponsoredShortcut: Trying to long click: $sponsoredShortcutTitle sponsored shortcut") sponsoredShortcut(sponsoredShortcutTitle).perform(longClick()) - Log.i(TAG, "openContextMenuOnSponsoredShortcut: Long clicked to open context menu for $sponsoredShortcutTitle sponsored shortcut") + Log.i(TAG, "openContextMenuOnSponsoredShortcut: Long clicked: $sponsoredShortcutTitle sponsored shortcut") HomeScreenRobot().interact() return Transition() @@ -620,86 +768,112 @@ class HomeScreenRobot { title: String, interact: BrowserRobot.() -> Unit, ): BrowserRobot.Transition { + Log.i(TAG, "openTopSiteTabWithTitle: Trying to click top site with title $title") onView(withId(R.id.top_sites_list)).perform( actionOnItem(hasDescendant(withText(title)), click()), ) + Log.i(TAG, "openTopSiteTabWithTitle:Clicked top site with title $title") BrowserRobot().interact() return BrowserRobot.Transition() } fun openSponsoredShortcut(sponsoredShortcutTitle: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "openSponsoredShortcut: Trying to click sponsored top site with title: $sponsoredShortcutTitle") sponsoredShortcut(sponsoredShortcutTitle).click() + Log.i(TAG, "openSponsoredShortcut: Clicked sponsored top site with title: $sponsoredShortcutTitle") BrowserRobot().interact() return BrowserRobot.Transition() } fun renameTopSite(title: String, interact: HomeScreenRobot.() -> Unit): Transition { + Log.i(TAG, "renameTopSite: Trying to click context menu \"Rename\" button") onView(withText("Rename")) .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) .perform(click()) + Log.i(TAG, "renameTopSite: Clicked context menu \"Rename\" button") + Log.i(TAG, "renameTopSite: Trying to set top site title to: $title") onView(Matchers.allOf(withId(R.id.top_site_title), instanceOf(EditText::class.java))) .perform(ViewActions.replaceText(title)) + Log.i(TAG, "renameTopSite: Set top site title to: $title") + Log.i(TAG, "renameTopSite: Trying to click \"Ok\" rename top site dialog button") onView(withId(android.R.id.button1)).perform((click())) + Log.i(TAG, "renameTopSite: Clicked \"Ok\" rename top site dialog button") HomeScreenRobot().interact() return Transition() } fun removeTopSite(interact: HomeScreenRobot.() -> Unit): Transition { + Log.i(TAG, "removeTopSite: Trying to click context menu \"Remove\" button") onView(withText("Remove")) .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) .perform(click()) + Log.i(TAG, "removeTopSite: Clicked context menu \"Remove\" button") HomeScreenRobot().interact() return Transition() } fun deleteTopSiteFromHistory(interact: HomeScreenRobot.() -> Unit): Transition { + Log.i(TAG, "deleteTopSiteFromHistory: Waiting for $waitingTime ms for context menu \"Remove from history\" button to exist") mDevice.findObject( UiSelector().resourceId("$packageName:id/simple_text"), ).waitForExists(waitingTime) + Log.i(TAG, "deleteTopSiteFromHistory: Waited for $waitingTime ms for context menu \"Remove from history\" button to exist") + Log.i(TAG, "deleteTopSiteFromHistory: Trying to click context menu \"Remove from history\" button") deleteFromHistory().click() + Log.i(TAG, "deleteTopSiteFromHistory: Clicked context menu \"Remove from history\" button") HomeScreenRobot().interact() return Transition() } fun openTopSiteInPrivateTab(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "openTopSiteInPrivateTab: Trying to click context menu \"Open in private tab\" button") onView(withText("Open in private tab")) .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) .perform(click()) + Log.i(TAG, "openTopSiteInPrivateTab: Clicked context menu \"Open in private tab\" button") BrowserRobot().interact() return BrowserRobot.Transition() } fun clickSponsorsAndPrivacyButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "clickSponsorsAndPrivacyButton: Waiting for $waitingTime ms for context menu \"Our sponsors & your privacy\" button to exist") sponsorsAndPrivacyButton().waitForExists(waitingTime) + Log.i(TAG, "clickSponsorsAndPrivacyButton: Waited for $waitingTime ms for context menu \"Our sponsors & your privacy\" button to exist") + Log.i(TAG, "clickSponsorsAndPrivacyButton: Trying to click \"Our sponsors & your privacy\" context menu button and wait for $waitingTime ms for a new window") sponsorsAndPrivacyButton().clickAndWaitForNewWindow(waitingTime) + Log.i(TAG, "clickSponsorsAndPrivacyButton: Clicked \"Our sponsors & your privacy\" context menu button and waited for $waitingTime ms for a new window") BrowserRobot().interact() return BrowserRobot.Transition() } fun clickSponsoredShortcutsSettingsButton(interact: SettingsSubMenuHomepageRobot.() -> Unit): SettingsSubMenuHomepageRobot.Transition { - Log.i(TAG, "clickSponsoredShortcutsSettingsButton: Looking for: ${sponsoredShortcutsSettingsButton().selector}") + Log.i(TAG, "clickSponsoredShortcutsSettingsButton: Waiting for $waitingTime ms for context menu \"Settings\" button to exist") sponsoredShortcutsSettingsButton().waitForExists(waitingTime) + Log.i(TAG, "clickSponsoredShortcutsSettingsButton: Waited for $waitingTime ms for context menu \"Settings\" button to exist") + Log.i(TAG, "clickSponsoredShortcutsSettingsButton: Trying to click \"Settings\" context menu button and wait for $waitingTime for a new window") sponsoredShortcutsSettingsButton().clickAndWaitForNewWindow(waitingTime) - Log.i(TAG, "clickSponsoredShortcutsSettingsButton: Clicked ${sponsoredShortcutsSettingsButton().selector} and waiting for $waitingTime for a new window") + Log.i(TAG, "clickSponsoredShortcutsSettingsButton: Clicked \"Settings\" context menu button and waited for $waitingTime for a new window") SettingsSubMenuHomepageRobot().interact() return SettingsSubMenuHomepageRobot.Transition() } fun openCommonMythsLink(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "openCommonMythsLink: Trying to click private browsing home screen common myths link") mDevice.findObject( UiSelector() .textContains( getStringResource(R.string.private_browsing_common_myths), ), ).also { it.click() } + Log.i(TAG, "openCommonMythsLink: Clicked private browsing home screen common myths link") BrowserRobot().interact() return BrowserRobot.Transition() @@ -707,7 +881,9 @@ class HomeScreenRobot { fun clickSaveTabsToCollectionButton(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { scrollToElementByText(getStringResource(R.string.no_collections_description2)) + Log.i(TAG, "clickSaveTabsToCollectionButton: Trying to click save tabs to collection button") saveTabsToCollectionButton().click() + Log.i(TAG, "clickSaveTabsToCollectionButton: Clicked save tabs to collection button") TabDrawerRobot().interact() return TabDrawerRobot.Transition() @@ -715,15 +891,18 @@ class HomeScreenRobot { fun clickSaveTabsToCollectionButton(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition { scrollToElementByText(getStringResource(R.string.no_collections_description2)) + Log.i(TAG, "clickSaveTabsToCollectionButton: Trying to click save tabs to collection button") saveTabsToCollectionButton().click() - + Log.i(TAG, "clickSaveTabsToCollectionButton: Clicked save tabs to collection button") ComposeTabDrawerRobot(composeTestRule).interact() return ComposeTabDrawerRobot.Transition(composeTestRule) } fun expandCollection(title: String, interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { assertUIObjectExists(itemContainingText(title)) + Log.i(TAG, "expandCollection: Trying to click collection with title: $title and wait for $waitingTimeShort ms for a new window") itemContainingText(title).clickAndWaitForNewWindow(waitingTimeShort) + Log.i(TAG, "expandCollection: Clicked collection with title: $title and waited for $waitingTimeShort ms for a new window") assertUIObjectExists(itemWithDescription(getStringResource(R.string.remove_tab_from_collection))) CollectionRobot().interact() @@ -733,49 +912,62 @@ class HomeScreenRobot { fun openRecentlyVisitedSearchGroupHistoryList(title: String, interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { scrollToElementByText("Recently visited") val searchGroup = mDevice.findObject(UiSelector().text(title)) + Log.i(TAG, "openRecentlyVisitedSearchGroupHistoryList: Waiting for $waitingTimeShort ms for recently visited search group with title: $title to exist") searchGroup.waitForExists(waitingTimeShort) + Log.i(TAG, "openRecentlyVisitedSearchGroupHistoryList: Waited for $waitingTimeShort ms for recently visited search group with title: $title to exist") + Log.i(TAG, "openRecentlyVisitedSearchGroupHistoryList: Trying to click recently visited search group with title: $title") searchGroup.click() + Log.i(TAG, "openRecentlyVisitedSearchGroupHistoryList: Clicked recently visited search group with title: $title") HistoryRobot().interact() return HistoryRobot.Transition() } fun openCustomizeHomepage(interact: SettingsSubMenuHomepageRobot.() -> Unit): SettingsSubMenuHomepageRobot.Transition { + Log.i(TAG, "openCustomizeHomepage: Trying to perform ${LISTS_MAXSWIPES}x a scroll action to the end of the home screen") homeScreenList().scrollToEnd(LISTS_MAXSWIPES) + Log.i(TAG, "openCustomizeHomepage: Performed ${LISTS_MAXSWIPES}x a scroll action to the end of the home screen") + Log.i(TAG, "openCustomizeHomepage: Trying to click \"Customize homepage\" button and wait for $waitingTime ms for a new window") mDevice.findObject( UiSelector() .textContains( "Customize homepage", ), ).clickAndWaitForNewWindow(waitingTime) + Log.i(TAG, "openCustomizeHomepage: Clicked \"Customize homepage\" button and wait for $waitingTime ms for a new window") SettingsSubMenuHomepageRobot().interact() return SettingsSubMenuHomepageRobot.Transition() } fun clickJumpBackInShowAllButton(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + Log.i(TAG, "clickJumpBackInShowAllButton: Trying to click \"Show all\" button and wait for $waitingTime ms for a new window") mDevice .findObject( UiSelector() .textContains(getStringResource(R.string.recent_tabs_show_all)), ).clickAndWaitForNewWindow(waitingTime) + Log.i(TAG, "clickJumpBackInShowAllButton: Clicked \"Show all\" button and wait for $waitingTime ms for a new window") TabDrawerRobot().interact() return TabDrawerRobot.Transition() } fun clickJumpBackInShowAllButton(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition { + Log.i(TAG, "clickJumpBackInShowAllButton: Trying to click \"Show all\" button and wait for $waitingTime ms for a new window") mDevice .findObject( UiSelector() .textContains(getStringResource(R.string.recent_tabs_show_all)), ).clickAndWaitForNewWindow(waitingTime) + Log.i(TAG, "clickJumpBackInShowAllButton: Clicked \"Show all\" button and wait for $waitingTime ms for a new window") ComposeTabDrawerRobot(composeTestRule).interact() return ComposeTabDrawerRobot.Transition(composeTestRule) } fun clickPocketStoryItem(publisher: String, position: Int, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "clickPocketStoryItem: Trying to click pocket story item published by: $publisher at position: $position and wait for $waitingTime ms for a new window") mDevice.findObject( UiSelector() .className("android.view.View") @@ -786,18 +978,25 @@ class HomeScreenRobot { .index(1) .textContains(publisher), ).clickAndWaitForNewWindow(waitingTime) + Log.i(TAG, "clickPocketStoryItem: Clicked pocket story item published by: $publisher at position: $position and wait for $waitingTime ms for a new window") BrowserRobot().interact() return BrowserRobot.Transition() } fun clickPocketDiscoverMoreButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "clickPocketDiscoverMoreButton: Trying to scroll into view the \"Discover more\" button") pocketStoriesList() .scrollIntoView(UiSelector().text("Discover more")) + Log.i(TAG, "clickPocketDiscoverMoreButton: Scrolled into view the \"Discover more\" button") mDevice.findObject(UiSelector().text("Discover more")).also { + Log.i(TAG, "clickPocketDiscoverMoreButton: Waiting for $waitingTime ms for \"Discover more\" button to exist") it.waitForExists(waitingTimeShort) + Log.i(TAG, "clickPocketDiscoverMoreButton: Waited for $waitingTime ms for \"Discover more\" button to exist") + Log.i(TAG, "clickPocketDiscoverMoreButton: Trying to click \"Discover more\" button") it.click() + Log.i(TAG, "clickPocketDiscoverMoreButton: Clicked \"Discover more\" button") } BrowserRobot().interact() @@ -805,7 +1004,9 @@ class HomeScreenRobot { } fun clickPocketLearnMoreLink(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "clickPocketLearnMoreLink: Trying to click pocket \"Learn more\" link") composeTestRule.onNodeWithTag("pocket.header.subtitle", true).performClick() + Log.i(TAG, "clickPocketLearnMoreLink: Clicked pocket \"Learn more\" link") BrowserRobot().interact() return BrowserRobot.Transition() @@ -815,9 +1016,11 @@ class HomeScreenRobot { composeTestRule: ComposeTestRule, interact: SettingsRobot.() -> Unit, ): SettingsRobot.Transition { + Log.i(TAG, "clickSetAsDefaultBrowserOnboardingButton: Trying to click \"Set as default browser\" onboarding button") composeTestRule.onNodeWithText( getStringResource(R.string.juno_onboarding_default_browser_positive_button), ).performClick() + Log.i(TAG, "clickSetAsDefaultBrowserOnboardingButton: Clicked \"Set as default browser\" onboarding button") SettingsRobot().interact() return SettingsRobot.Transition() @@ -827,9 +1030,11 @@ class HomeScreenRobot { composeTestRule: ComposeTestRule, interact: SyncSignInRobot.() -> Unit, ): SyncSignInRobot.Transition { + Log.i(TAG, "clickSignInOnboardingButton: Trying to click \"Sign in\" onboarding button") composeTestRule.onNodeWithText( getStringResource(R.string.juno_onboarding_sign_in_positive_button), ).performClick() + Log.i(TAG, "clickSignInOnboardingButton: Clicked \"Sign in\" onboarding button") SyncSignInRobot().interact() return SyncSignInRobot.Transition() From 56ae080d8374021e87617e53757c244fcca47284 Mon Sep 17 00:00:00 2001 From: "oana.horvath" Date: Tue, 6 Feb 2024 14:44:20 +0200 Subject: [PATCH 117/586] Bug 1878868 - Create TestSetup helper: Test classes A-C --- .../org/mozilla/fenix/helpers/TestSetup.kt | 50 +++++++++++++++++++ .../mozilla/fenix/ui/AddressAutofillTest.kt | 22 +------- .../org/mozilla/fenix/ui/BookmarksTest.kt | 33 ++---------- .../fenix/ui/BrowsingErrorPagesTest.kt | 23 +-------- .../org/mozilla/fenix/ui/CollectionTest.kt | 26 ++-------- .../org/mozilla/fenix/ui/ContextMenusTest.kt | 30 ++--------- .../fenix/ui/CookieBannerBlockerTest.kt | 3 +- .../mozilla/fenix/ui/CrashReportingTest.kt | 26 ++-------- .../fenix/ui/CreditCardAutofillTest.kt | 22 +------- .../org/mozilla/fenix/ui/CustomTabsTest.kt | 30 ++--------- 10 files changed, 74 insertions(+), 191 deletions(-) create mode 100644 fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt new file mode 100644 index 000000000000..d19f50c3ffe2 --- /dev/null +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt @@ -0,0 +1,50 @@ +package org.mozilla.fenix.helpers + +import android.util.Log +import kotlinx.coroutines.runBlocking +import mozilla.appservices.places.BookmarkRoot +import mozilla.components.browser.storage.sync.PlacesBookmarksStorage +import okhttp3.mockwebserver.MockWebServer +import org.junit.Before +import org.mozilla.fenix.helpers.Constants.TAG +import org.mozilla.fenix.helpers.TestHelper.appContext +import org.mozilla.fenix.ui.robots.notificationShade + +open class TestSetup { + lateinit var mockWebServer: MockWebServer + private val bookmarksStorage = PlacesBookmarksStorage(appContext.applicationContext) + + @Before + fun setUp() { + Log.i(TAG, "TestSetup: Starting the @Before setup") + // Clear pre-existing notifications + notificationShade { + cancelAllShownNotifications() + } + runBlocking { + // Reset locale to EN-US if needed. + AppAndSystemHelper.resetSystemLocaleToEnUS() + // Check and clear the downloads folder + AppAndSystemHelper.clearDownloadsFolder() + // Make sure the Wifi and Mobile Data connections are on + AppAndSystemHelper.setNetworkEnabled(true) + // Clear bookmarks left after a failed test + val bookmarks = bookmarksStorage.getTree(BookmarkRoot.Mobile.id)?.children + Log.i(TAG, "Before cleanup: Bookmarks storage contains: $bookmarks") + bookmarks?.forEach { bookmarksStorage.deleteNode(it.guid) } + // TODO: Follow-up with a method to handle the DB update; the logs will still show the bookmarks in the storage before the test starts. + Log.i(TAG, "After cleanup: Bookmarks storage contains: $bookmarks") + } + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + } + try { + Log.i(TAG, "Try starting mockWebServer") + mockWebServer.start() + } catch (e: Exception) { + Log.i(TAG, "Exception caught. Re-starting mockWebServer") + mockWebServer.shutdown() + mockWebServer.start() + } + } +} diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt index 4631b8a7ac3e..b8b675778923 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt @@ -4,27 +4,22 @@ 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.customannotations.SmokeTest -import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.packageName +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.autofillScreen import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar -class AddressAutofillTest { - private lateinit var mockWebServer: MockWebServer - +class AddressAutofillTest : TestSetup() { object FirstAddressAutofillDetails { var navigateToAutofillSettings = true var isAddressAutofillEnabled = true @@ -58,19 +53,6 @@ class AddressAutofillTest { @get:Rule val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() - @Before - fun setUp() { - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836845 @SmokeTest @Test diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt index 2d2a1fc9723b..8b7b220ceb5b 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt @@ -8,20 +8,13 @@ import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu import androidx.test.espresso.Espresso.pressBack import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation -import androidx.test.uiautomator.UiDevice import kotlinx.coroutines.runBlocking -import mozilla.appservices.places.BookmarkRoot -import okhttp3.mockwebserver.MockWebServer -import org.junit.After -import org.junit.Before import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest -import org.mozilla.fenix.ext.bookmarkStorage import org.mozilla.fenix.ext.settings -import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MockBrowserDataHelper.createBookmarkItem @@ -31,8 +24,10 @@ import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.appContext import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem +import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.restartApp import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.bookmarksMenu import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.homeScreen @@ -42,9 +37,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar /** * Tests for verifying basic functionality of bookmarks */ -class BookmarksTest { - private lateinit var mockWebServer: MockWebServer - private lateinit var mDevice: UiDevice +class BookmarksTest : TestSetup() { private val bookmarksFolderName = "New Folder" private val testBookmark = object { var title: String = "Bookmark title" @@ -61,26 +54,6 @@ class BookmarksTest { @JvmField val retryTestRule = RetryTestRule(3) - @Before - fun setUp() { - mDevice = UiDevice.getInstance(getInstrumentation()) - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - // Clearing all bookmarks data after each test to avoid overlapping data - val bookmarksStorage = activityTestRule.activity?.bookmarkStorage - runBlocking { - val bookmarks = bookmarksStorage?.getTree(BookmarkRoot.Mobile.id)?.children - bookmarks?.forEach { bookmarksStorage.deleteNode(it.guid) } - } - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/522919 @Test fun verifyEmptyBookmarksMenuTest() { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt index de05a516a622..608c0e9191c0 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt @@ -5,20 +5,17 @@ package org.mozilla.fenix.ui import androidx.core.net.toUri -import okhttp3.mockwebserver.MockWebServer -import org.junit.After -import org.junit.Before import org.junit.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.AppAndSystemHelper.setNetworkEnabled import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.navigationToolbar @@ -26,13 +23,12 @@ import org.mozilla.fenix.ui.robots.navigationToolbar /** * Tests that verify errors encountered while browsing websites: unsafe pages, connection errors, etc */ -class BrowsingErrorPagesTest { +class BrowsingErrorPagesTest : TestSetup() { private val malwareWarning = getStringResource(R.string.mozac_browser_errorpages_safe_browsing_malware_uri_title) private val phishingWarning = getStringResource(R.string.mozac_browser_errorpages_safe_phishing_uri_title) private val unwantedSoftwareWarning = getStringResource(R.string.mozac_browser_errorpages_safe_browsing_unwanted_uri_title) private val harmfulSiteWarning = getStringResource(R.string.mozac_browser_errorpages_safe_harmful_uri_title) - private lateinit var mockWebServer: MockWebServer @get: Rule val mActivityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides() @@ -41,21 +37,6 @@ class BrowsingErrorPagesTest { @JvmField val retryTestRule = RetryTestRule(3) - @Before - fun setUp() { - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - // Restoring network connection - setNetworkEnabled(true) - mockWebServer.shutdown() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326774 @SmokeTest @Test diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt index c917f4d3fc5f..74e7b136ccb6 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt @@ -5,20 +5,16 @@ 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.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.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.collectionRobot import org.mozilla.fenix.ui.robots.homeScreen @@ -30,9 +26,7 @@ import org.mozilla.fenix.ui.robots.tabDrawer * */ -class CollectionTest { - private lateinit var mDevice: UiDevice - private lateinit var mockWebServer: MockWebServer +class CollectionTest : TestSetup() { private val firstCollectionName = "testcollection_1" private val secondCollectionName = "testcollection_2" private val collectionName = "First Collection" @@ -51,20 +45,6 @@ class CollectionTest { ), ) { it.activity } - @Before - fun setUp() { - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/353823 @SmokeTest @Test diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt index eeeec68a73e6..80f2d2a75c86 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt @@ -5,15 +5,8 @@ package org.mozilla.fenix.ui import androidx.core.net.toUri -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.uiautomator.UiDevice -import okhttp3.mockwebserver.MockWebServer -import org.junit.After -import org.junit.Before import org.junit.Rule import org.junit.Test -import org.mozilla.fenix.ext.settings -import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AppAndSystemHelper.assertExternalAppOpens import org.mozilla.fenix.helpers.Constants.PackageName.YOUTUBE_APP import org.mozilla.fenix.helpers.HomeActivityIntentTestRule @@ -22,7 +15,9 @@ 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.clickSnackbarButton +import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.clickContextMenuItem import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.downloadRobot @@ -44,32 +39,15 @@ import org.mozilla.fenix.ui.robots.shareOverlay * */ -class ContextMenusTest { - private lateinit var mDevice: UiDevice - private lateinit var mockWebServer: MockWebServer +class ContextMenusTest : TestSetup() { @get:Rule - val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + val activityIntentTestRule = HomeActivityIntentTestRule(isJumpBackInCFREnabled = false) @Rule @JvmField val retryTestRule = RetryTestRule(3) - @Before - fun setUp() { - activityIntentTestRule.activity.applicationContext.settings().shouldShowJumpBackInCFR = false - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243837 @Test fun verifyOpenLinkNewTabContextMenuOptionTest() { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt index 7ff48e390f3e..cc9fff3d17e7 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt @@ -12,13 +12,14 @@ import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithCondition import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.TestHelper.appContext +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar /** * Tests for verifying the new Cookie banner blocker option and functionality. */ -class CookieBannerBlockerTest { +class CookieBannerBlockerTest : TestSetup() { @get:Rule val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt index f246930bd4e4..84083e014ddf 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt @@ -5,29 +5,23 @@ 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.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest -import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.TestAssetHelper +import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar -class CrashReportingTest { - private lateinit var mDevice: UiDevice - private lateinit var mockWebServer: MockWebServer +class CrashReportingTest : TestSetup() { private val tabCrashMessage = getStringResource(R.string.tab_crash_title_2) @get:Rule @@ -40,20 +34,6 @@ class CrashReportingTest { ), ) { it.activity } - @Before - fun setUp() { - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/308906 @Test fun closeTabFromCrashedTabReporterTest() { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt index f9eb0891b377..9a9b5697bfe1 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt @@ -4,13 +4,9 @@ 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.customannotations.SmokeTest -import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AppAndSystemHelper.bringAppToForeground import org.mozilla.fenix.helpers.AppAndSystemHelper.putAppToBackground import org.mozilla.fenix.helpers.HomeActivityIntentTestRule @@ -19,14 +15,13 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.packageName +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar import java.time.LocalDate -class CreditCardAutofillTest { - private lateinit var mockWebServer: MockWebServer - +class CreditCardAutofillTest : TestSetup() { object MockCreditCard1 { const val MOCK_CREDIT_CARD_NUMBER = "5555555555554444" const val MOCK_LAST_CARD_DIGITS = "4444" @@ -48,19 +43,6 @@ class CreditCardAutofillTest { @get:Rule val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() - @Before - fun setUp() { - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512792 @SmokeTest @Test diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt index b014dbb6156e..1e2aa93e832f 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt @@ -7,25 +7,20 @@ package org.mozilla.fenix.ui import androidx.core.net.toUri -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.rule.ActivityTestRule -import androidx.test.uiautomator.UiDevice -import okhttp3.mockwebserver.MockWebServer -import org.junit.After -import org.junit.Before import org.junit.Rule import org.junit.Test import org.mozilla.fenix.IntentReceiverActivity import org.mozilla.fenix.customannotations.SmokeTest -import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AppAndSystemHelper.openAppFromExternalLink import org.mozilla.fenix.helpers.DataGenerationHelper.createCustomTabIntent -import org.mozilla.fenix.helpers.FeatureSettingsHelperDelegate import org.mozilla.fenix.helpers.HomeActivityIntentTestRule 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.TestHelper.exitMenu +import org.mozilla.fenix.helpers.TestHelper.mDevice +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.customTabScreen @@ -36,9 +31,7 @@ import org.mozilla.fenix.ui.robots.notificationShade import org.mozilla.fenix.ui.robots.openEditURLView import org.mozilla.fenix.ui.robots.searchScreen -class CustomTabsTest { - private lateinit var mDevice: UiDevice - private lateinit var mockWebServer: MockWebServer +class CustomTabsTest : TestSetup() { private val customMenuItem = "TestMenuItem" private val customTabActionButton = "CustomActionButton" @@ -58,23 +51,6 @@ class CustomTabsTest { false, ) - private val featureSettingsHelper = FeatureSettingsHelperDelegate() - - @Before - fun setUp() { - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - featureSettingsHelper.resetAllFeatureFlags() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/249659 @SmokeTest @Test From dd540f05aaa3bd78d5737fca9e481b1cd04e010a Mon Sep 17 00:00:00 2001 From: Alexandru2909 Date: Tue, 6 Feb 2024 20:21:06 +0200 Subject: [PATCH 118/586] Bug 1848139 - Remove unnecessary glean-gradle-plugin step from crash and nimbus builds --- .../components/lib/crash/README.md | 2 +- .../components/lib/crash/build.gradle | 1 - .../components/lib/crash/docs/metrics.md | 66 ------------------- .../components/service/nimbus/build.gradle | 1 - .../components/service/nimbus/docs/metrics.md | 34 ---------- 5 files changed, 1 insertion(+), 103 deletions(-) delete mode 100644 android-components/components/lib/crash/docs/metrics.md delete mode 100644 android-components/components/service/nimbus/docs/metrics.md diff --git a/android-components/components/lib/crash/README.md b/android-components/components/lib/crash/README.md index 00e8224e3132..43208dd3ceb4 100644 --- a/android-components/components/lib/crash/README.md +++ b/android-components/components/lib/crash/README.md @@ -106,7 +106,7 @@ CrashReporter( [Glean](https://docs.telemetry.mozilla.org/concepts/glean/glean.html) is a new way to collect telemetry by Mozilla. This will record crash counts as a labeled counter with each label corresponding to a specific type of crash (`fatal_native_code_crash`, `nonfatal_native_code_crash`, `caught_exception`, `uncaught_exception`, currently). -The list of collected metrics is available in the [metrics.yaml file](metrics.yaml), with their documentation [living here](docs/metrics.md). +The list of collected metrics is available in the [metrics.yaml file](metrics.yaml), with their documentation [living here](https://dictionary.telemetry.mozilla.org/apps/fenix/pings/crash). Due to the fact that Glean can only be recorded to in the main process and lib-crash runs in a separate process when it runs to handle the crash, lib-crash persists the data in a file format and then reads and records the data from the main process when the application is next run since the `GleanCrashReporterService` constructor is loaded from the main process. diff --git a/android-components/components/lib/crash/build.gradle b/android-components/components/lib/crash/build.gradle index e4cc3ea84964..ae0e55bdd8d1 100644 --- a/android-components/components/lib/crash/build.gradle +++ b/android-components/components/lib/crash/build.gradle @@ -90,7 +90,6 @@ dependencies { testImplementation ComponentsDependencies.mozilla_glean_forUnitTests } -ext.gleanGenerateMarkdownDocs = true apply plugin: "org.mozilla.telemetry.glean-gradle-plugin" apply from: '../../../android-lint.gradle' apply from: '../../../publish.gradle' diff --git a/android-components/components/lib/crash/docs/metrics.md b/android-components/components/lib/crash/docs/metrics.md deleted file mode 100644 index 5b51f9c8ce29..000000000000 --- a/android-components/components/lib/crash/docs/metrics.md +++ /dev/null @@ -1,66 +0,0 @@ - - -# Metrics - -This document enumerates the metrics collected by this project using the [Glean SDK](https://mozilla.github.io/glean/book/index.html). -This project may depend on other projects which also collect metrics. -This means you might have to go searching through the dependency tree to get a full picture of everything collected by this project. - -# Pings - -- [crash](#crash) -- [metrics](#metrics) - -## crash - -A ping to report crash information. This information is sent as soon as possible after a crash occurs (whether the crash is a background/content process or the main process). It is expected to be used for crash report analysis and to reduce blind spots in crash reporting. - - -This ping includes the [client id](https://mozilla.github.io/glean/book/user/pings/index.html#the-client_info-section). - -**Data reviews for this ping:** - -- - -**Bugs related to this ping:** - -- - -**Reasons this ping may be sent:** - -- `crash`: A process crashed and a ping was immediately sent. - -- `event_found`: A process crashed and produced a crash event, which was later found and sent in a ping. - - -All Glean pings contain built-in metrics in the [`ping_info`](https://mozilla.github.io/glean/book/user/pings/index.html#the-ping_info-section) and [`client_info`](https://mozilla.github.io/glean/book/user/pings/index.html#the-client_info-section) sections. - -In addition to those built-in metrics, the following metrics are added to the ping: - -| Name | Type | Description | Data reviews | Extras | Expiration | [Data Sensitivity](https://wiki.mozilla.org/Firefox/Data_Collection) | -| --- | --- | --- | --- | --- | --- | --- | -| crash.cause |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |The cause of the crash. May be one of `os_fault` or `java_exception`. |[Bug 1839697](https://bugzilla.mozilla.org/show_bug.cgi?id=1839697#c5)||never |1 | -| crash.process_type |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |The type of process that experienced a crash. See the full list of options [here](https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/data/crash-ping.html#process-types). |[Bug 1790569](https://bugzilla.mozilla.org/show_bug.cgi?id=1790569#c12)||never |1 | -| crash.remote_type |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |Type of the child process, can be set to "web", "file" or "extension" but could also be unavailable. |[Bug 1851518](https://bugzilla.mozilla.org/show_bug.cgi?id=1851518#c6)||never |1 | -| crash.startup |[boolean](https://mozilla.github.io/glean/book/user/metrics/boolean.html) |If true, the crash occurred during process startup. |[Bug 1790569](https://bugzilla.mozilla.org/show_bug.cgi?id=1790569#c12)||never |1 | -| crash.time |[datetime](https://mozilla.github.io/glean/book/user/metrics/datetime.html) |The time at which the crash occurred. |[Bug 1790569](https://bugzilla.mozilla.org/show_bug.cgi?id=1790569#c12)||never |1 | -| crash.uptime |[timespan](https://mozilla.github.io/glean/book/user/metrics/timespan.html) |The application uptime. This is equivalent to the legacy crash ping's `UptimeTS` field. |[Bug 1790569](https://bugzilla.mozilla.org/show_bug.cgi?id=1790569#c12)||never |1 | - -## metrics - -This is a built-in ping that is assembled out of the box by the Glean SDK. - -See the Glean SDK documentation for the [`metrics` ping](https://mozilla.github.io/glean/book/user/pings/metrics.html). - -All Glean pings contain built-in metrics in the [`ping_info`](https://mozilla.github.io/glean/book/user/pings/index.html#the-ping_info-section) and [`client_info`](https://mozilla.github.io/glean/book/user/pings/index.html#the-client_info-section) sections. - -In addition to those built-in metrics, the following metrics are added to the ping: - -| Name | Type | Description | Data reviews | Extras | Expiration | [Data Sensitivity](https://wiki.mozilla.org/Firefox/Data_Collection) | -| --- | --- | --- | --- | --- | --- | --- | -| crash_metrics.crash_count |[labeled_counter](https://mozilla.github.io/glean/book/user/metrics/labeled_counters.html) |Counts the number of crashes that occur in the application. This measures only the counts of each crash in association with the labeled type of the crash. The labels correspond to the types of crashes handled by lib-crash. Deprecated: `native_code_crash`, `fatal_native_code_crash` and `nonfatal_native_code_crash` replaced by `main_proc_native_code_crash`, `fg_proc_native_code_crash` and `bg_proc_native_code_crash`. |[Bug 1553935](https://bugzilla.mozilla.org/show_bug.cgi?id=1553935#c3), [mozilla-mobile/android-components#5700](https://github.com/mozilla-mobile/android-components/pull/5700#pullrequestreview-347721248), [mozilla-mobile/android-components#11908](https://github.com/mozilla-mobile/android-components/pull/11908#issuecomment-1075243414)|
  • uncaught_exception
  • caught_exception
  • main_proc_native_code_crash
  • fg_proc_native_code_crash
  • bg_proc_native_code_crash
  • fatal_native_code_crash
  • nonfatal_native_code_crash
|never |1 | - -Data categories are [defined here](https://wiki.mozilla.org/Firefox/Data_Collection). - - - diff --git a/android-components/components/service/nimbus/build.gradle b/android-components/components/service/nimbus/build.gradle index 0bc272aac838..d233169ce3c7 100644 --- a/android-components/components/service/nimbus/build.gradle +++ b/android-components/components/service/nimbus/build.gradle @@ -121,5 +121,4 @@ nimbus { ? gradle.getProperty('localProperties.autoPublish.application-services.dir') : null } -ext.gleanGenerateMarkdownDocs = true apply plugin: "org.mozilla.telemetry.glean-gradle-plugin" diff --git a/android-components/components/service/nimbus/docs/metrics.md b/android-components/components/service/nimbus/docs/metrics.md deleted file mode 100644 index 4a490068bd80..000000000000 --- a/android-components/components/service/nimbus/docs/metrics.md +++ /dev/null @@ -1,34 +0,0 @@ - - -# Metrics - -This document enumerates the metrics collected by this project using the [Glean SDK](https://mozilla.github.io/glean/book/index.html). -This project may depend on other projects which also collect metrics. -This means you might have to go searching through the dependency tree to get a full picture of everything collected by this project. - -# Pings - -- [events](#events) - -## events - -This is a built-in ping that is assembled out of the box by the Glean SDK. - -See the Glean SDK documentation for the [`events` ping](https://mozilla.github.io/glean/book/user/pings/events.html). - -All Glean pings contain built-in metrics in the [`ping_info`](https://mozilla.github.io/glean/book/user/pings/index.html#the-ping_info-section) and [`client_info`](https://mozilla.github.io/glean/book/user/pings/index.html#the-client_info-section) sections. - -In addition to those built-in metrics, the following metrics are added to the ping: - -| Name | Type | Description | Data reviews | Extras | Expiration | [Data Sensitivity](https://wiki.mozilla.org/Firefox/Data_Collection) | -| --- | --- | --- | --- | --- | --- | --- | -| messaging.malformed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A message was malformed. |[mozilla-mobile/fenix/issues/24224](https://github.com/mozilla-mobile/fenix/issues/24224), [mozilla-mobile/firefox-android#1101](https://github.com/mozilla-mobile/firefox-android/pull/1101)|
  • message_key: The id of the message
|never |2 | -| messaging.message_clicked |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A message was clicked by the user. |[mozilla-mobile/fenix/issues/24224](https://github.com/mozilla-mobile/fenix/issues/24224), [mozilla-mobile/firefox-android#1101](https://github.com/mozilla-mobile/firefox-android/pull/1101)|
  • action_uuid: The uuid of the action
  • message_key: The id of the message
|never |2 | -| messaging.message_dismissed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A message was dismissed by the user. |[mozilla-mobile/fenix/issues/24224](https://github.com/mozilla-mobile/fenix/issues/24224), [mozilla-mobile/firefox-android#1101](https://github.com/mozilla-mobile/firefox-android/pull/1101)|
  • message_key: The id of the message
|never |2 | -| messaging.message_expired |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A message maxDisplayCount has been surpassed. |[mozilla-mobile/fenix/issues/24224](https://github.com/mozilla-mobile/fenix/issues/24224), [mozilla-mobile/firefox-android#1101](https://github.com/mozilla-mobile/firefox-android/pull/1101)|
  • message_key: The id of the message
|never |2 | -| messaging.message_shown |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A message was shown to the user. |[mozilla-mobile/fenix#24426](https://github.com/mozilla-mobile/fenix/pull/24426), [mozilla-mobile/firefox-android#1101](https://github.com/mozilla-mobile/firefox-android/pull/1101)|
  • message_key: The id of the message
|never |2 | - -Data categories are [defined here](https://wiki.mozilla.org/Firefox/Data_Collection). - - - From b6efccdd0df0d50c391b2b5671f776665c24e8e0 Mon Sep 17 00:00:00 2001 From: Noah Bond Date: Tue, 6 Feb 2024 15:50:25 -0800 Subject: [PATCH 119/586] Bug 1860778 - Remove increased fab shadow while it's pressed --- .../org/mozilla/fenix/compose/button/FloatingActionButton.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/compose/button/FloatingActionButton.kt b/fenix/app/src/main/java/org/mozilla/fenix/compose/button/FloatingActionButton.kt index 29ed7f83f278..954e40a61bd2 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/compose/button/FloatingActionButton.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/compose/button/FloatingActionButton.kt @@ -47,7 +47,10 @@ fun FloatingActionButton( modifier: Modifier = Modifier, contentDescription: String? = null, label: String? = null, - elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(defaultElevation = 5.dp), + elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation( + defaultElevation = 5.dp, + pressedElevation = 5.dp, + ), onClick: () -> Unit, ) { FloatingActionButton( From 8044e95d0daa321bbc5cf7888e5a14821a9fa04f Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 7 Feb 2024 17:19:07 +0000 Subject: [PATCH 120/586] Update GeckoView (Nightly) to 124.0.20240207134313. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 73972e4e0d0f..b25fa17aa9d9 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240205205906" + const val version = "124.0.20240207134313" /** * GeckoView channel From 1977419c5ba75c0cf1ddbe2a3a868eadd63f299d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 14:05:00 +0000 Subject: [PATCH 121/586] Bump cryptography Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.6 to 42.0.0. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/41.0.6...42.0.0) --- updated-dependencies: - dependency-name: cryptography dependency-type: indirect ... Signed-off-by: dependabot[bot] --- .../fenix/syncintegration/Pipfile.lock | 59 +++++++++++-------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/Pipfile.lock b/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/Pipfile.lock index 3e3d538a01cc..b42b86bfb55c 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/Pipfile.lock +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/Pipfile.lock @@ -95,7 +95,7 @@ "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" ], - "markers": "python_version >= '3.8'", + "markers": "platform_python_implementation != 'PyPy'", "version": "==1.16.0" }, "charset-normalizer": { @@ -196,33 +196,42 @@ }, "cryptography": { "hashes": [ - "sha256:068bc551698c234742c40049e46840843f3d98ad7ce265fd2bd4ec0d11306596", - "sha256:0f27acb55a4e77b9be8d550d762b0513ef3fc658cd3eb15110ebbcbd626db12c", - "sha256:2132d5865eea673fe6712c2ed5fb4fa49dba10768bb4cc798345748380ee3660", - "sha256:3288acccef021e3c3c10d58933f44e8602cf04dba96d9796d70d537bb2f4bbc4", - "sha256:35f3f288e83c3f6f10752467c48919a7a94b7d88cc00b0668372a0d2ad4f8ead", - "sha256:398ae1fc711b5eb78e977daa3cbf47cec20f2c08c5da129b7a296055fbb22aed", - "sha256:422e3e31d63743855e43e5a6fcc8b4acab860f560f9321b0ee6269cc7ed70cc3", - "sha256:48783b7e2bef51224020efb61b42704207dde583d7e371ef8fc2a5fb6c0aabc7", - "sha256:4d03186af98b1c01a4eda396b137f29e4e3fb0173e30f885e27acec8823c1b09", - "sha256:5daeb18e7886a358064a68dbcaf441c036cbdb7da52ae744e7b9207b04d3908c", - "sha256:60e746b11b937911dc70d164060d28d273e31853bb359e2b2033c9e93e6f3c43", - "sha256:742ae5e9a2310e9dade7932f9576606836ed174da3c7d26bc3d3ab4bd49b9f65", - "sha256:7e00fb556bda398b99b0da289ce7053639d33b572847181d6483ad89835115f6", - "sha256:85abd057699b98fce40b41737afb234fef05c67e116f6f3650782c10862c43da", - "sha256:8efb2af8d4ba9dbc9c9dd8f04d19a7abb5b49eab1f3694e7b5a16a5fc2856f5c", - "sha256:ae236bb8760c1e55b7a39b6d4d32d2279bc6c7c8500b7d5a13b6fb9fc97be35b", - "sha256:afda76d84b053923c27ede5edc1ed7d53e3c9f475ebaf63c68e69f1403c405a8", - "sha256:b27a7fd4229abef715e064269d98a7e2909ebf92eb6912a9603c7e14c181928c", - "sha256:b648fe2a45e426aaee684ddca2632f62ec4613ef362f4d681a9a6283d10e079d", - "sha256:c5a550dc7a3b50b116323e3d376241829fd326ac47bc195e04eb33a8170902a9", - "sha256:da46e2b5df770070412c46f87bac0849b8d685c5f2679771de277a422c7d0b86", - "sha256:f39812f70fc5c71a15aa3c97b2bbe213c3f2a460b79bd21c40d033bb34a9bf36", - "sha256:ff369dd19e8fe0528b02e8df9f2aeb2479f89b1270d90f96a63500afe9af5cae" + "sha256:0a68bfcf57a6887818307600c3c0ebc3f62fbb6ccad2240aa21887cda1f8df1b", + "sha256:146e971e92a6dd042214b537a726c9750496128453146ab0ee8971a0299dc9bd", + "sha256:14e4b909373bc5bf1095311fa0f7fcabf2d1a160ca13f1e9e467be1ac4cbdf94", + "sha256:206aaf42e031b93f86ad60f9f5d9da1b09164f25488238ac1dc488334eb5e221", + "sha256:3005166a39b70c8b94455fdbe78d87a444da31ff70de3331cdec2c568cf25b7e", + "sha256:324721d93b998cb7367f1e6897370644751e5580ff9b370c0a50dc60a2003513", + "sha256:33588310b5c886dfb87dba5f013b8d27df7ffd31dc753775342a1e5ab139e59d", + "sha256:35cf6ed4c38f054478a9df14f03c1169bb14bd98f0b1705751079b25e1cb58bc", + "sha256:3ca482ea80626048975360c8e62be3ceb0f11803180b73163acd24bf014133a0", + "sha256:56ce0c106d5c3fec1038c3cca3d55ac320a5be1b44bf15116732d0bc716979a2", + "sha256:5a217bca51f3b91971400890905a9323ad805838ca3fa1e202a01844f485ee87", + "sha256:678cfa0d1e72ef41d48993a7be75a76b0725d29b820ff3cfd606a5b2b33fda01", + "sha256:69fd009a325cad6fbfd5b04c711a4da563c6c4854fc4c9544bff3088387c77c0", + "sha256:6cf9b76d6e93c62114bd19485e5cb003115c134cf9ce91f8ac924c44f8c8c3f4", + "sha256:74f18a4c8ca04134d2052a140322002fef535c99cdbc2a6afc18a8024d5c9d5b", + "sha256:85f759ed59ffd1d0baad296e72780aa62ff8a71f94dc1ab340386a1207d0ea81", + "sha256:87086eae86a700307b544625e3ba11cc600c3c0ef8ab97b0fda0705d6db3d4e3", + "sha256:8814722cffcfd1fbd91edd9f3451b88a8f26a5fd41b28c1c9193949d1c689dc4", + "sha256:8fedec73d590fd30c4e3f0d0f4bc961aeca8390c72f3eaa1a0874d180e868ddf", + "sha256:9515ea7f596c8092fdc9902627e51b23a75daa2c7815ed5aa8cf4f07469212ec", + "sha256:988b738f56c665366b1e4bfd9045c3efae89ee366ca3839cd5af53eaa1401bce", + "sha256:a2a8d873667e4fd2f34aedab02ba500b824692c6542e017075a2efc38f60a4c0", + "sha256:bd7cf7a8d9f34cc67220f1195884151426ce616fdc8285df9054bfa10135925f", + "sha256:bdce70e562c69bb089523e75ef1d9625b7417c6297a76ac27b1b8b1eb51b7d0f", + "sha256:be14b31eb3a293fc6e6aa2807c8a3224c71426f7c4e3639ccf1a2f3ffd6df8c3", + "sha256:be41b0c7366e5549265adf2145135dca107718fa44b6e418dc7499cfff6b4689", + "sha256:c310767268d88803b653fffe6d6f2f17bb9d49ffceb8d70aed50ad45ea49ab08", + "sha256:c58115384bdcfe9c7f644c72f10f6f42bed7cf59f7b52fe1bf7ae0a622b3a139", + "sha256:c640b0ef54138fde761ec99a6c7dc4ce05e80420262c20fa239e694ca371d434", + "sha256:ca20550bb590db16223eb9ccc5852335b48b8f597e2f6f0878bbfd9e7314eb17", + "sha256:d97aae66b7de41cdf5b12087b5509e4e9805ed6f562406dfcf60e8481a9a28f8", + "sha256:e9326ca78111e4c645f7e49cbce4ed2f3f85e17b61a563328c85a5208cf34440" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==41.0.6" + "version": "==42.0.0" }, "distro": { "hashes": [ From 8aef5bd3c9520a13474a80f8b9a8dd9cbcc88752 Mon Sep 17 00:00:00 2001 From: Aaron Train Date: Wed, 7 Feb 2024 14:15:50 -0500 Subject: [PATCH 122/586] Revert "Bug 1878868 - Create TestSetup helper: Test classes A-C" This reverts commit 56ae080d8374021e87617e53757c244fcca47284. --- .../org/mozilla/fenix/helpers/TestSetup.kt | 50 ------------------- .../mozilla/fenix/ui/AddressAutofillTest.kt | 22 +++++++- .../org/mozilla/fenix/ui/BookmarksTest.kt | 33 ++++++++++-- .../fenix/ui/BrowsingErrorPagesTest.kt | 23 ++++++++- .../org/mozilla/fenix/ui/CollectionTest.kt | 26 ++++++++-- .../org/mozilla/fenix/ui/ContextMenusTest.kt | 30 +++++++++-- .../fenix/ui/CookieBannerBlockerTest.kt | 3 +- .../mozilla/fenix/ui/CrashReportingTest.kt | 26 ++++++++-- .../fenix/ui/CreditCardAutofillTest.kt | 22 +++++++- .../org/mozilla/fenix/ui/CustomTabsTest.kt | 30 +++++++++-- 10 files changed, 191 insertions(+), 74 deletions(-) delete mode 100644 fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt deleted file mode 100644 index d19f50c3ffe2..000000000000 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt +++ /dev/null @@ -1,50 +0,0 @@ -package org.mozilla.fenix.helpers - -import android.util.Log -import kotlinx.coroutines.runBlocking -import mozilla.appservices.places.BookmarkRoot -import mozilla.components.browser.storage.sync.PlacesBookmarksStorage -import okhttp3.mockwebserver.MockWebServer -import org.junit.Before -import org.mozilla.fenix.helpers.Constants.TAG -import org.mozilla.fenix.helpers.TestHelper.appContext -import org.mozilla.fenix.ui.robots.notificationShade - -open class TestSetup { - lateinit var mockWebServer: MockWebServer - private val bookmarksStorage = PlacesBookmarksStorage(appContext.applicationContext) - - @Before - fun setUp() { - Log.i(TAG, "TestSetup: Starting the @Before setup") - // Clear pre-existing notifications - notificationShade { - cancelAllShownNotifications() - } - runBlocking { - // Reset locale to EN-US if needed. - AppAndSystemHelper.resetSystemLocaleToEnUS() - // Check and clear the downloads folder - AppAndSystemHelper.clearDownloadsFolder() - // Make sure the Wifi and Mobile Data connections are on - AppAndSystemHelper.setNetworkEnabled(true) - // Clear bookmarks left after a failed test - val bookmarks = bookmarksStorage.getTree(BookmarkRoot.Mobile.id)?.children - Log.i(TAG, "Before cleanup: Bookmarks storage contains: $bookmarks") - bookmarks?.forEach { bookmarksStorage.deleteNode(it.guid) } - // TODO: Follow-up with a method to handle the DB update; the logs will still show the bookmarks in the storage before the test starts. - Log.i(TAG, "After cleanup: Bookmarks storage contains: $bookmarks") - } - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - } - try { - Log.i(TAG, "Try starting mockWebServer") - mockWebServer.start() - } catch (e: Exception) { - Log.i(TAG, "Exception caught. Re-starting mockWebServer") - mockWebServer.shutdown() - mockWebServer.start() - } - } -} diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt index b8b675778923..4631b8a7ac3e 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt @@ -4,22 +4,27 @@ 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.customannotations.SmokeTest +import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.packageName -import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.autofillScreen import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar -class AddressAutofillTest : TestSetup() { +class AddressAutofillTest { + private lateinit var mockWebServer: MockWebServer + object FirstAddressAutofillDetails { var navigateToAutofillSettings = true var isAddressAutofillEnabled = true @@ -53,6 +58,19 @@ class AddressAutofillTest : TestSetup() { @get:Rule val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + @Before + fun setUp() { + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + start() + } + } + + @After + fun tearDown() { + mockWebServer.shutdown() + } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836845 @SmokeTest @Test diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt index 8b7b220ceb5b..2d2a1fc9723b 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt @@ -8,13 +8,20 @@ import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu import androidx.test.espresso.Espresso.pressBack import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation +import androidx.test.uiautomator.UiDevice import kotlinx.coroutines.runBlocking +import mozilla.appservices.places.BookmarkRoot +import okhttp3.mockwebserver.MockWebServer +import org.junit.After +import org.junit.Before import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.ext.bookmarkStorage import org.mozilla.fenix.ext.settings +import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MockBrowserDataHelper.createBookmarkItem @@ -24,10 +31,8 @@ import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.appContext import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem -import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.restartApp import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText -import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.bookmarksMenu import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.homeScreen @@ -37,7 +42,9 @@ import org.mozilla.fenix.ui.robots.navigationToolbar /** * Tests for verifying basic functionality of bookmarks */ -class BookmarksTest : TestSetup() { +class BookmarksTest { + private lateinit var mockWebServer: MockWebServer + private lateinit var mDevice: UiDevice private val bookmarksFolderName = "New Folder" private val testBookmark = object { var title: String = "Bookmark title" @@ -54,6 +61,26 @@ class BookmarksTest : TestSetup() { @JvmField val retryTestRule = RetryTestRule(3) + @Before + fun setUp() { + mDevice = UiDevice.getInstance(getInstrumentation()) + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + start() + } + } + + @After + fun tearDown() { + mockWebServer.shutdown() + // Clearing all bookmarks data after each test to avoid overlapping data + val bookmarksStorage = activityTestRule.activity?.bookmarkStorage + runBlocking { + val bookmarks = bookmarksStorage?.getTree(BookmarkRoot.Mobile.id)?.children + bookmarks?.forEach { bookmarksStorage.deleteNode(it.guid) } + } + } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/522919 @Test fun verifyEmptyBookmarksMenuTest() { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt index 608c0e9191c0..de05a516a622 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt @@ -5,17 +5,20 @@ package org.mozilla.fenix.ui import androidx.core.net.toUri +import okhttp3.mockwebserver.MockWebServer +import org.junit.After +import org.junit.Before import org.junit.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.AppAndSystemHelper.setNetworkEnabled import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset -import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.navigationToolbar @@ -23,12 +26,13 @@ import org.mozilla.fenix.ui.robots.navigationToolbar /** * Tests that verify errors encountered while browsing websites: unsafe pages, connection errors, etc */ -class BrowsingErrorPagesTest : TestSetup() { +class BrowsingErrorPagesTest { private val malwareWarning = getStringResource(R.string.mozac_browser_errorpages_safe_browsing_malware_uri_title) private val phishingWarning = getStringResource(R.string.mozac_browser_errorpages_safe_phishing_uri_title) private val unwantedSoftwareWarning = getStringResource(R.string.mozac_browser_errorpages_safe_browsing_unwanted_uri_title) private val harmfulSiteWarning = getStringResource(R.string.mozac_browser_errorpages_safe_harmful_uri_title) + private lateinit var mockWebServer: MockWebServer @get: Rule val mActivityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides() @@ -37,6 +41,21 @@ class BrowsingErrorPagesTest : TestSetup() { @JvmField val retryTestRule = RetryTestRule(3) + @Before + fun setUp() { + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + start() + } + } + + @After + fun tearDown() { + // Restoring network connection + setNetworkEnabled(true) + mockWebServer.shutdown() + } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326774 @SmokeTest @Test diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt index 74e7b136ccb6..c917f4d3fc5f 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt @@ -5,16 +5,20 @@ 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.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.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText -import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.collectionRobot import org.mozilla.fenix.ui.robots.homeScreen @@ -26,7 +30,9 @@ import org.mozilla.fenix.ui.robots.tabDrawer * */ -class CollectionTest : TestSetup() { +class CollectionTest { + private lateinit var mDevice: UiDevice + private lateinit var mockWebServer: MockWebServer private val firstCollectionName = "testcollection_1" private val secondCollectionName = "testcollection_2" private val collectionName = "First Collection" @@ -45,6 +51,20 @@ class CollectionTest : TestSetup() { ), ) { it.activity } + @Before + fun setUp() { + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + start() + } + } + + @After + fun tearDown() { + mockWebServer.shutdown() + } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/353823 @SmokeTest @Test diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt index 80f2d2a75c86..eeeec68a73e6 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt @@ -5,8 +5,15 @@ package org.mozilla.fenix.ui import androidx.core.net.toUri +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import okhttp3.mockwebserver.MockWebServer +import org.junit.After +import org.junit.Before import org.junit.Rule import org.junit.Test +import org.mozilla.fenix.ext.settings +import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AppAndSystemHelper.assertExternalAppOpens import org.mozilla.fenix.helpers.Constants.PackageName.YOUTUBE_APP import org.mozilla.fenix.helpers.HomeActivityIntentTestRule @@ -15,9 +22,7 @@ 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.clickSnackbarButton -import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText -import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.clickContextMenuItem import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.downloadRobot @@ -39,15 +44,32 @@ import org.mozilla.fenix.ui.robots.shareOverlay * */ -class ContextMenusTest : TestSetup() { +class ContextMenusTest { + private lateinit var mDevice: UiDevice + private lateinit var mockWebServer: MockWebServer @get:Rule - val activityIntentTestRule = HomeActivityIntentTestRule(isJumpBackInCFREnabled = false) + val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() @Rule @JvmField val retryTestRule = RetryTestRule(3) + @Before + fun setUp() { + activityIntentTestRule.activity.applicationContext.settings().shouldShowJumpBackInCFR = false + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + start() + } + } + + @After + fun tearDown() { + mockWebServer.shutdown() + } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243837 @Test fun verifyOpenLinkNewTabContextMenuOptionTest() { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt index cc9fff3d17e7..7ff48e390f3e 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt @@ -12,14 +12,13 @@ import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithCondition import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.TestHelper.appContext -import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar /** * Tests for verifying the new Cookie banner blocker option and functionality. */ -class CookieBannerBlockerTest : TestSetup() { +class CookieBannerBlockerTest { @get:Rule val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt index 84083e014ddf..f246930bd4e4 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt @@ -5,23 +5,29 @@ 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.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.TestAssetHelper -import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName -import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar -class CrashReportingTest : TestSetup() { +class CrashReportingTest { + private lateinit var mDevice: UiDevice + private lateinit var mockWebServer: MockWebServer private val tabCrashMessage = getStringResource(R.string.tab_crash_title_2) @get:Rule @@ -34,6 +40,20 @@ class CrashReportingTest : TestSetup() { ), ) { it.activity } + @Before + fun setUp() { + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + start() + } + } + + @After + fun tearDown() { + mockWebServer.shutdown() + } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/308906 @Test fun closeTabFromCrashedTabReporterTest() { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt index 9a9b5697bfe1..f9eb0891b377 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt @@ -4,9 +4,13 @@ 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.customannotations.SmokeTest +import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AppAndSystemHelper.bringAppToForeground import org.mozilla.fenix.helpers.AppAndSystemHelper.putAppToBackground import org.mozilla.fenix.helpers.HomeActivityIntentTestRule @@ -15,13 +19,14 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.packageName -import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar import java.time.LocalDate -class CreditCardAutofillTest : TestSetup() { +class CreditCardAutofillTest { + private lateinit var mockWebServer: MockWebServer + object MockCreditCard1 { const val MOCK_CREDIT_CARD_NUMBER = "5555555555554444" const val MOCK_LAST_CARD_DIGITS = "4444" @@ -43,6 +48,19 @@ class CreditCardAutofillTest : TestSetup() { @get:Rule val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + @Before + fun setUp() { + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + start() + } + } + + @After + fun tearDown() { + mockWebServer.shutdown() + } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512792 @SmokeTest @Test diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt index 1e2aa93e832f..b014dbb6156e 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt @@ -7,20 +7,25 @@ package org.mozilla.fenix.ui import androidx.core.net.toUri +import androidx.test.platform.app.InstrumentationRegistry import androidx.test.rule.ActivityTestRule +import androidx.test.uiautomator.UiDevice +import okhttp3.mockwebserver.MockWebServer +import org.junit.After +import org.junit.Before import org.junit.Rule import org.junit.Test import org.mozilla.fenix.IntentReceiverActivity import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AppAndSystemHelper.openAppFromExternalLink import org.mozilla.fenix.helpers.DataGenerationHelper.createCustomTabIntent +import org.mozilla.fenix.helpers.FeatureSettingsHelperDelegate import org.mozilla.fenix.helpers.HomeActivityIntentTestRule 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.TestHelper.exitMenu -import org.mozilla.fenix.helpers.TestHelper.mDevice -import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.customTabScreen @@ -31,7 +36,9 @@ import org.mozilla.fenix.ui.robots.notificationShade import org.mozilla.fenix.ui.robots.openEditURLView import org.mozilla.fenix.ui.robots.searchScreen -class CustomTabsTest : TestSetup() { +class CustomTabsTest { + private lateinit var mDevice: UiDevice + private lateinit var mockWebServer: MockWebServer private val customMenuItem = "TestMenuItem" private val customTabActionButton = "CustomActionButton" @@ -51,6 +58,23 @@ class CustomTabsTest : TestSetup() { false, ) + private val featureSettingsHelper = FeatureSettingsHelperDelegate() + + @Before + fun setUp() { + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + start() + } + } + + @After + fun tearDown() { + mockWebServer.shutdown() + featureSettingsHelper.resetAllFeatureFlags() + } + // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/249659 @SmokeTest @Test From 1c2a3ea9bf00c0d50149c9c1c25897c6d1cad7a8 Mon Sep 17 00:00:00 2001 From: Roger Yang Date: Mon, 5 Feb 2024 13:53:30 -0500 Subject: [PATCH 123/586] Bug 1832357 - Fallback to loading new window requests in custom tab --- .../customtabs/CustomTabWindowFeature.kt | 9 ++---- .../customtabs/CustomTabWindowFeatureTest.kt | 29 ++++++++++--------- .../browser/ExternalAppBrowserFragment.kt | 4 +-- docs/changelog.md | 5 +++- .../customtabs/ExternalAppBrowserFragment.kt | 18 +----------- 5 files changed, 24 insertions(+), 41 deletions(-) diff --git a/android-components/components/feature/customtabs/src/main/java/mozilla/components/feature/customtabs/CustomTabWindowFeature.kt b/android-components/components/feature/customtabs/src/main/java/mozilla/components/feature/customtabs/CustomTabWindowFeature.kt index 6b6e84137b43..43d72b0791ea 100644 --- a/android-components/components/feature/customtabs/src/main/java/mozilla/components/feature/customtabs/CustomTabWindowFeature.kt +++ b/android-components/components/feature/customtabs/src/main/java/mozilla/components/feature/customtabs/CustomTabWindowFeature.kt @@ -6,7 +6,6 @@ package mozilla.components.feature.customtabs import android.app.Activity import android.content.ActivityNotFoundException -import android.net.Uri import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting.Companion.PRIVATE import androidx.browser.customtabs.CustomTabColorSchemeParams @@ -33,7 +32,6 @@ class CustomTabWindowFeature( private val activity: Activity, private val store: BrowserStore, private val sessionId: String, - internal val onLaunchUrlFallback: (Uri) -> Unit, ) : LifecycleAwareFeature { private var scope: CoroutineScope? = null @@ -87,13 +85,12 @@ class CustomTabWindowFeature( val uri = windowRequest.url.toUri() // This could only fail if the above intent is for our application // and we are not registered to handle its schemes. - // Let's log this to better asses how often this happens in real world and - // if we need to add new schemes to properly support this workflow. - // See Fenix #8412 try { intent.launchUrl(activity, uri) } catch (e: ActivityNotFoundException) { - onLaunchUrlFallback(uri) + // Workaround for unsupported schemes + // See https://bugzilla.mozilla.org/show_bug.cgi?id=1878704 + state.engineState.engineSession?.loadUrl(windowRequest.url) } store.dispatch(ContentAction.ConsumeWindowRequestAction(sessionId)) } diff --git a/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/CustomTabWindowFeatureTest.kt b/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/CustomTabWindowFeatureTest.kt index f46c84612431..4aaaa6759bb2 100644 --- a/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/CustomTabWindowFeatureTest.kt +++ b/android-components/components/feature/customtabs/src/test/java/mozilla/components/feature/customtabs/CustomTabWindowFeatureTest.kt @@ -7,8 +7,6 @@ package mozilla.components.feature.customtabs import android.app.Activity import android.content.ActivityNotFoundException import android.graphics.Color -import android.net.Uri -import androidx.core.net.toUri import androidx.test.ext.junit.runners.AndroidJUnit4 import mozilla.components.browser.state.action.ContentAction import mozilla.components.browser.state.state.BrowserState @@ -17,6 +15,7 @@ import mozilla.components.browser.state.state.CustomTabConfig import mozilla.components.browser.state.state.CustomTabMenuItem import mozilla.components.browser.state.state.createCustomTab import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.concept.engine.EngineSession import mozilla.components.concept.engine.window.WindowRequest import mozilla.components.support.test.any import mozilla.components.support.test.ext.joinBlocking @@ -31,7 +30,6 @@ import org.junit.runner.RunWith import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.verify -import org.mockito.Mockito.verifyNoInteractions @RunWith(AndroidJUnit4::class) class CustomTabWindowFeatureTest { @@ -42,17 +40,22 @@ class CustomTabWindowFeatureTest { private lateinit var store: BrowserStore private val sessionId = "session-uuid" private lateinit var activity: Activity - private val launchUrlFallback: (Uri) -> Unit = spy { _ -> } + private lateinit var engineSession: EngineSession @Before fun setup() { activity = mock() + engineSession = mock() store = spy( BrowserStore( BrowserState( customTabs = listOf( - createCustomTab(id = sessionId, url = "https://www.mozilla.org"), + createCustomTab( + id = sessionId, + url = "https://www.mozilla.org", + engineSession = engineSession, + ), ), ), ), @@ -63,7 +66,7 @@ class CustomTabWindowFeatureTest { @Test fun `given a request to open window, when the url can be handled, then the activity should start`() { - val feature = spy(CustomTabWindowFeature(activity, store, sessionId, launchUrlFallback)) + val feature = spy(CustomTabWindowFeature(activity, store, sessionId)) val windowRequest: WindowRequest = mock() feature.start() @@ -78,7 +81,7 @@ class CustomTabWindowFeatureTest { @Test fun `given a request to open window, when the url can't be handled, then handleError should be called`() { val exception = ActivityNotFoundException() - val feature = spy(CustomTabWindowFeature(activity, store, sessionId, launchUrlFallback)) + val feature = spy(CustomTabWindowFeature(activity, store, sessionId)) val windowRequest: WindowRequest = mock() feature.start() @@ -86,13 +89,12 @@ class CustomTabWindowFeatureTest { whenever(windowRequest.url).thenReturn("blob:https://www.firefox.com") whenever(activity.startActivity(any(), any())).thenThrow(exception) store.dispatch(ContentAction.UpdateWindowRequestAction(sessionId, windowRequest)).joinBlocking() - - verify(launchUrlFallback).invoke("blob:https://www.firefox.com".toUri()) + verify(engineSession).loadUrl("blob:https://www.firefox.com") } @Test fun `creates intent based on default custom tab config`() { - val feature = CustomTabWindowFeature(activity, store, sessionId, launchUrlFallback) + val feature = CustomTabWindowFeature(activity, store, sessionId) val config = CustomTabConfig() val intent = feature.configToIntent(config) @@ -103,7 +105,7 @@ class CustomTabWindowFeatureTest { @Test fun `creates intent based on custom tab config`() { - val feature = CustomTabWindowFeature(activity, store, sessionId, launchUrlFallback) + val feature = CustomTabWindowFeature(activity, store, sessionId) val config = CustomTabConfig( toolbarColor = Color.RED, navigationBarColor = Color.BLUE, @@ -120,7 +122,7 @@ class CustomTabWindowFeatureTest { @Test fun `creates intent with same menu items`() { - val feature = CustomTabWindowFeature(activity, store, sessionId, launchUrlFallback) + val feature = CustomTabWindowFeature(activity, store, sessionId) val config = CustomTabConfig( actionButtonConfig = CustomTabActionButtonConfig( description = "button", @@ -142,7 +144,7 @@ class CustomTabWindowFeatureTest { @Test fun `handles no requests when stopped`() { - val feature = CustomTabWindowFeature(activity, store, sessionId, launchUrlFallback) + val feature = CustomTabWindowFeature(activity, store, sessionId) feature.start() feature.stop() @@ -151,7 +153,6 @@ class CustomTabWindowFeatureTest { whenever(windowRequest.url).thenReturn("https://www.firefox.com") store.dispatch(ContentAction.UpdateWindowRequestAction(sessionId, windowRequest)).joinBlocking() verify(activity, never()).startActivity(any(), any()) - verifyNoInteractions(launchUrlFallback) verify(store, never()).dispatch(ContentAction.ConsumeWindowRequestAction(sessionId)) } } diff --git a/android-components/samples/browser/src/main/java/org/mozilla/samples/browser/ExternalAppBrowserFragment.kt b/android-components/samples/browser/src/main/java/org/mozilla/samples/browser/ExternalAppBrowserFragment.kt index 9c05fb06760c..f397eb870f3e 100644 --- a/android-components/samples/browser/src/main/java/org/mozilla/samples/browser/ExternalAppBrowserFragment.kt +++ b/android-components/samples/browser/src/main/java/org/mozilla/samples/browser/ExternalAppBrowserFragment.kt @@ -71,9 +71,7 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler requireActivity(), components.store, sessionId!!, - ) { - // No-op. Client may override this - } + ) lifecycle.addObserver(windowFeature) if (manifest != null) { diff --git a/docs/changelog.md b/docs/changelog.md index 71ab00f69d56..06a453a17cc4 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -24,6 +24,9 @@ permalink: /changelog/ * Add `showMenuButton` and `hideMenuButton` API to `BrowserToolbar` and `DisplayToolbar` to allow hiding and showing of the menu button in the `BrowserToolbar` [Bug 1864760](https://bugzilla.mozilla.org/show_bug.cgi?id=1864760) +* **feature-customtabs** + * Fallback behaviour when failing to open a new window in custom tab will now be loading the URL directly in the same custom tab. [Bug 1832357](https://bugzilla.mozilla.org/show_bug.cgi?id=1832357) + # 123.0 * [Commits](https://github.com/mozilla-mobile/firefox-android/compare/releases_v122..releases_v123) * [Dependencies](https://github.com/mozilla-mobile/firefox-android/blob/releases_v123/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt) @@ -31,7 +34,7 @@ permalink: /changelog/ * [Configuration](https://github.com/mozilla-mobile/firefox-android/blob/releases_v123/android-components/.config.yml) * **feature-customtabs** - * Sharing a URL from a custom tab always uses the current url of the session. [Bug 1831803](https://bugzilla.mozilla.org/show_bug.cgi?id=1831803) + * Sharing a URL from a custom tab always uses the current url of the session. [Bug 1831803](https://bugzilla.mozilla.org/show_bug.cgi?id=1831803) # 122.0 * [Commits](https://github.com/mozilla-mobile/firefox-android/compare/releases_v121..releases_v122) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt index be147c0393b1..c2df28f24da9 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt @@ -5,7 +5,6 @@ package org.mozilla.fenix.customtabs import android.content.Context -import android.content.Intent import android.view.View import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.isVisible @@ -28,7 +27,6 @@ import mozilla.components.feature.pwa.feature.WebAppHideToolbarFeature import mozilla.components.feature.pwa.feature.WebAppSiteControlsFeature import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.ktx.android.arch.lifecycle.addObservers -import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.R import org.mozilla.fenix.browser.BaseBrowserFragment import org.mozilla.fenix.browser.CustomTabContextMenuCandidate @@ -80,21 +78,7 @@ class ExternalAppBrowserFragment : BaseBrowserFragment() { ) windowFeature.set( - feature = CustomTabWindowFeature( - activity, - components.core.store, - customTabSessionId, - ) { uri -> - val intent = - Intent.parseUri("${BuildConfig.DEEP_LINK_SCHEME}://open?url=$uri", 0) - if (intent.action == Intent.ACTION_VIEW) { - intent.addCategory(Intent.CATEGORY_BROWSABLE) - intent.component = null - intent.selector = null - intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK - } - activity.startActivity(intent) - }, + feature = CustomTabWindowFeature(activity, components.core.store, customTabSessionId), owner = this, view = view, ) From d6f2e48696b1925bc48fdd09335c569b8f703c87 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 31 Jan 2024 21:31:58 -0500 Subject: [PATCH 124/586] Bug 1877889 - Update Sentry to version 7.3.0 --- .../plugins/dependencies/src/main/java/DependenciesPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt index a5bbfff587b4..44340909cd8d 100644 --- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt +++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt @@ -36,7 +36,7 @@ object Versions { const val detekt = "1.23.5" const val ktlint = "0.49.1" - const val sentry = "7.2.0" + const val sentry = "7.3.0" const val zxing = "3.5.2" From 47f7099f5491f7d87ba4d7b9713bb00dc262d66e Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 7 Feb 2024 23:08:14 +0000 Subject: [PATCH 125/586] Update GeckoView (Nightly) to 124.0.20240207192507. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index b25fa17aa9d9..57970e34fc62 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240207134313" + const val version = "124.0.20240207192507" /** * GeckoView channel From 9991e6fb0224219f80c1c84763227579d6376027 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 8 Feb 2024 00:03:17 +0000 Subject: [PATCH 126/586] Import translations from android-l10n --- .../addons/src/main/res/values-sl/strings.xml | 4 +- .../src/main/res/values-nn-rNO/strings.xml | 19 ++++ fenix/app/src/main/res/values-azb/strings.xml | 97 +++++++++++++++++++ fenix/app/src/main/res/values-bg/strings.xml | 3 + fenix/app/src/main/res/values-cy/strings.xml | 3 + fenix/app/src/main/res/values-de/strings.xml | 3 + .../src/main/res/values-es-rAR/strings.xml | 3 + fenix/app/src/main/res/values-hsb/strings.xml | 3 + fenix/app/src/main/res/values-it/strings.xml | 3 + fenix/app/src/main/res/values-iw/strings.xml | 3 + fenix/app/src/main/res/values-ko/strings.xml | 3 + .../src/main/res/values-nn-rNO/strings.xml | 6 ++ .../src/main/res/values-pt-rPT/strings.xml | 3 + fenix/app/src/main/res/values-ru/strings.xml | 3 + fenix/app/src/main/res/values-sl/strings.xml | 4 +- .../src/main/res/values-sv-rSE/strings.xml | 3 + .../app/src/main/res/values-be/strings.xml | 8 +- .../app/src/main/res/values-bg/strings.xml | 7 +- .../app/src/main/res/values-tt/strings.xml | 18 ++-- 19 files changed, 175 insertions(+), 21 deletions(-) diff --git a/android-components/components/feature/addons/src/main/res/values-sl/strings.xml b/android-components/components/feature/addons/src/main/res/values-sl/strings.xml index f5a56ebc8da6..da77caa578be 100644 --- a/android-components/components/feature/addons/src/main/res/values-sl/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-sl/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> dostop do vaših podatkov za %1$d drugih domen + + %1$s, %2$d od %3$d dostop do zavihkov brskalnika @@ -75,7 +77,7 @@ Avtor - Avtorji + Avtorji Zadnja posodobitev diff --git a/android-components/components/feature/prompts/src/main/res/values-nn-rNO/strings.xml b/android-components/components/feature/prompts/src/main/res/values-nn-rNO/strings.xml index f8fc591e3179..8a15c8bacc05 100644 --- a/android-components/components/feature/prompts/src/main/res/values-nn-rNO/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-nn-rNO/strings.xml @@ -18,6 +18,8 @@ Passord Ikkje lagre + + Ikkje no Lagre aldri @@ -26,16 +28,24 @@ Lagre Ikkje oppdater + + Ikkje no Oppdater Passordfeltet kan ikkje stå tomt + Skriv inn passord + Klarte ikkje å lagre innlogginga Lagre denne innlogginga? + + Lagre passord? Vil du oppdatere denne innlogginga? + + Oppdatere passord? Leggje brukarnamn til lagra passord? @@ -85,6 +95,8 @@ Oppgi tid Handsam innloggingar + + Handsam passord Utvid føreslåtte innloggingar @@ -92,6 +104,9 @@ Føreslåtte innloggingar + + Lagra passord + Sende data på nytt til denne nettstaden? Oppdatering av denne sida kan duplisere nylege handlingar, til dømes å sende ei betaling eller leggje igjen ein kommentar to gongar. @@ -103,12 +118,16 @@ Vel betalingskort + + Bruk lagra kort Utvid føreslått betalingskort Minimer føreslått betalingskort Handsam betalingskort + + Handsam kort Lagre dette kortet trygt? diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml index d3b9fa55415a..0e3f87e96f46 100644 --- a/fenix/app/src/main/res/values-azb/strings.xml +++ b/fenix/app/src/main/res/values-azb/strings.xml @@ -295,6 +295,8 @@ اسکن آختاریش موتورونون تنظیم‌لری + + باغلانتی‌نی کلیپ بورددان آل ایجازه وئر @@ -303,9 +305,76 @@ اؤزل اوتورم‌لاردا آختاریش تکلیف‌لرینه ایجازه وئریلسین؟ + + %s آدرس چوبوغونا یازدیغینیز هر شئیی وارساییلان آختاریش موتورونوزلا پایلاشاجاق. %s ایله آختار + + موستقیم آدرس چوبوغوندان آختارین + + آختاریش تنظیم‌لری + + بو دفعه بوردا آختار: + + + %s آختاریش موتورو + + + + اؤزللشدیریلمیش آنایارپاق‌نان تانیش اولون. سون تاغلار، بوکمارک‌لار و آختاریش سونوچلاری بورادا گؤرونه‌جک. + + داها اؤزل اینترنته خوش گلیبسیز + + داها رنگلی، داها گیزلی. پول اوچون دئییل، اینسانلیک اوچون. + + اکرانلاری دگیشمک همیشه‌دن داها آساندیر + + ایندی آیری جهازلارداکی تاغلارلا، قالدیغینیز یئردن ایدامه وئرین. + + باشلایین + + گیریش + + گئچ + + تاغلارینیز دونگل‌لنیر! آیری جهازینیزدا قالدیغینیز یئردن دوام ائدین. + + باغلا + + + + بیلدیریش‌لر %s ایله داها چوخ شئی ائتمه‌گه کومک ائدیر. + + تاغلارینیزی جهازلار آراسیندا دؤنگل‌ ائله‌یین، یئندیرمه‌لری ایداره ائله‌یین، %s گیزلیلیک قوروماسیندان لاب یاخچی یارارلانماق حاقیندا اطلاعات آلین و آیری شئی‌لر. + + ایدامه وئر + + ایندی یوخ + + + + فایرفاکس گیزللیک بیلدیریمی + + + سیزی قوروماغی سئویریک + + گیزلیلیک بیلدیریمی + + وارساییلان مورورچو ائله + + ایندی یوخ + + گیریش + + ایندی یوخ + + بیلدیریش‌لری آچ + + ایندی یوخ ایندی یوخ @@ -326,6 +395,34 @@ عمومی + + آختاریش + + + لغو + + + + + اوست + + آلت + + + + آچیق + + قارانلیق + + باتری ساخلیان طرفیندن تنظیم‌لنیر + + + + رفرش اوچون چک + + آلت‌لر چوبوغونو گیزلتمک اوچون اسکرول ائله‌ + +
diff --git a/fenix/app/src/main/res/values-bg/strings.xml b/fenix/app/src/main/res/values-bg/strings.xml index 36085508a123..04883adee5ec 100644 --- a/fenix/app/src/main/res/values-bg/strings.xml +++ b/fenix/app/src/main/res/values-bg/strings.xml @@ -2183,6 +2183,9 @@ Търсене с %s + + Сменете браузъра по подразбиране + Задайте Firefox като стандартно приложение за отваряне на страници, електронна поща и съобщения. diff --git a/fenix/app/src/main/res/values-cy/strings.xml b/fenix/app/src/main/res/values-cy/strings.xml index 37ff8d461f12..bc5f735d6a5f 100644 --- a/fenix/app/src/main/res/values-cy/strings.xml +++ b/fenix/app/src/main/res/values-cy/strings.xml @@ -2170,6 +2170,9 @@ Chwilio gan %s + + Newidiwch eich porwr rhagosodedig + Gosod dolenni o wefannau, e-byst, a negeseuon i agor yn awtomatig yn Firefox. diff --git a/fenix/app/src/main/res/values-de/strings.xml b/fenix/app/src/main/res/values-de/strings.xml index f970da8caf36..6cbb619a2927 100644 --- a/fenix/app/src/main/res/values-de/strings.xml +++ b/fenix/app/src/main/res/values-de/strings.xml @@ -2205,6 +2205,9 @@ %s-Suche + + Ihren Standardbrowser wechseln + Stellen Sie Links von Websites, E-Mails und Nachrichten so ein, dass sie in Firefox automatisch geöffnet werden. diff --git a/fenix/app/src/main/res/values-es-rAR/strings.xml b/fenix/app/src/main/res/values-es-rAR/strings.xml index 82c069db99ca..91f8340b8b12 100644 --- a/fenix/app/src/main/res/values-es-rAR/strings.xml +++ b/fenix/app/src/main/res/values-es-rAR/strings.xml @@ -2198,6 +2198,9 @@ Buscar en %s + + Cambia tu navegador predeterminado + Configurar enlaces de sitios web, correos electrónicos y mensajes para que se abran automáticamente en Firefox. diff --git a/fenix/app/src/main/res/values-hsb/strings.xml b/fenix/app/src/main/res/values-hsb/strings.xml index c3b5c4e7c235..a43969e127c0 100644 --- a/fenix/app/src/main/res/values-hsb/strings.xml +++ b/fenix/app/src/main/res/values-hsb/strings.xml @@ -2179,6 +2179,9 @@ Z %s pytać + + Waš standardny wobhladowak změnić + Nastajće wotkazy z websydłow, mejlkow a powěsćow, zo bychu so awtomatisce we Firefox wočinili. diff --git a/fenix/app/src/main/res/values-it/strings.xml b/fenix/app/src/main/res/values-it/strings.xml index 8e50ec4f74e0..3a6cd2169c9f 100644 --- a/fenix/app/src/main/res/values-it/strings.xml +++ b/fenix/app/src/main/res/values-it/strings.xml @@ -2214,6 +2214,9 @@ Ricerca %s + + Cambia il browser predefinito + Apri link da siti web, email e messaggi in Firefox per impostazione predefinita. diff --git a/fenix/app/src/main/res/values-iw/strings.xml b/fenix/app/src/main/res/values-iw/strings.xml index 72c8c8a79542..58167cd3ba27 100644 --- a/fenix/app/src/main/res/values-iw/strings.xml +++ b/fenix/app/src/main/res/values-iw/strings.xml @@ -2178,6 +2178,9 @@ חיפוש ב־%s + + החלפת דפדפן ברירת המחדל שלך + הגדרת קישורים מאתרים, מהודעות דוא״ל ומהודעות לפתיחה אוטומטית ב־Firefox. diff --git a/fenix/app/src/main/res/values-ko/strings.xml b/fenix/app/src/main/res/values-ko/strings.xml index 539fed7c058b..c327340f904d 100644 --- a/fenix/app/src/main/res/values-ko/strings.xml +++ b/fenix/app/src/main/res/values-ko/strings.xml @@ -2225,6 +2225,9 @@ %s 검색 + + 기본 브라우저 전환 + Firefox에서 자동으로 열리도록 웹 사이트, 이메일 및 메시지의 링크를 설정합니다. diff --git a/fenix/app/src/main/res/values-nn-rNO/strings.xml b/fenix/app/src/main/res/values-nn-rNO/strings.xml index c4b58e1d2ae8..ce0c47f0c87c 100644 --- a/fenix/app/src/main/res/values-nn-rNO/strings.xml +++ b/fenix/app/src/main/res/values-nn-rNO/strings.xml @@ -248,6 +248,7 @@ Tilpasse startsida + Startskjerm @@ -255,6 +256,9 @@ Slett nettlesarhistorikk + + Omset sida + Valt språk @@ -2383,6 +2387,8 @@ Omsetjing i framdrift + + Vel eit språk Det oppstod eit problem med å omsetje. Prøv på nytt. diff --git a/fenix/app/src/main/res/values-pt-rPT/strings.xml b/fenix/app/src/main/res/values-pt-rPT/strings.xml index cfc3e91f19cb..1885805a741c 100644 --- a/fenix/app/src/main/res/values-pt-rPT/strings.xml +++ b/fenix/app/src/main/res/values-pt-rPT/strings.xml @@ -2180,6 +2180,9 @@ Pesquisa %s + + Alterar o seu navegador predefinido + Definir para que as ligações de sites, e-mails e mensagens sejam abertas automaticamente no Firefox. diff --git a/fenix/app/src/main/res/values-ru/strings.xml b/fenix/app/src/main/res/values-ru/strings.xml index 6c1ec56f56a6..93e9cd3c1c99 100644 --- a/fenix/app/src/main/res/values-ru/strings.xml +++ b/fenix/app/src/main/res/values-ru/strings.xml @@ -2200,6 +2200,9 @@ Поиск в %s + + Смените браузер по умолчанию + Настройте автоматическое открытие ссылок с сайтов, из электронных писем и сообщений в Firefox. diff --git a/fenix/app/src/main/res/values-sl/strings.xml b/fenix/app/src/main/res/values-sl/strings.xml index 1376022d9b7a..91d638d45655 100644 --- a/fenix/app/src/main/res/values-sl/strings.xml +++ b/fenix/app/src/main/res/values-sl/strings.xml @@ -2027,6 +2027,8 @@ Uredi Ali ste prepričani, da želite izbrisati to prijavo? + + Ali ste prepričani, da želite izbrisati to geslo? Izbriši @@ -2168,7 +2170,7 @@ Iskalnik %s - + Nastavite, naj se povezave s spletnih strani, e-pošte in sporočil samodejno odpirajo v Firefoxu. diff --git a/fenix/app/src/main/res/values-sv-rSE/strings.xml b/fenix/app/src/main/res/values-sv-rSE/strings.xml index a7ab3de349d3..b4c270ba6e1c 100644 --- a/fenix/app/src/main/res/values-sv-rSE/strings.xml +++ b/fenix/app/src/main/res/values-sv-rSE/strings.xml @@ -2189,6 +2189,9 @@ Sök med %s + + Ändra din standardwebbläsare + Ställ in länkar från webbplatser, e-post och meddelanden så att de öppnas automatiskt i Firefox. diff --git a/focus-android/app/src/main/res/values-be/strings.xml b/focus-android/app/src/main/res/values-be/strings.xml index a7df565d74a3..2ac0129e8fec 100644 --- a/focus-android/app/src/main/res/values-be/strings.xml +++ b/focus-android/app/src/main/res/values-be/strings.xml @@ -53,7 +53,6 @@ Выдаліць з цэтлікаў - Што новага Налады @@ -87,10 +86,9 @@ sharing an URL. --> Падзяліцца праз - + Сцерці гісторыю аглядання? + Націсніце або ачысціце гэта апавяшчэнне, каб надзейна сцерці гісторыю аглядання. + Сцерці гісторыю аглядання diff --git a/focus-android/app/src/main/res/values-bg/strings.xml b/focus-android/app/src/main/res/values-bg/strings.xml index 323492285e0a..da4903312d0f 100644 --- a/focus-android/app/src/main/res/values-bg/strings.xml +++ b/focus-android/app/src/main/res/values-bg/strings.xml @@ -83,10 +83,9 @@ sharing an URL. --> Споделяне чрез - + Изчистване историята на разглеждането? + Докоснете или изчистете това известие, за да изтриете сигурно историята на сърфирането. + Изчистване историята на разглеждането diff --git a/focus-android/app/src/main/res/values-tt/strings.xml b/focus-android/app/src/main/res/values-tt/strings.xml index 2b5f1e41ec74..1533cb9f5705 100644 --- a/focus-android/app/src/main/res/values-tt/strings.xml +++ b/focus-android/app/src/main/res/values-tt/strings.xml @@ -53,7 +53,6 @@ Ярлыклардан алып ату - Яңалыклар Көйләүләр Хакында Ярдәм @@ -85,10 +84,9 @@ sharing an URL. --> Аша уртаклашу - + Гизү тарихы бетерелсенме? + Гизү тарихыгызны хәвефсез рәвештә бетерү өчен бу искәртүгә басыгыз яки аны чистартыгыз. + Гизү тарихын бетерү @@ -157,7 +155,7 @@ - Стандарт итү, автотөгәлләү + Төп итү, автотөгәлләү @@ -177,7 +175,7 @@ Гомуми - Стандарт браузер, тел + Төп браузер, тел Мәгълүмат туплау һәм аны куллану @@ -191,7 +189,7 @@ %1$s Сез адрес юлында язганны Сезнең эзләү системасына җибәрәчәк - Стандарт + Төп Эзләү системасы @@ -373,7 +371,7 @@ Эзләү системасын сайлау - Стандарт эзләү системаларын яңадан торгызу + Төп эзләү системаларын яңадан торгызу @@ -552,7 +550,7 @@ Сезнең эзләү, Сезнең кагыйдәләр - Башка берәр нәрсә эзлисезме? Көйләүләр менюсына кереп, стандарт итеп башка бер эзләү системасын сайлый аласыз. + Башка берәр нәрсә эзлисезме? Көйләүләр менюсына кереп, төп итеп башка бер эзләү системасын сайлый аласыз. Өй экранына ярлыклар өстәгез From 890a7b2ceadcb9a03df040cb1cd6ff021d1d0b2d Mon Sep 17 00:00:00 2001 From: JohanLorenzo Date: Wed, 7 Feb 2024 20:02:40 +0000 Subject: [PATCH 127/586] Update Fenix initial_experiments.json based on the current first-run experiments in experimenter --- .../src/main/res/raw/initial_experiments.json | 82 ------------------- 1 file changed, 82 deletions(-) diff --git a/fenix/app/src/main/res/raw/initial_experiments.json b/fenix/app/src/main/res/raw/initial_experiments.json index 9369f46a4e9b..f7397a63c0cd 100644 --- a/fenix/app/src/main/res/raw/initial_experiments.json +++ b/fenix/app/src/main/res/raw/initial_experiments.json @@ -389,88 +389,6 @@ "localizations": null, "locales": null, "publishedDate": null - }, - { - "schemaVersion": "1.12.0", - "slug": "splash-screen-test", - "id": "splash-screen-test", - "arguments": {}, - "application": "org.mozilla.firefox", - "appName": "fenix", - "appId": "org.mozilla.firefox", - "channel": "release", - "userFacingName": "Splash screen Test", - "userFacingDescription": "Testing a splasshcreen on app launch.", - "isEnrollmentPaused": true, - "isRollout": false, - "bucketConfig": { - "randomizationUnit": "nimbus_id", - "namespace": "fenix-splash-screen-release-2", - "start": 0, - "count": 10000, - "total": 10000 - }, - "featureIds": [ - "splash-screen" - ], - "probeSets": [], - "outcomes": [ - { - "slug": "onboarding", - "priority": "primary" - } - ], - "branches": [ - { - "slug": "control", - "ratio": 1, - "feature": { - "featureId": "this-is-included-for-mobile-pre-96-support", - "enabled": false, - "value": {} - }, - "features": [ - { - "featureId": "splash-screen", - "enabled": true, - "value": { - "enabled": false, - "maximum_duration_ms": 0 - } - } - ] - }, - { - "slug": "treatment-b", - "ratio": 1, - "feature": { - "featureId": "this-is-included-for-mobile-pre-96-support", - "enabled": false, - "value": {} - }, - "features": [ - { - "featureId": "splash-screen", - "enabled": true, - "value": { - "enabled": true, - "maximum_duration_ms": 6000 - } - } - ] - } - ], - "targeting": "((is_already_enrolled) || ((isFirstRun == 'true') && (app_version|versionCompare('121.!') >= 0) && (region in ['AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AO', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ', 'BR', 'BS', 'BT', 'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'EH', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GG', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IM', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT', 'JE', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KP', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN', 'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PS', 'PT', 'PW', 'PY', 'QA', 'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'SS', 'ST', 'SV', 'SX', 'SY', 'SZ', 'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', 'TK', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TW', 'TZ', 'UA', 'UG', 'UM', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI', 'VN', 'VU', 'WF', 'WS', 'YE', 'YT', 'ZA', 'ZM', 'ZW'])))", - "startDate": "2023-12-06", - "enrollmentEndDate": "2024-01-10", - "endDate": null, - "proposedDuration": 49, - "proposedEnrollment": 21, - "referenceBranch": "control", - "featureValidationOptOut": false, - "localizations": null, - "locales": null, - "publishedDate": null } ] } From 710aeb60b1621cb03dd76e9be043a494de6671a5 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 8 Feb 2024 01:45:46 +0000 Subject: [PATCH 128/586] Update GeckoView (Nightly) to 124.0.20240207214625. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 57970e34fc62..d93f2ac315ad 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240207192507" + const val version = "124.0.20240207214625" /** * GeckoView channel From 0a52c98c014ffd381746c39c8d374b468c4a9a83 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 8 Feb 2024 05:48:37 +0000 Subject: [PATCH 129/586] Update A-S to 124.20240208050312. --- .../plugins/dependencies/src/main/java/ApplicationServices.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt index 036f32d9b7e4..e57bd82fb28a 100644 --- a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt +++ b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // These lines are generated by android-components/automation/application-services-nightly-bump.py -val VERSION = "124.20240207050252" +val VERSION = "124.20240208050312" val CHANNEL = ApplicationServicesChannel.NIGHTLY object ApplicationServicesConfig { From c2ba347dee5b40b8f2b7f7f9dcb24e17ca03dc73 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 8 Feb 2024 13:21:21 +0000 Subject: [PATCH 130/586] Update GeckoView (Nightly) to 124.0.20240208095423. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index d93f2ac315ad..240522b21aeb 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240207214625" + const val version = "124.0.20240208095423" /** * GeckoView channel From bcc0398f67cd2ebc97419a52797972d312b05db0 Mon Sep 17 00:00:00 2001 From: William Durand Date: Thu, 8 Feb 2024 09:43:28 +0100 Subject: [PATCH 131/586] Bug 1870326 - Do not allow the add-on name to be focused (browser action) --- .../src/main/res/layout/mozac_browser_menu_web_extension.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/android-components/components/browser/menu/src/main/res/layout/mozac_browser_menu_web_extension.xml b/android-components/components/browser/menu/src/main/res/layout/mozac_browser_menu_web_extension.xml index b8d1d265f42b..1ccecbf48d99 100644 --- a/android-components/components/browser/menu/src/main/res/layout/mozac_browser_menu_web_extension.xml +++ b/android-components/components/browser/menu/src/main/res/layout/mozac_browser_menu_web_extension.xml @@ -31,6 +31,7 @@ android:paddingEnd="16dp" android:paddingStart="16dp" android:clickable="false" + android:focusable="false" tools:ignore="RtlCompat" tools:text="uBlock Origin" /> From e0006765346d1ca614180956948823990aa9723d Mon Sep 17 00:00:00 2001 From: William Durand Date: Thu, 8 Feb 2024 10:47:17 +0100 Subject: [PATCH 132/586] Bug 1870345 - Mark headings as such in the list of add-ons --- .../components/feature/addons/ui/AddonsManagerAdapter.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt index 5eede548e3bd..4ed1ad119614 100644 --- a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt +++ b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt @@ -18,6 +18,7 @@ import androidx.annotation.DrawableRes import androidx.annotation.StringRes import androidx.annotation.VisibleForTesting import androidx.core.content.ContextCompat +import androidx.core.view.ViewCompat import androidx.core.view.isInvisible import androidx.core.view.isVisible import androidx.recyclerview.widget.DiffUtil @@ -198,6 +199,7 @@ class AddonsManagerAdapter( @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal fun bindSection(holder: SectionViewHolder, section: Section, position: Int) { holder.titleView.setText(section.title) + ViewCompat.setAccessibilityHeading(holder.titleView, true) style?.let { holder.divider.isVisible = it.visibleDividers && position != 0 From 7a6a7944c1d72f00b0799831895fe4a687d7d622 Mon Sep 17 00:00:00 2001 From: William Durand Date: Thu, 8 Feb 2024 10:00:21 +0100 Subject: [PATCH 133/586] Bug 1870329 - Add add-on name to the content description of each install button --- .../components/feature/addons/ui/AddonsManagerAdapter.kt | 5 +++++ .../addons/src/main/res/layout/mozac_feature_addons_item.xml | 1 - .../feature/addons/src/main/res/values/strings.xml | 4 +++- .../fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt index 4ed1ad119614..64c4df655d26 100644 --- a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt +++ b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt @@ -248,6 +248,7 @@ class AddonsManagerAdapter( } @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + @Suppress("LongMethod") internal fun bindAddon( holder: AddonViewHolder, addon: Addon, @@ -291,6 +292,10 @@ class AddonsManagerAdapter( } holder.addButton.isInvisible = addon.isInstalled() + holder.addButton.contentDescription = context.getString( + R.string.mozac_feature_addons_install_addon_content_description_2, + addonName, + ) holder.addButton.setOnClickListener { if (!addon.isInstalled()) { addonsManagerDelegate.onInstallAddonButtonClicked(addon) diff --git a/android-components/components/feature/addons/src/main/res/layout/mozac_feature_addons_item.xml b/android-components/components/feature/addons/src/main/res/layout/mozac_feature_addons_item.xml index 24b066ad25d1..9ed77d46fef8 100644 --- a/android-components/components/feature/addons/src/main/res/layout/mozac_feature_addons_item.xml +++ b/android-components/components/feature/addons/src/main/res/layout/mozac_feature_addons_item.xml @@ -151,7 +151,6 @@ android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:background="?attr/selectableItemBackgroundBorderless" - android:contentDescription="@string/mozac_feature_addons_install_addon_content_description" app:srcCompat="@drawable/mozac_ic_plus_24" app:tint="?android:attr/textColorPrimary" /> diff --git a/android-components/components/feature/addons/src/main/res/values/strings.xml b/android-components/components/feature/addons/src/main/res/values/strings.xml index 2091d64276a9..e1279908e6ce 100644 --- a/android-components/components/feature/addons/src/main/res/values/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values/strings.xml @@ -140,7 +140,9 @@ Cancel - Install Add-on + Install Add-on + + Install %1$s Cancel diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt index 3c73bc82a616..94c5c3f50074 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt @@ -204,7 +204,7 @@ class SettingsSubMenuAddonsManagerRobot { private fun installButtonForAddon(addonName: String) = onView( allOf( - withContentDescription(R.string.mozac_feature_addons_install_addon_content_description), + withContentDescription("Install $addonName"), isDescendantOfA(withId(R.id.add_on_item)), hasSibling(hasDescendant(withText(addonName))), ), From 43987ccc3d79a37f2b0b9ed2c8400af2a4520ca3 Mon Sep 17 00:00:00 2001 From: ohall-m Date: Thu, 8 Feb 2024 12:24:34 -0500 Subject: [PATCH 134/586] Bug 1878365 - Translations AC Page Settings Bug This patch updates: * `requestTranslationPageSettings` is refactored to `requestPageSettings` to match new naming conventions * A missing dispatch in `TranslationsMiddleware` for fetching page settings in `requestPageSettings` * Corrects the test that was not blocking correctly that resulted in the missing dispatch going unnoticed. * Resets the error to null on `SetPageSettingsAction` --- .../middleware/TranslationsMiddleware.kt | 31 ++-- .../state/reducer/TranslationsStateReducer.kt | 1 + .../state/action/TranslationsActionTest.kt | 1 + .../middleware/TranslationsMiddlewareTest.kt | 134 +++++++++++------- 4 files changed, 102 insertions(+), 65 deletions(-) diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt index 0dcae6f3d964..ab984747ef92 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt @@ -48,7 +48,7 @@ class TranslationsMiddleware( } TranslationOperation.FETCH_PAGE_SETTINGS -> { scope.launch { - requestTranslationPageSettings(context, action.tabId) + requestPageSettings(context, action.tabId) } } TranslationOperation.FETCH_NEVER_TRANSLATE_SITES -> { @@ -151,7 +151,7 @@ class TranslationsMiddleware( * @param context Context to use to dispatch to the store. * @param tabId Tab ID associated with the request. */ - private suspend fun requestTranslationPageSettings( + private suspend fun requestPageSettings( context: MiddlewareContext, tabId: String, ) { @@ -175,22 +175,25 @@ class TranslationsMiddleware( neverTranslateLanguage != null && neverTranslateSite != null ) { - TranslationsAction.SetPageSettingsAction( - tabId = tabId, - pageSettings = - TranslationPageSettings( - alwaysOfferPopup = alwaysOfferPopup, - alwaysTranslateLanguage = alwaysTranslateLanguage, - neverTranslateLanguage = neverTranslateLanguage, - neverTranslateSite = neverTranslateSite, + context.store.dispatch( + TranslationsAction.SetPageSettingsAction( + tabId = tabId, + pageSettings = TranslationPageSettings( + alwaysOfferPopup = alwaysOfferPopup, + alwaysTranslateLanguage = alwaysTranslateLanguage, + neverTranslateLanguage = neverTranslateLanguage, + neverTranslateSite = neverTranslateSite, + ), ), ) } else { // Any null values indicate something went wrong, alert an error occurred - TranslationsAction.TranslateExceptionAction( - tabId = tabId, - operation = TranslationOperation.FETCH_PAGE_SETTINGS, - translationError = TranslationError.CouldNotLoadPageSettingsError(null), + context.store.dispatch( + TranslationsAction.TranslateExceptionAction( + tabId = tabId, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + translationError = TranslationError.CouldNotLoadPageSettingsError(null), + ), ) } } diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt index 3930578a5d83..154ae8f4a99b 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt @@ -179,6 +179,7 @@ internal object TranslationsStateReducer { state.copyWithTranslationsState(action.tabId) { it.copy( pageSettings = action.pageSettings, + settingsError = null, ) } diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt index 4e0dc165bc19..0eed569f0604 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt @@ -343,6 +343,7 @@ class TranslationsActionTest { ).joinBlocking() assertEquals(pageSettings, tabState().translationsState.pageSettings) + assertNull(tabState().translationsState.settingsError) // Action started store.dispatch( diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt index 011ab19a4731..237d69a5a85a 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt @@ -21,6 +21,7 @@ import mozilla.components.concept.engine.translate.LanguageSetting import mozilla.components.concept.engine.translate.TranslationEngineState import mozilla.components.concept.engine.translate.TranslationError import mozilla.components.concept.engine.translate.TranslationOperation +import mozilla.components.concept.engine.translate.TranslationPageSettings import mozilla.components.concept.engine.translate.TranslationSupport import mozilla.components.lib.state.MiddlewareContext import mozilla.components.support.test.any @@ -70,6 +71,24 @@ class TranslationsMiddlewareTest { store.waitUntilIdle() } + /** + * Use with tests that need a mock translations engine state. + */ + private fun setupMockState() { + val mockFrom = "es" + val mockTo = "en" + val mockDetectedLanguages = DetectedLanguages( + documentLangTag = mockFrom, + supportedDocumentLang = true, + userPreferredLangTag = mockTo, + ) + val mockState = TranslationsState( + translationEngineState = TranslationEngineState(mockDetectedLanguages), + ) + + whenever(store.state.findTab(tab.id)?.translationsState).thenReturn(mockState) + } + @Test fun `WHEN OperationRequestedAction is dispatched to fetch languages AND succeeds THEN SetSupportedLanguagesAction is dispatched`() = runTest { val supportedLanguages = TranslationSupport( @@ -123,79 +142,92 @@ class TranslationsMiddlewareTest { } @Test - fun `WHEN OperationRequestedAction is dispatched WITH FETCH_PAGE_SETTINGS AND fetching languages is successful THEN TranslationPageSettings is dispatched`() = runTest { - // Mock detected languages are required to pull the language settings - val mockFrom = "es" - val mockTo = "en" - val mockDetectedLanguages = DetectedLanguages( - documentLangTag = mockFrom, - supportedDocumentLang = true, - userPreferredLangTag = mockTo, - ) - val mockState = TranslationsState( - translationEngineState = TranslationEngineState(mockDetectedLanguages), - ) - // Had mock issues when mocking anything more granular - whenever(store.state.findTab(tab.id)?.translationsState).thenReturn(mockState) + fun `WHEN OperationRequestedAction is dispatched WITH FETCH_PAGE_SETTINGS AND fetching settings is successful THEN TranslationPageSettings is dispatched`() = runTest { + // Setup + setupMockState() - // Always offer behavior - val offerResponse = true - whenever(engine.getTranslationsOfferPopup()).thenAnswer { offerResponse } - - // Page language - val languageSettingCallback = argumentCaptor<((LanguageSetting) -> Unit)>() - val languageResponse = LanguageSetting.ALWAYS - whenever( - engine.getLanguageSetting( - languageCode = any(), - onSuccess = languageSettingCallback.capture(), - onError = any(), - ), + val mockPageSettings = TranslationPageSettings( + alwaysOfferPopup = true, + alwaysTranslateLanguage = true, + neverTranslateLanguage = false, + neverTranslateSite = true, ) - .thenAnswer { - languageSettingCallback.value.invoke(languageResponse) - } - // Never translate site behavior - val neverTranslateSiteCallback = argumentCaptor<((Boolean) -> Unit)>() - val neverSiteResponse = true - whenever( - engineSession.getNeverTranslateSiteSetting( - onResult = neverTranslateSiteCallback.capture(), - onException = any(), - ), - ) - .thenAnswer { - neverTranslateSiteCallback.value.invoke(neverSiteResponse) - } + whenever(engine.getTranslationsOfferPopup()).thenAnswer { mockPageSettings.alwaysOfferPopup } - store.dispatch( + // Send Action + val action = TranslationsAction.OperationRequestedAction( tabId = tab.id, operation = TranslationOperation.FETCH_PAGE_SETTINGS, - ), - ).joinBlocking() - + ) + translationsMiddleware.invoke(context, {}, action) waitForIdle() + // Check Behavior + // Popup always offer behavior + verify(engine).getTranslationsOfferPopup() + + // Page language behavior + val languageSettingCallback = argumentCaptor<((LanguageSetting) -> Unit)>() + verify(engine).getLanguageSetting( + languageCode = any(), + onSuccess = languageSettingCallback.capture(), + onError = any(), + ) + val languageResponse = LanguageSetting.ALWAYS + languageSettingCallback.value.invoke(languageResponse) + + // Never translate site behavior behavior + val neverTranslateSiteCallback = argumentCaptor<((Boolean) -> Unit)>() + verify(engineSession).getNeverTranslateSiteSetting( + onResult = neverTranslateSiteCallback.capture(), + onException = any(), + ) + neverTranslateSiteCallback.value.invoke(mockPageSettings.neverTranslateSite!!) + verify(store).dispatch( TranslationsAction.SetPageSettingsAction( tabId = tab.id, - pageSettings = any(), + pageSettings = mockPageSettings, ), ) + waitForIdle() } @Test - fun `WHEN OperationRequestedAction AND fetching data fails THEN TranslateExceptionAction is dispatched`() { - store.dispatch( + fun `WHEN OperationRequestedAction WITH FETCH_PAGE_SETTINGS AND fetching settings fails THEN TranslateExceptionAction is dispatched`() { + // Setup + setupMockState() + whenever(engine.getTranslationsOfferPopup()).thenAnswer { false } + + // Send Action + val action = TranslationsAction.OperationRequestedAction( tabId = tab.id, operation = TranslationOperation.FETCH_PAGE_SETTINGS, - ), - ).joinBlocking() + ) + translationsMiddleware.invoke(context, {}, action) waitForIdle() + // Check Behavior + // Page language behavior + val languageErrorCallback = argumentCaptor<((Throwable) -> Unit)>() + verify(engine).getLanguageSetting( + languageCode = any(), + onSuccess = any(), + onError = languageErrorCallback.capture(), + ) + languageErrorCallback.value.invoke(Throwable()) + + // Never translate site behavior behavior + val neverTranslateSiteErrorCallback = argumentCaptor<((Throwable) -> Unit)>() + verify(engineSession).getNeverTranslateSiteSetting( + onResult = any(), + onException = neverTranslateSiteErrorCallback.capture(), + ) + neverTranslateSiteErrorCallback.value.invoke(Throwable()) + verify(store).dispatch( TranslationsAction.TranslateExceptionAction( tabId = tab.id, From 3a9a39c7586d4c90e3e7553b3e87d4ad2c995c1b Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Fri, 9 Feb 2024 00:16:42 +0000 Subject: [PATCH 135/586] Update GeckoView (Nightly) to 124.0.20240208210654. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 240522b21aeb..5763b408ca4b 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240208095423" + const val version = "124.0.20240208210654" /** * GeckoView channel From 912d4819ef3f8f643067881599aa13469634e2af Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 9 Feb 2024 00:03:29 +0000 Subject: [PATCH 136/586] Import translations from android-l10n --- .../menu/src/main/res/values-et/strings.xml | 2 + .../menu/src/main/res/values-ro/strings.xml | 2 + .../cfr/src/main/res/values-et/strings.xml | 5 + .../src/main/res/values-ro/strings.xml | 7 + .../src/main/res/values-cak/strings.xml | 2 + .../addons/src/main/res/values-et/strings.xml | 34 +++- .../media/src/main/res/values-cak/strings.xml | 23 ++- .../src/main/res/values-cak/strings.xml | 14 ++ .../src/main/res/values-ro/strings.xml | 4 + .../src/main/res/values-ro/strings.xml | 5 + fenix/app/src/main/res/values-azb/strings.xml | 97 ++++++++++ fenix/app/src/main/res/values-de/strings.xml | 2 +- fenix/app/src/main/res/values-el/strings.xml | 3 + .../src/main/res/values-es-rAR/strings.xml | 2 +- fenix/app/src/main/res/values-et/strings.xml | 132 ++++--------- fenix/app/src/main/res/values-fr/strings.xml | 3 + fenix/app/src/main/res/values-ia/strings.xml | 3 + fenix/app/src/main/res/values-kk/strings.xml | 3 + fenix/app/src/main/res/values-nl/strings.xml | 3 + .../src/main/res/values-pa-rIN/strings.xml | 3 + .../src/main/res/values-pt-rBR/strings.xml | 3 + fenix/app/src/main/res/values-ro/strings.xml | 179 ++++++++++++------ .../src/main/res/values-zh-rTW/strings.xml | 3 + 23 files changed, 373 insertions(+), 161 deletions(-) create mode 100644 android-components/components/compose/cfr/src/main/res/values-et/strings.xml create mode 100644 android-components/components/compose/tabstray/src/main/res/values-ro/strings.xml create mode 100644 android-components/components/ui/widgets/src/main/res/values-ro/strings.xml diff --git a/android-components/components/browser/menu/src/main/res/values-et/strings.xml b/android-components/components/browser/menu/src/main/res/values-et/strings.xml index ab1d0ed94053..f1741c06e087 100644 --- a/android-components/components/browser/menu/src/main/res/values-et/strings.xml +++ b/android-components/components/browser/menu/src/main/res/values-et/strings.xml @@ -8,4 +8,6 @@ Lisad Lisade haldur + + Liigu üles diff --git a/android-components/components/browser/menu/src/main/res/values-ro/strings.xml b/android-components/components/browser/menu/src/main/res/values-ro/strings.xml index 523d40062143..645ad104c51c 100644 --- a/android-components/components/browser/menu/src/main/res/values-ro/strings.xml +++ b/android-components/components/browser/menu/src/main/res/values-ro/strings.xml @@ -8,4 +8,6 @@ Suplimente Manager de suplimente + + Navighează în sus diff --git a/android-components/components/compose/cfr/src/main/res/values-et/strings.xml b/android-components/components/compose/cfr/src/main/res/values-et/strings.xml new file mode 100644 index 000000000000..e6ef08c0b2b9 --- /dev/null +++ b/android-components/components/compose/cfr/src/main/res/values-et/strings.xml @@ -0,0 +1,5 @@ + + + + Peida + diff --git a/android-components/components/compose/tabstray/src/main/res/values-ro/strings.xml b/android-components/components/compose/tabstray/src/main/res/values-ro/strings.xml new file mode 100644 index 000000000000..4e5f9a7a12ef --- /dev/null +++ b/android-components/components/compose/tabstray/src/main/res/values-ro/strings.xml @@ -0,0 +1,7 @@ + + + + 1 filă deschisă. Atinge pentru a comuta între file. + + %1$s file deschise. Atinge pentru a comuta între file. + diff --git a/android-components/components/feature/addons/src/main/res/values-cak/strings.xml b/android-components/components/feature/addons/src/main/res/values-cak/strings.xml index 7fa343a96216..0ff4c47a6e43 100644 --- a/android-components/components/feature/addons/src/main/res/values-cak/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-cak/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Katok pan atzij pa %1$d chik ajk\'amal + + %1$s, %2$d richin %3$d Tok pa ri taq ruwi\' okik\'amaya\'l diff --git a/android-components/components/feature/addons/src/main/res/values-et/strings.xml b/android-components/components/feature/addons/src/main/res/values-et/strings.xml index 78245984f74e..75b2b71a5942 100644 --- a/android-components/components/feature/addons/src/main/res/values-et/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-et/strings.xml @@ -1,5 +1,5 @@ - + privaatsussätete vaatamine ja muutmine @@ -38,6 +38,8 @@ andmete hankimine vahemälust andmete sisestamine vahemällu + + Lehitsemise ajaloo lugemine failide allalaadimine ja allalaaditud failide ajaloo vaatamine ning muutmine @@ -68,8 +70,10 @@ arendajate tööriistade laiendamine, et pääseda ligi avatud kaartide andmetele Versioon + + Autor - Autorid + Autorid Viimati uuendatud @@ -106,14 +110,24 @@ Üksikasjad Õigused - + Eemalda + + Raporteeri Kas paigaldada lisa %1$s? + + %1$s nõuab täiendavaid õigusi. See lisa nõuab järgmisi õigusi: + + Nõutavad õigused: Paigalda + + Luba + + Keeldu Loobu @@ -128,6 +142,8 @@ Lisad Lisade haldur + + Avasta veel lisasid Luba @@ -166,6 +182,16 @@ Lisa %1$s paigaldamine õnnestus Lisa %1$s paigaldamine ebaõnnestus + + Lisa paigaldamine ebaõnnestus. + + Lisa polnud ühenduse ebaõnnestumise tõttu võimalik alla laadida. + + Lisa polnud võimalik paigaldada, kuna see on vigane. + + Lisa polnud võimalik paigaldada, kuna see pole verifitseeritud. + + Lisa %1$s polnud võimalik paigaldada, kuna see võib põhjustada tõsiseid stabiilsuse või turvalisuse probleeme. Lisa %1$s lubamine õnnestus @@ -208,4 +234,4 @@ Ava menüüs Olgu, sain aru - + diff --git a/android-components/components/feature/media/src/main/res/values-cak/strings.xml b/android-components/components/feature/media/src/main/res/values-cak/strings.xml index 1f9759f76e24..1fd18fea2c30 100644 --- a/android-components/components/feature/media/src/main/res/values-cak/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-cak/strings.xml @@ -1,5 +1,5 @@ - + K\'ïy k\'oxom @@ -10,6 +10,27 @@ E tzijïl ri elesäy wachib\'äl chuqa\' ri q\'asäy ch\'ab\'äl + + Tachapa\' richin najäq ri ruwi\' nrokisaj ri elesäy awachib\'äl. + + Tachapa\' richin nijaq ri ruwi\' nrokisaj ri q\'asäy ach\'ab\'äl. + + + + Tachapa\' richin najäq ri ruwi\' nrokisaj ri q\'asäy ach\'ab\'äl chuqa\' ri elesäy awachib\'al. + + + + Runataxik: %1$s tajin nrokisaj na ri elesäy awachib\'al. Tachapa\' richin najäq ri ruwi\'. + + Runataxik: %1$s tajin nrokisaj na ri q\'asäy ach\'ab\'äl. Tachapa\' richin najäq ri ruwi\'. + + Runataxik: %1$s tajin nrokisaj na ri q\'asäy ach\'ab\'äl. Tachapa\' richin najäq ri ruwi\'. + + Runataxik: %1$s tajin nrokisaj na ri q\'asäy ach\'ab\'äl chuqa\' elesäy awachib\'al. Tachapa\' richin najäq ri ruwi\' + + Runataxik: %1$s tajin nrokisaj na ri q\'asäy ach\'ab\'äl chuqa\' elesäy awachib\'al. Tachapa\' richin najäq ri ruwi\'. + Titzij diff --git a/android-components/components/feature/prompts/src/main/res/values-cak/strings.xml b/android-components/components/feature/prompts/src/main/res/values-cak/strings.xml index 2ec2ce37ea61..8f5c874dca8c 100644 --- a/android-components/components/feature/prompts/src/main/res/values-cak/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-cak/strings.xml @@ -18,6 +18,8 @@ Ewan tzij Man tiyak + + Wakami mani Majub\'ey tiyak @@ -26,16 +28,26 @@ Tiyak Man tik\'ex ruwäch + + Wakami mani Tik\'ex Man tikirel ta kowöl ri ruk\'ojlem ewan tzij + Titz\'ib\'äx jun ewan tzij + Man xtikïr ta xyak rutikirib\'al molojri\'ïl + + Man tikirel ta niyak ri ewan tzij ¿La niyak rutikirib\'al re moloj re\'? + + ¿La niyak ewan tzij? ¿La nik\'ex rutikirib\'al re moloj re\'? + + ¿La nik\'ex ri ewan tzij? ¿La nitz\'aqatisäx rub\'i\' winäq pa ri ewan tzij yakon? @@ -85,6 +97,8 @@ Tib\'an ruk\'ojlem wakami Tinuk\'samajïx rutikirib\'al molojri\'ïl + + Kenuk\'samajïx ewan taq tzij Kerik\' ri chilab\'en tikirib\'äl taq molojri\'ïl diff --git a/android-components/components/ui/tabcounter/src/main/res/values-ro/strings.xml b/android-components/components/ui/tabcounter/src/main/res/values-ro/strings.xml index 3fca736a129d..e2726988b105 100644 --- a/android-components/components/ui/tabcounter/src/main/res/values-ro/strings.xml +++ b/android-components/components/ui/tabcounter/src/main/res/values-ro/strings.xml @@ -1,5 +1,9 @@ + + 1 filă deschisă. Atinge pentru a comuta între file. + + %1$s file deschise. Atinge pentru a comuta între file. Filă privată nouă diff --git a/android-components/components/ui/widgets/src/main/res/values-ro/strings.xml b/android-components/components/ui/widgets/src/main/res/values-ro/strings.xml new file mode 100644 index 000000000000..be7fc12e65a0 --- /dev/null +++ b/android-components/components/ui/widgets/src/main/res/values-ro/strings.xml @@ -0,0 +1,5 @@ + + + + Imaginea a fost copiată în clipboard + diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml index 0e3f87e96f46..dd604a09ab9c 100644 --- a/fenix/app/src/main/res/values-azb/strings.xml +++ b/fenix/app/src/main/res/values-azb/strings.xml @@ -360,6 +360,10 @@ سیزی قوروماغی سئویریک + + نفع آختارمیان مورورچوموز، شیرکتلرین سیزی وب‌ده گیزلیجه تعقیب ائتمه‌سینی مسدود ائلییر. + + نفع آختارمیان مورورچوموز، شیرکتلرین سیزی گیزلیجه اینترنتده تعقیب ائتمه‌لرینی مسدود ائلییر. گیزلیلیک بیلدیریمی @@ -367,14 +371,34 @@ وارساییلان مورورچو ائله ایندی یوخ + + جهازلار آراسیندا گئچیش ائلین زامان رمزلنمیش قالین. + + گیریش و دؤنگل ائتدیگینیز زامان داها گوونلی اولورسوز. فایرفاکس رمزلری، بوکمارکلاری و آیری شئی‌لری رمزلشدیریر. گیریش ایندی یوخ + + بیلدیریش‌لر فایرفاکس ایله داها امن قالماغینیزا کومک ائدیر. + + تاغلاری جهازلاریز آراسیندا گوونلی شکلده گؤندرین و فایرفاکسین آیری اؤزللیکلرینی کشف ائله‌یین. بیلدیریش‌لری آچ ایندی یوخ + + فایرفاکس آختاریش ویجتینی ایمتیحان ائله‌یین + + فایرفاکسی آنا اکرانیزا آرتیرساز گیزلیلیگه اؤنجه‌لیک وئرن مورورچونوزا آسانلیق‌لا الینیز چاتار. + + فایرفاکس ویجتینی آرتیر ایندی یوخ @@ -395,13 +419,86 @@ عمومی + + حاقیندا + + بیرینی سئچ + + باشقا آختارما موتورلارینی ایداره ائدین + + آختاریش منوسوندا گؤرونن موتورلاری دوزه‌لیش ائدین + + آختاریش منوسوندا گؤرونن موتورلار + + وارساییلان آختاریش موتورو آختاریش + + آختاریش موتورلاری + + آختاریش موتورلاریندان تکلیف‌لر + + آدرس چوبوغو ترجیح‌لری + + آدرس چوبوغو -فایرفاکس تکلیفی + + فایرفاکس تکلیفی حاقیندا آرتیق بیلگی آلین + + قوقل پلی‌ده امتیاز وئر + + %1$s حاقیندا + + وارساییلان مورورچو ائله + + قاباغجیل + + + گیزلیلیک و گوونلیک + + سایت ایجازه‌لری + + گیزلی مورور + + باغلانتی‌نی گیزلی تاغدا آچ + + + گیزلی موروردا اسکرین شاتا ایجازه وئر + + اگر اجازه وئریلیرسه، گیزلی تاغلار بیرنئچه اپلیکیشن آچیلدیغی زامان‌دا گؤرونه‌جک + + گیزلی مورور شورتکاتینی آرتیر + + یالنیز HTTPS حالتی + + + کوکی بنر مسدود ائلیه‌نی + + گیزلی موروردا کوکی بنر مسدود ائلینی + + بو سایتدا باغلی لغو + + ایستک یوللا + + بو سایت اوچون آرخالاما ایستنسین؟ + + ایستک گؤندریلدی + + بو سایت اوچون آچیق + + آرخالاما ایستکی گوندریلدی + + سایت هله‌لیک آرخالانمیر + + %1$s اوچون کوکی بنر مسدود ائلین ایشله‌سین؟ + + %1$s اوچون کوکی بنر مسدود ائلین ایشدن سالینسین؟ + اوست diff --git a/fenix/app/src/main/res/values-de/strings.xml b/fenix/app/src/main/res/values-de/strings.xml index 6cbb619a2927..d31cb9ca6268 100644 --- a/fenix/app/src/main/res/values-de/strings.xml +++ b/fenix/app/src/main/res/values-de/strings.xml @@ -2206,7 +2206,7 @@ - Ihren Standardbrowser wechseln + Wechseln Sie Ihren Standardbrowser Stellen Sie Links von Websites, E-Mails und Nachrichten so ein, dass sie in Firefox automatisch geöffnet werden. diff --git a/fenix/app/src/main/res/values-el/strings.xml b/fenix/app/src/main/res/values-el/strings.xml index 7f8b4eb65304..f99fb52bdcce 100644 --- a/fenix/app/src/main/res/values-el/strings.xml +++ b/fenix/app/src/main/res/values-el/strings.xml @@ -2195,6 +2195,9 @@ Αναζήτηση %s + + Αλλαγή προεπιλεγμένου προγράμματος περιήγησης + Αυτόματο άνοιγμα συνδέσμων από ιστοτόπους, email και μηνύματα στο Firefox. diff --git a/fenix/app/src/main/res/values-es-rAR/strings.xml b/fenix/app/src/main/res/values-es-rAR/strings.xml index 91f8340b8b12..36b024d21b91 100644 --- a/fenix/app/src/main/res/values-es-rAR/strings.xml +++ b/fenix/app/src/main/res/values-es-rAR/strings.xml @@ -2199,7 +2199,7 @@ - Cambia tu navegador predeterminado + Cambiá tu navegador predeterminado Configurar enlaces de sitios web, correos electrónicos y mensajes para que se abran automáticamente en Firefox. diff --git a/fenix/app/src/main/res/values-et/strings.xml b/fenix/app/src/main/res/values-et/strings.xml index c60c503150c3..998bcdd8f8b4 100644 --- a/fenix/app/src/main/res/values-et/strings.xml +++ b/fenix/app/src/main/res/values-et/strings.xml @@ -192,6 +192,7 @@ Muuda Kohanda avalehte + Avaleht @@ -208,8 +209,6 @@ Skanni - - Otsingumootor Otsingumootori sätted @@ -223,7 +222,7 @@ %s jagab vaikeotsingumootoriga kõike, mida aadressiribale sisestad. - + Otsi otsingumootoriga %s Otsi otse aadressiribalt @@ -231,6 +230,9 @@ Otsingusätted + + Otsi seekord järgneva otsingumootoriga: + Ava uus kaart %1$sis @@ -253,8 +255,6 @@ Vaikeotsingumootor Otsimine - - Aadressiriba Hinda Google Plays Ainult HTTPS-režiim + + Sellel saidil väljas + + Sellel saidil sees + Kõrgendatud turvalisuse nimel üritatakse saitidega ühenduda ainult HTTPSi krüptitud protokolli vahendusel. - - Sees Väljas @@ -303,12 +306,8 @@ Siiski on võimalik, et sellega on seotud ka ründaja. Saidi külastamise jätkamisel ära sisesta tundliku teavet. Jätkamisel lülitatakse saidi jaoks ajutiselt ainult HTTPSi režiim välja. Hõlbustus - - Kohandatud Firefoxi konto server Kohandatud sünkroonimise server - - Firefoxi konto/sünkroniseerimise server muutus. Muudatuste rakendumiseks väljutakse äpist… Konto @@ -321,8 +320,6 @@ Žestid Kohandamine - - Firefoxi konto Sünkroniseerimise jätkamiseks loo ühendus uuesti @@ -334,8 +331,6 @@ Andmete kogumine Remote debugging via USB - - Kuvatakse otsingumootoreid Kuvatakse otsingu soovitusi @@ -364,6 +359,7 @@ Mitte kunagi Kasutatakse välist allalaadimishaldurit + Lisad @@ -413,13 +409,6 @@ Vaata - - - Lisa pole toetatud - - Lisa on juba paigaldatud - - Sünkroniseeri kohe @@ -558,13 +547,6 @@ Loobu - - %d sait - - %d saiti - Hiljuti suletud kaardid @@ -699,10 +681,10 @@ Ava kaardid Kollektsiooni nimi - - Muuda nime - - Eemalda + + Muuda nime + + Eemalda Kustuta ajaloost @@ -879,10 +861,10 @@ Keelatud Androidi poolt Erandid - - Sees Väljas + + Tavaline Range @@ -971,7 +953,7 @@ Jaga Salvesta PDFina - + PDFi loomine pole võimalik Edasta seadmele @@ -1080,13 +1062,9 @@ Avatud kaardid %d kaarti - - Lehitsemise ajalugu ja saitide andmed %d aadressi - - Küpsised Sind logitakse enamikest saitidest välja @@ -1124,39 +1102,11 @@ Grupp kustutatud + Sync on sisse lülitatud - - Tavaline (vaikimisi) - - Tasakaalustatud privaatsuse ja jõudluse jaoks. Lehed laaditakse tavapäraselt. - - Range - - Blokib rohkem jälitajaid ning lehed laadivad kiiremini, aga mõned lehtedel olevad funktsionaalsused võivad katki minna. - - Vali oma tööriistariba asukoht - - Loe meie privaatsuspoliitikat - - - Alusta veebilehitsemist - - - Vali oma teema - - Säästa akut ja oma silmi, lubades tume teema. - - Automaatne - - Kohandub sinu seadme sätetega - - Tume teema - - Hele teema - Kaardid on saadetud! @@ -1192,23 +1142,21 @@ Kaitse sätted Täiustatud jälitamisvastane kaitse - - Lehitse veebi ilma jälitamiseta - - Hoia oma andmed endale. %s kaitseb sind paljude tuntud jälitajate eest, kes jälgivad, mida sa võrgus olles teed. + + %s kaitseb sind paljude tuntud jälitajate eest, kes jälgivad, mida sa võrgus olles teed. Rohkem teavet Tavaline (vaikimisi) - Tasakaalustatud privaatsuse ja jõudluse jaoks. Lehed laaditakse tavapäraselt. + Lehed laadivad normaalselt, kuid blokitakse vähem jälitajaid. Mis on blokitud tavalise jälitamisvastase kaitse poolt Range - Blokib rohkem jälitajaid ning lehed laadivad kiiremini, aga mõned lehtedel olevad funktsionaalsused võivad katki minna. + Tugevam jälitamisvastane kaitse ja suurem jõudlus, kuid mõned saidid ei pruugi korralikult töötada. Mis on blokitud tugevama jälitamisvastase kaitse poolt @@ -1228,6 +1176,10 @@ kõik kolmanda osapoole küpsised (võib põhjustada mõnel veebisaidil probleeme) kõik küpsised (mõned veebisaidid lähevad katki) + + Eraldatakse saidiülesed küpsised + + Veebisaite juhendatakse andmeid mitte müüma ega jagama Jälitav sisu @@ -1252,8 +1204,12 @@ Saitideülesed jälitamisküpsised + + Saidiülesed küpsised Blokib küpsised, mida reklaami- ja analüüsiettevõtted üle paljude saitide sinu andmete kogumiseks kasutavad. + + Täielik küpsistevastane eraldab külastatava saidi küpsiseid, nii et jälitajad, nt reklaamivõrgustikud, ei saa nende abil sind saitide üleselt jälitada. Krüptorahakaevurid @@ -1557,21 +1513,11 @@ Otsingumootori lisamine Otsingumootori muutmine - - Lisa - - Salvesta Muuda Kustuta - - Muu - - Nimi - - Kasutatav otsingustring Päringu asendamiseks kasuta “%s”. Näiteks \nhttps://www.google.com/search?q=%s @@ -1702,14 +1648,14 @@ Olgu, sain aru Otseteed - - Nimi + + Nimi Otsetee nimi - - Olgu - - Loobu + + Olgu + + Loobu Sätted @@ -1738,7 +1684,7 @@ Automaatne sulgemine on lubatud - + Määra Firefox automaatselt avama linke, e-posti ja sõnumeid. @@ -1773,4 +1719,6 @@ Mine sätetesse + + diff --git a/fenix/app/src/main/res/values-fr/strings.xml b/fenix/app/src/main/res/values-fr/strings.xml index c6e72ec33509..a99ae4fe9989 100644 --- a/fenix/app/src/main/res/values-fr/strings.xml +++ b/fenix/app/src/main/res/values-fr/strings.xml @@ -2204,6 +2204,9 @@ Recherche %s + + Changez de navigateur par défaut + Faites en sorte que les liens des sites web, des e-mails et des messages s’ouvrent automatiquement dans Firefox. diff --git a/fenix/app/src/main/res/values-ia/strings.xml b/fenix/app/src/main/res/values-ia/strings.xml index 9d9fe0724939..0970b4b78005 100644 --- a/fenix/app/src/main/res/values-ia/strings.xml +++ b/fenix/app/src/main/res/values-ia/strings.xml @@ -2223,6 +2223,9 @@ Cercar %s + + Cambia tu navigator predefinite + Stabilir qual ligamines de sitos web, e-mails e messages se aperi automaticamente in Firefox. diff --git a/fenix/app/src/main/res/values-kk/strings.xml b/fenix/app/src/main/res/values-kk/strings.xml index a960da8715bd..acd6830c39d4 100644 --- a/fenix/app/src/main/res/values-kk/strings.xml +++ b/fenix/app/src/main/res/values-kk/strings.xml @@ -2170,6 +2170,9 @@ %s іздеуі + + Негізгі браузеріңізді ауыстыру + Веб-сайттар, эл. пошта хаттары және хабарламалардан сілтемелерді Firefox-та автоматты түрде ашылатындай етіп баптау. diff --git a/fenix/app/src/main/res/values-nl/strings.xml b/fenix/app/src/main/res/values-nl/strings.xml index 27fb89c2f833..bfd32fd02e98 100644 --- a/fenix/app/src/main/res/values-nl/strings.xml +++ b/fenix/app/src/main/res/values-nl/strings.xml @@ -2184,6 +2184,9 @@ Zoeken met %s + + Uw standaardbrowser wisselen + Koppelingen van websites, e-mail en berichten automatisch in Firefox openen. diff --git a/fenix/app/src/main/res/values-pa-rIN/strings.xml b/fenix/app/src/main/res/values-pa-rIN/strings.xml index f5c180e02c36..e9e3d83bff7d 100644 --- a/fenix/app/src/main/res/values-pa-rIN/strings.xml +++ b/fenix/app/src/main/res/values-pa-rIN/strings.xml @@ -2192,6 +2192,9 @@ %s ਖੋਜ + + ਆਪਣੇ ਮੂਲ ਬਰਾਊਜ਼ਰ ਨੂੰ ਬਦਲੋ + ਵੈੱਬਸਾਈਟਾਂ, ਈਮੇਲਾਂ ਅਤੇ ਸੁਨੇਹਿਆਂ ਨੂੰ Firefox ਵਿੱਚ ਆਪਣੇ ਖੋਲ੍ਹਣ ਲਈ ਲਿੰਕ ਸੈੱਟ ਕਰੋ। diff --git a/fenix/app/src/main/res/values-pt-rBR/strings.xml b/fenix/app/src/main/res/values-pt-rBR/strings.xml index 332fdda58ba0..e32bdb52c3bf 100644 --- a/fenix/app/src/main/res/values-pt-rBR/strings.xml +++ b/fenix/app/src/main/res/values-pt-rBR/strings.xml @@ -2182,6 +2182,9 @@ Pesquisa do %s + + Mude seu navegador padrão + Abra links, emails e mensagens automaticamente no Firefox. diff --git a/fenix/app/src/main/res/values-ro/strings.xml b/fenix/app/src/main/res/values-ro/strings.xml index 0c577c121461..b6efef041d95 100644 --- a/fenix/app/src/main/res/values-ro/strings.xml +++ b/fenix/app/src/main/res/values-ro/strings.xml @@ -44,14 +44,39 @@ %1$s îți șterge istoricul de căutare și navigare din filele private când le închizi sau când ieși din aplicație. Deși nu te anonimizează pe site-urile web sau pentru furnizorul de servicii de internet, ușurează păstrarea confidențialității asupra a ce faci online față de oricine altcineva folosește acest dispozitiv. Mituri comune despre navigarea privată + + + Nu lăsa urme pe acest dispozitiv + + + %1$s îți șterge cookie-urile, istoricul și datele site-urilor când închizi toate ferestrele private. %2$s + + Cine ar putea să-mi vadă activitatea? + + + Adaugă în ecranul de start Nu, mulțumesc + + + Poți seta %1$s să deschidă automat linkuri în aplicații. Mergi la setări Înlătură + + + + Atinge aici pentru a începe o nouă sesiune privată. Șterge-ți istoricul, cookie-urile — totul. + + Înlătură @@ -70,12 +95,23 @@ Filă privată nouă + + Comandă rapidă pentru parole + Revino la această filă Afișează toate + + Elimină + + + + Vizitate recent + Înapoi @@ -99,12 +135,16 @@ Bibliotecă Versiune site de desktop + + Deschide într-o filă nouă Adaugă în ecranul de start Instalează Caută în pagină + + Tradu pagina Salvează în colecție @@ -131,6 +171,10 @@ Editează + + Șterge istoricul de navigare + Limbă selectată @@ -142,8 +186,6 @@ Scanează - - Motor de căutare Setări pentru motorul de căutare @@ -158,13 +200,36 @@ %s va partaja tot ce tastezi în bara de adrese cu motorul de căutare implicit. - - - Desemnează %s drept browserul implicit - + Motor de căutare %s + + + + Ne place să te protejăm + + Browserul nostru, susținut de o organizație non-profit, ajută la oprirea companiilor să te urmărească în secret pe web.\n\nAflă mai multe în notificarea noastră privind confidențialitatea. + + Păstrează-ți datele criptate când treci de pe un dispozitiv pe altul + + Când ești autentificat și sincronizat, ești mai în siguranță. Firefox criptează parolele, marcajele și multe altele. + + Notificările te ajută să fii mai în siguranță cu Firefox + + Trimite-ți securizat file între dispozitive și descoperă alte funcții de confidențialitate în Firefox. + + Încearcă widgetul de căutare Firefox + - Desemnează Firefox drept browserul implicit + Cu Firefox pe ecranul de start vei avea acces facil la primul browser orientat pe confidențailitate care blochează elementele de urmărire inter-site-uri. + + Adaugă widgetul Firefox + + Nu acum Căutare @@ -181,12 +246,22 @@ Generalități Despre + + Selectează una dintre opțiuni + + Gestionează motoarele de căutare alternative + + Editează motoarele vizibile în meniul de căutare + + Motoare vizibile în meniul de căutare Motor de căutare implicit Căutare - - Bară de adrese + + Motoare de căutare + + Sugestii de la motoarele de căutare Evaluează pe Google Play Accesibilitate - - Server personalizat pentru contul Firefox Server personalizat de sincronizare - - Server de cont Firefox/sincronizare modificat. Se închide aplicația pentru implementarea modificărilor… Cont Bară de unelte Temă + + Pagină de start Personalizare - - Cont Firefox Reconectează-te pentru a continua sincronizarea @@ -237,8 +308,6 @@ Colectare de date Depanare de la distanță prin USB - - Afișează motoare de căutare Afișează sugestii de căutare @@ -257,6 +326,7 @@ Deschide linkuri în aplicații Manager extern pentru descărcări + Suplimente @@ -268,7 +338,16 @@ Numele colecției - + + Marcaje recente + + Vizitate recent + + Povești sponsorizate + + Comenzi rapide sponsorizate + Sincronizează acum @@ -403,6 +482,10 @@ După o lună + + Pagină de start + + Pagina de start după patru ore de inactivitate Închide manual @@ -412,6 +495,11 @@ Închide după o lună + + Deschide pe pagina de start + + Deschide ultima filă + OK @@ -453,7 +541,7 @@ Deschide filele - Șterge + Șterge Șterge din istoric @@ -752,13 +840,9 @@ %d (de) file - - Istoric de navigare și date site-uri %d (de) adrese - - Cookie-uri Vei fi deconectat(ă) de pe majoritatea site-urilor @@ -787,31 +871,11 @@ Se șterg datele de navigare… + Sync este activat - - Standard (implicit) - - Strictă - - - Citește notificarea noastră privind confidențialitatea - - - Începe navigarea - - Alege o temă - - Automat - - Se adaptează la setările dispozitivului - - Temă întunecată - - Temă deschisă - File trimise! @@ -844,11 +908,7 @@ Setări de protecție Protecție îmbunătățită împotriva urmăririi - - Navighează fără să fii urmărit(ă) - - Păstrează-ți datele pentru tine. %s te protejează de multe dintre cele mai frecvente elemente de urmărire care monitorizează ce faci online. Află mai multe @@ -969,6 +1029,9 @@ Denumire comandă rapidă + + Poți adăuga cu ușurință acest site web în ecranul de start al dispozitivului pentru acces instant și o navigare mai rapidă, ca și cum ai fi într-o aplicație. + Date de autentificare și parole @@ -1047,21 +1110,11 @@ Adaugă un motor de căutare Editează motorul de căutare - - Adaugă - - Salvează Editează Șterge - - Altele - - Denumire - - Șir de căutare de utilizat Înlocuiește interogarea cu „%s”. Exemplu: \nhttps://www.google.com/search?q=%s @@ -1157,11 +1210,11 @@ Comenzi rapide - - Nume + + Nume - OK + OK @@ -1170,4 +1223,6 @@ Elimină + + diff --git a/fenix/app/src/main/res/values-zh-rTW/strings.xml b/fenix/app/src/main/res/values-zh-rTW/strings.xml index 6a8a722d63eb..78fe069347f7 100644 --- a/fenix/app/src/main/res/values-zh-rTW/strings.xml +++ b/fenix/app/src/main/res/values-zh-rTW/strings.xml @@ -2205,6 +2205,9 @@ %s 搜尋 + + 切換您的預設瀏覽器 + 設定使用 Firefox 自動開啟網站、郵件、簡訊當中的鏈結。 From 0f0edf392c2858fddbcba475381f55dd00610375 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Wed, 7 Feb 2024 11:41:41 +0200 Subject: [PATCH 137/586] Bug 1874662 - Fix flaky closeAllTabsTest UI tests --- .../java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt index 62842aa21c75..38d5a4f848e5 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt @@ -144,7 +144,12 @@ class HomeScreenRobot { } fun verifyTabCounter(numberOfOpenTabs: String) = - assertUIObjectExists(tabCounter(numberOfOpenTabs)) + onView( + allOf( + withId(R.id.counter_text), + withText(numberOfOpenTabs), + ), + ).check(matches(isDisplayed())) fun verifyWallpaperImageApplied(isEnabled: Boolean) = assertUIObjectExists(itemWithResId("$packageName:id/wallpaperImageView"), exists = isEnabled) From f628f7602ffa68aafd2433d76dc423fa75af90d1 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Wed, 7 Feb 2024 16:11:02 +0200 Subject: [PATCH 138/586] Bug 1879288 - Add missing pairs of logs to BrowserRobot --- .../mozilla/fenix/ui/robots/BrowserRobot.kt | 172 +++++++++++++----- 1 file changed, 124 insertions(+), 48 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt index c873372f26dd..d98e22a9cc7e 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt @@ -71,6 +71,7 @@ class BrowserRobot { fun verifyCurrentPrivateSession(context: Context) { val selectedTab = context.components.core.store.state.selectedTab + Log.i(TAG, "verifyCurrentPrivateSession: Trying to verify that current browsing session is private") assertTrue("Current session is private", selectedTab?.content?.private ?: false) Log.i(TAG, "verifyCurrentPrivateSession: Verified that current browsing session is private") } @@ -228,6 +229,7 @@ class BrowserRobot { fun verifyNavURLBarHidden() = assertUIObjectIsGone(navURLBar()) fun verifyMenuButton() { + Log.i(TAG, "verifyMenuButton: Trying to verify main menu button is displayed") threeDotButton().check(matches(isDisplayed())) Log.i(TAG, "verifyMenuButton: Verified main menu button is displayed") } @@ -249,6 +251,7 @@ class BrowserRobot { assertUIObjectExists(itemWithResId("$packageName:id/notification_dot")) fun dismissContentContextMenu() { + Log.i(TAG, "dismissContentContextMenu: Trying to click device back button") mDevice.pressBack() Log.i(TAG, "dismissContentContextMenu: Clicked device back button") assertUIObjectExists(itemWithResId("$packageName:id/engineView")) @@ -280,7 +283,9 @@ class BrowserRobot { fun clickSubmitLoginButton() { clickPageObject(itemWithResId("submit")) assertUIObjectIsGone(itemWithResId("submit")) + Log.i(TAG, "clickSubmitLoginButton: Waiting for device to be idle for $waitingTimeLong ms") mDevice.waitForIdle(waitingTimeLong) + Log.i(TAG, "clickSubmitLoginButton: Waited for device to be idle for $waitingTimeLong ms") } fun enterPassword(password: String) { @@ -323,11 +328,13 @@ class BrowserRobot { // failing to swipe on Firebase sometimes, so it tries again try { Log.i(TAG, "swipeNavBarRight: Try block") + Log.i(TAG, "swipeNavBarRight: Trying to perform swipe right action on navigation toolbar") navURLBar().swipeRight(2) Log.i(TAG, "swipeNavBarRight: Performed swipe right action on navigation toolbar") assertUIObjectIsGone(itemWithText(tabUrl)) } catch (e: AssertionError) { Log.i(TAG, "swipeNavBarRight: AssertionError caught, executing fallback methods") + Log.i(TAG, "swipeNavBarRight: Trying to perform swipe right action on navigation toolbar") navURLBar().swipeRight(2) Log.i(TAG, "swipeNavBarRight: Performed swipe right action on navigation toolbar") assertUIObjectIsGone(itemWithText(tabUrl)) @@ -338,11 +345,13 @@ class BrowserRobot { // failing to swipe on Firebase sometimes, so it tries again try { Log.i(TAG, "swipeNavBarLeft: Try block") + Log.i(TAG, "swipeNavBarLeft: Trying to perform swipe left action on navigation toolbar") navURLBar().swipeLeft(2) Log.i(TAG, "swipeNavBarLeft: Performed swipe left action on navigation toolbar") assertUIObjectIsGone(itemWithText(tabUrl)) } catch (e: AssertionError) { Log.i(TAG, "swipeNavBarLeft: AssertionError caught, executing fallback methods") + Log.i(TAG, "swipeNavBarLeft: Trying to perform swipe left action on navigation toolbar") navURLBar().swipeLeft(2) Log.i(TAG, "swipeNavBarLeft: Performed swipe left action on navigation toolbar") assertUIObjectIsGone(itemWithText(tabUrl)) @@ -354,6 +363,7 @@ class BrowserRobot { try { Log.i(TAG, "clickSuggestedLoginsButton: Started try #$i") mDevice.waitForObjects(suggestedLogins()) + Log.i(TAG, "clickSuggestedLoginsButton: Trying to click suggested logins button") suggestedLogins().click() Log.i(TAG, "clickSuggestedLoginsButton: Clicked suggested logins button") mDevice.waitForObjects(suggestedLogins()) @@ -370,6 +380,7 @@ class BrowserRobot { } fun setTextForApartmentTextBox(apartment: String) { + Log.i(TAG, "setTextForApartmentTextBox: Trying to set the text for the apartment text box to: $apartment") itemWithResId("apartment").setText(apartment) Log.i(TAG, "setTextForApartmentTextBox: The text for the apartment text box was set to: $apartment") } @@ -388,8 +399,9 @@ class BrowserRobot { try { Log.i(TAG, "clickSelectAddressButton: Started try #$i") assertUIObjectExists(selectAddressButton()) + Log.i(TAG, "clickSelectAddressButton: Trying to click the select address button and wait for $waitingTime ms for a new window") selectAddressButton().clickAndWaitForNewWindow(waitingTime) - Log.i(TAG, "clickSelectAddressButton: Clicked select address button") + Log.i(TAG, "clickSelectAddressButton: Clicked the select address button and waited for $waitingTime ms for a new window") break } catch (e: AssertionError) { @@ -409,37 +421,51 @@ class BrowserRobot { fun verifySelectAddressButtonExists(exists: Boolean) = assertUIObjectExists(selectAddressButton(), exists = exists) fun changeCreditCardExpiryDate(expiryDate: String) { + Log.i(TAG, "changeCreditCardExpiryDate: Trying to set credit card expiry date to: $expiryDate") itemWithResId("expiryMonthAndYear").setText(expiryDate) Log.i(TAG, "changeCreditCardExpiryDate: Credit card expiry date was set to: $expiryDate") } fun clickCreditCardNumberTextBox() { - Log.i(TAG, "clickCreditCardNumberTextBox: Waiting for credit card number text box") + Log.i(TAG, "clickCreditCardNumberTextBox: Waiting for $waitingTime ms until finding the credit card number text box") mDevice.wait(Until.findObject(By.res("cardNumber")), waitingTime) + Log.i(TAG, "clickCreditCardNumberTextBox: Waited for $waitingTime ms until the credit card number text box was found") + Log.i(TAG, "clickCreditCardNumberTextBox: Trying to click the credit card number text box") mDevice.findObject(By.res("cardNumber")).click() - Log.i(TAG, "clickCreditCardNumberTextBox: Clicked credit card number text box") + Log.i(TAG, "clickCreditCardNumberTextBox: Clicked the credit card number text box") + Log.i(TAG, "clickCreditCardNumberTextBox: Waiting for $waitingTimeShort ms for $appName window to be updated") mDevice.waitForWindowUpdate(appName, waitingTimeShort) + Log.i(TAG, "clickCreditCardNumberTextBox: Waited for $waitingTimeShort ms for $appName window to be updated") } fun clickCreditCardFormSubmitButton() { + Log.i(TAG, "clickCreditCardFormSubmitButton: Trying to click the credit card form submit button and wait for $waitingTime ms for a new window") itemWithResId("submit").clickAndWaitForNewWindow(waitingTime) - Log.i(TAG, "clickCreditCardFormSubmitButton: Clicked credit card form submit button") + Log.i(TAG, "clickCreditCardFormSubmitButton: Clicked the credit card form submit button and waited for $waitingTime ms for a new window") } fun fillAndSaveCreditCard(cardNumber: String, cardName: String, expiryMonthAndYear: String) { + Log.i(TAG, "fillAndSaveCreditCard: Tying to set credit card number to: $cardNumber") itemWithResId("cardNumber").setText(cardNumber) - Log.i(TAG, "fillAndSaveCreditCard: Set card number to: $cardNumber") + Log.i(TAG, "fillAndSaveCreditCard: Credit card number was set to: $cardNumber") mDevice.waitForIdle(waitingTime) + Log.i(TAG, "fillAndSaveCreditCard: Trying to set credit card name to: $cardName") itemWithResId("nameOnCard").setText(cardName) - Log.i(TAG, "fillAndSaveCreditCard: Set card name to: $cardName") + Log.i(TAG, "fillAndSaveCreditCard: Credit card name was set to: $cardName") mDevice.waitForIdle(waitingTime) + Log.i(TAG, "fillAndSaveCreditCard: Trying to set credit card expiry month and year to: $expiryMonthAndYear") itemWithResId("expiryMonthAndYear").setText(expiryMonthAndYear) - Log.i(TAG, "fillAndSaveCreditCard: Set expiry month and year to: $expiryMonthAndYear") + Log.i(TAG, "fillAndSaveCreditCard: Credit card expiry month and year were set to: $expiryMonthAndYear") + Log.i(TAG, "fillAndSaveCreditCard: Waiting for device to be idle for $waitingTime ms") mDevice.waitForIdle(waitingTime) + Log.i(TAG, "fillAndSaveCreditCard: Waited for device to be idle for $waitingTime ms") + Log.i(TAG, "fillAndSaveCreditCard: Trying to click the credit card form submit button and wait for $waitingTime ms for a new window") itemWithResId("submit").clickAndWaitForNewWindow(waitingTime) - Log.i(TAG, "fillAndSaveCreditCard: Clicked credit card form submit button") + Log.i(TAG, "fillAndSaveCreditCard: Clicked the credit card form submit button and waited for $waitingTime ms for a new window") waitForPageToLoad() + Log.i(TAG, "fillAndSaveCreditCard: Waiting for $waitingTime ms for $packageName window to be updated") mDevice.waitForWindowUpdate(packageName, waitingTime) + Log.i(TAG, "fillAndSaveCreditCard: Waited for $waitingTime ms for $packageName window to be updated") } fun verifyUpdateOrSaveCreditCardPromptExists(exists: Boolean) = @@ -463,7 +489,9 @@ class BrowserRobot { } fun verifySuggestedUserName(userName: String) { + Log.i(TAG, "verifySuggestedUserName: Waiting for $waitingTime ms for suggested logins fragment to exist") itemWithResId("$packageName:id/mozac_feature_login_multiselect_expand").waitForExists(waitingTime) + Log.i(TAG, "verifySuggestedUserName: Waited for $waitingTime ms for suggested logins fragment to exist") assertUIObjectExists(itemContainingText(userName)) } @@ -548,43 +576,54 @@ class BrowserRobot { fun verifyCookiesProtectionHintIsDisplayed(composeTestRule: HomeActivityComposeTestRule, isDisplayed: Boolean) { if (isDisplayed) { + Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Trying to verify that the total cookie protection message is displayed") composeTestRule.onNodeWithTag("tcp_cfr.message").assertIsDisplayed() Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified total cookie protection message is displayed") + Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Trying to verify that the total cookie protection learn more link is displayed") composeTestRule.onNodeWithTag("tcp_cfr.action").assertIsDisplayed() - Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified total cookie protection learn more link is displayed") + Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified that the total cookie protection learn more link is displayed") + Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Trying to verify that the total cookie protection dismiss button is displayed") composeTestRule.onNodeWithTag("cfr.dismiss").assertIsDisplayed() Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified total cookie protection dismiss button is displayed") } else { + Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Trying to verify that the total cookie protection message does not exist") composeTestRule.onNodeWithTag("tcp_cfr.message").assertDoesNotExist() - Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified total cookie protection message does not exist") + Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified that the total cookie protection message does not exist") + Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Trying to verify that the total cookie protection learn more link does not exist") composeTestRule.onNodeWithTag("tcp_cfr.action").assertDoesNotExist() Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified total cookie protection learn more link does not exist") + Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Trying to verify that the total cookie protection dismiss button does not exist") composeTestRule.onNodeWithTag("cfr.dismiss").assertDoesNotExist() - Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified total cookie protection dismiss button does not exist") + Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified that the total cookie protection dismiss button does not exist") } } fun clickTCPCFRLearnMore(composeTestRule: HomeActivityComposeTestRule) { + Log.i(TAG, "clickTCPCFRLearnMore: Trying to click the total cookie protection learn more link") composeTestRule.onNodeWithTag("tcp_cfr.action").performClick() Log.i(TAG, "clickTCPCFRLearnMore: Clicked total cookie protection learn more link") } fun dismissTCPCFRPopup(composeTestRule: HomeActivityComposeTestRule) { + Log.i(TAG, "dismissTCPCFRPopup: Trying to click the total cookie protection dismiss button") composeTestRule.onNodeWithTag("cfr.dismiss").performClick() Log.i(TAG, "dismissTCPCFRPopup: Clicked total cookie protection dismiss button") } fun verifyShouldShowCFRTCP(shouldShow: Boolean, settings: Settings) { if (shouldShow) { + Log.i(TAG, "verifyShouldShowCFRTCP: Trying to verify that the TCP CFR should be shown") assertTrue(settings.shouldShowTotalCookieProtectionCFR) - Log.i(TAG, "verifyShouldShowCFRTCP: Verified that TCP CFR should be shown") + Log.i(TAG, "verifyShouldShowCFRTCP: Verified that the TCP CFR should be shown") } else { + Log.i(TAG, "verifyShouldShowCFRTCP: Trying to verify that the TCP CFR should not be shown") assertFalse(settings.shouldShowTotalCookieProtectionCFR) - Log.i(TAG, "verifyShouldShowCFRTCP: Verified that TCP CFR should not be shown") + Log.i(TAG, "verifyShouldShowCFRTCP: Verified that the TCP CFR should not be shown") } } fun selectTime(hour: Int, minute: Int) { + Log.i(TAG, "selectTime: Trying to select time picker hour: $hour and minute: $minute") onView( isAssignableFrom(TimePicker::class.java), ).inRoot( @@ -674,17 +713,18 @@ class BrowserRobot { for (i in 1..RETRY_COUNT) { try { Log.i(TAG, "verifySelectedDropDownOption: Started try #$i") - Log.i(TAG, "verifySelectedDropDownOption: Looking for \"Submit drop down option\" form button") + Log.i(TAG, "verifySelectedDropDownOption: Waiting for $waitingTime ms for \"Submit drop down option\" form button to exist") mDevice.findObject( UiSelector() .textContains("Submit drop down option") .resourceId("submitOption"), ).waitForExists(waitingTime) - + Log.i(TAG, "verifySelectedDropDownOption: Waited for $waitingTime ms for \"Submit drop down option\" form button to exist") assertUIObjectExists(itemContainingText("Selected option is: $optionName")) break } catch (e: AssertionError) { + Log.i(TAG, "verifySelectedDropDownOption: AssertionError caught, executing fallback methods") Log.e(TAG, "Selected option isn't displayed ${e.localizedMessage}") clickPageObject(itemWithResId("dropDown")) @@ -704,16 +744,18 @@ class BrowserRobot { fun verifyCookieBannerExists(exists: Boolean) { for (i in 1..RETRY_COUNT) { - Log.i(TAG, "verifyCookieBannerExists: For loop: $i") + Log.i(TAG, "verifyCookieBannerExists: Started try #$i") try { // Wait for the blocker to kick-in and make the cookie banner disappear + Log.i(TAG, "verifyCookieBannerExists: Waiting for $waitingTime ms for cookie banner to be gone") itemWithResId("CybotCookiebotDialog").waitUntilGone(waitingTime) - Log.i(TAG, "verifyCookieBannerExists: Waiting for window update") + Log.i(TAG, "verifyCookieBannerExists: Waited for $waitingTime ms for cookie banner to be gone") // Assert that the blocker properly dismissed the cookie banner assertUIObjectExists(itemWithResId("CybotCookiebotDialog"), exists = exists) break } catch (e: AssertionError) { + Log.i(TAG, "verifyCookieBannerExists: AssertionError caught, executing fallback methods") if (i == RETRY_COUNT) { throw e } @@ -840,11 +882,12 @@ class BrowserRobot { assertUIObjectExists(itemWithDescription("Close")) fun clickOpenLinksInAppsDismissCFRButton() { + Log.i(TAG, "clickOpenLinksInAppsDismissCFRButton: Trying to click the open links in apps banner \"Dismiss\" button") itemWithResIdContainingText( "$packageName:id/dismiss", getStringResource(R.string.open_in_app_cfr_negative_button_text), ).click() - Log.i(TAG, "clickOpenLinksInAppsDismissCFRButton: Clicked open links in apps banner \"Dismiss\" button") + Log.i(TAG, "clickOpenLinksInAppsDismissCFRButton: Clicked the open links in apps banner \"Dismiss\" button") } fun clickTakeSurveyButton() { @@ -871,6 +914,7 @@ class BrowserRobot { } fun longClickToolbar() { + Log.i(TAG, "longClickToolbar: Trying to long click the toolbar") onView(withId(R.id.mozac_browser_toolbar_url_view)).perform(longClick()) Log.i(TAG, "longClickToolbar: Long clicked the toolbar") } @@ -903,27 +947,31 @@ class BrowserRobot { } fun clickStayInPrivateBrowsingPromptButton() { + Log.i(TAG, "clickStayInPrivateBrowsingPromptButton: Trying to click the \"STAY IN PRIVATE BROWSING\" prompt button") itemWithResIdContainingText( "$packageName:id/deny_button", getStringResource(R.string.mozac_feature_downloads_cancel_active_private_downloads_deny), ).click() - Log.i(TAG, "clickStayInPrivateBrowsingPromptButton: Clicked \"STAY IN PRIVATE BROWSING\" prompt button") + Log.i(TAG, "clickStayInPrivateBrowsingPromptButton: Clicked the \"STAY IN PRIVATE BROWSING\" prompt button") } fun clickCancelPrivateDownloadsPromptButton() { + Log.i(TAG, "clickCancelPrivateDownloadsPromptButton: Trying to click the \"CANCEL DOWNLOADS\" prompt button") itemWithResIdContainingText( "$packageName:id/accept_button", getStringResource(R.string.mozac_feature_downloads_cancel_active_downloads_accept), ).click() - Log.i(TAG, "clickCancelPrivateDownloadsPromptButton: Clicked \"CANCEL DOWNLOADS\" prompt button") - + Log.i(TAG, "clickCancelPrivateDownloadsPromptButton: Clicked the \"CANCEL DOWNLOADS\" prompt button") + Log.i(TAG, "clickCancelPrivateDownloadsPromptButton: Waiting for $waitingTime ms for $packageName window to be updated") mDevice.waitForWindowUpdate(packageName, waitingTime) + Log.i(TAG, "clickCancelPrivateDownloadsPromptButton: Waited for $waitingTime ms for $packageName window to be updated") } fun fillPdfForm(name: String) { // Set PDF form text for the text box + Log.i(TAG, "fillPdfForm: Trying to set the text of the PDF form text box to: $name") itemWithResId("pdfjs_internal_id_10R").setText(name) - Log.i(TAG, "fillPdfForm: Set PDF form text box text to: $name") + Log.i(TAG, "fillPdfForm: PDF form text box text was set to: $name") mDevice.waitForWindowUpdate(packageName, waitingTime) if ( !itemWithResId("pdfjs_internal_id_11R").exists() && @@ -932,18 +980,22 @@ class BrowserRobot { .contains("mInputShown=true") ) { // Close the keyboard + Log.i(TAG, "fillPdfForm: Trying to close the keyboard using device back button") mDevice.pressBack() - Log.i(TAG, "fillPdfForm: Closing the keyboard using device back button") + Log.i(TAG, "fillPdfForm: Closed the keyboard using device back button") } // Click PDF form check box + Log.i(TAG, "fillPdfForm: Trying to click the PDF form check box") itemWithResId("pdfjs_internal_id_11R").click() Log.i(TAG, "fillPdfForm: Clicked PDF form check box") } class Transition { fun openThreeDotMenu(interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition { + Log.i(TAG, "openThreeDotMenu: Waiting for device to be idle for $waitingTime ms") mDevice.waitForIdle(waitingTime) Log.i(TAG, "openThreeDotMenu: Device was idle for $waitingTime ms") + Log.i(TAG, "openThreeDotMenu: Trying to click the main menu button") threeDotButton().perform(click()) Log.i(TAG, "openThreeDotMenu: Clicked the main menu button") @@ -953,8 +1005,9 @@ class BrowserRobot { fun openNavigationToolbar(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition { clickPageObject(navURLBar()) - Log.i(TAG, "openNavigationToolbar: Looking for search bar") + Log.i(TAG, "openNavigationToolbar: Waiting for $waitingTime ms for for search bar to exist") searchBar().waitForExists(waitingTime) + Log.i(TAG, "openNavigationToolbar: Waited for $waitingTime ms for for search bar to exist") NavigationToolbarRobot().interact() return NavigationToolbarRobot.Transition() @@ -971,7 +1024,7 @@ class BrowserRobot { ), waitingTime, ) - + Log.i(TAG, "openTabDrawer: Trying to click the tab counter button") tabsCounter().click() Log.i(TAG, "openTabDrawer: Clicked the tab counter button") assertUIObjectExists(itemWithResId("$packageName:id/new_tab_button")) @@ -982,8 +1035,9 @@ class BrowserRobot { if (i == RETRY_COUNT) { throw e } else { + Log.i(TAG, "openTabDrawer: Waiting for device to be idle") mDevice.waitForIdle() - Log.i(TAG, "openTabDrawer: Device waited to be idle") + Log.i(TAG, "openTabDrawer: Waited for device to be idle") } } } @@ -1005,10 +1059,10 @@ class BrowserRobot { ), waitingTime, ) - + Log.i(TAG, "openComposeTabDrawer: Trying to click the tab counter button") tabsCounter().click() Log.i(TAG, "openComposeTabDrawer: Clicked the tab counter button") - + Log.i(TAG, "openComposeTabDrawer: Trying to verify the tabs tray exists") composeTestRule.onNodeWithTag(TabsTrayTestTag.tabsTray).assertExists() Log.i(TAG, "openComposeTabDrawer: Verified the tabs tray exists") @@ -1018,22 +1072,24 @@ class BrowserRobot { if (i == RETRY_COUNT) { throw e } else { + Log.i(TAG, "openComposeTabDrawer: Waiting for device to be idle") mDevice.waitForIdle() - Log.i(TAG, "openComposeTabDrawer: Device waited to be idle") + Log.i(TAG, "openComposeTabDrawer: Waited for device to be idle") } } } - + Log.i(TAG, "openComposeTabDrawer: Trying to verify the tabs tray new tab FAB button exists") composeTestRule.onNodeWithTag(TabsTrayTestTag.fab).assertExists() - Log.i(TAG, "openComposeTabDrawer: Verified the tabs tray new tab button exists") + Log.i(TAG, "openComposeTabDrawer: Verified the tabs tray new tab FAB button exists") ComposeTabDrawerRobot(composeTestRule).interact() return ComposeTabDrawerRobot.Transition(composeTestRule) } fun openNotificationShade(interact: NotificationRobot.() -> Unit): NotificationRobot.Transition { + Log.i(TAG, "openNotificationShade: Trying to open the notification tray") mDevice.openNotification() - Log.i(TAG, "openNotificationShade: Opened notification tray") + Log.i(TAG, "openNotificationShade: Opened the notification tray") NotificationRobot().interact() return NotificationRobot.Transition() @@ -1041,8 +1097,7 @@ class BrowserRobot { fun goToHomescreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { clickPageObject(itemWithDescription("Home screen")) - - Log.i(TAG, "goToHomescreen: Looking for home screen layout or jump back in contextual hint") + Log.i(TAG, "goToHomescreen: Waiting for $waitingTime ms for for home screen layout or jump back in contextual hint to exist") mDevice.findObject(UiSelector().resourceId("$packageName:id/homeLayout")) .waitForExists(waitingTime) || mDevice.findObject( @@ -1050,6 +1105,7 @@ class BrowserRobot { getStringResource(R.string.onboarding_home_screen_jump_back_contextual_hint_2), ), ).waitForExists(waitingTime) + Log.i(TAG, "goToHomescreen: Waited for $waitingTime ms for for home screen layout or jump back in contextual hint to exist") HomeScreenRobot().interact() return HomeScreenRobot.Transition() @@ -1058,7 +1114,7 @@ class BrowserRobot { fun goToHomescreenWithComposeTopSites(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTopSitesRobot.() -> Unit): ComposeTopSitesRobot.Transition { clickPageObject(itemWithDescription("Home screen")) - Log.i(TAG, "goToHomescreenWithComposeTopSites: Looking for home screen layout or jump back in contextual hint") + Log.i(TAG, "goToHomescreenWithComposeTopSites: Waiting for $waitingTime ms for for home screen layout or jump back in contextual hint to exist") mDevice.findObject(UiSelector().resourceId("$packageName:id/homeLayout")) .waitForExists(waitingTime) || mDevice.findObject( @@ -1066,12 +1122,14 @@ class BrowserRobot { getStringResource(R.string.onboarding_home_screen_jump_back_contextual_hint_2), ), ).waitForExists(waitingTime) + Log.i(TAG, "goToHomescreenWithComposeTopSites: Waited for $waitingTime ms for for home screen layout or jump back in contextual hint to exist") ComposeTopSitesRobot(composeTestRule).interact() return ComposeTopSitesRobot.Transition(composeTestRule) } fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + Log.i(TAG, "goBack: Trying to click device back button") mDevice.pressBack() Log.i(TAG, "goBack: Clicked device back button") @@ -1081,7 +1139,9 @@ class BrowserRobot { fun clickTabCrashedCloseButton(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { clickPageObject(itemWithText("Close tab")) + Log.i(TAG, "clickTabCrashedCloseButton: Waiting for device to be idle") mDevice.waitForIdle() + Log.i(TAG, "clickTabCrashedCloseButton: Waited for device to be idle") HomeScreenRobot().interact() return HomeScreenRobot.Transition() @@ -1167,50 +1227,56 @@ class BrowserRobot { } fun openSiteSecuritySheet(interact: SiteSecurityRobot.() -> Unit): SiteSecurityRobot.Transition { - Log.i(TAG, "openSiteSecuritySheet: Looking for site security toolbar button") + Log.i(TAG, "openSiteSecuritySheet: Waiting for $waitingTime ms for site security toolbar button to exist") siteSecurityToolbarButton().waitForExists(waitingTime) + Log.i(TAG, "openSiteSecuritySheet: Waited for $waitingTime ms for site security toolbar button to exist") + Log.i(TAG, "openSiteSecuritySheet: Trying to click the site security toolbar button and wait for $waitingTime ms for a new window") siteSecurityToolbarButton().clickAndWaitForNewWindow(waitingTime) - Log.i(TAG, "openSiteSecuritySheet: Clicked site security toolbar button") + Log.i(TAG, "openSiteSecuritySheet: Clicked the site security toolbar button and waited for $waitingTime ms for a new window") SiteSecurityRobot().interact() return SiteSecurityRobot.Transition() } fun clickManageAddressButton(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition { + Log.i(TAG, "clickManageAddressButton: Trying to click the manage address button and wait for $waitingTime ms for a new window") itemWithResId("$packageName:id/manage_addresses") .clickAndWaitForNewWindow(waitingTime) - Log.i(TAG, "clickManageAddressButton: Clicked manage address button") + Log.i(TAG, "clickManageAddressButton: Clicked the manage address button and waited for $waitingTime ms for a new window") SettingsSubMenuAutofillRobot().interact() return SettingsSubMenuAutofillRobot.Transition() } fun clickManageCreditCardsButton(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition { + Log.i(TAG, "clickManageCreditCardsButton: Trying to click the manage credit cards button and wait for $waitingTime ms for a new window") itemWithResId("$packageName:id/manage_credit_cards") .clickAndWaitForNewWindow(waitingTime) - Log.i(TAG, "clickManageCreditCardsButton: Clicked manage credit cards button") + Log.i(TAG, "clickManageCreditCardsButton: Clicked the manage credit cards button and waited for $waitingTime ms for a new window") SettingsSubMenuAutofillRobot().interact() return SettingsSubMenuAutofillRobot.Transition() } fun clickOpenLinksInAppsGoToSettingsCFRButton(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { + Log.i(TAG, "clickOpenLinksInAppsGoToSettingsCFRButton: Trying to click the \"Go to settings\" open links in apps CFR button and wait for $waitingTime ms for a new window") itemWithResIdContainingText( "$packageName:id/action", getStringResource(R.string.open_in_app_cfr_positive_button_text), ).clickAndWaitForNewWindow(waitingTime) - Log.i(TAG, "clickOpenLinksInAppsGoToSettingsCFRButton: Clicked \"Go to settings\" open links in apps CFR button") + Log.i(TAG, "clickOpenLinksInAppsGoToSettingsCFRButton: Clicked the \"Go to settings\" open links in apps CFR button and waited for $waitingTime ms for a new window") SettingsRobot().interact() return SettingsRobot.Transition() } fun clickDownloadPDFButton(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { + Log.i(TAG, "clickDownloadPDFButton: Trying to click the download PDF button") itemWithResIdContainingText( "download", "Download", ).click() - Log.i(TAG, "clickDownloadPDFButton: Clicked download PDF button") + Log.i(TAG, "clickDownloadPDFButton: Clicked the download PDF button") DownloadRobot().interact() return DownloadRobot.Transition() @@ -1270,8 +1336,10 @@ fun clickPageObject(item: UiObject) { for (i in 1..RETRY_COUNT) { try { Log.i(TAG, "clickPageObject: Started try #$i") - Log.i(TAG, "clickPageObject: Looking for ${item.selector}") + Log.i(TAG, "clickPageObject: Waiting for $waitingTime ms for ${item.selector} to exist") item.waitForExists(waitingTime) + Log.i(TAG, "clickPageObject: Waited for $waitingTime ms for ${item.selector} to exist") + Log.i(TAG, "clickPageObject: Trying to click ${item.selector}") item.click() Log.i(TAG, "clickPageObject: Clicked ${item.selector}") @@ -1295,8 +1363,10 @@ fun longClickPageObject(item: UiObject) { for (i in 1..RETRY_COUNT) { try { Log.i(TAG, "longClickPageObject: Started try #$i") - Log.i(TAG, "longClickPageObject: Looking for ${item.selector}") + Log.i(TAG, "longClickPageObject: Waiting for $waitingTime ms for ${item.selector} to exist") item.waitForExists(waitingTime) + Log.i(TAG, "longClickPageObject: Waited for $waitingTime ms for ${item.selector} to exist") + Log.i(TAG, "longClickPageObject: Trying to long click ${item.selector}") item.longClick() Log.i(TAG, "longClickPageObject: Long clicked ${item.selector}") @@ -1321,21 +1391,25 @@ fun clickContextMenuItem(item: String) { Until.findObject(text(item)), waitingTime, ) + Log.i(TAG, "clickContextMenuItem: Trying to click context menu item: $item") mDevice.findObject(text(item)).click() - Log.i(TAG, "longClickPageObject: Clicked context menu item: $item") + Log.i(TAG, "clickContextMenuItem: Clicked context menu item: $item") } fun setPageObjectText(webPageItem: UiObject, text: String) { for (i in 1..RETRY_COUNT) { - Log.i(TAG, "setPageObjectText: For loop i = $i") + Log.i(TAG, "setPageObjectText: Started try #$i") try { webPageItem.also { - Log.i(TAG, "setPageObjectText: Looking for ${webPageItem.selector}") + Log.i(TAG, "setPageObjectText: Waiting for $waitingTime ms for ${webPageItem.selector} to exist") it.waitForExists(waitingTime) + Log.i(TAG, "setPageObjectText: Waited for $waitingTime ms for ${webPageItem.selector} to exist") + Log.i(TAG, "setPageObjectText: Trying to clear ${webPageItem.selector} text field") it.clearTextField() Log.i(TAG, "setPageObjectText: Cleared ${webPageItem.selector} text field") + Log.i(TAG, "setPageObjectText: Trying to set ${webPageItem.selector} text to $text") it.text = text - Log.i(TAG, "setPageObjectText: ${webPageItem.selector} text set to $text") + Log.i(TAG, "setPageObjectText: ${webPageItem.selector} text was set to $text") } break @@ -1355,8 +1429,10 @@ fun setPageObjectText(webPageItem: UiObject, text: String) { } fun clearTextFieldItem(item: UiObject) { - Log.i(TAG, "clearTextFieldItem: Looking for ${item.selector}") + Log.i(TAG, "clearTextFieldItem: Waiting for $waitingTime ms for ${item.selector} to exist") item.waitForExists(waitingTime) + Log.i(TAG, "clearTextFieldItem: Waited for $waitingTime ms for ${item.selector} to exist") + Log.i(TAG, "clearTextFieldItem: Trying to clear ${item.selector} text field") item.clearTextField() Log.i(TAG, "clearTextFieldItem: Cleared ${item.selector} text field") } From 254e126dad48279dade8740cb022bb0ba297b6f1 Mon Sep 17 00:00:00 2001 From: William Durand Date: Thu, 8 Feb 2024 13:10:49 +0100 Subject: [PATCH 139/586] Bug 1870362 - Add underline to each link in the add-on details view --- .../org/mozilla/fenix/addons/AddonDetailsBindingDelegate.kt | 5 +++++ .../mozilla/fenix/addons/AddonDetailsBindingDelegateTest.kt | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegate.kt b/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegate.kt index 3ff2f85f6887..fef044b050c4 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegate.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegate.kt @@ -22,6 +22,7 @@ import mozilla.components.feature.addons.ui.updatedAtDate import mozilla.components.support.ktx.android.content.getColorFromAttr import org.mozilla.fenix.R import org.mozilla.fenix.databinding.FragmentAddOnDetailsBinding +import org.mozilla.fenix.ext.addUnderline import java.text.DateFormat import java.text.NumberFormat import java.util.Locale @@ -70,6 +71,7 @@ class AddonDetailsBindingDelegate( if (addon.ratingUrl.isNotBlank()) { binding.reviewCount.setTextColor(binding.root.context.getColorFromAttr(R.attr.textAccent)) + binding.reviewCount.addUnderline() binding.reviewCount.setOnClickListener { interactor.openWebsite(addon.ratingUrl.toUri()) } @@ -85,6 +87,7 @@ class AddonDetailsBindingDelegate( return } + binding.homePageLabel.addUnderline() binding.homePageLabel.setOnClickListener { interactor.openWebsite(addon.homepageUrl.toUri()) } @@ -134,6 +137,7 @@ class AddonDetailsBindingDelegate( if (author.url.isNotBlank()) { binding.authorText.setTextColor(binding.root.context.getColorFromAttr(R.attr.textAccent)) + binding.authorText.addUnderline() binding.authorText.setOnClickListener { interactor.openWebsite(author.url.toUri()) } @@ -181,6 +185,7 @@ class AddonDetailsBindingDelegate( return } + binding.detailUrl.addUnderline() binding.detailUrl.setOnClickListener { interactor.openWebsite(addon.detailUrl.toUri()) } diff --git a/fenix/app/src/test/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegateTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegateTest.kt index 8df9a2a29ec2..91f27b9e9e7f 100644 --- a/fenix/app/src/test/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegateTest.kt +++ b/fenix/app/src/test/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegateTest.kt @@ -85,7 +85,7 @@ class AddonDetailsBindingDelegateTest { ratingUrl = "https://example.org/", ), ) - assertEquals("100", binding.reviewCount.text) + assertEquals("100", binding.reviewCount.text.toString()) binding.reviewCount.performClick() @@ -163,7 +163,7 @@ class AddonDetailsBindingDelegateTest { baseAddon.copy(author = Addon.Author(name = "Sarah Jane", url = "https://example.org/")), ) - assertEquals("Sarah Jane", binding.authorText.text) + assertEquals("Sarah Jane", binding.authorText.text.toString()) assertEquals(testContext.getColorFromAttr(R.attr.textAccent), binding.authorText.currentTextColor) binding.authorText.performClick() From 9c4e2efccbe488ede92534fe3b680d410f38aa55 Mon Sep 17 00:00:00 2001 From: "oana.horvath" Date: Tue, 6 Feb 2024 14:44:20 +0200 Subject: [PATCH 140/586] Bug 1878868 - Create TestSetup helper: Test classes A-C --- .../fenix/helpers/AppAndSystemHelper.kt | 105 ++++++++++++------ .../org/mozilla/fenix/helpers/TestSetup.kt | 52 +++++++++ .../mozilla/fenix/ui/AddressAutofillTest.kt | 22 +--- .../org/mozilla/fenix/ui/BookmarksTest.kt | 33 +----- .../fenix/ui/BrowsingErrorPagesTest.kt | 23 +--- .../org/mozilla/fenix/ui/CollectionTest.kt | 26 +---- .../org/mozilla/fenix/ui/ContextMenusTest.kt | 30 +---- .../fenix/ui/CookieBannerBlockerTest.kt | 3 +- .../mozilla/fenix/ui/CrashReportingTest.kt | 26 +---- .../fenix/ui/CreditCardAutofillTest.kt | 22 +--- .../org/mozilla/fenix/ui/CustomTabsTest.kt | 30 +---- 11 files changed, 150 insertions(+), 222 deletions(-) create mode 100644 fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt index 4ef27f9e9f8f..f9b95a2dc478 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt @@ -14,11 +14,11 @@ import android.content.pm.PackageManager import android.content.res.Configuration import android.net.Uri import android.os.Build +import android.os.Environment import android.os.storage.StorageManager import android.os.storage.StorageVolume import android.provider.Settings import android.util.Log -import androidx.annotation.RequiresApi import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.test.espresso.Espresso import androidx.test.espresso.IdlingRegistry @@ -33,6 +33,7 @@ import androidx.test.uiautomator.UiObject import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import junit.framework.AssertionFailedError +import kotlinx.coroutines.runBlocking import org.junit.Assert import org.junit.Assert.assertEquals import org.mozilla.fenix.Config @@ -60,46 +61,88 @@ object AppAndSystemHelper { } } - @RequiresApi(Build.VERSION_CODES.R) + /** + * Checks if a specific download file is inside the device storage and deletes it. + * Different implementation needed for newer API levels, + * as Environment.getExternalStorageDirectory() is deprecated starting with API 29. + * + */ fun deleteDownloadedFileOnStorage(fileName: String) { - val storageManager: StorageManager? = TestHelper.appContext.getSystemService(Context.STORAGE_SERVICE) as StorageManager? - val storageVolumes = storageManager!!.storageVolumes - val storageVolume: StorageVolume = storageVolumes[0] - val file = File(storageVolume.directory!!.path + "/Download/" + fileName) - try { - if (file.exists()) { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { + val storageManager: StorageManager? = + TestHelper.appContext.getSystemService(Context.STORAGE_SERVICE) as StorageManager? + val storageVolumes = storageManager!!.storageVolumes + val storageVolume: StorageVolume = storageVolumes[0] + val file = File(storageVolume.directory!!.path + "/Download/" + fileName) + try { + if (file.exists()) { + file.delete() + Log.d("TestLog", "File delete try 1") + Assert.assertFalse("The file was not deleted", file.exists()) + } + } catch (e: AssertionError) { file.delete() - Log.d("TestLog", "File delete try 1") + Log.d("TestLog", "File delete retried") Assert.assertFalse("The file was not deleted", file.exists()) } - } catch (e: AssertionError) { - file.delete() - Log.d("TestLog", "File delete retried") - Assert.assertFalse("The file was not deleted", file.exists()) + } else { + runBlocking { + val downloadedFile = File( + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), + fileName, + ) + + if (downloadedFile.exists()) { + Log.i(TAG, "deleteDownloadedFileOnStorage: Verifying if $downloadedFile exists.") + downloadedFile.delete() + Log.i(TAG, "deleteDownloadedFileOnStorage: $downloadedFile deleted.") + } + } } } - @RequiresApi(Build.VERSION_CODES.R) + /** + * Checks if there are download files inside the device storage and deletes all of them. + * Different implementation needed for newer API levels, as + * Environment.getExternalStorageDirectory() is deprecated starting with API 29. + */ fun clearDownloadsFolder() { - val storageManager: StorageManager? = TestHelper.appContext.getSystemService(Context.STORAGE_SERVICE) as StorageManager? - val storageVolumes = storageManager!!.storageVolumes - val storageVolume: StorageVolume = storageVolumes[0] - val downloadsFolder = File(storageVolume.directory!!.path + "/Download/") - - // Check if the downloads folder exists - if (downloadsFolder.exists() && downloadsFolder.isDirectory) { - Log.i(TAG, "clearDownloadsFolder: Verified that \"DOWNLOADS\" folder exists") - val files = downloadsFolder.listFiles() - - // Check if the folder is not empty - if (files != null && files.isNotEmpty()) { - Log.i(TAG, "clearDownloadsFolder: Verified that \"DOWNLOADS\" folder is not empty") - // Delete all files in the folder - for (file in files) { - file.delete() - Log.i(TAG, "clearDownloadsFolder: Deleted $file from \"DOWNLOADS\" folder") + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { + Log.i(TAG, "clearDownloadsFolder: API > 29") + val storageManager: StorageManager? = + TestHelper.appContext.getSystemService(Context.STORAGE_SERVICE) as StorageManager? + val storageVolumes = storageManager!!.storageVolumes + val storageVolume: StorageVolume = storageVolumes[0] + val downloadsFolder = File(storageVolume.directory!!.path + "/Download/") + + // Check if the downloads folder exists + if (downloadsFolder.exists() && downloadsFolder.isDirectory) { + Log.i(TAG, "clearDownloadsFolder: Verified that \"DOWNLOADS\" folder exists") + val files = downloadsFolder.listFiles() + + // Check if the folder is not empty + if (files != null && files.isNotEmpty()) { + Log.i( + TAG, + "clearDownloadsFolder: Verified that \"DOWNLOADS\" folder is not empty", + ) + // Delete all files in the folder + for (file in files) { + file.delete() + Log.i(TAG, "clearDownloadsFolder: Deleted $file from \"DOWNLOADS\" folder") + } } } + } else { + runBlocking { + Log.i(TAG, "clearDownloadsFolder: API <= 29") + Log.i(TAG, "clearDownloadsFolder: Verifying if any download files exist.") + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + .listFiles()?.forEach { + it.delete() + Log.i(TAG, "clearDownloadsFolder: Download file $it deleted.") + } + } } } diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt new file mode 100644 index 000000000000..b080154c4a1b --- /dev/null +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt @@ -0,0 +1,52 @@ +package org.mozilla.fenix.helpers + +import android.util.Log +import kotlinx.coroutines.runBlocking +import mozilla.appservices.places.BookmarkRoot +import mozilla.components.browser.storage.sync.PlacesBookmarksStorage +import okhttp3.mockwebserver.MockWebServer +import org.junit.Before +import org.mozilla.fenix.helpers.Constants.TAG +import org.mozilla.fenix.helpers.TestHelper.appContext +import org.mozilla.fenix.ui.robots.notificationShade + +open class TestSetup { + lateinit var mockWebServer: MockWebServer + private val bookmarksStorage = PlacesBookmarksStorage(appContext.applicationContext) + + @Before + fun setUp() { + Log.i(TAG, "TestSetup: Starting the @Before setup") + // Clear pre-existing notifications + notificationShade { + cancelAllShownNotifications() + } + runBlocking { + // Reset locale to EN-US if needed. + AppAndSystemHelper.resetSystemLocaleToEnUS() + // Check and clear the downloads folder + AppAndSystemHelper.clearDownloadsFolder() + // Make sure the Wifi and Mobile Data connections are on + AppAndSystemHelper.setNetworkEnabled(true) + // Clear bookmarks left after a failed test + val bookmarks = bookmarksStorage.getTree(BookmarkRoot.Mobile.id)?.children + Log.i(TAG, "Before cleanup: Bookmarks storage contains: $bookmarks") + bookmarks?.forEach { + bookmarksStorage.deleteNode(it.guid) + // TODO: Follow-up with a method to handle the DB update; the logs will still show the bookmarks in the storage before the test starts. + Log.i(TAG, "After cleanup: Bookmarks storage contains: $bookmarks") + } + } + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + } + try { + Log.i(TAG, "Try starting mockWebServer") + mockWebServer.start() + } catch (e: Exception) { + Log.i(TAG, "Exception caught. Re-starting mockWebServer") + mockWebServer.shutdown() + mockWebServer.start() + } + } +} diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt index 4631b8a7ac3e..b8b675778923 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt @@ -4,27 +4,22 @@ 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.customannotations.SmokeTest -import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.packageName +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.autofillScreen import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar -class AddressAutofillTest { - private lateinit var mockWebServer: MockWebServer - +class AddressAutofillTest : TestSetup() { object FirstAddressAutofillDetails { var navigateToAutofillSettings = true var isAddressAutofillEnabled = true @@ -58,19 +53,6 @@ class AddressAutofillTest { @get:Rule val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() - @Before - fun setUp() { - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836845 @SmokeTest @Test diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt index 2d2a1fc9723b..8b7b220ceb5b 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt @@ -8,20 +8,13 @@ import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu import androidx.test.espresso.Espresso.pressBack import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation -import androidx.test.uiautomator.UiDevice import kotlinx.coroutines.runBlocking -import mozilla.appservices.places.BookmarkRoot -import okhttp3.mockwebserver.MockWebServer -import org.junit.After -import org.junit.Before import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest -import org.mozilla.fenix.ext.bookmarkStorage import org.mozilla.fenix.ext.settings -import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MockBrowserDataHelper.createBookmarkItem @@ -31,8 +24,10 @@ import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.appContext import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem +import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.restartApp import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.bookmarksMenu import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.homeScreen @@ -42,9 +37,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar /** * Tests for verifying basic functionality of bookmarks */ -class BookmarksTest { - private lateinit var mockWebServer: MockWebServer - private lateinit var mDevice: UiDevice +class BookmarksTest : TestSetup() { private val bookmarksFolderName = "New Folder" private val testBookmark = object { var title: String = "Bookmark title" @@ -61,26 +54,6 @@ class BookmarksTest { @JvmField val retryTestRule = RetryTestRule(3) - @Before - fun setUp() { - mDevice = UiDevice.getInstance(getInstrumentation()) - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - // Clearing all bookmarks data after each test to avoid overlapping data - val bookmarksStorage = activityTestRule.activity?.bookmarkStorage - runBlocking { - val bookmarks = bookmarksStorage?.getTree(BookmarkRoot.Mobile.id)?.children - bookmarks?.forEach { bookmarksStorage.deleteNode(it.guid) } - } - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/522919 @Test fun verifyEmptyBookmarksMenuTest() { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt index de05a516a622..608c0e9191c0 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt @@ -5,20 +5,17 @@ package org.mozilla.fenix.ui import androidx.core.net.toUri -import okhttp3.mockwebserver.MockWebServer -import org.junit.After -import org.junit.Before import org.junit.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.AppAndSystemHelper.setNetworkEnabled import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.navigationToolbar @@ -26,13 +23,12 @@ import org.mozilla.fenix.ui.robots.navigationToolbar /** * Tests that verify errors encountered while browsing websites: unsafe pages, connection errors, etc */ -class BrowsingErrorPagesTest { +class BrowsingErrorPagesTest : TestSetup() { private val malwareWarning = getStringResource(R.string.mozac_browser_errorpages_safe_browsing_malware_uri_title) private val phishingWarning = getStringResource(R.string.mozac_browser_errorpages_safe_phishing_uri_title) private val unwantedSoftwareWarning = getStringResource(R.string.mozac_browser_errorpages_safe_browsing_unwanted_uri_title) private val harmfulSiteWarning = getStringResource(R.string.mozac_browser_errorpages_safe_harmful_uri_title) - private lateinit var mockWebServer: MockWebServer @get: Rule val mActivityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides() @@ -41,21 +37,6 @@ class BrowsingErrorPagesTest { @JvmField val retryTestRule = RetryTestRule(3) - @Before - fun setUp() { - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - // Restoring network connection - setNetworkEnabled(true) - mockWebServer.shutdown() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326774 @SmokeTest @Test diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt index c917f4d3fc5f..74e7b136ccb6 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt @@ -5,20 +5,16 @@ 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.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.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.collectionRobot import org.mozilla.fenix.ui.robots.homeScreen @@ -30,9 +26,7 @@ import org.mozilla.fenix.ui.robots.tabDrawer * */ -class CollectionTest { - private lateinit var mDevice: UiDevice - private lateinit var mockWebServer: MockWebServer +class CollectionTest : TestSetup() { private val firstCollectionName = "testcollection_1" private val secondCollectionName = "testcollection_2" private val collectionName = "First Collection" @@ -51,20 +45,6 @@ class CollectionTest { ), ) { it.activity } - @Before - fun setUp() { - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/353823 @SmokeTest @Test diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt index eeeec68a73e6..80f2d2a75c86 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt @@ -5,15 +5,8 @@ package org.mozilla.fenix.ui import androidx.core.net.toUri -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.uiautomator.UiDevice -import okhttp3.mockwebserver.MockWebServer -import org.junit.After -import org.junit.Before import org.junit.Rule import org.junit.Test -import org.mozilla.fenix.ext.settings -import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AppAndSystemHelper.assertExternalAppOpens import org.mozilla.fenix.helpers.Constants.PackageName.YOUTUBE_APP import org.mozilla.fenix.helpers.HomeActivityIntentTestRule @@ -22,7 +15,9 @@ 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.clickSnackbarButton +import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.clickContextMenuItem import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.downloadRobot @@ -44,32 +39,15 @@ import org.mozilla.fenix.ui.robots.shareOverlay * */ -class ContextMenusTest { - private lateinit var mDevice: UiDevice - private lateinit var mockWebServer: MockWebServer +class ContextMenusTest : TestSetup() { @get:Rule - val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + val activityIntentTestRule = HomeActivityIntentTestRule(isJumpBackInCFREnabled = false) @Rule @JvmField val retryTestRule = RetryTestRule(3) - @Before - fun setUp() { - activityIntentTestRule.activity.applicationContext.settings().shouldShowJumpBackInCFR = false - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243837 @Test fun verifyOpenLinkNewTabContextMenuOptionTest() { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt index 7ff48e390f3e..cc9fff3d17e7 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt @@ -12,13 +12,14 @@ import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithCondition import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.TestHelper.appContext +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar /** * Tests for verifying the new Cookie banner blocker option and functionality. */ -class CookieBannerBlockerTest { +class CookieBannerBlockerTest : TestSetup() { @get:Rule val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt index f246930bd4e4..84083e014ddf 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt @@ -5,29 +5,23 @@ 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.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest -import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.TestAssetHelper +import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar -class CrashReportingTest { - private lateinit var mDevice: UiDevice - private lateinit var mockWebServer: MockWebServer +class CrashReportingTest : TestSetup() { private val tabCrashMessage = getStringResource(R.string.tab_crash_title_2) @get:Rule @@ -40,20 +34,6 @@ class CrashReportingTest { ), ) { it.activity } - @Before - fun setUp() { - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/308906 @Test fun closeTabFromCrashedTabReporterTest() { diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt index f9eb0891b377..9a9b5697bfe1 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt @@ -4,13 +4,9 @@ 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.customannotations.SmokeTest -import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AppAndSystemHelper.bringAppToForeground import org.mozilla.fenix.helpers.AppAndSystemHelper.putAppToBackground import org.mozilla.fenix.helpers.HomeActivityIntentTestRule @@ -19,14 +15,13 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.packageName +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar import java.time.LocalDate -class CreditCardAutofillTest { - private lateinit var mockWebServer: MockWebServer - +class CreditCardAutofillTest : TestSetup() { object MockCreditCard1 { const val MOCK_CREDIT_CARD_NUMBER = "5555555555554444" const val MOCK_LAST_CARD_DIGITS = "4444" @@ -48,19 +43,6 @@ class CreditCardAutofillTest { @get:Rule val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() - @Before - fun setUp() { - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512792 @SmokeTest @Test diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt index b014dbb6156e..1e2aa93e832f 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt @@ -7,25 +7,20 @@ package org.mozilla.fenix.ui import androidx.core.net.toUri -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.rule.ActivityTestRule -import androidx.test.uiautomator.UiDevice -import okhttp3.mockwebserver.MockWebServer -import org.junit.After -import org.junit.Before import org.junit.Rule import org.junit.Test import org.mozilla.fenix.IntentReceiverActivity import org.mozilla.fenix.customannotations.SmokeTest -import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AppAndSystemHelper.openAppFromExternalLink import org.mozilla.fenix.helpers.DataGenerationHelper.createCustomTabIntent -import org.mozilla.fenix.helpers.FeatureSettingsHelperDelegate import org.mozilla.fenix.helpers.HomeActivityIntentTestRule 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.TestHelper.exitMenu +import org.mozilla.fenix.helpers.TestHelper.mDevice +import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.customTabScreen @@ -36,9 +31,7 @@ import org.mozilla.fenix.ui.robots.notificationShade import org.mozilla.fenix.ui.robots.openEditURLView import org.mozilla.fenix.ui.robots.searchScreen -class CustomTabsTest { - private lateinit var mDevice: UiDevice - private lateinit var mockWebServer: MockWebServer +class CustomTabsTest : TestSetup() { private val customMenuItem = "TestMenuItem" private val customTabActionButton = "CustomActionButton" @@ -58,23 +51,6 @@ class CustomTabsTest { false, ) - private val featureSettingsHelper = FeatureSettingsHelperDelegate() - - @Before - fun setUp() { - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mockWebServer = MockWebServer().apply { - dispatcher = AndroidAssetDispatcher() - start() - } - } - - @After - fun tearDown() { - mockWebServer.shutdown() - featureSettingsHelper.resetAllFeatureFlags() - } - // TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/249659 @SmokeTest @Test From c26bf6793840f336bae8f52a8fed88ea7f6d2edb Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Thu, 8 Feb 2024 14:18:34 +0200 Subject: [PATCH 141/586] Bug 1879308 - Add missing pairs of logs to ComposeTabDrawerRobot --- .../fenix/ui/robots/ComposeTabDrawerRobot.kt | 177 ++++++++++++------ 1 file changed, 121 insertions(+), 56 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt index ffe888fbff34..d42fd8e4ddad 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTabDrawerRobot.kt @@ -48,8 +48,8 @@ import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.HomeActivityComposeTestRule import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText -import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime +import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.clickAtLocationInView import org.mozilla.fenix.helpers.idlingresource.BottomSheetBehaviorStateIdlingResource @@ -64,31 +64,37 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest fun verifyNormalBrowsingButtonIsSelected(isSelected: Boolean = true) { if (isSelected) { + Log.i(TAG, "verifyNormalBrowsingButtonIsSelected: Trying to verify that the normal browsing button is selected") composeTestRule.normalBrowsingButton().assertIsSelected() - Log.i(TAG, "verifyNormalBrowsingButtonIsSelected: Verified normal browsing button is selected") + Log.i(TAG, "verifyNormalBrowsingButtonIsSelected: Verified that the normal browsing button is selected") } else { + Log.i(TAG, "verifyNormalBrowsingButtonIsSelected: Trying to verify that the normal browsing button is not selected") composeTestRule.normalBrowsingButton().assertIsNotSelected() - Log.i(TAG, "verifyNormalBrowsingButtonIsSelected: Verified normal browsing button is not selected") + Log.i(TAG, "verifyNormalBrowsingButtonIsSelected: Verified that the normal browsing button is not selected") } } fun verifyPrivateBrowsingButtonIsSelected(isSelected: Boolean = true) { if (isSelected) { + Log.i(TAG, "verifyPrivateBrowsingButtonIsSelected: Trying to verify that the private browsing button is selected") composeTestRule.privateBrowsingButton().assertIsSelected() - Log.i(TAG, "verifyPrivateBrowsingButtonIsSelected: Verified private browsing button is selected") + Log.i(TAG, "verifyPrivateBrowsingButtonIsSelected: Verified that the private browsing button is selected") } else { + Log.i(TAG, "verifyPrivateBrowsingButtonIsSelected: Trying to verify that the private browsing button is not selected") composeTestRule.privateBrowsingButton().assertIsNotSelected() - Log.i(TAG, "verifyPrivateBrowsingButtonIsSelected: Verified private browsing button is not selected") + Log.i(TAG, "verifyPrivateBrowsingButtonIsSelected: Verified that the private browsing button is not selected") } } fun verifySyncedTabsButtonIsSelected(isSelected: Boolean = true) { if (isSelected) { + Log.i(TAG, "verifySyncedTabsButtonIsSelected: Trying to verify that the synced tabs button is selected") composeTestRule.syncedTabsButton().assertIsSelected() - Log.i(TAG, "verifySyncedTabsButtonIsSelected: Verified synced tabs button is selected") + Log.i(TAG, "verifySyncedTabsButtonIsSelected: Verified that the synced tabs button is selected") } else { + Log.i(TAG, "verifySyncedTabsButtonIsSelected: Trying to verify that the synced tabs button is not selected") composeTestRule.syncedTabsButton().assertIsNotSelected() - Log.i(TAG, "verifySyncedTabsButtonIsSelected: Verified synced tabs button is not selected") + Log.i(TAG, "verifySyncedTabsButtonIsSelected: Verified that the synced tabs button is not selected") } } @@ -103,18 +109,22 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest fun verifyExistingOpenTabs(vararg titles: String) { titles.forEach { title -> + Log.i(TAG, "verifyExistingOpenTabs: Waiting for $waitingTime ms for tab with title: $title to exist") itemContainingText(title).waitForExists(waitingTime) + Log.i(TAG, "verifyExistingOpenTabs: Waited for $waitingTime ms for tab with title: $title to exist") + Log.i(TAG, "verifyExistingOpenTabs: Trying to verify that the open tab with title: $title exists") composeTestRule.tabItem(title).assertExists() - Log.i(TAG, "verifyExistingOpenTabs: Verified open tab with title: $title exists") + Log.i(TAG, "verifyExistingOpenTabs: Verified that the open tab with title: $title exists") } } fun verifyOpenTabsOrder(title: String, position: Int) { + Log.i(TAG, "verifyOpenTabsOrder: Trying to verify that the open tab at position: $position has title: $title") composeTestRule.normalTabsList() .onChildAt(position - 1) .assert(hasTestTag(TabsTrayTestTag.tabItemRoot)) .assert(hasAnyChild(hasText(title))) - Log.i(TAG, "verifyOpenTabsOrder: Verified open tab at position: $position has title: $title") + Log.i(TAG, "verifyOpenTabsOrder: Verified that the open tab at position: $position has title: $title") } fun verifyNoExistingOpenTabs(vararg titles: String) { @@ -127,109 +137,129 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest } fun verifyNormalTabsList() { + Log.i(TAG, "verifyNormalTabsList: Trying to verify that the normal tabs list exists") composeTestRule.normalTabsList().assertExists() - Log.i(TAG, "verifyNormalTabsList: Verified normal tabs list exists") + Log.i(TAG, "verifyNormalTabsList: Verified that the normal tabs list exists") } fun verifyPrivateTabsList() { + Log.i(TAG, "verifyPrivateTabsList: Trying to verify that the private tabs list exists") composeTestRule.privateTabsList().assertExists() - Log.i(TAG, "verifyPrivateTabsList: Verified private tabs list exists") + Log.i(TAG, "verifyPrivateTabsList: Verified that the private tabs list exists") } fun verifySyncedTabsList() { + Log.i(TAG, "verifySyncedTabsList: Trying to verify that the synced tabs list exists") composeTestRule.syncedTabsList().assertExists() - Log.i(TAG, "verifySyncedTabsList: Verified synced tabs list exists") + Log.i(TAG, "verifySyncedTabsList: Verified that the synced tabs list exists") } fun verifyNoOpenTabsInNormalBrowsing() { + Log.i(TAG, "verifyNoOpenTabsInNormalBrowsing: Trying to verify that the empty normal tabs list exists") composeTestRule.emptyNormalTabsList().assertExists() - Log.i(TAG, "verifyNoOpenTabsInNormalBrowsing: Verified empty normal tabs list exists") + Log.i(TAG, "verifyNoOpenTabsInNormalBrowsing: Verified that the empty normal tabs list exists") } fun verifyNoOpenTabsInPrivateBrowsing() { + Log.i(TAG, "verifyNoOpenTabsInPrivateBrowsing: Trying to verify that the empty private tabs list exists") composeTestRule.emptyPrivateTabsList().assertExists() - Log.i(TAG, "verifyNoOpenTabsInPrivateBrowsing: Verified empty private tabs list exists") + Log.i(TAG, "verifyNoOpenTabsInPrivateBrowsing: Verified that the empty private tabs list exists") } fun verifyAccountSettingsButton() { + Log.i(TAG, "verifyAccountSettingsButton: Trying to verify that the \"Account settings\" menu button exists") composeTestRule.dropdownMenuItemAccountSettings().assertExists() - Log.i(TAG, "verifyAccountSettingsButton: Verified \"Account settings\" menu button exists") + Log.i(TAG, "verifyAccountSettingsButton: Verified that the \"Account settings\" menu button exists") } fun verifyCloseAllTabsButton() { + Log.i(TAG, "verifyCloseAllTabsButton: Trying to verify that the \"Close all tabs\" menu button exists") composeTestRule.dropdownMenuItemCloseAllTabs().assertExists() - Log.i(TAG, "verifyCloseAllTabsButton: Verified \"Close all tabs\" menu button exists") + Log.i(TAG, "verifyCloseAllTabsButton: Verified that the \"Close all tabs\" menu button exists") } fun verifySelectTabsButton() { + Log.i(TAG, "verifySelectTabsButton: Trying to verify that the \"Select tabs\" menu button exists") composeTestRule.dropdownMenuItemSelectTabs().assertExists() - Log.i(TAG, "verifySelectTabsButton: Verified \"Select tabs\" menu button exists") + Log.i(TAG, "verifySelectTabsButton: Verified that the \"Select tabs\" menu button exists") } fun verifyShareAllTabsButton() { + Log.i(TAG, "verifyShareAllTabsButton: Trying to verify that the \"Share all tabs\" menu button exists") composeTestRule.dropdownMenuItemShareAllTabs().assertExists() - Log.i(TAG, "verifyShareAllTabsButton: Verified \"Share all tabs\" menu button exists") + Log.i(TAG, "verifyShareAllTabsButton: Verified that the \"Share all tabs\" menu button exists") } fun verifyRecentlyClosedTabsButton() { + Log.i(TAG, "verifyRecentlyClosedTabsButton: Trying to verify that the \"Recently closed tabs\" menu button exists") composeTestRule.dropdownMenuItemRecentlyClosedTabs().assertExists() - Log.i(TAG, "verifyRecentlyClosedTabsButton: Verified \"Recently closed tabs\" menu button exists") + Log.i(TAG, "verifyRecentlyClosedTabsButton: Verified that the \"Recently closed tabs\" menu button exists") } fun verifyTabSettingsButton() { + Log.i(TAG, "verifyTabSettingsButton: Trying to verify that the \"Tab settings\" menu button exists") composeTestRule.dropdownMenuItemTabSettings().assertExists() - Log.i(TAG, "verifyTabSettingsButton: Verified \"Tab settings\" menu button exists") + Log.i(TAG, "verifyTabSettingsButton: Verified that the \"Tab settings\" menu button exists") } fun verifyThreeDotButton() { + Log.i(TAG, "verifyThreeDotButton: Trying to verify that the three dot button exists") composeTestRule.threeDotButton().assertExists() - Log.i(TAG, "verifyThreeDotButton: Verified three dot button exists") + Log.i(TAG, "verifyThreeDotButton: Verified that the three dot button exists") } fun verifyFab() { + Log.i(TAG, "verifyFab: Trying to verify that the new tab FAB button exists") composeTestRule.tabsTrayFab().assertExists() - Log.i(TAG, "verifyFab: Verified new tab FAB button exists") + Log.i(TAG, "verifyFab: Verified that the new tab FAB button exists") } fun verifyNormalTabCounter() { + Log.i(TAG, "verifyNormalTabCounter: Trying to verify that the normal tabs list counter exists") composeTestRule.normalTabsCounter().assertExists() - Log.i(TAG, "verifyNormalTabCounter: Verified normal tabs list counter exists") + Log.i(TAG, "verifyNormalTabCounter: Verified that the normal tabs list counter exists") } /** * Verifies a tab's thumbnail when there is only one tab open. */ fun verifyTabThumbnail() { + Log.i(TAG, "verifyTabThumbnail: Trying to verify that the tab thumbnail exists") composeTestRule.tabThumbnail().assertExists() - Log.i(TAG, "verifyTabThumbnail: Verified tab thumbnail exists") + Log.i(TAG, "verifyTabThumbnail: Verified that the tab thumbnail exists") } /** * Verifies a tab's close button when there is only one tab open. */ fun verifyTabCloseButton() { + Log.i(TAG, "verifyTabCloseButton: Trying to verify that the close tab button exists") composeTestRule.closeTabButton().assertExists() - Log.i(TAG, "verifyTabCloseButton: Verified close tab button exists") + Log.i(TAG, "verifyTabCloseButton: Verified that the close tab button exists") } fun verifyTabsTrayBehaviorState(expectedState: Int) { + Log.i(TAG, "verifyTabsTrayBehaviorState: Trying to verify that the tabs tray state matches: $expectedState") tabsTrayView().check(ViewAssertions.matches(BottomSheetBehaviorStateMatcher(expectedState))) Log.i(TAG, "verifyTabsTrayBehaviorState: Verified that the tabs tray state matches: $expectedState") } fun verifyMinusculeHalfExpandedRatio() { + Log.i(TAG, "verifyMinusculeHalfExpandedRatio: Trying to verify the tabs tray half expanded ratio") tabsTrayView().check(ViewAssertions.matches(BottomSheetBehaviorHalfExpandedMaxRatioMatcher(0.001f))) - Log.i(TAG, "verifyMinusculeHalfExpandedRatio: Verified that the tabs tray half expanded ratio") + Log.i(TAG, "verifyMinusculeHalfExpandedRatio: Verified the tabs tray half expanded ratio") } fun verifyTabTrayIsOpen() { + Log.i(TAG, "verifyTabTrayIsOpen: Trying to verify that the tabs tray exists") composeTestRule.tabsTray().assertExists() - Log.i(TAG, "verifyTabTrayIsOpen: Verified that the open tabs tray exists") + Log.i(TAG, "verifyTabTrayIsOpen: Verified that the tabs tray exists") } fun verifyTabTrayIsClosed() { + Log.i(TAG, "verifyTabTrayIsClosed: Trying to verify that the tabs tray does not exist") composeTestRule.tabsTray().assertDoesNotExist() - Log.i(TAG, "verifyTabTrayIsClosed: Verified that the tabs tray is closed") + Log.i(TAG, "verifyTabTrayIsClosed: Verified that the tabs tray does not exist") } /** @@ -237,16 +267,22 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest */ @OptIn(ExperimentalTestApi::class) fun closeTab() { + Log.i(TAG, "closeTab: Waiting until the close tab button exists") composeTestRule.waitUntilAtLeastOneExists(hasTestTag(TabsTrayTestTag.tabItemClose)) + Log.i(TAG, "closeTab: Waited until the close tab button exists") + Log.i(TAG, "closeTab: Trying to verify that the close tab button exists") composeTestRule.closeTabButton().assertExists() + Log.i(TAG, "closeTab: Verified that the close tab button exists") + Log.i(TAG, "closeTab: Trying to click the close tab button") composeTestRule.closeTabButton().performClick() - Log.i(TAG, "closeTab: Clicked close tab button") + Log.i(TAG, "closeTab: Clicked the close tab button") } /** * Swipes a tab with [title] left. */ fun swipeTabLeft(title: String) { + Log.i(TAG, "swipeTabLeft: Trying to perform swipe left action on tab: $title") composeTestRule.tabItem(title).performTouchInput { swipeLeft() } Log.i(TAG, "swipeTabLeft: Performed swipe left action on tab: $title") } @@ -255,6 +291,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest * Swipes a tab with [title] right. */ fun swipeTabRight(title: String) { + Log.i(TAG, "swipeTabRight: Trying to perform swipe right action on tab: $title") composeTestRule.tabItem(title).performTouchInput { swipeRight() } Log.i(TAG, "swipeTabRight: Performed swipe right action on tab: $title") } @@ -267,10 +304,12 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest collectionName: String, firstCollection: Boolean = true, ) { + Log.i(TAG, "createCollection: Trying to click the three dot button") composeTestRule.threeDotButton().performClick() - Log.i(TAG, "createCollection: Clicked 3 dot button") + Log.i(TAG, "createCollection: Clicked the three dot button") + Log.i(TAG, "createCollection: Trying to click the \"Select tabs\" menu button") composeTestRule.dropdownMenuItemSelectTabs().performClick() - Log.i(TAG, "createCollection: Clicked \"Select tabs\" menu button") + Log.i(TAG, "createCollection: Clicked the \"Select tabs\" menu button") for (tab in tabTitles) { selectTab(tab) @@ -289,8 +328,10 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest */ @OptIn(ExperimentalTestApi::class) fun selectTab(title: String) { - Log.i(TAG, "selectTab: Waiting for tab with title: $title to exist") + Log.i(TAG, "selectTab: Waiting for $waitingTime ms until the tab with title: $title exists") composeTestRule.waitUntilExactlyOneExists(hasText(title), waitingTime) + Log.i(TAG, "selectTab: Waited for $waitingTime ms until the tab with title: $title exists") + Log.i(TAG, "selectTab: Trying to click tab with title: $title") composeTestRule.tabItem(title).performClick() Log.i(TAG, "selectTab: Clicked tab with title: $title") } @@ -299,6 +340,7 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest * Performs a long click on a tab with [title]. */ fun longClickTab(title: String) { + Log.i(TAG, "longClickTab: Trying to long click tab with title: $title") composeTestRule.tabItem(title) .performTouchInput { longClick(durationMillis = Constants.LONG_CLICK_DURATION) } Log.i(TAG, "longClickTab: Long clicked tab with title: $title") @@ -308,9 +350,10 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest * Verifies the multi selection counter displays [numOfTabs]. */ fun verifyTabsMultiSelectionCounter(numOfTabs: Int) { + Log.i(TAG, "verifyTabsMultiSelectionCounter: Trying to verify that $numOfTabs tabs are selected") composeTestRule.multiSelectionCounter() .assert(hasText("$numOfTabs selected")) - Log.i(TAG, "verifyTabsMultiSelectionCounter: Verified $numOfTabs are selected") + Log.i(TAG, "verifyTabsMultiSelectionCounter: Verified that $numOfTabs tabs are selected") } /** @@ -318,11 +361,13 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest */ @OptIn(ExperimentalTestApi::class) fun verifyTabMediaControlButtonState(action: String) { - Log.i(TAG, "verifyTabMediaControlButtonStateTab: Waiting for media tab control button: $action to exist") + Log.i(TAG, "verifyTabMediaControlButtonStateTab: Waiting for $waitingTime ms until the media tab control button: $action exists") composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(action), waitingTime) + Log.i(TAG, "verifyTabMediaControlButtonStateTab: Waited for $waitingTime ms until the media tab control button: $action exists") + Log.i(TAG, "verifyTabMediaControlButtonStateTab: Trying to verify that the tab media control button: $action exists") composeTestRule.tabMediaControlButton(action) .assertExists() - Log.i(TAG, "verifyTabMediaControlButtonStateTab: Verified media tab control button: $action exists") + Log.i(TAG, "verifyTabMediaControlButtonStateTab: Verified tab media control button: $action exists") } /** @@ -330,65 +375,75 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest */ @OptIn(ExperimentalTestApi::class) fun clickTabMediaControlButton(action: String) { - Log.i(TAG, "clickTabMediaControlButton: Waiting for media tab control button: $action to exist") + Log.i(TAG, "clickTabMediaControlButton: Waiting for $waitingTime ms until the media tab control button: $action exists") composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(action), waitingTime) + Log.i(TAG, "clickTabMediaControlButton: Waited for $waitingTime ms until the media tab control button: $action exists") + Log.i(TAG, "clickTabMediaControlButton: Trying to click the tab media control button: $action") composeTestRule.tabMediaControlButton(action) .performClick() - Log.i(TAG, "clickTabMediaControlButton: Clicked media tab control button: $action") + Log.i(TAG, "clickTabMediaControlButton: Clicked the tab media control button: $action") } /** * Closes a tab with a given [title]. */ fun closeTabWithTitle(title: String) { + Log.i(TAG, "closeTabWithTitle: Trying to click the close button for tab with title: $title") composeTestRule.onAllNodesWithTag(TabsTrayTestTag.tabItemClose) .filter(hasParent(hasText(title))) .onFirst() .performClick() - Log.i(TAG, "closeTabWithTitle: Closed tab with title: $title") + Log.i(TAG, "closeTabWithTitle: Clicked the close button for tab with title: $title") } class Transition(private val composeTestRule: HomeActivityComposeTestRule) { fun openNewTab(interact: SearchRobot.() -> Unit): SearchRobot.Transition { + Log.i(TAG, "openNewTab: Waiting for device to be idle") mDevice.waitForIdle() - + Log.i(TAG, "openNewTab: Waited for device to be idle") + Log.i(TAG, "openNewTab: Trying to click the new tab FAB button") composeTestRule.tabsTrayFab().performClick() - Log.i(TAG, "openNewTab: Clicked new tab FAB button") + Log.i(TAG, "openNewTab: Clicked the new tab FAB button") SearchRobot().interact() return SearchRobot.Transition() } fun toggleToNormalTabs(interact: ComposeTabDrawerRobot.() -> Unit): Transition { + Log.i(TAG, "toggleToNormalTabs: Trying to click the normal browsing button") composeTestRule.normalBrowsingButton().performClick() - Log.i(TAG, "toggleToNormalTabs: Clicked normal browsing button") + Log.i(TAG, "toggleToNormalTabs: Clicked the normal browsing button") ComposeTabDrawerRobot(composeTestRule).interact() return Transition(composeTestRule) } fun toggleToPrivateTabs(interact: ComposeTabDrawerRobot.() -> Unit): Transition { + Log.i(TAG, "toggleToPrivateTabs: Trying to click the private browsing button") composeTestRule.privateBrowsingButton().performClick() - Log.i(TAG, "toggleToPrivateTabs: Clicked private browsing button") + Log.i(TAG, "toggleToPrivateTabs: Clicked the private browsing button") ComposeTabDrawerRobot(composeTestRule).interact() return Transition(composeTestRule) } fun toggleToSyncedTabs(interact: ComposeTabDrawerRobot.() -> Unit): Transition { + Log.i(TAG, "toggleToSyncedTabs: Trying to click the synced tabs button") composeTestRule.syncedTabsButton().performClick() - Log.i(TAG, "toggleToSyncedTabs: Clicked synced tabs button") + Log.i(TAG, "toggleToSyncedTabs: Clicked the synced tabs button") ComposeTabDrawerRobot(composeTestRule).interact() return Transition(composeTestRule) } fun clickSignInToSyncButton(interact: SyncSignInRobot.() -> Unit): SyncSignInRobot.Transition { + Log.i(TAG, "clickSignInToSyncButton: Trying to click the sign in to sync button and wait for $waitingTimeShort ms for a new window") itemContainingText(getStringResource(R.string.sync_sign_in)) - .clickAndWaitForNewWindow(TestAssetHelper.waitingTimeShort) - Log.i(TAG, "clickSignInToSyncButton: Clicked sign in to sync button") + .clickAndWaitForNewWindow(waitingTimeShort) + Log.i(TAG, "clickSignInToSyncButton: Clicked the sign in to sync button and waited for $waitingTimeShort ms for a new window") SyncSignInRobot().interact() return SyncSignInRobot.Transition() } fun openThreeDotMenu(interact: ComposeTabDrawerRobot.() -> Unit): Transition { + Log.i(TAG, "openThreeDotMenu: Trying to click the three dot button") composeTestRule.threeDotButton().performClick() Log.i(TAG, "openThreeDotMenu: Clicked three dot button") ComposeTabDrawerRobot(composeTestRule).interact() @@ -396,37 +451,42 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest } fun closeAllTabs(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + Log.i(TAG, "closeAllTabs: Trying to click the \"Close all tabs\" menu button") composeTestRule.dropdownMenuItemCloseAllTabs().performClick() - Log.i(TAG, "closeAllTabs: Clicked \"Close all tabs\" menu button") + Log.i(TAG, "closeAllTabs: Clicked the \"Close all tabs\" menu button") HomeScreenRobot().interact() return HomeScreenRobot.Transition() } fun openTab(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - composeTestRule.tabItem(title) - .performScrollTo() - .performClick() - Log.i(TAG, "openTab: Scrolled and clicked tab with title: $title") + Log.i(TAG, "openTab: Trying to scroll to tab with title: $title") + composeTestRule.tabItem(title).performScrollTo() + Log.i(TAG, "openTab: Scrolled to tab with title: $title") + Log.i(TAG, "openTab: Trying to click tab with title: $title") + composeTestRule.tabItem(title).performClick() + Log.i(TAG, "openTab: Clicked tab with title: $title") BrowserRobot().interact() return BrowserRobot.Transition() } fun openPrivateTab(position: Int, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "openPrivateTab: Trying to click private tab at position: ${position + 1}") composeTestRule.privateTabsList() .onChildren()[position] .performClick() - Log.i(TAG, "openPrivateTab: Opened private tab at position: ${position + 1}") + Log.i(TAG, "openPrivateTab: Clicked private tab at position: ${position + 1}") BrowserRobot().interact() return BrowserRobot.Transition() } fun openNormalTab(position: Int, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "openNormalTab: Trying to click tab at position: ${position + 1}") composeTestRule.normalTabsList() .onChildren()[position] .performClick() - Log.i(TAG, "openNormalTab: Opened tab at position: ${position + 1}") + Log.i(TAG, "openNormalTab: Clicked tab at position: ${position + 1}") BrowserRobot().interact() return BrowserRobot.Transition() @@ -435,8 +495,9 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest fun clickTopBar(interact: ComposeTabDrawerRobot.() -> Unit): Transition { // The topBar contains other views. // Don't do the default click in the middle, rather click in some free space - top right. + Log.i(TAG, "clickTopBar: Trying to click the tabs tray top bar") Espresso.onView(ViewMatchers.withId(R.id.topBar)).clickAtLocationInView(GeneralLocation.TOP_RIGHT) - Log.i(TAG, "clickTopBar: Clicked tabs tray top bar") + Log.i(TAG, "clickTopBar: Clicked the tabs tray top bar") ComposeTabDrawerRobot(composeTestRule).interact() return Transition(composeTestRule) } @@ -493,14 +554,16 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest } fun closeTabDrawer(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "closeTabDrawer: Trying to close the tabs tray by clicking the handle") composeTestRule.bannerHandle().performSemanticsAction(SemanticsActions.OnClick) - Log.i(TAG, "closeTabDrawer: Closed tabs tray clicking the handle") + Log.i(TAG, "closeTabDrawer: Closed the tabs tray by clicking the handle") BrowserRobot().interact() return BrowserRobot.Transition() } fun clickSaveCollection(interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { + Log.i(TAG, "clickSaveCollection: Trying to click the collections button") composeTestRule.collectionsButton().performClick() Log.i(TAG, "clickSaveCollection: Clicked collections button") @@ -509,8 +572,9 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest } fun clickShareAllTabsButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { + Log.i(TAG, "clickShareAllTabsButton: Trying to click the \"Share all tabs\" menu button button") composeTestRule.dropdownMenuItemShareAllTabs().performClick() - Log.i(TAG, "clickShareAllTabsButton: Clicked \"Share all tabs\" menu button button") + Log.i(TAG, "clickShareAllTabsButton: Clicked the \"Share all tabs\" menu button button") ShareOverlayRobot().interact() return ShareOverlayRobot.Transition() @@ -530,8 +594,9 @@ fun composeTabDrawer(composeTestRule: HomeActivityComposeTestRule, interact: Com * Clicks on the Collections button in the Tabs Tray banner and opens a transition in the [CollectionRobot]. */ private fun clickCollectionsButton(composeTestRule: HomeActivityComposeTestRule, interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { + Log.i(TAG, "clickCollectionsButton: Trying to click the collections button") composeTestRule.collectionsButton().performClick() - Log.i(TAG, "clickCollectionsButton: Clicked collections button") + Log.i(TAG, "clickCollectionsButton: Clicked the collections button") CollectionRobot().interact() return CollectionRobot.Transition() From b14359121623eb7cf0a3adb31be25a716f9e97ab Mon Sep 17 00:00:00 2001 From: William Durand Date: Wed, 7 Feb 2024 16:01:41 +0100 Subject: [PATCH 142/586] Bug 1870319 - Announce title in add-ons sub-menu and use "navigate back" instead of "navigate up" --- .../components/browser/menu/WebExtensionBrowserMenuBuilder.kt | 2 +- .../components/browser/menu/src/main/res/values/strings.xml | 2 ++ fenix/app/src/main/res/values/strings.xml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/android-components/components/browser/menu/src/main/java/mozilla/components/browser/menu/WebExtensionBrowserMenuBuilder.kt b/android-components/components/browser/menu/src/main/java/mozilla/components/browser/menu/WebExtensionBrowserMenuBuilder.kt index 40f49ed6610b..1ca54f676467 100644 --- a/android-components/components/browser/menu/src/main/java/mozilla/components/browser/menu/WebExtensionBrowserMenuBuilder.kt +++ b/android-components/components/browser/menu/src/main/java/mozilla/components/browser/menu/WebExtensionBrowserMenuBuilder.kt @@ -91,7 +91,7 @@ class WebExtensionBrowserMenuBuilder( ): List { val addonsMenuItem = if (filteredExtensionMenuItems.isNotEmpty()) { val backPressMenuItem = BackPressMenuItem( - contentDescription = context.getString(R.string.action_bar_up_description), + contentDescription = context.getString(R.string.mozac_browser_menu_addons_description), label = context.getString(R.string.mozac_browser_menu_addons), imageResource = style.backPressMenuItemDrawableRes, iconTintColorResource = style.webExtIconTintColorResource, diff --git a/android-components/components/browser/menu/src/main/res/values/strings.xml b/android-components/components/browser/menu/src/main/res/values/strings.xml index 9901c1385be4..bb0b725b17cc 100644 --- a/android-components/components/browser/menu/src/main/res/values/strings.xml +++ b/android-components/components/browser/menu/src/main/res/values/strings.xml @@ -13,4 +13,6 @@ Add-ons Manager Navigate up + + Add-ons, navigate up diff --git a/fenix/app/src/main/res/values/strings.xml b/fenix/app/src/main/res/values/strings.xml index 119fb2d1d462..1796126135be 100644 --- a/fenix/app/src/main/res/values/strings.xml +++ b/fenix/app/src/main/res/values/strings.xml @@ -2101,7 +2101,7 @@ Click for more details - Navigate up + Navigate up Close From de70b19c65f58c8bb8db60f2b709edfe52f4bf5b Mon Sep 17 00:00:00 2001 From: William Durand Date: Thu, 8 Feb 2024 21:41:43 +0100 Subject: [PATCH 143/586] Bug 1870337 - Update description of the add-on post-install popup --- .../addons/ui/AddonInstallationDialogFragment.kt | 9 ++++++++- ...ture_addons_fragment_dialog_addon_installed.xml | 14 ++------------ .../feature/addons/src/main/res/values/strings.xml | 10 +++++++--- .../ui/AddonInstallationDialogFragmentTest.kt | 2 +- .../ui/robots/SettingsSubMenuAddonsManagerRobot.kt | 8 ++++---- 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragment.kt b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragment.kt index 0779680dbf21..56ab680cfc39 100644 --- a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragment.kt +++ b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragment.kt @@ -136,10 +136,17 @@ class AddonInstallationDialogFragment : AddonDialogFragment() { val binding = MozacFeatureAddonsFragmentDialogAddonInstalledBinding.bind(rootView) + val addonName = addon.translateName(requireContext()) rootView.findViewById(R.id.title).text = requireContext().getString( R.string.mozac_feature_addons_installed_dialog_title, - addon.translateName(requireContext()), + addonName, + requireContext().appName, + ) + rootView.findViewById(R.id.description).text = + requireContext().getString( + R.string.mozac_feature_addons_installed_dialog_description_2, + addonName, requireContext().appName, ) diff --git a/android-components/components/feature/addons/src/main/res/layout/mozac_feature_addons_fragment_dialog_addon_installed.xml b/android-components/components/feature/addons/src/main/res/layout/mozac_feature_addons_fragment_dialog_addon_installed.xml index f56c93853731..3c23c7a84482 100644 --- a/android-components/components/feature/addons/src/main/res/layout/mozac_feature_addons_fragment_dialog_addon_installed.xml +++ b/android-components/components/feature/addons/src/main/res/layout/mozac_feature_addons_fragment_dialog_addon_installed.xml @@ -50,17 +50,7 @@ android:paddingTop="4dp" android:paddingEnd="5dp" android:textColor="?android:attr/textColorPrimary" - android:text="@string/mozac_feature_addons_installed_dialog_description" /> - - + tools:text="@string/mozac_feature_addons_installed_dialog_description_2" /> diff --git a/android-components/components/feature/addons/src/main/res/values/strings.xml b/android-components/components/feature/addons/src/main/res/values/strings.xml index e1279908e6ce..dc1c822e25ae 100644 --- a/android-components/components/feature/addons/src/main/res/values/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values/strings.xml @@ -249,10 +249,14 @@ Status: %1$s has been added to %2$s - - Open it in the menu + + Open it in the menu + + Access %1$s from the %2$s menu. + + Okay, Got it - Okay, Got it + OK Learn more diff --git a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragmentTest.kt b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragmentTest.kt index 74d0fed4aa09..524392ea156c 100644 --- a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragmentTest.kt +++ b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragmentTest.kt @@ -56,7 +56,7 @@ class AddonInstallationDialogFragmentTest { val allowedInPrivateBrowsing = dialog.findViewById(R.id.allow_in_private_browsing) assertTrue(titleTextView.text.contains(name)) - assertTrue(description.text.contains(testContext.getString(R.string.mozac_feature_addons_installed_dialog_description))) + assertTrue(description.text.contains(name)) assertTrue(allowedInPrivateBrowsing.text.contains(testContext.getString(R.string.mozac_feature_addons_settings_allow_in_private_browsing))) } diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt index 94c5c3f50074..7847051388eb 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt @@ -98,7 +98,7 @@ class SettingsSubMenuAddonsManagerRobot { fun verifyAddonInstallCompleted(addonName: String, activityTestRule: HomeActivityIntentTestRule) { for (i in 1..RETRY_COUNT) { try { - assertUIObjectExists(itemWithText("Okay, Got it"), waitingTime = waitingTimeLong) + assertUIObjectExists(itemWithText("OK"), waitingTime = waitingTimeLong) break } catch (e: AssertionError) { @@ -123,10 +123,10 @@ class SettingsSubMenuAddonsManagerRobot { fun verifyAddonInstallCompletedPrompt(addonName: String) { onView( allOf( - withText("Okay, Got it"), + withText("OK"), withParent(instanceOf(RelativeLayout::class.java)), hasSibling(withText("$addonName has been added to $appName")), - hasSibling(withText("Open it in the menu")), + hasSibling(withText("Access $addonName from the $appName menu.")), hasSibling(withText("Allow in private browsing")), ), ) @@ -134,7 +134,7 @@ class SettingsSubMenuAddonsManagerRobot { } fun closeAddonInstallCompletePrompt() { - onView(withText("Okay, Got it")).click() + onView(withText("OK")).click() } fun verifyAddonIsInstalled(addonName: String) { From ab766724745d16dc734b51de2cac7fab9edce4d1 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Fri, 9 Feb 2024 05:21:28 +0000 Subject: [PATCH 144/586] Update A-S to 124.20240209050256. --- .../plugins/dependencies/src/main/java/ApplicationServices.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt index e57bd82fb28a..5dea01104e03 100644 --- a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt +++ b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // These lines are generated by android-components/automation/application-services-nightly-bump.py -val VERSION = "124.20240208050312" +val VERSION = "124.20240209050256" val CHANNEL = ApplicationServicesChannel.NIGHTLY object ApplicationServicesConfig { From 6e85bb1e08d6512ad6c034757d926e0c54c6ee05 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Thu, 8 Feb 2024 16:18:35 +0200 Subject: [PATCH 145/586] Bug 1879339 - Add missing pairs of logs to ComposeTopSitesRobot --- .../fenix/ui/robots/ComposeTopSitesRobot.kt | 59 +++++++++++++------ 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTopSitesRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTopSitesRobot.kt index 1a25a39e6915..53f1121bfaea 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTopSitesRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ComposeTopSitesRobot.kt @@ -34,25 +34,31 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR @OptIn(ExperimentalTestApi::class) fun verifyExistingTopSitesList() { - Log.i(TAG, "verifyExistingTopSitesList: Waiting for top sites list to exist") + Log.i(TAG, "verifyExistingTopSitesList: Waiting for $waitingTime ms until the top sites list exists") composeTestRule.waitUntilAtLeastOneExists(hasTestTag(TopSitesTestTag.topSites), timeoutMillis = waitingTime) + Log.i(TAG, "verifyExistingTopSitesList: Waited for $waitingTime ms until the top sites list to exists") } @OptIn(ExperimentalTestApi::class) fun verifyExistingTopSiteItem(vararg titles: String) { titles.forEach { title -> - Log.i(TAG, "verifyExistingTopSiteItem: Waiting for top site: $title to exist") + Log.i(TAG, "verifyExistingTopSiteItem: Waiting for $waitingTime ms until the top site with title: $title exists") composeTestRule.waitUntilAtLeastOneExists(hasText(title), timeoutMillis = waitingTime) + Log.i(TAG, "verifyExistingTopSiteItem: Waited for $waitingTime ms until the top site with title: $title exists") + Log.i(TAG, "verifyExistingTopSiteItem: Trying to verify that the top site with title: $title exists") composeTestRule.topSiteItem(title).assertExists() - Log.i(TAG, "verifyExistingTopSiteItem: Top site with $title exists") + Log.i(TAG, "verifyExistingTopSiteItem: Verified that the top site with title: $title exists") } } fun verifyNotExistingTopSiteItem(vararg titles: String) { titles.forEach { title -> + Log.i(TAG, "verifyNotExistingTopSiteItem: Waiting for $waitingTime ms for top site with title: $title to exist") itemContainingText(title).waitForExists(waitingTime) + Log.i(TAG, "verifyNotExistingTopSiteItem: Waited for $waitingTime ms for top site with title: $title to exist") + Log.i(TAG, "verifyNotExistingTopSiteItem: Trying to verify that top site with title: $title does not exist") composeTestRule.topSiteItem(title).assertDoesNotExist() - Log.i(TAG, "verifyNotExistingTopSiteItem: Top site with $title does not exist") + Log.i(TAG, "verifyNotExistingTopSiteItem: Verified that top site with title: $title does not exist") } } @@ -63,18 +69,21 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR } fun verifyTopSiteContextMenuOpenInPrivateTabButton() { + Log.i(TAG, "verifyTopSiteContextMenuOpenInPrivateTabButton: Trying to verify that the \"Open in private tab\" menu button exists") composeTestRule.contextMenuItemOpenInPrivateTab().assertExists() - Log.i(TAG, "verifyTopSiteContextMenuOpenInPrivateTabButton: Verified \"Open in private tab\" menu button exists") + Log.i(TAG, "verifyTopSiteContextMenuOpenInPrivateTabButton: Verified that the \"Open in private tab\" menu button exists") } fun verifyTopSiteContextMenuRenameButton() { + Log.i(TAG, "verifyTopSiteContextMenuRenameButton: Trying to verify that the \"Rename\" menu button exists") composeTestRule.contextMenuItemRename().assertExists() - Log.i(TAG, "verifyTopSiteContextMenuRenameButton: Verified \"Rename\" menu button exists") + Log.i(TAG, "verifyTopSiteContextMenuRenameButton: Verified that the \"Rename\" menu button exists") } fun verifyTopSiteContextMenuRemoveButton() { + Log.i(TAG, "verifyTopSiteContextMenuRemoveButton: Trying to verify that the \"Remove\" menu button exists") composeTestRule.contextMenuItemRemove().assertExists() - Log.i(TAG, "verifyTopSiteContextMenuRemoveButton: Verified \"Remove\" menu button exists") + Log.i(TAG, "verifyTopSiteContextMenuRemoveButton: Verified that the \"Remove\" menu button exists") } class Transition(private val composeTestRule: HomeActivityComposeTestRule) { @@ -83,8 +92,12 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR title: String, interact: BrowserRobot.() -> Unit, ): BrowserRobot.Transition { - composeTestRule.topSiteItem(title).performScrollTo().performClick() - Log.i(TAG, "openTopSiteTabWithTitle: Scrolled and clicked top site with title: $title") + Log.i(TAG, "openTopSiteTabWithTitle: Trying to scroll to top site with title: $title") + composeTestRule.topSiteItem(title).performScrollTo() + Log.i(TAG, "openTopSiteTabWithTitle: Scrolled to top site with title: $title") + Log.i(TAG, "openTopSiteTabWithTitle: Trying to click top site with title: $title") + composeTestRule.topSiteItem(title).performClick() + Log.i(TAG, "openTopSiteTabWithTitle: Clicked top site with title: $title") BrowserRobot().interact() return BrowserRobot.Transition() @@ -93,8 +106,9 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR fun openTopSiteInPrivate( interact: BrowserRobot.() -> Unit, ): BrowserRobot.Transition { + Log.i(TAG, "openTopSiteInPrivate: Trying to click the \"Open in private tab\" menu button") composeTestRule.contextMenuItemOpenInPrivateTab().performClick() - Log.i(TAG, "openTopSiteInPrivate: Clicked \"Open in private tab\" menu button") + Log.i(TAG, "openTopSiteInPrivate: Clicked the \"Open in private tab\" menu button") composeTestRule.waitForIdle() BrowserRobot().interact() @@ -105,9 +119,11 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR title: String, interact: ComposeTopSitesRobot.() -> Unit, ): Transition { - composeTestRule.topSiteItem(title).performScrollTo().performTouchInput { - longClick() - } + Log.i(TAG, "openContextMenuOnTopSitesWithTitle: Trying to scroll to top site with title: $title") + composeTestRule.topSiteItem(title).performScrollTo() + Log.i(TAG, "openContextMenuOnTopSitesWithTitle: Scrolled to top site with title: $title") + Log.i(TAG, "openContextMenuOnTopSitesWithTitle: Trying to long click top site with title: $title") + composeTestRule.topSiteItem(title).performTouchInput { longClick() } Log.i(TAG, "openContextMenuOnTopSitesWithTitle: Long clicked top site with title: $title") ComposeTopSitesRobot(composeTestRule).interact() @@ -118,16 +134,21 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR title: String, interact: ComposeTopSitesRobot.() -> Unit, ): Transition { + Log.i(TAG, "renameTopSite: Trying to click the \"Rename\" menu button") composeTestRule.contextMenuItemRename().performClick() - Log.i(TAG, "renameTopSite: Clicked \"Rename\" menu button") + Log.i(TAG, "renameTopSite: Clicked the \"Rename\" menu button") itemWithResId("$packageName:id/top_site_title") .also { + Log.i(TAG, "renameTopSite: Waiting for $waitingTimeShort ms for top site rename text box to exist") it.waitForExists(waitingTimeShort) + Log.i(TAG, "renameTopSite: Waited for $waitingTimeShort ms for top site rename text box to exist") + Log.i(TAG, "renameTopSite: Trying to set top site rename text box text to: $title") it.setText(title) + Log.i(TAG, "renameTopSite: Top site rename text box text was set to: $title") } - Log.i(TAG, "renameTopSite: Top site rename text box was set to: $title") + Log.i(TAG, "renameTopSite: Trying to click the \"Ok\" dialog button") itemWithResIdContainingText("android:id/button1", "OK").click() - Log.i(TAG, "renameTopSite: Clicked \"Ok\" dialog button") + Log.i(TAG, "renameTopSite: Clicked the \"Ok\" dialog button") ComposeTopSitesRobot(composeTestRule).interact() return Transition(composeTestRule) @@ -137,10 +158,12 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR fun removeTopSite( interact: ComposeTopSitesRobot.() -> Unit, ): Transition { + Log.i(TAG, "removeTopSite: Trying to click the \"Remove\" menu button") composeTestRule.contextMenuItemRemove().performClick() - Log.i(TAG, "removeTopSite: Clicked \"Remove\" menu button") + Log.i(TAG, "removeTopSite: Clicked the \"Remove\" menu button") + Log.i(TAG, "removeTopSite: Waiting for $waitingTime ms until the \"Remove\" menu button does not exist") composeTestRule.waitUntilDoesNotExist(hasTestTag(TopSitesTestTag.remove), waitingTime) - Log.i(TAG, "removeTopSite: Waited for \"Remove\" menu button to not exist") + Log.i(TAG, "removeTopSite: Waited for $waitingTime ms until the \"Remove\" menu button does not exist") ComposeTopSitesRobot(composeTestRule).interact() return Transition(composeTestRule) From b4daeab8c98ed5b3809d70ba1022633c52daa3fe Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Fri, 9 Feb 2024 12:23:15 +0200 Subject: [PATCH 146/586] Bug 1879498 - Add missing pairs of logs to CustomTabRobot --- .../mozilla/fenix/ui/robots/CustomTabRobot.kt | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt index 01959e7b8560..3c4d37710a50 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt @@ -48,21 +48,24 @@ class CustomTabRobot { fun verifyMainMenuButton() = assertUIObjectExists(mainMenuButton()) fun verifyDesktopSiteButtonExists() { + Log.i(TAG, "verifyDesktopSiteButtonExists: Trying to verify that the request desktop site button is displayed") desktopSiteButton().check(matches(isDisplayed())) - Log.i(TAG, "verifyDesktopSiteButtonExists: Verified request desktop site button is displayed") + Log.i(TAG, "verifyDesktopSiteButtonExists: Verified that the request desktop site button is displayed") } fun verifyFindInPageButtonExists() { + Log.i(TAG, "verifyFindInPageButtonExists: Trying to verify that the find in page button is displayed") findInPageButton().check(matches(isDisplayed())) - Log.i(TAG, "verifyFindInPageButtonExists: Verified find in page button is displayed") + Log.i(TAG, "verifyFindInPageButtonExists: Verified that the find in page button is displayed") } fun verifyPoweredByTextIsDisplayed() = assertUIObjectExists(itemContainingText("POWERED BY $appName")) fun verifyOpenInBrowserButtonExists() { + Log.i(TAG, "verifyOpenInBrowserButtonExists: Trying to verify that the \"Open in Firefox\" button is displayed") openInBrowserButton().check(matches(isDisplayed())) - Log.i(TAG, "verifyOpenInBrowserButtonExists: Verified open in browser button is displayed") + Log.i(TAG, "verifyOpenInBrowserButtonExists: Verified that the \"Open in Firefox\" button is displayed") } fun verifyBackButtonExists() = assertUIObjectExists(itemWithDescription("Back")) @@ -74,8 +77,9 @@ class CustomTabRobot { fun verifyCustomMenuItem(label: String) = assertUIObjectExists(itemContainingText(label)) fun verifyCustomTabCloseButton() { + Log.i(TAG, "verifyCustomTabCloseButton: Trying to verify that the close custom tab button is displayed") closeButton().check(matches(isDisplayed())) - Log.i(TAG, "verifyCustomTabCloseButton: Verified close custom tab button is displayed") + Log.i(TAG, "verifyCustomTabCloseButton: Verified that the close custom tab button is displayed") } fun verifyCustomTabToolbarTitle(title: String) { @@ -109,13 +113,16 @@ class CustomTabRobot { mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar")), waitingTime, ) + Log.i(TAG, "longCLickAndCopyToolbarUrl: Trying to long click the custom tab toolbar") customTabToolbar().click(LONG_CLICK_DURATION) - Log.i(TAG, "longCLickAndCopyToolbarUrl: Long clicked custom tab toolbar") + Log.i(TAG, "longCLickAndCopyToolbarUrl: Long clicked the custom tab toolbar") clickContextMenuItem("Copy") } fun fillAndSubmitLoginCredentials(userName: String, password: String) { + Log.i(TAG, "fillAndSubmitLoginCredentials: Waiting for device to be idle for $waitingTime ms") mDevice.waitForIdle(waitingTime) + Log.i(TAG, "fillAndSubmitLoginCredentials: Waited for device to be idle for $waitingTime ms") setPageObjectText(itemWithResId("username"), userName) setPageObjectText(itemWithResId("password"), password) clickPageObject(itemWithResId("submit")) @@ -126,11 +133,13 @@ class CustomTabRobot { } fun waitForPageToLoad() { + Log.i(TAG, "waitForPageToLoad: Waiting for $waitingTime ms until progress bar is gone") progressBar().waitUntilGone(waitingTime) - Log.i(TAG, "waitForPageToLoad: Waited $waitingTime ms until progress bar was gone") + Log.i(TAG, "waitForPageToLoad: Waited for $waitingTime ms until progress bar was gone") } fun clickCustomTabCloseButton() { + Log.i(TAG, "clickCustomTabCloseButton: Trying to click close custom tab button") closeButton().click() Log.i(TAG, "clickCustomTabCloseButton: Clicked close custom tab button") } @@ -147,10 +156,12 @@ class CustomTabRobot { class Transition { fun openMainMenu(interact: CustomTabRobot.() -> Unit): Transition { mainMenuButton().also { - Log.i(TAG, "openMainMenu: Looking for main menu button") + Log.i(TAG, "openMainMenu: Waiting for $waitingTime ms for the main menu button to exist") it.waitForExists(waitingTime) + Log.i(TAG, "openMainMenu: Waited for $waitingTime ms for the main menu button to exist") + Log.i(TAG, "openMainMenu: Trying to click the main menu button") it.click() - Log.i(TAG, "openMainMenu: Clicked main menu button") + Log.i(TAG, "openMainMenu: Clicked the main menu button") } CustomTabRobot().interact() @@ -158,16 +169,18 @@ class CustomTabRobot { } fun clickOpenInBrowserButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "clickOpenInBrowserButton: Trying to click the \"Open in Firefox\" button") openInBrowserButton().perform(click()) - Log.i(TAG, "clickOpenInBrowserButton: Clicked \"Open in Firefox\" button") + Log.i(TAG, "clickOpenInBrowserButton: Clicked the \"Open in Firefox\" button") BrowserRobot().interact() return BrowserRobot.Transition() } fun clickShareButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { + Log.i(TAG, "clickShareButton: Trying to click the share button") itemWithDescription(getStringResource(R.string.mozac_feature_customtabs_share_link)).click() - Log.i(TAG, "clickShareButton: Clicked share button") + Log.i(TAG, "clickShareButton: Clicked the share button") ShareOverlayRobot().interact() return ShareOverlayRobot.Transition() From d566743ea0f041ce27c1204da903de380f96b46e Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Fri, 9 Feb 2024 13:34:04 +0200 Subject: [PATCH 147/586] Bug 1879509 - Add missing pairs of logs to DownloadRobot --- .../mozilla/fenix/ui/robots/DownloadRobot.kt | 58 ++++++++++++------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt index 975000dd2095..eab72fffb12a 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt @@ -51,9 +51,8 @@ class DownloadRobot { fun verifyDownloadPrompt(fileName: String) { var currentTries = 0 while (currentTries++ < 3) { - Log.i(TAG, "verifyDownloadPrompt: While loop currentTries = $currentTries") + Log.i(TAG, "verifyDownloadPrompt: Started try #$currentTries") try { - Log.i(TAG, "verifyDownloadPrompt: Try block") assertUIObjectExists( itemWithResId("$packageName:id/download_button"), itemContainingText(fileName), @@ -61,7 +60,7 @@ class DownloadRobot { break } catch (e: AssertionError) { - Log.i(TAG, "verifyDownloadPrompt: Catch block") + Log.i(TAG, "verifyDownloadPrompt: AssertionError caught, executing fallback methods") Log.e("DOWNLOAD_ROBOT", "Failed to find locator: ${e.localizedMessage}") browserScreen { @@ -96,11 +95,12 @@ class DownloadRobot { ) fun clickTryAgainButton() { + Log.i(TAG, "clickTryAgainButton: Trying to click the \"TRY AGAIN\" in app prompt button") itemWithResIdAndText( "$packageName:id/download_dialog_action_button", "Try Again", ).click() - Log.i(TAG, "clickTryAgainButton: Clicked \"TRY AGAIN\" in app prompt button") + Log.i(TAG, "clickTryAgainButton: Clicked the \"TRY AGAIN\" in app prompt button") } fun verifyPhotosAppOpens() = assertExternalAppOpens(GOOGLE_APPS_PHOTOS) @@ -111,34 +111,40 @@ class DownloadRobot { fun verifyDownloadedFileIcon() = assertUIObjectExists(itemWithResId("$packageName:id/favicon")) fun verifyEmptyDownloadsList() { - Log.i(TAG, "verifyEmptyDownloadsList: Looking for empty download list") + Log.i(TAG, "verifyEmptyDownloadsList: Waiting for $waitingTime ms for for empty download list to exist") mDevice.findObject(UiSelector().resourceId("$packageName:id/download_empty_view")) .waitForExists(waitingTime) + Log.i(TAG, "verifyEmptyDownloadsList: Waited for $waitingTime ms for for empty download list to exist") + Log.i(TAG, "verifyEmptyDownloadsList: Trying to verify that the \"No downloaded files\" list message is displayed") onView(withText("No downloaded files")).check(matches(isDisplayed())) - Log.i(TAG, "verifyEmptyDownloadsList: Verified \"No downloaded files\" list message") + Log.i(TAG, "verifyEmptyDownloadsList: Verified that the \"No downloaded files\" list message is displayed") } fun waitForDownloadsListToExist() = assertUIObjectExists(itemWithResId("$packageName:id/download_list")) fun openDownloadedFile(fileName: String) { - downloadedFile(fileName) - .check(matches(isDisplayed())) - .click() + Log.i(TAG, "openDownloadedFile: Trying to verify that the downloaded file: $fileName is displayed") + downloadedFile(fileName).check(matches(isDisplayed())) + Log.i(TAG, "openDownloadedFile: Verified that the downloaded file: $fileName is displayed") + Log.i(TAG, "openDownloadedFile: Trying to click downloaded file: $fileName") + downloadedFile(fileName).click() Log.i(TAG, "openDownloadedFile: Clicked downloaded file: $fileName") } fun deleteDownloadedItem(fileName: String) { + Log.i(TAG, "deleteDownloadedItem: Trying to click the trash bin icon to delete downloaded file: $fileName") onView( allOf( withId(R.id.overflow_menu), hasSibling(withText(fileName)), ), ).click() - Log.i(TAG, "deleteDownloadedItem: Deleted downloaded file: $fileName using trash bin icon") + Log.i(TAG, "deleteDownloadedItem: Clicked the trash bin icon to delete downloaded file: $fileName") } fun longClickDownloadedItem(title: String) { + Log.i(TAG, "longClickDownloadedItem: Trying to long click downloaded file: $title") onView( allOf( withId(R.id.title), @@ -149,21 +155,24 @@ class DownloadRobot { } fun selectDownloadedItem(title: String) { + Log.i(TAG, "selectDownloadedItem: Trying click downloaded file: $title to select it") onView( allOf( withId(R.id.title), withText(title), ), ).perform(click()) - Log.i(TAG, "selectDownloadedItem: Selected downloaded file: $title") + Log.i(TAG, "selectDownloadedItem: Clicked downloaded file: $title to select it") } fun openMultiSelectMoreOptionsMenu() { + Log.i(TAG, "openMultiSelectMoreOptionsMenu: Trying to click multi-select more options button") itemWithDescription(getStringResource(R.string.content_description_menu)).click() Log.i(TAG, "openMultiSelectMoreOptionsMenu: Clicked multi-select more options button") } fun clickMultiSelectRemoveButton() { + Log.i(TAG, "clickMultiSelectRemoveButton: Trying to click multi-select remove button") itemWithResIdContainingText("$packageName:id/title", "Remove").click() Log.i(TAG, "clickMultiSelectRemoveButton: Clicked multi-select remove button") } @@ -180,27 +189,31 @@ class DownloadRobot { class Transition { fun clickDownload(interact: DownloadRobot.() -> Unit): Transition { + Log.i(TAG, "clickDownload: Trying to click the \"Download\" download prompt button") downloadButton().click() - Log.i(TAG, "clickDownload: Clicked \"DOWNLOAD\" button from prompt") + Log.i(TAG, "clickDownload: Clicked the \"Download\" download prompt button") DownloadRobot().interact() return Transition() } fun closeDownloadPrompt(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "closeDownloadPrompt: Trying to click the close download prompt button") itemWithResId("$packageName:id/download_dialog_close_button").click() - Log.i(TAG, "closeDownloadPrompt: Dismissed download prompt by clicking close prompt button") + Log.i(TAG, "closeDownloadPrompt: Clicked the close download prompt button") BrowserRobot().interact() return BrowserRobot.Transition() } fun clickOpen(type: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "clickOpen: Looking for \"OPEN\" download prompt button") + Log.i(TAG, "clickOpen: Waiting for $waitingTime ms for the for \"OPEN\" download prompt button to exist") openDownloadButton().waitForExists(waitingTime) + Log.i(TAG, "clickOpen: Waited for $waitingTime ms for the for \"OPEN\" download prompt button to exist") + Log.i(TAG, "clickOpen: Trying to click the \"OPEN\" download prompt button") openDownloadButton().click() - Log.i(TAG, "clickOpen: Clicked \"OPEN\" download prompt button") - + Log.i(TAG, "clickOpen: Clicked the \"OPEN\" download prompt button") + Log.i(TAG, "clickOpen: Trying to verify that the open intent is matched with associated data type") // verify open intent is matched with associated data type Intents.intended( allOf( @@ -208,37 +221,38 @@ class DownloadRobot { IntentMatchers.hasType(type), ), ) - Log.i(TAG, "clickOpen: Verified that open intent is matched with associated data type") + Log.i(TAG, "clickOpen: Verified that the open intent is matched with associated data type") BrowserRobot().interact() return BrowserRobot.Transition() } fun clickAllowPermission(interact: DownloadRobot.() -> Unit): Transition { - Log.i(TAG, "clickAllowPermission: Looking for \"ALLOW\" permission button") mDevice.waitNotNull( Until.findObject(By.res(getPermissionAllowID() + ":id/permission_allow_button")), waitingTime, ) - + Log.i(TAG, "clickAllowPermission: Trying to click the \"ALLOW\" permission button") mDevice.findObject(By.res(getPermissionAllowID() + ":id/permission_allow_button")).click() - Log.i(TAG, "clickAllowPermission: Clicked \"ALLOW\" permission button") + Log.i(TAG, "clickAllowPermission: Clicked the \"ALLOW\" permission button") DownloadRobot().interact() return Transition() } fun exitDownloadsManagerToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "exitDownloadsManagerToBrowser: Trying to click the navigate up toolbar button") onView(withContentDescription("Navigate up")).click() - Log.i(TAG, "exitDownloadsManagerToBrowser: Exited download manager to browser by clicking the navigate up toolbar button") + Log.i(TAG, "exitDownloadsManagerToBrowser: Clicked the navigate up toolbar button") BrowserRobot().interact() return BrowserRobot.Transition() } fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + Log.i(TAG, "goBack: Trying to click the navigate up toolbar button") goBackButton().click() - Log.i(TAG, "exitDownloadsManagerToBrowser: Exited download manager to home screen by clicking the navigate up toolbar button") + Log.i(TAG, "goBack: Clicked the navigate up toolbar button") HomeScreenRobot().interact() return HomeScreenRobot.Transition() From 01c2307b2bb198e97a403b674aa44b893e482361 Mon Sep 17 00:00:00 2001 From: sarah541 Date: Thu, 8 Feb 2024 10:59:45 -0500 Subject: [PATCH 148/586] Bug 1879135 - Add ecosia crawl website --- .../src/main/assets/extensions/ads/manifest.template.json | 3 ++- .../src/main/assets/extensions/search/manifest.template.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/android-components/components/feature/search/src/main/assets/extensions/ads/manifest.template.json b/android-components/components/feature/search/src/main/assets/extensions/ads/manifest.template.json index bacc0d7cac73..219e41b55454 100644 --- a/android-components/components/feature/search/src/main/assets/extensions/ads/manifest.template.json +++ b/android-components/components/feature/search/src/main/assets/extensions/ads/manifest.template.json @@ -204,7 +204,8 @@ "https://www.bing.com/search*", "https://www.baidu.com/*", "https://m.baidu.com/*", - "https://duckduckgo.com/*" + "https://duckduckgo.com/*", + "https://www.ecosia.org/*" ], "js": ["adsTelemetry.js"], "run_at": "document_end" diff --git a/android-components/components/feature/search/src/main/assets/extensions/search/manifest.template.json b/android-components/components/feature/search/src/main/assets/extensions/search/manifest.template.json index 642ad819ffc0..ae9cf13dac99 100644 --- a/android-components/components/feature/search/src/main/assets/extensions/search/manifest.template.json +++ b/android-components/components/feature/search/src/main/assets/extensions/search/manifest.template.json @@ -205,7 +205,8 @@ "https://m.baidu.com/*", "https://*search.yahoo.com/search*", "https://www.bing.com/search*", - "https://duckduckgo.com/*" + "https://duckduckgo.com/*", + "https://www.ecosia.org/*" ], "js": ["searchTelemetry.js"], "run_at": "document_end" From 0733fc077a9d0e82816efcc8aad6cd6b4ad0259f Mon Sep 17 00:00:00 2001 From: Titouan Thibaud Date: Fri, 9 Feb 2024 18:00:17 +0100 Subject: [PATCH 149/586] Bug 1879583 - Change the default for pull-to-refresh to enabled Co-authored-by: Jonathan Almeida --- fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt index 7b8f0343e656..1808eb3a30d6 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -1477,7 +1477,7 @@ class Settings(private val appContext: Context) : PreferencesHolder { var isPullToRefreshEnabledInBrowser by booleanPreference( appContext.getPreferenceKey(R.string.pref_key_website_pull_to_refresh), - default = Config.channel.isNightlyOrDebug, + default = true, ) var isDynamicToolbarEnabled by booleanPreference( From 48c917f78f4c94664790dba80c0874b92756d3ed Mon Sep 17 00:00:00 2001 From: Matthew Tighe Date: Fri, 9 Feb 2024 09:19:20 -0800 Subject: [PATCH 150/586] Revert "Bug 1833666 - Update original RFC guidelines with stakeholders" This reverts commit e1e6e86bf6525a123518919bfc620108396ad3dc. --- docs/rfcs/0001-rfc-process.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/rfcs/0001-rfc-process.md b/docs/rfcs/0001-rfc-process.md index 8f120399fa58..09919475460c 100644 --- a/docs/rfcs/0001-rfc-process.md +++ b/docs/rfcs/0001-rfc-process.md @@ -35,7 +35,6 @@ The high-level process of creating an RFC is: * Create an RFC document (like this one) using the template. * Open a pull request for the RFC document. * Ask for feedback on the pull request, via the [mailing list]() or in [chat](https://chat.mozilla.org/#/room/#android-components:mozilla.org). -* Assign or receive volunteers to act as stakeholders for the RFC. They will be responsible for a final decision on the proposal. This should include at least 2 internal team members, and at least 1 external team member if the proposal has been suggested from an external team. During the lifetime of an RFC: From 62072cdbec13bfca1d950eee968e6bc4e54e56eb Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 10 Feb 2024 00:03:28 +0000 Subject: [PATCH 151/586] Import translations from android-l10n --- .../addons/src/main/res/values-rm/strings.xml | 2 + .../src/main/res/values-cy/strings.xml | 2 +- .../media/src/main/res/values-et/strings.xml | 23 +++- .../media/src/main/res/values-rm/strings.xml | 11 +- .../src/main/res/values-hy-rAM/strings.xml | 3 + .../src/main/res/values-rm/strings.xml | 36 ++++++ fenix/app/src/main/res/values-azb/strings.xml | 104 ++++++++++++++++++ fenix/app/src/main/res/values-bg/strings.xml | 2 +- fenix/app/src/main/res/values-et/strings.xml | 68 ++++++++++++ .../src/main/res/values-hy-rAM/strings.xml | 3 + fenix/app/src/main/res/values-kab/strings.xml | 16 ++- fenix/app/src/main/res/values-rm/strings.xml | 74 ++++++------- fenix/app/src/main/res/values-sk/strings.xml | 3 + fenix/app/src/main/res/values-ug/strings.xml | 3 + 14 files changed, 301 insertions(+), 49 deletions(-) diff --git a/android-components/components/feature/addons/src/main/res/values-rm/strings.xml b/android-components/components/feature/addons/src/main/res/values-rm/strings.xml index f7b752cd4b87..2a1b17137b40 100644 --- a/android-components/components/feature/addons/src/main/res/values-rm/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-rm/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Acceder a tias datas per %1$d autras domenas + + %1$s, %2$d da %3$d Acceder als tabs dal navigatur diff --git a/android-components/components/feature/downloads/src/main/res/values-cy/strings.xml b/android-components/components/feature/downloads/src/main/res/values-cy/strings.xml index 4eb29e47c223..ba05a7e8248e 100644 --- a/android-components/components/feature/downloads/src/main/res/values-cy/strings.xml +++ b/android-components/components/feature/downloads/src/main/res/values-cy/strings.xml @@ -13,7 +13,7 @@ Llwytho (%1$s) - Llwytho + Llwytho i Lawr Diddymu diff --git a/android-components/components/feature/media/src/main/res/values-et/strings.xml b/android-components/components/feature/media/src/main/res/values-et/strings.xml index e8f8b7f37668..de103560f60e 100644 --- a/android-components/components/feature/media/src/main/res/values-et/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-et/strings.xml @@ -1,5 +1,5 @@ - + Meedia @@ -10,6 +10,27 @@ Kaamera ja mikrofon on sisse lülitatud + + Puuduta kaamerat kasutava kaardi avamiseks. + + Puuduta mikrofoni kasutava kaardi avamiseks. + + + + Puuduta mikrofoni ja kaamerat kasutava kaardi avamiseks. + + + + Meeldetuletus: %1$s kasutab endiselt kaamerat. Puuduta kaardi avamiseks. + + Meeldetuletus: %1$s kasutab endiselt mikrofoni. Puuduta kaardi avamiseks. + + Meeldetuletus: %1$s kasutab endiselt mikrofoni. Puuduta kaardi avamiseks. + + Meeldetuletus: %1$s kasutab endiselt mikrofoni ja kaamerat. Puuduta kaardi avamiseks. + + Meeldetuletus: %1$s kasutab endiselt mikrofoni ja kaamerat. Puuduta kaardi avamiseks. + Esita diff --git a/android-components/components/feature/media/src/main/res/values-rm/strings.xml b/android-components/components/feature/media/src/main/res/values-rm/strings.xml index 7d7b70d08ef7..5564d782111c 100644 --- a/android-components/components/feature/media/src/main/res/values-rm/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-rm/strings.xml @@ -1,5 +1,5 @@ - + Medias @@ -21,9 +21,14 @@ Promemoria: %1$s utilisescha anc adina tia camera. Tutgar per avrir il tab. - Promemoria: %1$s utilisescha anc adina tes microfon. Tutgar per avrir il tab + Promemoria: %1$s utilisescha anc adina tes microfon. Tutgar per avrir il tab + + Promemoria: %1$s utilisescha anc adina tes microfon. Tutgar per avrir il tab. + + Promemoria: %1$s utilisescha anc adina tes microfon e tia camera. Tutgar per avrir il tab + - Promemoria: %1$s utilisescha anc adina tes microfon e tia camera. Tutgar per avrir il tab + Promemoria: %1$s utilisescha anc adina tes microfon e tia camera. Tutgar per avrir il tab. Far ir diff --git a/android-components/components/feature/prompts/src/main/res/values-hy-rAM/strings.xml b/android-components/components/feature/prompts/src/main/res/values-hy-rAM/strings.xml index 4af6100e87d7..8190f8d45b30 100644 --- a/android-components/components/feature/prompts/src/main/res/values-hy-rAM/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-hy-rAM/strings.xml @@ -152,6 +152,9 @@ Քարտի համարը կկոդավորվի: Անվտանգության կոդը չի պահվի: + + %s-ը գաղտնագրում է ձեր քարտի համարը: Անվտանգության ձեր կոդը չի պահպանվի: + Ընտրեք հասցե diff --git a/android-components/components/feature/prompts/src/main/res/values-rm/strings.xml b/android-components/components/feature/prompts/src/main/res/values-rm/strings.xml index 29183ab85343..2b7976fc1042 100644 --- a/android-components/components/feature/prompts/src/main/res/values-rm/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-rm/strings.xml @@ -18,6 +18,8 @@ Pled-clav Betg memorisar + + Betg ussa Mai memorisar @@ -26,16 +28,26 @@ Memorisar Betg actualisar + + Betg ussa Actualisar Il champ dal pled-clav na dastga betg esser vid + Endatar in pled-clav + Impussibel da memorisar las datas d\'annunzia + + Impussibel da memorisar il pled-clav Memorisar questa infurmaziun d\'annunzia? + + Memorisar il pled-clav? Actualisar questa infurmaziun d\'annunzia? + + Actualisar il pled-clav? Agiuntar in num d\'utilisader al pled-clav memorisà? @@ -85,13 +97,22 @@ Drizzar l\'ura Administrar las datas d\'annunzia + + Administrar ils pleds-clav Expander las datas d\'annunzia proponidas + + Extender ils pleds-clav memorisads Reducir las datas d\'annunzia proponidas + + Reducir ils pleds-clav memorisads Datas d\'annunzia proponidas + + Pleds-clav memorisads + Proponer in ferm pled-clav @@ -110,12 +131,20 @@ Tscherner ina carta da credit + + Utilisar ina carta memorisada Expander las cartas da credit proponidas + + Extender las cartas memorisadas Reducir las cartas da credit proponidas + + Reducir las cartas memorisadas Administrar las cartas da credit + + Administrar las cartas Memorisar questa carta a moda segira? @@ -123,13 +152,20 @@ Il numer da la carta vegn criptà. Il code da segirezza na vegn betg memorisà. + + %s criptescha il numer da tia carta. Tes code da segirezza na vegn betg memorisà. + Tscherner l\'adressa Expander las adressas proponidas + + Extender las adressas proponidas Cumprimer las adressas proponidas + + Reducir las adressas memorisadas Administrar las adressas diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml index dd604a09ab9c..37a4ebc5fce0 100644 --- a/fenix/app/src/main/res/values-azb/strings.xml +++ b/fenix/app/src/main/res/values-azb/strings.xml @@ -499,6 +499,103 @@ %1$s اوچون کوکی بنر مسدود ائلین ایشدن سالینسین؟ + + %1$s بو سایتدا کوُکی ایستک‌لرینی اوْتوماتیک رد ائده بیلمز. گله‌جکده بوُ سایتی آرخالاماق اوُچون ایستک گؤندره بیلرسینیز. + + + باغلاییْن و %1$s کوُکی‌لری سیله‌جک و بو سایتیْ یئنی‌دن دوْلدوُراجاق. بوُ ، سیزی حسابدان چیخارا ویا آلیْش-وئریْش سبدلرینی بوْشالتا بیلر. + + + آچیْن و %1$s بو سایتداکیْ بوتون کوُکی بنرلرینی اوْتوماتیک رد ائتمه‌گه چالیْشاجاق. + + %1$s سیزین اوچون کوُکی‌لری رد ائتدی. + + + داها آز حواس داغیلماسیْ، بوُ سایتدا سیزی تعقیب ائدن کوُکی‌لر آز. + + + داها چوْخ گوونلیک اوچون HTTPS رمزله‌مه پروْتوکولوُندان ایستیفاده ائده‌رک سایتلارا اوْتوماتیک قوْشوُلماغا چالیْشیر. + + باغلیْ + + + بوتون تاغلاردا آچیْق + + بوتون گیزلی تاغلاردا آچیْق + + آرتیق بیلین + + بوتون تاغلاردا گوجلندیر + + بوتون گیزلی تاغلاردا گوجلندیر + + گوونلی سایت موجود دئییل + + ایحتیمالی چوْخ، سایت HTTPS-ی آرخالامیْر. + + + بوُنونلا بئله، حمله ائده‌نین‌ده ایشتیراک ائتمه‌سی موُمکوندور. ایدامه وئرسز، هئچ بیر بیلگی وئرمه‌یین. ایدامه وئرسز، یالنیز HTTPS حالتی گئچیجی اوْلاراق باغلاناجاقدیْر. + + + اَل چاتانلیق + + اؤزل موْزیلا حسابیْ سِروری + + اؤزل دؤنگل سرور + + + حساب + + ادوات چوبوغو + + تم + + آنایارپاق + + اؤزللشدیرمک + + موْزیلا حسابی + + دیل + + دیتا سئچیمی + + هر زامان + + هئچ زامان + + + تاخیلان‌لار + + + بیلدیریش‌لر + + ایجازه وئریلدی + + ایجازه وئریلمه‌دی + + + تامام + + لغو + + + آرتیق بیلین + + + ایندی دؤنگل‌لندیر + + گئچمیش + + بوُکمارک‌لار + + + رمز‌لر + + آچیْق تاغ‌لار + + چیخیش + اوست @@ -520,6 +617,13 @@ آلت‌لر چوبوغونو گیزلتمک اوچون اسکرول ائله‌ + + + یئندیرنلر + + بوُکمارک‌لار + + diff --git a/fenix/app/src/main/res/values-bg/strings.xml b/fenix/app/src/main/res/values-bg/strings.xml index 04883adee5ec..90068f68de43 100644 --- a/fenix/app/src/main/res/values-bg/strings.xml +++ b/fenix/app/src/main/res/values-bg/strings.xml @@ -526,7 +526,7 @@ Впишете се, за да синхронизирате раздели, отметки, пароли и други. - сметка в Mozilla + Профил в Mozilla Свържете повторно, за да бъде възобновено синхронизирането diff --git a/fenix/app/src/main/res/values-et/strings.xml b/fenix/app/src/main/res/values-et/strings.xml index 998bcdd8f8b4..b7312a3b4029 100644 --- a/fenix/app/src/main/res/values-et/strings.xml +++ b/fenix/app/src/main/res/values-et/strings.xml @@ -16,6 +16,14 @@ Keela privaatne veebilehitsemine Otsi või sisesta aadress + + Otsi veebist + + Otsi ajaloost + + Otsi järjehoidjatest + + Otsi kaartidest Sisesta otsitav fraas @@ -39,6 +47,9 @@ Valitud + + + Hiljuti salvestatud Kuva kõiki järjehoidjaid @@ -55,6 +66,24 @@ %1$s kustutab privaatsete kaartide otsimise ja lehitsemise ajaloo, kui väljud rakendusest või sulged privaatsed kaardid. Kuigi see ei muuda sind külastatavate veebilehtede või internetiteenuse pakkuja ees anonüümseks, kaitseb see siiski sinu privaatsust teiste selle seadme kasutajate eest.
Levinumad müüdid privaatse veebilehitsemise kohta + + + Ära jäta sellesse seadmesse jälgi + + %1$s kustutab küpsised, ajaloo ja saidiandmed, kui sulged kõik privaatsed kaardid. %2$s + + Kes võib minu tegevusi näha? + + + + Ava järgmine privaatne kaart ühe puudutusega. + + Lisa avaekraanile Tänan, ei soovi @@ -68,6 +97,19 @@ Peida + + + Meie võimsaim privaatsusfunktsioon, mis siiski eraldab saidiülesed jälitajad. + + + + Rohkem teavet täielikust küpsiste vastasest kaitsest + + + + Uue privaatseansi alustamiseks puuduta siit. Kustuta ajalugu, küpsised – kõik. + + Vajalik on ligipääs kaamerale. Mine Androidi sätetesse, puuduta õigusi ja seejärel puuduta lubamise valikut. @@ -103,6 +145,9 @@ Uus privaatne kaart + + Paroolide otsetee + Hiljutised kaardid @@ -115,6 +160,8 @@ Kuva kõiki sünkroniseeritud kaarte Sünkroniseeritud seade + + Eemalda Eemalda @@ -140,6 +187,8 @@ Peata Lisad + + Konto andmed Lisad puuduvad @@ -153,6 +202,8 @@ Kogumik Töölaua versioon + + Ava tavalisel kaardil Lisa avaekraanile @@ -163,6 +214,8 @@ Otsi lehelt + + Tõlgi leht Salvesta kollektsiooni @@ -197,6 +250,12 @@ Avaleht + + Kustuta lehitsemise ajalugu + + Tõlgi leht + Valitud keel @@ -233,6 +292,15 @@ Otsi seekord järgneva otsingumootoriga: + + %s otsingumootor + + + + Tutvu oma isikupärastatud kodulehega. Siin kuvatakse hiljutised kaardid, järjehoidjad ja otsingutulemused. + + Tere tulemast isikupärasemasse internetti + Ava uus kaart %1$sis diff --git a/fenix/app/src/main/res/values-hy-rAM/strings.xml b/fenix/app/src/main/res/values-hy-rAM/strings.xml index 50cd8346f91e..2e069658692a 100644 --- a/fenix/app/src/main/res/values-hy-rAM/strings.xml +++ b/fenix/app/src/main/res/values-hy-rAM/strings.xml @@ -2165,6 +2165,9 @@ %s որոնում + + Փոխարկեք ձեր սկզբնադիր զննարկիչը + Կայեք հղումներ կայքերից, էլ. նամակներից և հաղորդագրություններից, որոնք ինքնաբար կերպով կբացվեն Firefox-ում: diff --git a/fenix/app/src/main/res/values-kab/strings.xml b/fenix/app/src/main/res/values-kab/strings.xml index bdb13932b350..9f1bd4710373 100644 --- a/fenix/app/src/main/res/values-kab/strings.xml +++ b/fenix/app/src/main/res/values-kab/strings.xml @@ -2150,7 +2150,7 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Anadi %s - + Sbadu iseɣwan seg yismal web, seg yimaylen d yiznan i twaledyawt s wudem awurman deg Firefox. @@ -2329,14 +2329,21 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara ldi aseɣwen i wakken ad tissineḍ ugar + + %s, azwel Iseɣwan + + Iseɣwan i yellan + Suqqel asebter-a? + + Ԑreḍ tisuqilin tusligin n %1$s Issin ugar @@ -2354,13 +2361,20 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Suqqel + + Asuqel iteddu Fren tutlayt Yella wugur deg usuqqel. Ttxil-k ɛreḍ tikkelt niḍen. + + Nesḥassef, mazal ur nessefrak ara tutlayt %1$s. Issin ugar + + + Tixtiṛiyin n usuqel Sumer yal tikkelt tasuqqilt diff --git a/fenix/app/src/main/res/values-rm/strings.xml b/fenix/app/src/main/res/values-rm/strings.xml index 9d9fbb672b23..efa79cba3148 100644 --- a/fenix/app/src/main/res/values-rm/strings.xml +++ b/fenix/app/src/main/res/values-rm/strings.xml @@ -239,6 +239,7 @@ Persunalisar la pagina da partenza + Visur da partenza @@ -246,6 +247,9 @@ Stizzar la cronologia + + Translatar la pagina + Lingua tschernida @@ -257,8 +261,6 @@ Scannar - - Maschina da tschertgar Parameters da la maschina da tschertgar @@ -312,24 +314,29 @@ - Communicaziuns ta gidan da far dapli cun %s + Communicaziuns ta gidan da far dapli cun %s - Sincronisescha tes tabs tranter apparats, administrescha las telechargiadas, retschaiva tips per profitar il meglier da la protecziun da datas da %s ed auter pli. + Sincronisescha tes tabs tranter apparats, administrescha las telechargiadas, retschaiva tips per profitar il meglier da la protecziun da datas da %s ed auter pli. - Cuntinuar + Cuntinuar - Betg ussa + Betg ussa + + Las directivas da Firefox per la protecziun da datas + Nus ta protegin cun plaschair - Noss navigatur dad in\'organisaziun senza finamira da profit, gida ad evitar che interpresas ta persequiteschian a la zuppada en il web.\n + Noss navigatur dad in’organisaziun senza finamira da profit, gida ad evitar che interpresas ta persequiteschian a la zuppada en il web. + + Noss navigatur dad in\'organisaziun senza finamira da profit, gida ad evitar che interpresas ta persequiteschian a la zuppada en il web.\n \nLegia dapli dal tema en nossas infurmaziuns davart la protecziun da datas. - infurmaziuns davart la protecziun da datas + infurmaziuns davart la protecziun da datas Definir sco navigatur da standard @@ -432,21 +439,11 @@ Modus mo HTTPS - - Reducziun da bandieras da cookies Bloccada da bandieras da cookies Bloccada da bandieras da cookies en il modus privat - - Reducir las bandieras da cookies - - Deactivà - - Activà - - - %1$s emprova da refusar automaticamain dumondas da deponer cookies cura ch\'ina bandiera da cookies sa mussa. + Deactivà per questa website @@ -464,34 +461,16 @@ Questa website na vegn actualmain betg sustegnida - - Activar la reducziun da bandieras da cookies per %1$s? Activar la bloccada da bandieras da cookies per %1$s? - Deactivar la reducziun da bandieras da cookies per %1$s? - Deactivar la bloccada da bandieras da cookies per %1$s? %1$s na po betg refusar automaticamain dumondas da deponer cookies da questa website. Ti pos trametter ina dumonda da sustegnair questa website en avegnir. - %1$s vegn a stizzar ils cookies da questa website ed actualisar la pagina. Cun stizzar tut ils cookies vegns ti eventualmain deconnectà da websites ed i po dar che chanasters da cumpras vegnan svidads. - Suenter la deactivaziun vegn %1$s ad allontanar ils cookies e rechargiar questa website. Quai po ta deconnectar da la website e svidar eventuals chanasters da cumpras. - %1$s emprova da refusar automaticamain tut las dumondas da deponer cookies da paginas sustegnidas. - Activescha la bloccada e %1$s vegn ad empruvar da refusar automaticamain tut las bandieras da cookies sin questa website. - - Permetter a %1$s da refusar bandieras da cookies? - - %1$s po refusar automaticamain bleras dumondas da bandieras da cookies. - - Betg ussa - - Ti vegns a vesair damain dumondas da cookies - - Permetter %1$s ha refusà cookies per tai @@ -707,6 +686,8 @@ Segnapaginas Infurmaziuns d\'annunzia + + Pleds-clav Tabs averts @@ -733,6 +714,8 @@ Cartas da credit + + Metodas da pajament Adressas @@ -1266,8 +1249,6 @@ Serrar - Impussibel da stampar - Impussibel da stampar questa pagina Stampar @@ -1680,8 +1661,12 @@ Infurmaziuns d\'annunzia e pleds-clav + + Pleds-clav Memorisar las infurmaziuns d\'annunzia ed ils pleds-clav + + Memorisar ils pleds-clav Dumandar per memorisar @@ -1699,10 +1684,17 @@ Agiuntar infurmaziuns d\'annunzia + + Agiuntar in pled-clav + Sincronisar las infurmaziuns d\'annunzia + + Sincronisar ils pleds-clav Sincronisar las datas d\'annunzia tranter tes apparats + + Sincronisar ils pleds-clav sin tut ils apparats Infurmaziuns d\'annunzia memorisadas @@ -2107,7 +2099,7 @@ Tschertga %s - + Definescha che colliaziuns da websites, e-mails e messadis vegnan averts automaticamain en Firefox. @@ -2181,8 +2173,6 @@ accentuads derivan da las recensiun sin %s dals ultims 80 dis che nus tegnain per fidablas.]]> Ulteriuras infurmaziuns davart %s. - - co %s da Mozilla determinescha la qualitad da las recensiuns co %s determinescha la qualitad da las recensiuns diff --git a/fenix/app/src/main/res/values-sk/strings.xml b/fenix/app/src/main/res/values-sk/strings.xml index 03d13eb44897..9be4f869c3d9 100644 --- a/fenix/app/src/main/res/values-sk/strings.xml +++ b/fenix/app/src/main/res/values-sk/strings.xml @@ -2183,6 +2183,9 @@ Vyhľadávanie %s + + Zmeňte svoj predvolený prehliadač + Nastavte si automatické otváranie webových stránok, e‑mailov a správ vo Firefoxe. diff --git a/fenix/app/src/main/res/values-ug/strings.xml b/fenix/app/src/main/res/values-ug/strings.xml index 27f068117454..d0b0e1fdfd1b 100644 --- a/fenix/app/src/main/res/values-ug/strings.xml +++ b/fenix/app/src/main/res/values-ug/strings.xml @@ -2150,6 +2150,9 @@ %s ئىزدەش + + كۆڭۈلدىكى توركۆرگۈڭىزنى ئالماشتۇرۇڭ + تور بېكەت، ئېلخەت ۋە ئۇچۇر ئۇلانمىلىرىنى Firefox تا ئاپتوماتىك ئېچىشقا تەڭشەيدۇ. From 1509e4504097de0ab054521f0f635c418eb6e9a3 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Sat, 10 Feb 2024 02:31:44 +0000 Subject: [PATCH 152/586] Update GeckoView (Nightly) to 124.0.20240209214145. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 5763b408ca4b..fba0773afb05 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240208210654" + const val version = "124.0.20240209214145" /** * GeckoView channel From c077ee9dbfed5c037a8606e4466dc31470cf3028 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Sat, 10 Feb 2024 05:34:48 +0000 Subject: [PATCH 153/586] Update A-S to 124.20240210050349. --- .../plugins/dependencies/src/main/java/ApplicationServices.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt index 5dea01104e03..188a9b88fdf8 100644 --- a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt +++ b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // These lines are generated by android-components/automation/application-services-nightly-bump.py -val VERSION = "124.20240209050256" +val VERSION = "124.20240210050349" val CHANNEL = ApplicationServicesChannel.NIGHTLY object ApplicationServicesConfig { From 283c9f56842712f9e6aeb5d4945e085b0529e169 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Sat, 10 Feb 2024 13:05:06 +0000 Subject: [PATCH 154/586] Update GeckoView (Nightly) to 124.0.20240210094249. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index fba0773afb05..62d9b0ca99b9 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240209214145" + const val version = "124.0.20240210094249" /** * GeckoView channel From 0d564109bca765ceaeb64cba5d774e4810c0b011 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 11 Feb 2024 00:03:58 +0000 Subject: [PATCH 155/586] Import translations from android-l10n --- .../addons/src/main/res/values-co/strings.xml | 4 +- .../addons/src/main/res/values-cy/strings.xml | 2 +- .../src/main/res/values-nb-rNO/strings.xml | 4 +- .../src/main/res/values-et/strings.xml | 5 + .../src/main/res/values-et/strings.xml | 5 + .../media/src/main/res/values-co/strings.xml | 13 +- .../src/main/res/values-nb-rNO/strings.xml | 21 ++- .../src/main/res/values-co/strings.xml | 36 +++++ .../src/main/res/values-et/strings.xml | 56 ++++++- .../src/main/res/values-nb-rNO/strings.xml | 43 ++++++ .../search/src/main/res/values-et/strings.xml | 12 ++ .../src/main/res/values-cy/strings.xml | 2 +- .../src/main/res/values-et/strings.xml | 5 + fenix/app/src/main/res/values-co/strings.xml | 146 +++++++++++++----- fenix/app/src/main/res/values-cy/strings.xml | 22 +-- fenix/app/src/main/res/values-da/strings.xml | 3 + fenix/app/src/main/res/values-et/strings.xml | 28 ++++ fenix/app/src/main/res/values-fi/strings.xml | 9 ++ fenix/app/src/main/res/values-fur/strings.xml | 3 + fenix/app/src/main/res/values-kab/strings.xml | 5 + .../src/main/res/values-nb-rNO/strings.xml | 110 +++++++------ .../src/main/res/values-pt-rBR/strings.xml | 2 +- fenix/app/src/main/res/values-uk/strings.xml | 3 + fenix/app/src/main/res/values-vi/strings.xml | 3 + .../app/src/main/res/values-cy/strings.xml | 6 +- .../app/src/main/res/values-kab/strings.xml | 2 + .../src/main/res/values-nb-rNO/strings.xml | 8 +- 27 files changed, 438 insertions(+), 120 deletions(-) create mode 100644 android-components/components/feature/fxsuggest/src/main/res/values-et/strings.xml create mode 100644 android-components/components/feature/search/src/main/res/values-et/strings.xml create mode 100644 android-components/components/ui/widgets/src/main/res/values-et/strings.xml diff --git a/android-components/components/feature/addons/src/main/res/values-co/strings.xml b/android-components/components/feature/addons/src/main/res/values-co/strings.xml index e299aec205d6..5d431f3afef4 100644 --- a/android-components/components/feature/addons/src/main/res/values-co/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-co/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Accede à i vostri dati per %1$d altri duminii + + %1$s, %2$d nant’à %3$d Accede à l’unghjette di u navigatore @@ -75,7 +77,7 @@ Autore - Autori + Autori Ultima mudificazione diff --git a/android-components/components/feature/addons/src/main/res/values-cy/strings.xml b/android-components/components/feature/addons/src/main/res/values-cy/strings.xml index b64909330d48..fbde39f7c1c5 100644 --- a/android-components/components/feature/addons/src/main/res/values-cy/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-cy/strings.xml @@ -229,7 +229,7 @@ %1$s ychwanegyn - Dysgu rhagor + Darllen rhagor Wedi’i ddiweddaru’n llwyddiannus diff --git a/android-components/components/feature/addons/src/main/res/values-nb-rNO/strings.xml b/android-components/components/feature/addons/src/main/res/values-nb-rNO/strings.xml index db87ef580d98..50cd987ac8e7 100644 --- a/android-components/components/feature/addons/src/main/res/values-nb-rNO/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-nb-rNO/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Få tilgang til dine data på %1$d andre domener + + %1$s, %2$d av %3$d Få tilgang til faner @@ -75,7 +77,7 @@ Utvikler - Utviklere + Utviklere Sist oppdatert diff --git a/android-components/components/feature/app-links/src/main/res/values-et/strings.xml b/android-components/components/feature/app-links/src/main/res/values-et/strings.xml index eb5d9e1f3dd2..3f5389f6c08d 100644 --- a/android-components/components/feature/app-links/src/main/res/values-et/strings.xml +++ b/android-components/components/feature/app-links/src/main/res/values-et/strings.xml @@ -4,6 +4,11 @@ Ava link äpiga… Kas soovid avada äpis? Sinu tegevus ei pruugi siis enam privaatne olla. + + Ava teises äpis + + Kas soovid selle sisu vaatamiseks %sist lahkuda? Ava diff --git a/android-components/components/feature/fxsuggest/src/main/res/values-et/strings.xml b/android-components/components/feature/fxsuggest/src/main/res/values-et/strings.xml new file mode 100644 index 000000000000..7c4597fbadad --- /dev/null +++ b/android-components/components/feature/fxsuggest/src/main/res/values-et/strings.xml @@ -0,0 +1,5 @@ + + + + Sponsitud + diff --git a/android-components/components/feature/media/src/main/res/values-co/strings.xml b/android-components/components/feature/media/src/main/res/values-co/strings.xml index ed34bcd9d7e3..cffda386cb2d 100644 --- a/android-components/components/feature/media/src/main/res/values-co/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-co/strings.xml @@ -1,5 +1,5 @@ - + Multimedià @@ -19,11 +19,16 @@ - Ramentu : %1$s impiegheghja ancu u vostru apparechju-fotò. Picchichjà per apre l’unghjetta. + Ramentu : %1$s impiegheghja sempre u vostru apparechju-fotò. Picchichjà per apre l’unghjetta. - Ramentu : %1$s impiegheghja sempre u vostru microfonu. Picchichjà per apre l’unghjetta + Ramentu : %1$s impiegheghja sempre u vostru microfonu. Picchichjà per apre l’unghjetta + + Ramentu : %1$s impiegheghja sempre u vostru microfonu. Picchichjà per apre l’unghjetta. + + Ramentu : %1$s impiegheghja sempre i vostri microfonu è apparechju-fotò. Picchichjà per apre l’unghjetta + - Ramentu : %1$s impiegheghja ancu i vostri microfonu è apparechju-fotò. Picchichjà per apre l’unghjetta + Ramentu : %1$s impiegheghja sempre i vostri microfonu è apparechju-fotò. Picchichjà per apre l’unghjetta. Lettura diff --git a/android-components/components/feature/media/src/main/res/values-nb-rNO/strings.xml b/android-components/components/feature/media/src/main/res/values-nb-rNO/strings.xml index 3b7167d160fd..0ec9fd943af5 100644 --- a/android-components/components/feature/media/src/main/res/values-nb-rNO/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-nb-rNO/strings.xml @@ -1,5 +1,5 @@ - + Medier @@ -10,6 +10,25 @@ Kamera og mikrofon er på + + Trykk for å åpne fanen som bruker kameraet ditt. + + Trykk for å åpne fanen som bruker mikrofonen din. + + Trykk for å åpne fanen som bruker mikrofonen og kameraet ditt. + + + + Påminnelse: %1$s bruker fortsatt kameraet ditt. Trykk for å åpne fanen. + + Påminnelse: %1$s bruker fortsatt mikrofonen din. Trykk for å åpne fanen + + Påminnelse: %1$s bruker fortsatt mikrofonen din. Trykk for å åpne fanen. + + Påminnelse: %1$s bruker fortsatt mikrofonen og kameraet ditt. Trykk for å åpne fanen + + Påminnelse: %1$s bruker fortsatt mikrofonen og kameraet ditt. Trykk for å åpne fanen. + Spill av diff --git a/android-components/components/feature/prompts/src/main/res/values-co/strings.xml b/android-components/components/feature/prompts/src/main/res/values-co/strings.xml index 4396140b6a7e..7afbd91b65b0 100644 --- a/android-components/components/feature/prompts/src/main/res/values-co/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-co/strings.xml @@ -18,6 +18,8 @@ Parolla d’intesa Ùn arregistrà micca + + Micca subitu Ùn arregistrà mai @@ -26,16 +28,26 @@ Arregistrà Ùn micca rinnovà + + Micca subitu Piglià in contu U campu di a parolla d’intesa ùn deve micca esse viotu + Stampittate una parolla d’intesa + Impussibule d’arregistrà l’identificazione di cunnessione + + Ùn si pò micca arregistrà a parolla d’intesa Arregistrà st’identificazioni di cunnessione + + Arregistrà a parolla d’intesa ? Mudificà st’identificazione di cunnessione ? + + Mudificà a parolla d’intesa ? Aghjunghje un nome d’utilizatore à a parolla d’intesa arregistrata ? @@ -85,13 +97,22 @@ Sceglie l’ora Urganizà l’identificazioni di cunnessione + + Amministrà e parolle d’intesa Spiegà l’identificazioni di cunnessione suggerite + + Spiegà e parolle d’intesa arregistrate Ripiegà l’identificazioni di cunnessione suggerite + + Ripiegà e parolle d’intesa arregistrate Identificazioni di cunnessione suggerite + + Parolle d’intesa arregistrate + Suggerisce una parolla d’intesa forte @@ -110,12 +131,20 @@ Selezziunà una carta bancaria + + Impiegà una carta arregistrata Spiegà e carte bancarie suggerite + + Spiegà e carte arregistrate Ripiegà e carte bancarie suggerite + + Ripiegà e carte arregistrate Urganizà e carte bancarie + + Amministrà e carte Arregistrà sta carta di manera sicura ? @@ -123,13 +152,20 @@ U numeru di a carta serà cifratu. U codice di sicurità ùn serà micca arregistratu. + + %s cifra u vostru numeru di carta. U vostru codice di sicurità ùn serà micca arregistratu. + Selezziunà un indirizzu Spiegà l’indirizzi suggeriti + + Spiegà l’indirizzi arregistrati Ripiegà l’indirizzi suggeriti + + Ripiegà l’indirizzi arregistrati Urganizà l’indirizzi diff --git a/android-components/components/feature/prompts/src/main/res/values-et/strings.xml b/android-components/components/feature/prompts/src/main/res/values-et/strings.xml index 7f68c4554dec..5d0f71851a97 100644 --- a/android-components/components/feature/prompts/src/main/res/values-et/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-et/strings.xml @@ -18,6 +18,8 @@ Parool Ära salvesta + + Mitte praegu Ära salvesta kunagi @@ -26,16 +28,26 @@ Salvesta Ära uuenda + + Mitte praegu Uuenda Parooli väli ei tohi olla tühi + Sisesta parool + Kasutajatunnuste salvestamine pole võimalik + + Parooli ei saa salvestada Kas salvestada need kasutajatunnused? + + Salvesta parool? Kas uuendada kasutajatunnused? + + Uuenda parool? Kas lisada salvestatud paroolile kasutajanimi? @@ -81,15 +93,34 @@ nov dets + + Aja määramine Halda kasutajakontosid + + Halda paroole Laienda soovitatud kasutajakontosid + + Laienda salvestatud paroolid - Ahenda soovitatud kasutajakontosid + Ahenda soovitatud kasutajakontod + + Ahenda salvestatud paroolid Soovitatud kasutajakontod + + Salvestatud paroolid + + + Soovita tugevat parooli + + Soovita tugevat parooli + + + Kasuta tugevat parooli %1$s + Kas saata andmed sellele saidile uuesti? Selle lehe värskendamine võib dubleerida hiljutisi toiminguid, nagu makse saatmine või kommentaari postitamine. @@ -101,12 +132,20 @@ Vali krediitkaart + + Kasuta salvestatud kaarti Laienda soovitatud krediitkaarte + + Laienda salvestatud kaardid Ahenda soovitatud krediitkaarte + + Ahenda salvestatud kaardid Halda krediitkaarte + + Halda kaarte Kas salvestada see kaart turvaliselt? @@ -114,13 +153,28 @@ Kaardi number krüptitakse. Turvakoodi ei salvestata. + + %s krüpteerib kaardi numbri. Turvakoodi ei salvestata. + Vali aadress Laienda soovitatud aadressid + + Laienda salvestatud aadressid Ahenda soovitatud aadressid + + Ahenda salvestatud aadressid Halda aadresse + + + + Konto pilt + + Jätka + + Loobu diff --git a/android-components/components/feature/prompts/src/main/res/values-nb-rNO/strings.xml b/android-components/components/feature/prompts/src/main/res/values-nb-rNO/strings.xml index cf3ce8418676..a35beb81bff7 100644 --- a/android-components/components/feature/prompts/src/main/res/values-nb-rNO/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-nb-rNO/strings.xml @@ -18,6 +18,8 @@ Passord Ikke lagre + + Ikke nå Lagre aldri @@ -26,16 +28,26 @@ Lagre Ikke oppdater + + Ikke nå Oppdater Passordfeltet kan ikke stå tomt + Skriv inn et passord + Klarte ikke å lagre innloggingen + + Kan ikke lagre passordet Lagre denne innloggingen? + + Lagre passord? Vil du oppdatere denne innloggingen? + + Oppdatere passord? Vil du legge til brukernavn til lagret passord? @@ -85,13 +97,29 @@ Angi tid Behandle innlogginger + + Behandle passord Utvid foreslåtte innlogginger + + Utvid lagrede passord Slå sammen foreslåtte innlogginger + + Skjul lagrede passord Foreslåtte innlogginger + + Lagrede passord + + + Foreslå sterkt passord + + Foreslå sterkt passord + + Bruk sterkt passord: %1$s + Send data på nytt til dette nettstedet? Oppdatering av denne siden kan duplisere nylige handlinger, for eksempel å sende en betaling eller legge igjen en kommentar to ganger. @@ -103,12 +131,20 @@ Velg betalingskort + + Bruk lagret kort Utvid foreslåtte betalingskort + + Utvid lagrede kort Slå sammen foreslåtte betalingskort + + Skjul lagrede kort Behandle betalingskort + + Behandle kort Lagre dette kortet trygt? @@ -116,13 +152,20 @@ Kortnummer vil bli kryptert. Sikkerhetskoden blir ikke lagret. + + %s krypterer kortnummeret ditt. Sikkerhetskoden din blir ikke lagret. + Velg adresse Utvid foreslåtte adresser + + Utvid lagrede adresser Slå sammen foreslåtte adresser + + Skjul lagrede adresser Behandle adresser diff --git a/android-components/components/feature/search/src/main/res/values-et/strings.xml b/android-components/components/feature/search/src/main/res/values-et/strings.xml new file mode 100644 index 000000000000..077b8a047c95 --- /dev/null +++ b/android-components/components/feature/search/src/main/res/values-et/strings.xml @@ -0,0 +1,12 @@ + + + + + Ava uus kaart %1$sis + + Otsing + + Otsi veebist + + Häälotsing + diff --git a/android-components/components/feature/sitepermissions/src/main/res/values-cy/strings.xml b/android-components/components/feature/sitepermissions/src/main/res/values-cy/strings.xml index 270644b6c908..e937f6fc0a99 100644 --- a/android-components/components/feature/sitepermissions/src/main/res/values-cy/strings.xml +++ b/android-components/components/feature/sitepermissions/src/main/res/values-cy/strings.xml @@ -44,5 +44,5 @@ Rhwystro - Dysgu rhagor + Darllen rhagor diff --git a/android-components/components/ui/widgets/src/main/res/values-et/strings.xml b/android-components/components/ui/widgets/src/main/res/values-et/strings.xml new file mode 100644 index 000000000000..b77f8fe2fc7d --- /dev/null +++ b/android-components/components/ui/widgets/src/main/res/values-et/strings.xml @@ -0,0 +1,5 @@ + + + + Pilt kopeeriti vahemällu + diff --git a/fenix/app/src/main/res/values-co/strings.xml b/fenix/app/src/main/res/values-co/strings.xml index a83ceb26785f..b233b981bff3 100644 --- a/fenix/app/src/main/res/values-co/strings.xml +++ b/fenix/app/src/main/res/values-co/strings.xml @@ -247,6 +247,7 @@ Persunalizà a pagina d’accolta + Screnu d’accolta @@ -254,6 +255,9 @@ Squassà a cronolugia di navigazione + + Traduce a pagina + Lingua selezziunata @@ -265,8 +269,6 @@ Numerizà - - Mutore di ricerca Preferenze di u mutore di ricerca @@ -321,14 +323,14 @@ - E nutificazioni vi aiutanu à fane di più cù %s + E nutificazioni vi aiutanu à fane di più cù %s - Sincrunizate l’unghjette trà i vostri apparechji, urganizate i scaricamenti, ottinite cunsiglii per sfruttà u più bellu di a prutezzione di a vita privata da %s, è ancu di più. + Sincrunizate l’unghjette trà i vostri apparechji, urganizate i scaricamenti, ottinite cunsiglii per sfruttà u più bellu di a prutezzione di a vita privata da %s, è ancu di più. - Cuntinuà + Cuntinuà - Micca subitu + Micca subitu @@ -447,22 +449,11 @@ Modu solu HTTPS - - Riduzzione di e striscie di cannistrelli Blucchime di e striscie di cannistrelli Blucchime di e striscie di cannistrelli in navigazione privata - - Riduce e striscie di canistrelli - - - Disattivata - - Attivata - - %1$s prova autumaticamente di righjittà e dumande di canistrelli quandu ci hè striscie di canistrelli. Disattivata per stu situ @@ -480,36 +471,17 @@ Attualmente u situ ùn hè micca accettatu - Attivà a riduzzione di e striscie di cannistrelli per %1$s ? - Attivà u blucchime di e striscie di cannistrelli per %1$s ? - - Disattivà a riduzzione di e striscie di cannistrelli per %1$s ? Disattivà u blucchime di e striscie di cannistrelli per %1$s ? %1$s ùn pò micca righjittà autumaticamente e dumande di canistrelli nant’à stu situ. Pudete mandà una richiesta per ch’ellu sia accettallu in u futuru. - - %1$s squasserà i canistrelli di stu situ è attualizerà a pagina. A squassatura di tutti i canistrelli puderia discunnettevi o viutà e sporte di comprera. Disattivate l’ozzione è %1$s squasserà i canistrelli è ricaricherà stu situ. St’azzioni ponu discunettevi o viutà e vostre sporte di comprera. - %1$s prova autumaticamente di righjittà tutte e dumande di canistrelli nant’à i siti accettati. - Attivate l’ozzione è %1$s pruverà di righjittà autumaticamente tutte e striscie di canistrelli nant’à stu situ. - - Permette à %1$s di righjettà e striscie di canistrelli ? - - %1$s pò righjittà autumaticamente parechje dumande di striscie di canistrelli. - - Micca subitu - - Viderete menu richieste di cannistrelli - - - Permette %1$s hà righjittatu i canistrelli per voi @@ -730,6 +702,8 @@ Indette Identificazioni di cunnessione + + Parolle d’intesa Apre l’unghjette @@ -757,6 +731,8 @@ Carte bancarie + + Metode di pagamentu Indirizzi @@ -1300,8 +1276,6 @@ Chjode - Impussibule di stampà - Impussibule di stampà sta pagina Stampà @@ -1702,8 +1676,12 @@ Identificazioni è parolle d’intesa + + Parolle d’intesa Arregistrà l’identificazioni è e parolle d’intesa + + Arregistrà e parolle d’intesa Dumandà per arregistrà @@ -1721,27 +1699,46 @@ Aghjunghje un’identificazione di cunnessione + + Aghjunghje una parolla d’intesa + Sincrunizà l’identificazioni + + Sincrunizà e parolle d’intesa - Sincrunizà l’identificazioni di cunnessione trà tutti l’apparechji + Sincrunizà l’identificazioni di cunnessione trà l’apparechji + + Sincrunizà e parolle d’intesa trà l’apparechji Identificazioni di cunnessione arregistrate + + Parolle d’intesa arregistrate L’identificazioni di cunnessione chì voi arregistrate o sincrunizate cù %s seranu affissate quì. + + E parolle d’intesa chì vo arregistrate o sincrunizate cù %s seranu affissate quì. Tutte e parolle d’intesa chì vo arregistrate sò cifrate. Sapene di più nant’à Sync. + + Sapene di più nant’à a sincrunizazione Eccezzioni L’identificazioni è parolle d’intesa chì ùn sò micca arregistrate seranu affissate quì. + + %s ùn arregistrerà micca e parolle d’intesa per i siti allistinati quì. L’identificazioni è parolle d’intesa ùn seranu micca arregistrate per sti siti. + + %s ùn arregistrerà micca e parolle d’intesa per sti siti. Squassà tutte l’eccezzioni Ricercà identificazioni di cunnessione + + Ricercà parolle d’intesa Situ @@ -1771,10 +1768,16 @@ Piattà a parolla d’intesa Spalancate per affissà l’identificazioni di cunnessione arregistrate + + Spalancate per affissà e vostre parolle d’intesa arregistrate Prutigite e vostre identificazioni di cunnessione è parolle d’intesa + + Prutigite e vostre parolle d’intesa arregistrate Definite un dissegnu di chjusura, un codice PIN o una parolla d’intesa per prutege e vostre identificazioni di cunnessione è parolle d’intesa arregistrate s’ellu ci era qualchissia chì accidissi à u vostru apparechju. + + Definite un dissegnu di chjuditura, un codice PIN o una parolla d’intesa per prutege e vostre parolle d’intesa arregistrate s’ellu ci era qualchissia chì accidissi à u vostru apparechju. Dopu @@ -1794,6 +1797,9 @@ Listinu di classificazione di l’identificazioni + + Listinu di classificazione di e parolle d’intesa + Riempiimentu autumaticu @@ -1801,18 +1807,28 @@ Indirizzi Carte bancarie + + Metode di pagamentu Arregistrà è riempie autumaticamente e carte + + Arregistrà è rinsignà e metode di pagamentu I dati sò cifrati + + %s cifra tutte e metode di pagamentu chì vo arregistrate Sincrunizate e carte trà i vostri apparechji Sincrunizà e carte Aghjunghje una carta bancaria + + Aghjunghje una carta Amministrà e carte arregistrate + + Amministrà e carte Aghjunghje un indirizzu @@ -1820,9 +1836,14 @@ Arregistrà è riempie autumaticamente l’indirizzi + + Arregistrà è rinsignà l’indirizzi Include l’infurmazioni cum’è i numeri, i messaghji elettronichi è l’indirizzi di spedizione + + Include i numeri di telefonu è l’indirizzi elettronichi + Aghjunghje una carta @@ -1844,6 +1865,8 @@ Squassà a carta Vulete veramente squassà sta carta bancaria ? + + Squassà a carta ? Squassà @@ -1858,15 +1881,23 @@ Ci vole à stampittà un numeru accettevule di carta bancaria + + Stampittate un numeru di carta bancaria accettevule Ci vole à riempie stu campu + + Aghjunghje un nome Spalancate per affissà e vostre carte arregistrate Prutege e vostre carte bancarie + + Prutigite e vostre metode di pagamentu arregistrate Definite un dissegnu di chjusura, un codice PIN o una parolla d’intesa per prutege e vostre carte arregistrate s’ellu ci era qualchissia chì accidissi à u vostru apparechju. + + Definite un dissegnu di chjusura, un codice PIN o una parolla d’intesa per prutege e vostre metode di pagamentu arregistrate s’ellu ci era qualchissia chì accidissi à u vostru apparechju. Cunfigurà subitu @@ -1876,6 +1907,8 @@ Spalancate per impiegà l’infurmazione di e carte bancarie arregistrate + + Spalancate per impiegà e metode di pagamentu arregistrate Aghjunghje un indirizzu @@ -1913,6 +1946,8 @@ Squassà l’indirizzu Vulete veramente squassà st’indirizzu ? + + Squassà st’indirizzu ? Squassà @@ -2012,30 +2047,52 @@ Mudificà Vulete veramente squassà st’identificazione di cunnessione ? + + Vulete veramente squassà sta parolla d’intesa ? Squassà Abbandunà Ozzioni di l’identificazione + + Ozzioni di parolla d’intesa U campu di testu mudifichevule per l’indirizzu web di l’identificazione. + + U campu di testu mudifichevule per l’indirizzu di u situ web. U campu di testu mudifichevule per u nome d’utilizatore di l’identificazione. + + U campu di testu mudifichevule per u nome d’utilizatore. U campu di testu mudifichevule per a parolla d’intesa di l’identificazione. + + U campu di testu mudifichevule per a parolla d’intesa. Arregistrà i cambiamenti di l’identificazione. + + Arregistrà i cambiamenti. Mudificà + + Mudificà a parolla d’intesa Aghjunghje una nova identificazione di cunnessione + + Aghjunghje una parolla d’intesa Parolla d’intesa richiesta + + Stampittate una parolla d’intesa U nome d’utilizatore hè richiestu + + Stampittate un nome d’utilizatore U nome d’ospite hè richiestu + + Stampittate un indirizzu web Ricerca vucale @@ -2134,6 +2191,9 @@ Ricerca cù %s + + Cambià di navigatore predefinitu + Definisce chì i liami di i siti web, i currieri elettronichi è i messaghji s’aprinu autumaticamente in Firefox. @@ -2212,8 +2272,6 @@ Sapene di più nant’à %s. - - cumu %s da Mozilla determineghja a qualità di l’avisi cumu %s determineghja a qualità di l’avisi @@ -2402,6 +2460,8 @@ Traduzzione in corsu + + Sciglite una lingua Un prublema hè accadutu durante a traduzzione. Ci vole à pruvà torna. @@ -2422,6 +2482,10 @@ Ùn traduce mai in %1$s Ùn traduce mai stu situ + + Supraneghja tutte l’altre preferenze + + Supraneghja e pruposte di traduzzione Preferenze di traduzzione diff --git a/fenix/app/src/main/res/values-cy/strings.xml b/fenix/app/src/main/res/values-cy/strings.xml index bc5f735d6a5f..c86dbcc717f0 100644 --- a/fenix/app/src/main/res/values-cy/strings.xml +++ b/fenix/app/src/main/res/values-cy/strings.xml @@ -490,7 +490,7 @@ Ymlaen mewn tabiau preifat - Dysgu rhagor + Darllen rhagor Galluogi ym mhob tab @@ -641,7 +641,7 @@ Methu newid papur wal - Dysgu rhagor + Darllen rhagor %s clasurol @@ -743,7 +743,7 @@ Mae eithriadau’n caniatáu i chi analluogi diogelwch rhag trasio ar wefannau penodol. - Dysgu rhagor + Darllen rhagor Data defnydd a thechnegol @@ -913,7 +913,7 @@ Gall %1$s osod a rhedeg astudiaethau o bryd i’w gilydd. - Dysgu rhagor + Darllen rhagor Bydd yr ap yn cau er mwyn gosod y newidiadau @@ -1511,7 +1511,7 @@ Mae %s yn eich diogelu rhag llawer o’r tracwyr mwyaf cyffredin sy’n dilyn yr hyn rydych chi’n ei wneud ar-lein. - Dysgu rhagor + Darllen rhagor Safonol (rhagosodedig) @@ -1610,7 +1610,7 @@ as we use it on the UI to indicate which trackers have been partially unblocked. --> Mae rhai tracwyr sydd wedi’u marcio isod wedi cael eu dad-rwystr’n rhannol ar y dudalen hon oherwydd i chi ryngweithio â nhw *. - Dysgu rhagor + Darllen rhagor @@ -2065,7 +2065,7 @@ Mae angen cyfrinair - Rhoi cyfrinair + Rhowch gyfrinair Mae angen enw defnyddiwr @@ -2199,7 +2199,7 @@ Rhan o deulu Firefox. %s - Dysgu rhagor + Darllen rhagor Noddwyd @@ -2423,7 +2423,7 @@ Cyfieithu - Ceisio eto + Ceisiwch Eto Yn cyfieithu @@ -2439,7 +2439,7 @@ Ymddiheuriadau, nid ydym yn cefnogi %1$s eto. - Dysgu rhagor + Darllen rhagor @@ -2499,7 +2499,7 @@ - Peidio byth â chyfieithu\'r gwefannau hyn + Peidio â chyfieithu\'r gwefannau hyn I ychwanegu gwefan newydd: Ewch yno a dewis “Peidio byth â chyfieithu\'r wefan hon” o\'r ddewislen cyfieithu. + + Skift din standardbrowser + Indstil links fra websteder, mails og beskeder til automatisk at blive åbnet i Firefox. diff --git a/fenix/app/src/main/res/values-et/strings.xml b/fenix/app/src/main/res/values-et/strings.xml index b7312a3b4029..c0aef4b9c76a 100644 --- a/fenix/app/src/main/res/values-et/strings.xml +++ b/fenix/app/src/main/res/values-et/strings.xml @@ -301,6 +301,34 @@ Tere tulemast isikupärasemasse internetti + + Rohkem värve. Parem privaatsus. Sama pühendunud inimestele kasumi asemel. + + + Ekraani vahetamine on lihtsam kui kunagi varem + + Jätka sealt, kus pooleli jäid, kasutades kaarte teistest seadmetest avalehel. + + Tee algust + + Logi sisse + + Jäta vahele + + Kaarte sünkroonitakse! Jätka teises seadmes sealt, kus pooleli jäid. + + Sulge + + + + Teavitused aitavad %siga rohkem ära teha + + Sünkrooni kaarte seadmete vahel, halda allalaadimisi ning hangi näpunäiteid %si privaatsuskaitse maksimaalse kasutamise kohta ja palju muud. + + Jätka + Ava uus kaart %1$sis diff --git a/fenix/app/src/main/res/values-fi/strings.xml b/fenix/app/src/main/res/values-fi/strings.xml index 01e16e803004..2ca2abadd915 100644 --- a/fenix/app/src/main/res/values-fi/strings.xml +++ b/fenix/app/src/main/res/values-fi/strings.xml @@ -1899,6 +1899,8 @@ Suojaa tallennetut maksutavat Aseta laitteen avaukseen tarkoitettu kuvio, PIN-koodi tai salasana suojataksesi tallennetut luottokorttitiedot siltä varalta, että joku saa laitteesi haltuunsa. + + Määritä laitteen lukituskuvio, PIN-koodi tai salasana suojataksesi tallennettuja maksutapojasi, jos laitteesi on jollain toisella. Aseta nyt @@ -2061,8 +2063,12 @@ Salasanojen asetukset Muokattava tekstikenttä kirjautumisen verkkosivua varten. + + Verkkosivuston muokattava tekstikenttä. Muokattava tekstikenttä kirjautumisen käyttäjätunnusta varten. + + Käyttäjätunnuksen muokattava tekstikenttä. Muokattava tekstikenttä kirjautumisen salasanaa varten. @@ -2187,6 +2193,9 @@ %s-haku + + Vaihda oletusselain + Aseta verkkosivustojen, sähköpostien ja viestien linkit avautumaan automaattisesti Firefoxissa. diff --git a/fenix/app/src/main/res/values-fur/strings.xml b/fenix/app/src/main/res/values-fur/strings.xml index c01770abef49..1360e9100785 100644 --- a/fenix/app/src/main/res/values-fur/strings.xml +++ b/fenix/app/src/main/res/values-fur/strings.xml @@ -2163,6 +2163,9 @@ Ricercje %s + + Cambie il navigadôr predefinît + Configure i colegaments di sîts web, e-mails e messaçs in mût che a vegnin vierts in automatic cun Firefox. diff --git a/fenix/app/src/main/res/values-kab/strings.xml b/fenix/app/src/main/res/values-kab/strings.xml index 9f1bd4710373..099ae1be7691 100644 --- a/fenix/app/src/main/res/values-kab/strings.xml +++ b/fenix/app/src/main/res/values-kab/strings.xml @@ -2053,6 +2053,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Sekcem isem n useqdac Asenneftaɣ yettwasra + + Sekcem tansa web Anadi s taɣect @@ -2150,6 +2152,9 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Anadi %s + + + Beddel iminig-ik·im amezwer Sbadu iseɣwan seg yismal web, seg yimaylen d yiznan i twaledyawt s wudem awurman deg Firefox. diff --git a/fenix/app/src/main/res/values-nb-rNO/strings.xml b/fenix/app/src/main/res/values-nb-rNO/strings.xml index c6bf155c6c7b..86347ea1afd6 100644 --- a/fenix/app/src/main/res/values-nb-rNO/strings.xml +++ b/fenix/app/src/main/res/values-nb-rNO/strings.xml @@ -212,6 +212,8 @@ Synkroniser på nytt Finn på siden + + Oversett siden Lagre i samling @@ -241,6 +243,7 @@ Tilpass startsiden + Startskjerm @@ -248,6 +251,9 @@ Slett nettleserhistorikk + + Oversett siden + Valgt språk @@ -260,8 +266,6 @@ Skann - - Søkemotor Innstillinger for søkemotor @@ -315,24 +319,29 @@ - Varsler hjelper deg å gjøre mer med %s + Varsler hjelper deg å gjøre mer med %s - Synkroniser fanene dine mellom enheter, behandle nedlastinger, få tips om hvordan du får mest mulig ut av %s sitt personvern, og mer. + Synkroniser fanene dine mellom enheter, behandle nedlastinger, få tips om hvordan du får mest mulig ut av %s sitt personvern, og mer. - Fortsett + Fortsett - Ikke nå + Ikke nå + + Firefox personvernerklæring + Vi beskytter deg gjerne - Vår ideelle nettleser forhindrer selskaper i å spore aktiviteten din i hemmelighet på nettet.\n\nLes mer i personvernerklæringen vår. + Vår ideelle nettleser forhindrer selskaper i å spore aktiviteten din i hemmelighet på nettet. + + Vår ideelle nettleser forhindrer selskaper i å spore aktiviteten din i hemmelighet på nettet.\n\nLes mer i personvernerklæringen vår. - personvernerklæring + personvernerklæring Bruk som standard nettleser @@ -435,21 +444,11 @@ Kun-HTTPS-modus - - Redusering av infokapselbannere Blokkering av infokapselbanner Blokkering av infokapselbanner i privat nettlesing - - Reduser infokapselbannere - - Av - - - - - %1$s prøver automatisk å avvise infokapselforespørsler på infokapselbannere. + Av for dette nettstedet @@ -467,35 +466,16 @@ Nettstedet støttes for øyeblikket ikke - Vil du slå på reduksjon av infokapselbannere for %1$s? - Vil du slå på blokkering av infokapselbanner for %1$s? - Vil du slå av reduksjon av infokapselbannere for %1$s? - Vil du slå av blokkering av infokapselbanner for %1$s? %1$s kan ikke automatisk avvise forespørsler om infokapsler på dette nettstedet. Du kan sende en forespørsel om å støtte dette nettstedet i fremtiden. - - %1$s vill slette infokapsler og oppdatere siden. Sletting av alle infokapsler kan føre til at du blir logget ut eller at handlekurver blir tømt. Slå av, og %1$s sletter infokapsler og laster inn dette nettstedet på nytt. Dette kan logge deg ut eller tømme handlekurver. - %1$s prøver å automatisk avvise alle infokapselforespørsler på støttede nettsteder. - Slå på, og %1$s vil prøve å automatisk nekte infokapselbannere på dette nettstedet. - - Tillat at %1$s avviser infokapselbannere? - - %1$s kan automatisk avvise mange infokapselbanner-forespørsler. - - Ikke nå - - Du vil se færre forespørsler om infokapsler - - - Tillat %1$s nektet nettopp infokapsler for deg @@ -712,6 +692,8 @@ Bokmerker Innlogginger + + Passord Åpne faner @@ -738,6 +720,8 @@ Betalingskort + + Betalingsmetoder Adresser @@ -1280,8 +1264,6 @@ Ignorer - Kan ikke å skrive ut - Kan ikke å skrive ut denne siden Skriv ut @@ -1325,6 +1307,11 @@ Lukk private faner + + + Lukk private faner? + Trykk eller sveip dette varselet for å lukke private faner. + Markedsføring @@ -1682,8 +1669,12 @@ Innlogginger og passord + + Passord Lagre innlogginger og passord + + Lagre passord Spør om å lagre @@ -1701,27 +1692,46 @@ Legg til innlogging + + Legg til passord + Synkroniser innlogginger + + Synkroniser passord Synkroniser innlogginger på tvers av enheter + + Synkroniser passord på tvers av enheter Lagrede innlogginger + + Lagrede passord De innlogginger du lagrer eller synkroniserer til %s vil vises her. + + Passordene du lagrer eller synkroniserer med %s vil bli oppført her. Alle passord du lagrer er kryptert. Les mer om Sync. + + Les mer om synkronisering Unntak Innlogginger og passord som ikke er lagret vil vises her. + + %s vil ikke lagre passord for nettsteder som er oppført her. Innlogginger og passord vil ikke bli lagret for disse nettstedene. + + %s vil ikke lagre passord for disse nettstedene. Slett alle unntak Søk innlogginger + + Søk etter passord Nettsted @@ -1751,8 +1761,12 @@ Skjul passord Lås opp for å se dine lagrede innlogginger + + Lås opp for å se dine lagrede passord Sikre dine innlogginger og passord + + Sikre dine lagrede passord Konfigurer en PIN-kode, et passord eller et låsemønster for å forhindre at andre mennesker får tilgang de lagrede innloggingene og passordene dine, hvis de har adgang til din enhet. @@ -2112,7 +2126,7 @@ %s-søk - + Angi at lenker fra nettsteder, e-postmeldinger og meldinger skal åpnes automatisk i Firefox. @@ -2186,8 +2200,6 @@ Høydepunkter er fra %s-vurderinger i løpet av de siste 80 dagene som vi mener er pålitelige.]]> Les mer om %s. - - hvordan %s fra Mozilla bestemmer vurderingskvalitet hvordan %s bestemmer vurderingskvalitet @@ -2271,17 +2283,17 @@ Les mer - Ved å velge «Ja, prøv det» godtar du %1$s fra Mozilla sine %2$s og %3$s. + Ved å velge «Ja, prøv det» godtar du %1$s fra Mozilla sine %2$s og %3$s. - Ved å velge «Ja, prøv det» godtar du følgende fra %1$s: + Ved å velge «Ja, prøv det» godtar du følgende fra %1$s: - personvernbestemmelser + personvernbestemmelser - Personvernbestemmelser + Personvernbestemmelser - vilkår for bruk + vilkår for bruk - Vilkår for bruk + Vilkår for bruk Ja, prøv det diff --git a/fenix/app/src/main/res/values-pt-rBR/strings.xml b/fenix/app/src/main/res/values-pt-rBR/strings.xml index e32bdb52c3bf..ad71b6832367 100644 --- a/fenix/app/src/main/res/values-pt-rBR/strings.xml +++ b/fenix/app/src/main/res/values-pt-rBR/strings.xml @@ -401,7 +401,7 @@ Selecione um - Gerencie mecanismos de pesquisa alternativos + Gerenciar mecanismos de pesquisa alternativos Editar mecanismos visíveis no menu de pesquisa diff --git a/fenix/app/src/main/res/values-uk/strings.xml b/fenix/app/src/main/res/values-uk/strings.xml index 90504d5dafd8..b9f1506f0a69 100644 --- a/fenix/app/src/main/res/values-uk/strings.xml +++ b/fenix/app/src/main/res/values-uk/strings.xml @@ -2183,6 +2183,9 @@ %s пошук + + Змініть типовий браузер + Автоматично відкривати посилання з вебсайтів, електронних листів та повідомлень у Firefox. diff --git a/fenix/app/src/main/res/values-vi/strings.xml b/fenix/app/src/main/res/values-vi/strings.xml index 736a82c332fc..356737044dd8 100644 --- a/fenix/app/src/main/res/values-vi/strings.xml +++ b/fenix/app/src/main/res/values-vi/strings.xml @@ -2161,6 +2161,9 @@ Tìm kiếm trên %s + + Đặt làm trình duyệt mặc định của bạn + Đặt các liên kết từ trang web, email và tin nhắn để tự động mở trong Firefox. diff --git a/focus-android/app/src/main/res/values-cy/strings.xml b/focus-android/app/src/main/res/values-cy/strings.xml index 67cc2aca970d..95a8cdd2dfdb 100644 --- a/focus-android/app/src/main/res/values-cy/strings.xml +++ b/focus-android/app/src/main/res/values-cy/strings.xml @@ -251,7 +251,7 @@ Tynnu URLau cyfaddas - Dysgu rhagor + Darllen rhagor Ychwanegu a rheoli URLs awtogwblhau cyfaddas. @@ -344,7 +344,7 @@ Anfon data defnydd - Dysgu rhagor + Darllen rhagor Mae Mozilla\'n ceisio casglu dim ond yr hyn sydd ei angen arnom i ddarparu a gwella %1$s ar gyfer pawb. @@ -832,7 +832,7 @@ Efallai y bydd Firefox yn gosod a rhedeg astudiaethau o bryd i’w gilydd. - Dysgu rhagor + Darllen rhagor Bydd yr ap yn cau er mwyn gosod y newidiadau diff --git a/focus-android/app/src/main/res/values-kab/strings.xml b/focus-android/app/src/main/res/values-kab/strings.xml index 5e7559129c7b..2d5b089a0b06 100644 --- a/focus-android/app/src/main/res/values-kab/strings.xml +++ b/focus-android/app/src/main/res/values-kab/strings.xml @@ -86,6 +86,8 @@ Sfeḍ amazray n tunigin? + Sit ɣef telɣut-a neɣ kkes-itt i wakken ad tekkseḍ azray-ik n tunigin s wudem aɣelsan. + Sfeḍ amazray n tunigin diff --git a/focus-android/app/src/main/res/values-nb-rNO/strings.xml b/focus-android/app/src/main/res/values-nb-rNO/strings.xml index 2e61c7e582d1..e5257880a9bd 100644 --- a/focus-android/app/src/main/res/values-nb-rNO/strings.xml +++ b/focus-android/app/src/main/res/values-nb-rNO/strings.xml @@ -53,7 +53,6 @@ Fjern fra snarveier - Hva er nytt Innstillinger Om Hjelp @@ -84,10 +83,9 @@ sharing an URL. --> Del via - + Slett nettleserhistorikk? + Trykk eller fjern dette varselet for å slette nettleserhistorikken din på en sikker måte. + Slett nettleserhistorikk From 744c77429a98851b7a481860cf2cef0ea16a4b6a Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Sun, 11 Feb 2024 00:48:36 +0000 Subject: [PATCH 156/586] Update GeckoView (Nightly) to 124.0.20240210210518. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 62d9b0ca99b9..68e3ede7293f 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240210094249" + const val version = "124.0.20240210210518" /** * GeckoView channel From 2d69fcc0c174e8f2e6541db7df542ed3c9f20033 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Sun, 11 Feb 2024 12:24:26 +0000 Subject: [PATCH 157/586] Update GeckoView (Nightly) to 124.0.20240211090343. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 68e3ede7293f..6151e8e4691c 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240210210518" + const val version = "124.0.20240211090343" /** * GeckoView channel From 01938092c80bdfc3c2c512de8021daa3717b8bc6 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 12 Feb 2024 00:03:31 +0000 Subject: [PATCH 158/586] Import translations from android-l10n --- .../addons/src/main/res/values-eo/strings.xml | 2 + .../addons/src/main/res/values-ja/strings.xml | 4 +- .../addons/src/main/res/values-pl/strings.xml | 4 +- .../media/src/main/res/values-eo/strings.xml | 11 +- .../media/src/main/res/values-ja/strings.xml | 11 +- .../media/src/main/res/values-pl/strings.xml | 11 +- .../src/main/res/values-eo/strings.xml | 36 ++++ .../src/main/res/values-ja/strings.xml | 36 ++++ .../src/main/res/values-pl/strings.xml | 36 ++++ fenix/app/src/main/res/values-azb/strings.xml | 47 ++++++ fenix/app/src/main/res/values-co/strings.xml | 2 +- fenix/app/src/main/res/values-cs/strings.xml | 3 + fenix/app/src/main/res/values-dsb/strings.xml | 3 + .../src/main/res/values-en-rGB/strings.xml | 3 + fenix/app/src/main/res/values-eo/strings.xml | 154 ++++++++++++----- fenix/app/src/main/res/values-is/strings.xml | 3 + fenix/app/src/main/res/values-ja/strings.xml | 154 ++++++++++++----- fenix/app/src/main/res/values-pl/strings.xml | 156 +++++++++++++----- fenix/app/src/main/res/values-rm/strings.xml | 81 +++++++++ fenix/app/src/main/res/values-tg/strings.xml | 49 ++++++ fenix/app/src/main/res/values-tr/strings.xml | 3 + .../app/src/main/res/values-eo/strings.xml | 8 +- .../app/src/main/res/values-pl/strings.xml | 10 +- 23 files changed, 677 insertions(+), 150 deletions(-) diff --git a/android-components/components/feature/addons/src/main/res/values-eo/strings.xml b/android-components/components/feature/addons/src/main/res/values-eo/strings.xml index 83ffd79ad57b..affab0359586 100644 --- a/android-components/components/feature/addons/src/main/res/values-eo/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-eo/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Aliri viajn datumojn de %1$d aliaj nomregnoj + + %1$s, %2$d el %3$d Aliri retumilajn langetojn diff --git a/android-components/components/feature/addons/src/main/res/values-ja/strings.xml b/android-components/components/feature/addons/src/main/res/values-ja/strings.xml index f03d79b68a83..2027ae146f51 100644 --- a/android-components/components/feature/addons/src/main/res/values-ja/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-ja/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> その他 %1$d ドメイン上のデータへのアクセス + + %1$s、%2$d / %3$d ブラウザーのタブへのアクセス @@ -75,7 +77,7 @@ 作者 - 作者 + 作者 最終更新日時 diff --git a/android-components/components/feature/addons/src/main/res/values-pl/strings.xml b/android-components/components/feature/addons/src/main/res/values-pl/strings.xml index d6632d7d8f4b..7dd3bbc45556 100644 --- a/android-components/components/feature/addons/src/main/res/values-pl/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-pl/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Dostęp do danych użytkownika w %1$d innych domenach + + %1$s, %2$d z %3$d Dostęp do kart przeglądarki @@ -75,7 +77,7 @@ Autor - Autorzy + Autorzy Ostatnia aktualizacja diff --git a/android-components/components/feature/media/src/main/res/values-eo/strings.xml b/android-components/components/feature/media/src/main/res/values-eo/strings.xml index 640a56aef077..7c98f55eec30 100644 --- a/android-components/components/feature/media/src/main/res/values-eo/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-eo/strings.xml @@ -1,5 +1,5 @@ - + Aŭdvidaĵo @@ -22,10 +22,15 @@ Memorigo: %1$s ankoraŭ uzas vian filmilon. Tuŝetu por malfermi la langeton. - Memorigo: %1$s ankoraŭ uzas vian mikrofonon. Tuŝetu por malfermi la langeton. + Memorigo: %1$s ankoraŭ uzas vian mikrofonon. Tuŝetu por malfermi la langeton. + + + Memorigo: %1$s ankoraŭ uzas vian mikrofonon. Tuŝetu por malfermi la langeton. + + Memorigo: %1$s ankoraŭ uzas vian mikrofonon kaj filmilon. Tuŝetu por malfermi la langeton. - Memorigo: %1$s ankoraŭ uzas vian mikrofonon kaj filmilon. Tuŝetu por malfermi la langeton. + Memorigo: %1$s ankoraŭ uzas vian mikrofonon kaj filmilon. Tuŝetu por malfermi la langeton. Ludi diff --git a/android-components/components/feature/media/src/main/res/values-ja/strings.xml b/android-components/components/feature/media/src/main/res/values-ja/strings.xml index 5ad6081ea8ba..c1cfbc4c7d80 100644 --- a/android-components/components/feature/media/src/main/res/values-ja/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-ja/strings.xml @@ -1,5 +1,5 @@ - + メディア @@ -23,9 +23,14 @@ 通知: %1$s がまだカメラを使用しています。タップしてタブを開いてください。 - 通知: %1$s がまだマイクを使用しています。タップしてタブを開いてください。 + 通知: %1$s がまだマイクを使用しています。タップしてタブを開いてください。 + + 通知: %1$s がまだマイクを使用しています。タップしてタブを開いてください。 + + 通知: %1$s がまだマイクとカメラを使用しています。タップしてタブを開いてください。 + - 通知: %1$s がまだマイクとカメラを使用しています。タップしてタブを開いてください。 + 通知: %1$s がまだマイクとカメラを使用しています。タップしてタブを開いてください。 再生 diff --git a/android-components/components/feature/media/src/main/res/values-pl/strings.xml b/android-components/components/feature/media/src/main/res/values-pl/strings.xml index a0c7466ff71d..9c22f9a90b51 100644 --- a/android-components/components/feature/media/src/main/res/values-pl/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-pl/strings.xml @@ -1,5 +1,5 @@ - + Multimedia @@ -21,9 +21,14 @@ Przypomnienie: %1$s nadal korzysta z aparatu. Stuknij, aby otworzyć kartę. - Przypomnienie: %1$s nadal korzysta z mikrofonu. Stuknij, aby otworzyć kartę + Przypomnienie: %1$s nadal korzysta z mikrofonu. Stuknij, aby otworzyć kartę + + Przypomnienie: %1$s nadal korzysta z mikrofonu. Stuknij, aby otworzyć kartę. + + Przypomnienie: %1$s nadal korzysta z mikrofonu i aparatu. Stuknij, aby otworzyć kartę + - Przypomnienie: %1$s nadal korzysta z mikrofonu i aparatu. Stuknij, aby otworzyć kartę + Przypomnienie: %1$s nadal korzysta z mikrofonu i aparatu. Stuknij, aby otworzyć kartę. Odtwórz diff --git a/android-components/components/feature/prompts/src/main/res/values-eo/strings.xml b/android-components/components/feature/prompts/src/main/res/values-eo/strings.xml index 781e22d78aa7..a6cc86761b9c 100644 --- a/android-components/components/feature/prompts/src/main/res/values-eo/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-eo/strings.xml @@ -18,6 +18,8 @@ Pasvorto Ne konservi + + Ne nun Neniam konservi @@ -26,16 +28,26 @@ Konservi Ne ĝisdatigi + + Ne nun Ĝisdatigi La pasvorto ne povas esti malplena + Tajpu pasvorton + Ne eblas konservi legitimilon + + Ne eblas konservi la pasvorton Ĉu konservi tiun ĉi legitimilon? + + Ĉu konservi pasvorton? Ĉu ĝisdatigi tiun ĉi akreditilon? + + Ĉu ĝisdatigi pasvorton? Ĉu aldoni nomon de uzanto al la konservita pasvorto? @@ -85,13 +97,22 @@ Difini horon Administri legitimilojn + + Administri pasvortojn Malfaldi sugestitajn legitimilojn + + Malfaldi konservitajn pasvortojn Faldi sugestitajn legitimilojn + + Faldi konservitajn pasvortojn Sugestitaj legitimiloj + + Konservitaj pasvortoj + Sugesti fortan pasvorton @@ -110,12 +131,20 @@ Elekti kreditkarton + + Uzi konservitan karton Malfaldi sugestitajn kreditkartojn + + Elporti konservitajn pasvortojn Faldi sugestitajn kreditkartojn + + Faldi konservitajn kartojn Administri kreditkartojn + + Administri kartojn Ĉu sekure konservi tiun ĉi kreditkarton? @@ -123,13 +152,20 @@ La numero de kreditkaro estos ĉifrita. La sekureca kodo ne estos konservita. + + %s ĉifras vian numeron de karto. Via sekureca kodo ne estos konservita. + Elekti adresojn Malfaldi sugestitajn adresojn + + Malfaldi konservitajn adresojn Faldi sugestitajn adresojn + + Faldi konservitajn adresojn Administri adresojn diff --git a/android-components/components/feature/prompts/src/main/res/values-ja/strings.xml b/android-components/components/feature/prompts/src/main/res/values-ja/strings.xml index d72f03a9a1f7..9b0ba18b329c 100644 --- a/android-components/components/feature/prompts/src/main/res/values-ja/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-ja/strings.xml @@ -26,6 +26,8 @@ 保存しない + + 後で 保存しない @@ -34,16 +36,26 @@ 保存する 更新しない + + 後で 更新 パスワードを入力してください + パスワードを入力してください + ログイン情報を保存できません + + パスワードを保存できません このログイン情報を保存しますか? + + パスワードを保存しますか? このログイン情報を更新しますか? + + パスワードを更新しますか? 保存されたパスワードにユーザー名を追加しますか? @@ -97,13 +109,22 @@ 時刻の設定 ログイン情報の管理 + + パスワードを管理 提案されたログイン情報を展開 + + 保存したパスワードを展開 提案されたログイン情報を折りたたむ + + 保存したパスワードを折りたたむ 提案されたログイン情報 + + 保存されたパスワード + 強固なパスワードを提案する @@ -122,12 +143,20 @@ クレジットカードを選択 + + 保存したカード情報を使用 提案されたクレジットカード情報を展開する + + 保存したカード情報を展開 提案されたクレジットカード情報を折りたたむ + + 保存したカード情報を折りたたむ クレジットカードを管理 + + カード情報を管理 このカードの情報を安全に保存しますか? @@ -135,13 +164,20 @@ カード番号は暗号化されます。セキュリティコードは保存されません。 + + %s がカード番号を暗号化します。セキュリティコードは保存しません。 + アドレスの選択 提案されたアドレス情報を展開する + + 保存したアドレス情報を展開 提案されたアドレス情報を折りたたむ + + 保存したアドレス情報を折りたたむ アドレスの管理 diff --git a/android-components/components/feature/prompts/src/main/res/values-pl/strings.xml b/android-components/components/feature/prompts/src/main/res/values-pl/strings.xml index c11e34a80a3c..92107e968fd8 100644 --- a/android-components/components/feature/prompts/src/main/res/values-pl/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-pl/strings.xml @@ -18,6 +18,8 @@ Hasło Nie zachowuj + + Nie teraz Nigdy nie zachowuj @@ -26,16 +28,26 @@ Zachowaj Nie aktualizuj + + Nie teraz Aktualizuj Pole hasła nie może być puste + Wpisz hasło + Nie można zachować danych logowania + + Nie można zachować hasła Czy zachować te dane logowania? + + Czy zachować hasło? Czy zaktualizować te dane logowania? + + Czy zaktualizować hasło? Czy dodać nazwę użytkownika do zachowanego hasła? @@ -85,13 +97,22 @@ Ustaw czas Zarządzaj danymi logowania + + Zarządzaj hasłami Rozwiń podpowiadane dane logowania + + Rozwiń zachowane hasła Zwiń podpowiadane dane logowania + + Zwiń zachowane hasła Podpowiadane dane logowania + + Zachowane hasła + Zaproponuj silne hasło @@ -110,12 +131,20 @@ Wybierz kartę płatniczą + + Użyj zachowanej karty Rozwiń podpowiadane karty płatnicze + + Rozwiń zachowane karty Zwiń podpowiadane karty płatnicze + + Zwiń zachowane karty Zarządzaj kartami płatniczymi + + Zarządzaj kartami Czy bezpiecznie zachować tę kartę? @@ -123,13 +152,20 @@ Numer karty zostanie zaszyfrowany. Kod zabezpieczający nie zostanie zachowany. + + %s szyfruje numer karty. Kod zabezpieczający nie zostanie zachowany. + Wybierz adres Rozwiń podpowiadane adresy + + Rozwiń zachowane adresy Zwiń podpowiadane adresy + + Zwiń zachowane adresy Zarządzaj adresami diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml index 37a4ebc5fce0..1c5e4b0c8767 100644 --- a/fenix/app/src/main/res/values-azb/strings.xml +++ b/fenix/app/src/main/res/values-azb/strings.xml @@ -543,6 +543,8 @@ اؤزل دؤنگل سرور + + موْزیلا حسابیْ/دؤنگل سروری دگیشدیریلدی. دگیشمه‌لری یئرینه سالماق اوچون اپلیکیشن‌دن چیخیلیر... حساب @@ -551,19 +553,64 @@ تم آنایارپاق + + ایشاره‌لر اؤزللشدیرمک + + تاغلاریْ، بوکمارک‌لاریْ، رمزلری و داها چوْخوُنو دؤنگل ائتمک اوچون گیریش ائله‌یین. موْزیلا حسابی + + دؤنگلی ایدامه وئرمک اوچون یئنی‌دن باغلانین. دیل دیتا سئچیمی + + دیتا یئغیلماسیْ + + USB طریقی‌نن اوُزاقدان سازلاما + + آختاریْش تکلیف‌لرینی گؤستر + + سس‌لی آختاریشیْ گؤستر + + گیزلی اوْتوروُم‌لاردا گؤستر + + کلیپ‌بوْرد تکلیف‌لرینی گؤستر + + موُرور گئچمیشینده آختار + + بوکمارک‌دا آختار + + دؤنگل ائدیلمیش تاغ‌لاردا آختار + + حساب تنظیم‌لری + + اؤزاؤزونه URL تکمیل‌لشمه‌سی + + اسپانسرلردن تکلیف‌لر + + بعضاً اسپانسرلیق تکلیف‌لری ایله %1$s -یی آرخالایین. + + %1$s تکلیف‌لری + + وب‌دن آختاریْنیزلا باغلیْ تکلیف‌لری آلیْن. + + اَپ‌لرده باغلانتی‌ْلاری آچیْن. هر زامان + + آچمازدان اؤنجه سوْروُشون. هئچ زامان + + خاریجی یئندیرمه موْدیری. + تاخیلان‌لار diff --git a/fenix/app/src/main/res/values-co/strings.xml b/fenix/app/src/main/res/values-co/strings.xml index b233b981bff3..e41a5e4c1073 100644 --- a/fenix/app/src/main/res/values-co/strings.xml +++ b/fenix/app/src/main/res/values-co/strings.xml @@ -1837,7 +1837,7 @@ Arregistrà è riempie autumaticamente l’indirizzi - Arregistrà è rinsignà l’indirizzi + Arregistrà è rinsignà autumaticamente l’indirizzi Include l’infurmazioni cum’è i numeri, i messaghji elettronichi è l’indirizzi di spedizione diff --git a/fenix/app/src/main/res/values-cs/strings.xml b/fenix/app/src/main/res/values-cs/strings.xml index d257bf7c056b..2a9bafda93c7 100644 --- a/fenix/app/src/main/res/values-cs/strings.xml +++ b/fenix/app/src/main/res/values-cs/strings.xml @@ -2189,6 +2189,9 @@ Vyhledat pomocí %s + + Změňte svůj výchozí prohlížeč + Nastavte si automatické otevírání odkazů, e-mailů a zpráv ve Firefoxu. diff --git a/fenix/app/src/main/res/values-dsb/strings.xml b/fenix/app/src/main/res/values-dsb/strings.xml index bbc3d240baff..629b72032271 100644 --- a/fenix/app/src/main/res/values-dsb/strings.xml +++ b/fenix/app/src/main/res/values-dsb/strings.xml @@ -2172,6 +2172,9 @@ Z %s pytaś + + Standardny wobglědowak změniś + Nastajśo wótkaze z websedłow, mejlkow a powěsćow, aby se awtomatiski we Firefox wócynili. diff --git a/fenix/app/src/main/res/values-en-rGB/strings.xml b/fenix/app/src/main/res/values-en-rGB/strings.xml index ea001e9be880..31dfb31b8d99 100644 --- a/fenix/app/src/main/res/values-en-rGB/strings.xml +++ b/fenix/app/src/main/res/values-en-rGB/strings.xml @@ -2162,6 +2162,9 @@ %s search + + Switch your default browser + Set links from web sites, emails, and messages to open automatically in Firefox. diff --git a/fenix/app/src/main/res/values-eo/strings.xml b/fenix/app/src/main/res/values-eo/strings.xml index 64032af01be0..adae84f571a2 100644 --- a/fenix/app/src/main/res/values-eo/strings.xml +++ b/fenix/app/src/main/res/values-eo/strings.xml @@ -239,6 +239,7 @@ Personecigi ekan paĝon + Hejmekrano @@ -246,6 +247,9 @@ Viŝi retuman historion + + Traduki paĝon + Elektita lingvo @@ -257,8 +261,6 @@ Skani - - Serĉilo Agordoj de serĉilo @@ -312,23 +314,28 @@ - Sciigoj helpas vin plenumi pli per %s + Sciigoj helpas vin plenumi pli per %s - Spegulu viajn langetojn inter aparatoj, administru elŝutojn, ricevu konsiletojn por eltiri la maksimumon el la privateca protekto de %s, kaj pli. + Spegulu viajn langetojn inter aparatoj, administru elŝutojn, ricevu konsiletojn por eltiri la maksimumon el la privateca protekto de %s, kaj pli. - Daŭrigi + Daŭrigi - Ne nun + Ne nun + + Rimarko de Firefox pri privateco + Ni amas teni vin sekura - Nia retumilo, subtenata de nenprofitcela organizo, helpas eviti ke entreprenoj kaŝe sekvu vin tra la reto.\n\nPli da informo en nia rimarko pri privateco. + Nia retumilo, subtenata de nenprofitcela organizo, helpas eviti ke entreprenoj kaŝe sekvu vin tra la reto. + + Nia retumilo, subtenata de nenprofitcela organizo, helpas eviti ke entreprenoj kaŝe sekvu vin tra la reto.\n\nPli da informo en nia rimarko pri privateco. - rimarko pri privateco + rimarko pri privateco Difini kiel norman retumilon @@ -432,21 +439,11 @@ HTTPS-nura reĝimo - - Redukto de kuketaj anoncoj Blokilo de kuketaj anoncoj Blokilo de kuketaj anoncoj en privata retumo - - Redukti kuketajn anoncojn - - Malŝaltita - - Ŝaltita - - - %1$s aŭtomate klopodos rifuzi kuketajn petojn en kuketaj anoncoj. + Malŝaltita por tiu ĉi retejo @@ -463,38 +460,19 @@ Peto pri subteno sendita Retejo nuntempe ne subtenata - - Ĉu ŝalti la redukton de kuketaj anoncoj en %1$s? Ĉu ŝalti la blokilon de kuketaj anoncoj por %1$s? - Ĉu malŝalti la redukton de kuketaj anoncoj en %1$s? - Ĉu malŝalti la blokilon de kuketaj anoncoj por %1$s? %1$s ne povas aŭtomate rifuzi kuketojn en tiu ĉi retejo. Vi povas sendi peton por aldoni subtenon por tiu ĉi retejo en la estonteco. - - %1$s forigos la kuketojn de tiuj ĉi retejo kaj reŝargos la paĝon. Forigo de ĉiuj kuketoj povas fini seancojn aŭ malplenigi aĉetumĉarojn. Malŝaltu kaj %1$s forigos kuketojn kaj reŝagos tiun ĉi retejon. Tiu ĉi ago povus fini la seancon aŭ malplenigi aĉetumĉaron. - - %1$s klopodas aŭtomate rifuzi ĉiujn kuketajn petojn en subtenataj retejoj. Ŝaltu, kaj %1$s klopodos aŭtomate rifuzi kuketajn anoncojn en tiu ĉi retejo. - - Ĉu permesi al %1$s rifuzi kuketajn anoncojn? - - %1$s povas aŭtomate rifuzi multajn petojn de kuketaj anoncoj. - - Ne nun - - Vi vidos malpli da kuketaj anoncoj - - - Permesi %1$s ĵus rifuzis kuketojn por vi @@ -712,6 +690,8 @@ legosignojn legitimilojn + + Pasvortoj Malfermitaj langetoj @@ -738,6 +718,8 @@ Kreditkartoj + + Pagmetodoj Adresoj @@ -1282,8 +1264,6 @@ Ignori - Ne eblas presi - Ne eblas presi tiun ĉi paĝon Presi @@ -1691,8 +1671,12 @@ Legitimiloj kaj pasvortoj + + Pasvortoj Konservi legitimilojn kaj pasvortojn + + Konservi pasvortojn Demandi antaŭ ol konservi @@ -1709,27 +1693,46 @@ Aldoni legitimilon + + Aldoni pasvorton + Speguli legitimilojn + + Speguli pasvortojn Speguli legitimilojn inter aparatoj + + Speguli pasvortojn inter aparatoj Konservitaj legitimiloj + + Konservitaj pasvortoj La legitimiloj, kiujn vi konservas aŭ spegulas al %s, aperos ĉi tie. + + La pasvortoj konservitaj aŭ spegulitaj al %s estos listigitaj ĉi tie. Ĉiuj konservitaj pasvortoj estos ĉifritaj. Pli da informo pri Spegulado. + + Pli da informo pri spegulado Esceptoj Nekonservitaj nomoj de uzantoj kaj pasvortoj estos montritaj ĉi tie. + + %s ne konservos pasvortojn por retejoj listigitaj ĉi tie. Nomoj de uzanto kaj pasvortoj por tiuj ĉi retejoj ne estos konservitaj. + + %s ne konservos pasvortojn por tiuj ĉi retejoj. Forigi ĉiujn esceptojn Serĉi legitimilojn + + Serĉi pasvortojn Retejo @@ -1759,10 +1762,16 @@ Malŝlosu por vidi viajn konservitajn legitimilojn + + Malŝlosi por vidi viajn konservitajn pasvortojn Protektu viajn legitimilojn kaj pasvortojn + + Protektu viajn konservitajn pasvortojn Difinu blokan desegnon, PIN aŭ pasvorton por protekti viajn konservitajn legitimilojn kaj pasvortojn se iu alia havas vian aparaton. + + Difinu blokan desegnon, PIN aŭ pasvorton por protekti viajn konservitajn pasvortojn se iu alia havas vian aparaton. Poste @@ -1781,6 +1790,9 @@ Ordigi menuon de legitimiloj + + Menuo por ordigi pasvortojn + Aŭtomata plenigo @@ -1788,27 +1800,42 @@ Adresoj Kreditkartoj + + Pagmetodoj Konservi kaj aŭtomate plenigi kreditkartojn + + Konservi kaj aŭtomate plenigi pagmetodojn La datumoj estas ĉifritaj + + %s ĉifras ĉiujn pagmetodojn, kiujn vi konservis Speguli kreditkartojn inter aparatoj Speguli kreditkartojn Aldoni kreditkarton + + Aldoni kreditkarton Administri konservitajn kreditkartojn + + Administri kartojn Aldoni adreson Administri adresojn Konservi kaj aŭtomate plenigi adresojn + + Konservi kaj aŭtomate plenigi adresojn Inkluzivi informojn kiel numerojn, retpoŝtajn kaj liverajn adresojn + + Telefonnumeroj kaj retpoŝtaj adresoj inkluzivitaj + Aldoni kreditkarton @@ -1830,6 +1857,8 @@ Forigi kreditkarton Ĉu vi certe volas forigi tiun ĉi kreditkarton? + + Ĉu forigi karton? Forigi @@ -1844,14 +1873,22 @@ Bonvolu tajpi validan kreditkaran numeron + + Tajpu validan numeron de karto Bonvolu plenigi tiun ĉi kampon + + Aldoni nomon Malŝlosu por vidi viajn konservitajn kreditkartojn Sekurigu viajn kreditkartojn + + Protektu viajn konservitajn pagmetodojn Difinu blokan desegnon, PIN aŭ pasvorton por protekti viajn konservitajn kreditkartojn se iu alia havas vian aparaton. + + Difinu blokan desegnon, PIN aŭ pasvorton por protekti viajn konservitajn pagmetodojn se iu alia havas vian aparaton. Agordi nun @@ -1861,6 +1898,8 @@ Malŝlosu por uzi la konservitan informon pri kreditkartojn + + Malŝlosu por uzi konservitajn pagmetodojn Aldoni adreson @@ -1898,6 +1937,8 @@ Forigi adreson Ĉu vi certe volas forigi tiun ĉi adreson? + + Ĉu forigi tiun ĉi adreson? Forigi @@ -1997,30 +2038,52 @@ Modifi Ĉu vi certe volas forigi tiun ĉi legitimilon? + + Ĉu vi certe volas forigi tiun ĉi pasvorton? Forigi Nuligi Preferoj de komenco de seanco + + Pasvortaj elektebloj La modifebla teksta kampo de la retadreso por komenci seancon. + + La modifebla teksta kampo de la reteja retadreso. La modifebla teksta kampo de la nomo de uzanto por komenci seancon. + + La modifebla teksta kampo de la uzanto. La modifebla teksta kampo de la pasvorto por komenci seancon. + + La modifebla teksta kampo de la pasvorto. Konservi ŝanĝojn je komenco de seanco. + + Konservi ŝanĝojn. Modifi + + Modifi pasvorton Aldoni novan legitimilon + + Aldoni pasvorton Pasvorto postulata + + Tajpu pasvorton Nomo de uzanto postulata + + Tajpu nomon de uzanto Nomo de servilo postulata + + Tajpu retadreson Voĉa serĉo @@ -2119,6 +2182,9 @@ Serĉo de %s + + Ŝanĝi vian norman retumilon + Aŭtomate malfermi ligilon en retejoj, retpoŝtoj kaj mesaĝoj per Firefox. @@ -2193,8 +2259,6 @@ Elstaraĵoj venas el recenzoj de %s, kiujn ni opinias fidindaj kaj okazis dum la lastaj 80 tagoj.]]> Pli da informo pri %s. - - Kiel %s (de Mozilla) determinas la kvaliton de recenzoj kiel %s determinas la kvaliton de recenzoj @@ -2378,6 +2442,8 @@ Traduko Traduko okazas + + Elektu lingvon Okazis problemo dum traduko. Bonvolu provi denove. @@ -2398,6 +2464,10 @@ Neniam traduki %1$s Neniam traduki tiun ĉi retejon + + Superregi ĉiujn aliajn agordojn + + Superregi tradukproponojn Tradukaj agordoj diff --git a/fenix/app/src/main/res/values-is/strings.xml b/fenix/app/src/main/res/values-is/strings.xml index bdb531e46c93..46dd967e512e 100644 --- a/fenix/app/src/main/res/values-is/strings.xml +++ b/fenix/app/src/main/res/values-is/strings.xml @@ -2164,6 +2164,9 @@ %s leit + + Skiptu um sjálfgefinn vafra + Stilltu tengla frá vefsvæðum, tölvupósti og skilaboðum til að opna sjálfkrafa í Firefox. diff --git a/fenix/app/src/main/res/values-ja/strings.xml b/fenix/app/src/main/res/values-ja/strings.xml index 9b75f0b363a5..e7af7cfc386c 100644 --- a/fenix/app/src/main/res/values-ja/strings.xml +++ b/fenix/app/src/main/res/values-ja/strings.xml @@ -248,6 +248,7 @@ ホームページをカスタマイズ + ホーム画面 @@ -255,6 +256,9 @@ 閲覧履歴を消去 + + ページを翻訳 + 選択した言語 @@ -266,8 +270,6 @@ スキャン - - 検索エンジン 検索エンジンの設定 @@ -323,23 +325,28 @@ - 通知は %s を活用するのに役立ちます + 通知は %s を活用するのに役立ちます - 端末間でタブを共有したり、ダウンロードを管理したり、%s のプライバシー保護機能を最大限に活用するためのヒントを入手できます。 + 端末間でタブを共有したり、ダウンロードを管理したり、%s のプライバシー保護機能を最大限に活用するためのヒントを入手できます。 - 続ける + 続ける - 後で + 後で + + Firefox のプライバシー通知 + 私たちはあなたの安全を守りたいと願っています - 非営利で作られた私たちのブラウザーは、企業によるウェブ上の密かな追跡を阻止するのに役立ちます。\n\n詳細はプライバシー通知をご覧ください。 + 非営利で作られた私たちのブラウザーは、企業によるウェブ上の密かな追跡を阻止するのに役立ちます。 + + 非営利で作られた私たちのブラウザーは、企業によるウェブ上の密かな追跡を阻止するのに役立ちます。\n\n詳細はプライバシー通知をご覧ください。 - プライバシー通知 + プライバシー通知 既定のブラウザーに設定 @@ -445,22 +452,11 @@ HTTPS-Only モード - - Cookie バナーの削減 Cookie バナーブロッカー プライベートブラウジングでの Cookie バナーブロッカー - - Cookie バナーを減らす - - オフ - - オン - - - %1$s が自動的に Cookie バナー上の Cookie 要求を拒否しようとします。 このサイトでオフ @@ -479,36 +475,16 @@ 現在サポートされていないサイトです - %1$s で Cookie バナー削減を有効にしますか? - %1$s で Cookie バナーブロッカーをオンにしますか? - %1$s で Cookie バナー削減を無効にしますか? - %1$s で Cookie バナーブロッカーをオフにしますか? %1$s は現在、このサイトの Cookie 使用要求を自動的に拒否できません。このサイトへの対処を要求してください。 - - %1$s はこのサイトの Cookie を消去してページを読み込み直します。すべての Cookie を消去すると、ログアウトしたり、ショッピングカートが空になったりする場合があります。 オフにすると、%1$s に保存された Cookie を消去してこのサイトを再読み込みします。サイトからログアウトしたり、買い物かごが空になったりする場合があります。 - %1$s はサポートされたサイト上の Cookie 要求を自動的に拒否しようとします。 - オンにすると、このサイトのすべての Cookie バナーに対して %1$s が自動的に拒否を試みます。 - - %1$s に Cookie バナーを拒否させますか? - - %1$s は多くの Cookie バナーの同意確認を自動的に拒否できます。 - - 後で - - - Cookie 要求が少なくなります - - - 許可 %1$s が Cookie を拒否しました @@ -726,6 +702,8 @@ ブックマーク ログイン情報 + + パスワード 開いているタブ @@ -752,6 +730,8 @@ クレジットカード情報 + + 支払い方法 住所 @@ -1298,8 +1278,6 @@ 閉じる - 印刷できません - このページを印刷できません 印刷 @@ -1708,8 +1686,12 @@ ログイン情報とパスワード + + パスワード ログイン情報を保存する + + パスワードを保存 保存するか確認する @@ -1727,26 +1709,45 @@ ログイン情報を追加 + + パスワードを追加 + ログイン情報を同期 + + パスワードを同期 端末間でログイン情報を同期します + + 端末間でパスワードを同期 保存されたログイン情報 + + 保存されたパスワード 端末に保存または %s と同期したログイン情報がここに表示されます。 + + %s に保存または同期したパスワードがこのリストに表示されます。保存されたすべてのパスワードは暗号化されます。 Sync についての詳細情報。 + + Sync についての詳細情報 例外 ログイン情報が保存されないサイトがここに表示されます。 + + %s は、このリストに表示されているサイトのパスワードを保存しません。 これらのサイトではログイン情報が保存されません。 + + %s はこれらのサイトのパスワードを保存しません。 すべての例外を削除 ログイン情報を検索 + + パスワードを検索 サイト @@ -1775,10 +1776,16 @@ パスワードを隠す ロック解除して保存されたログイン情報を表示します + + 保存されたパスワードを表示するにはロック解除してください ログイン情報とパスワードの保護 + + 保存されたパスワードを保護してください 端末のロックパターンや PIN、パスワードを設定して、保存されたログイン情報とパスワードを他人の不正なアクセスから保護しましょう。 + + 端末のロックパターンや PIN、パスワードを設定して、保存されたパスワードを他人の不正なアクセスから保護しましょう。 後で @@ -1798,6 +1805,9 @@ ログイン情報メニューの並べ替え + + パスワードを並べ替えます + 自動入力 @@ -1806,18 +1816,28 @@ クレジットカード + + 支払い方法 カード情報を保存して自動入力する + + 支払い方法を保存して入力する データは暗号化されています + + %s は保存したすべての支払い方法を暗号化します 端末間でカード情報を同期する クレジットカード情報を同期 クレジットカードを追加 + + カード情報を追加 保存したカードを管理 + + カード情報を管理 アドレスを追加 @@ -1825,9 +1845,14 @@ アドレスを保存して自動入力する + + 住所を保存して入力する カード番号、メールアドレス、配送先などの情報を含める + + 電話番号とメールアドレスを含みます + カードの追加 @@ -1849,6 +1874,8 @@ カードを削除 本当にこのクレジットカード情報を削除してもよろしいですか? + + カード情報を削除しますか? 削除 @@ -1864,15 +1891,23 @@ 有効なクレジットカード番号を入力してください + + 正しいカード番号を入力してください このフィールドは入力必須です + + 名前を追加してください 保存されたカード情報を表示するにはロック解除してください クレジットカード情報の保護 + + 保存された支払い方法を保護してください 端末のロックパターンや PIN、パスワードを設定して、保存されたクレジットカード情報とパスワードを他人の不正なアクセスから保護しましょう。 + + 端末のロックパターンや PIN、パスワードを設定して、保存された支払い方法を他人の不正なアクセスから保護しましょう。 今すぐ設定 @@ -1883,6 +1918,8 @@ ロックを解除して保存したクレジットカード情報を使用します + + 保存された支払い方法を使用するにはロック解除してください アドレスを追加 @@ -1920,6 +1957,8 @@ 本当にこの住所を削除してもよろしいですか? + + このアドレスを削除しますか? 削除 @@ -2018,6 +2057,8 @@ 編集 このログイン情報を削除してもよろしいですか? + + 本当にこのパスワードを削除してもよろしいですか? 削除 @@ -2025,24 +2066,44 @@ キャンセル ログインオプション + + パスワードのオプション ログイン情報のウェブアドレスの編集可能なテキストフィールド。 + + ウェブサイトのアドレスの編集可能なテキストフィールド。 ログイン情報のユーザー名の編集可能なテキストフィールド。 + + ユーザー名の編集可能なテキストフィールド。 ログイン情報のパスワードの編集可能なテキストフィールド。 + + パスワードの編集可能なテキストフィールド。 変更を保存してログインします。 + + 変更を保存します。 編集 + + パスワードを編集 新しいログイン情報の追加 + + パスワードを追加 パスワードが必要です + + パスワードを入力してください ユーザー名は必須です + + ユーザー名を入力してください ホスト名は必須です + + ウェブアドレスを入力してください 音声検索 @@ -2139,6 +2200,9 @@ %s 検索 + + 既定のブラウザーを変更しませんか + ウェブサイトやメール、メッセージのリンクを自動的に Firefox で開きます。 @@ -2213,8 +2277,6 @@ 注目レビュー は最近 80 日以内の %s からのレビューで私たちが信頼するに足ると評価したものです。]]> %s についての詳細。 - - %s by Mozilla がレビュー品質を決定する方法について %s がレビュー品質を決定する方法について @@ -2400,6 +2462,8 @@ 翻訳中 翻訳中です + + 言語を選択 翻訳時に問題が発生しました。もう一度試してください。 @@ -2420,6 +2484,10 @@ %1$s のページは翻訳しない このサイトは翻訳しない + + 他のすべての設定を上書きします + + 翻訳機能の設定を上書きします 翻訳設定 diff --git a/fenix/app/src/main/res/values-pl/strings.xml b/fenix/app/src/main/res/values-pl/strings.xml index f9642e66f6a2..ae67905ffff8 100644 --- a/fenix/app/src/main/res/values-pl/strings.xml +++ b/fenix/app/src/main/res/values-pl/strings.xml @@ -244,6 +244,7 @@ Dostosuj stronę startową + Strona startowa @@ -251,6 +252,9 @@ Usuń historię przeglądania + + Przetłumacz stronę + Wybrany język @@ -262,8 +266,6 @@ Skanuj - - Wyszukiwarka Ustawienia wyszukiwarki @@ -318,23 +320,28 @@ - Dzięki powiadomieniom lepiej wykorzystasz przeglądarkę %s + Dzięki powiadomieniom lepiej wykorzystasz przeglądarkę %s - Synchronizuj karty między urządzeniami, zarządzaj pobieranymi plikami, otrzymuj wskazówki, jak najlepiej wykorzystać ochronę prywatności w przeglądarce %s i nie tylko. + Synchronizuj karty między urządzeniami, zarządzaj pobieranymi plikami, otrzymuj wskazówki, jak najlepiej wykorzystać ochronę prywatności w przeglądarce %s i nie tylko. - Kontynuuj + Kontynuuj - Nie teraz + Nie teraz + + Zasady ochrony prywatności Firefoksa + Uwielbiamy zapewniać Ci bezpieczeństwo - Nasza przeglądarka wspierana przez organizację non-profit pomaga powstrzymywać firmy przed potajemnym śledzeniem Cię w Internecie.\n\nWięcej informacji znajdziesz w naszych zasadach ochrony prywatności. + Nasza przeglądarka wspierana przez organizację non-profit pomaga powstrzymywać firmy przed potajemnym śledzeniem Cię w Internecie. + + Nasza przeglądarka wspierana przez organizację non-profit pomaga powstrzymywać firmy przed potajemnym śledzeniem Cię w Internecie.\n\nWięcej informacji znajdziesz w naszych zasadach ochrony prywatności. - zasadach ochrony prywatności + zasadach ochrony prywatności Ustaw jako domyślną przeglądarkę @@ -438,21 +445,11 @@ Tryb używania wyłącznie protokołu HTTPS - - Ograniczanie informacji o ciasteczkach Blokowanie informacji o ciasteczkach Blokowanie informacji o ciasteczkach w trybie prywatnym - - Ograniczanie informacji o ciasteczkach - - Wyłączone - - Włączone - - - %1$s automatycznie próbuje odrzucać prośby o akceptację ciasteczek. + Wyłączone na tej witrynie @@ -470,36 +467,17 @@ Witryna obecnie nie jest obsługiwana - Włączyć ograniczanie informacji o ciasteczkach na witrynie %1$s? - Włączyć blokowanie informacji o ciasteczkach na witrynie %1$s? - - Wyłączyć ograniczanie informacji o ciasteczkach na witrynie %1$s? Wyłączyć blokowanie informacji o ciasteczkach na witrynie %1$s? %1$s nie może automatycznie odrzucać próśb o akceptację ciasteczek na tej witrynie. Można wysłać prośbę o dodanie obsługi tej witryny w przyszłości. - - %1$s usunie ciasteczka tej witryny i odświeży stronę. Usunięcie wszystkich ciasteczek może spowodować wylogowanie ze strony lub opróżnienie koszyka w sklepie. Wyłącz, a %1$s usunie ciasteczka i ponownie wczyta tę stronę. Może to spowodować wylogowanie ze strony lub opróżnienie koszyka w sklepie. - %1$s próbuje automatycznie odrzucać wszystkie prośby o akceptację ciasteczek na obsługiwanych witrynach. - Włącz, a %1$s spróbuje automatycznie odrzucać wszystkie prośby o akceptację ciasteczek na tej witrynie. - - Pozwolić przeglądarce %1$s odrzucać prośby o akceptację ciasteczek? - - %1$s może automatycznie odrzucać wiele próśb o akceptację ciasteczek. - - Nie teraz - - Będziesz widzieć mniej próśb o akceptację ciasteczek - - - Pozwól %1$s właśnie odrzucił ciasteczka za Ciebie @@ -718,6 +696,8 @@ Zakładki Dane logowania + + Hasła Otwarte karty @@ -746,6 +726,8 @@ Karty płatnicze + + Metody płatności Adresy @@ -1284,8 +1266,6 @@ Zamknij - Nie można wydrukować - Nie można wydrukować tej strony Drukuj @@ -1693,8 +1673,12 @@ Dane logowania i hasła + + Hasła Zachowywanie danych logowania i haseł + + Zachowywanie haseł Pytanie o zachowanie @@ -1711,26 +1695,45 @@ Dodaj dane logowania + + Dodaj hasło + Synchronizowanie danych logowania + + Synchronizowanie haseł - Synchronizuj karty między urządzeniami + Synchronizuj dane logowania między urządzeniami + + Synchronizuj hasła między urządzeniami Zachowane dane logowania + + Zachowane hasła Zachowane lub synchronizowane z przeglądarką %s dane logowania będą wyświetlane w tym miejscu. + + Tutaj będą wyświetlane hasła zachowane lub synchronizowane w przeglądarce %s. Wszystkie zachowywane hasła są zaszyfrowane. Więcej informacji o synchronizacji. + + Więcej informacji o synchronizacji Wyjątki Tutaj będą wyświetlane dane logowania i hasła, które nie będą zachowywane. + + %s nie będzie zachowywać haseł do wymienionych tutaj witryn. Dane logowania i hasła dla tych witryn nie będą zachowywane. + + %s nie będzie zachowywać haseł do tych witryn. Usuń wszystkie wyjątki Szukaj danych logowania + + Szukaj haseł Witryna @@ -1759,10 +1762,16 @@ Ukryj hasło Odblokuj, aby wyświetlić zachowane dane logowania + + Odblokuj, aby wyświetlić zachowane hasła Zabezpiecz dane logowania i hasła + + Zabezpiecz zachowane hasła Skonfiguruj wzór blokady, kod PIN lub hasło, aby ochronić zachowane dane logowania i hasła w przypadku, gdy ktoś inny uzyska dostęp do urządzenia. + + Skonfiguruj wzór blokady, kod PIN lub hasło, aby ochronić zachowane hasła w przypadku, gdy ktoś inny uzyska dostęp do urządzenia. Później @@ -1781,6 +1790,9 @@ Menu sortowania danych logowania + + Menu sortowania haseł + Automatyczne wypełnianie @@ -1789,10 +1801,16 @@ Karty płatnicze + + Metody płatności Zachowywanie i automatyczne wypełnianie kart + + Zachowywanie i wypełnianie metod płatności Dane są zaszyfrowane + + %s szyfruje wszystkie zachowywane metody płatności Synchronizuj karty między urządzeniami @@ -1800,8 +1818,12 @@ Dodaj kartę płatniczą + + Dodaj kartę Zarządzaj zachowanymi kartami + + Zarządzaj kartami Dodaj adres @@ -1809,9 +1831,14 @@ Zachowywanie i automatyczne wypełnianie adresów + + Zachowywanie i wypełnianie adresów Zawiera informacje takie jak numery, adresy e-mail i adresy wysyłki + + W tym numery telefonów i adresy e-mail + Dodaj kartę @@ -1832,6 +1859,8 @@ Usuń kartę Czy na pewno usunąć tę kartę płatniczą? + + Czy usunąć kartę? Usuń @@ -1846,14 +1875,22 @@ Wprowadź prawidłowy numer karty płatniczej + + Podaj prawidłowy numer karty Wypełnij to pole + + Dodaj imię i nazwisko Odblokuj, aby wyświetlić zachowane karty Zabezpiecz karty płatnicze + + Zabezpiecz zachowane metody płatności Skonfiguruj wzór blokady, kod PIN lub hasło, aby ochronić zachowane karty płatnicze w przypadku, gdy ktoś inny uzyska dostęp do urządzenia. + + Skonfiguruj wzór blokady, kod PIN lub hasło, aby ochronić zachowane metody płatności w przypadku, gdy ktoś inny uzyska dostęp do urządzenia. Skonfiguruj teraz @@ -1864,6 +1901,8 @@ Odblokuj, aby użyć przechowywanych informacji o kartach płatniczych + + Odblokuj, aby użyć zachowanych metod płatności Dodaj adres @@ -1900,6 +1939,8 @@ Usuń adres Czy na pewno usunąć ten adres? + + Czy usunąć ten adres? Usuń @@ -1998,30 +2039,52 @@ Edytuj Czy na pewno usunąć te dane logowania? + + Czy na pewno usunąć to hasło? Usuń Anuluj Opcje danych logowania + + Opcje haseł Edytowalne pole tekstowe dla adresu witryny danych logowania. + + Edytowalne pole tekstowe dla adresu witryny. Edytowalne pole tekstowe dla nazwy użytkownika danych logowania. + + Edytowalne pole tekstowe dla nazwy użytkownika. Edytowalne pole tekstowe dla hasła danych logowania. + + Edytowalne pole tekstowe dla hasła. - Zapisz zmiany danych logowania. + Zachowaj zmiany danych logowania. + + Zachowaj zmiany. Edycja + + Edycja hasła Dodanie nowych danych logowania + + Dodanie hasła Hasło jest wymagane + + Wpisz hasło Nazwa użytkownika jest wymagana + + Wpisz nazwę użytkownika Adres jest wymagany + + Wpisz adres witryny Wyszukiwanie głosowe @@ -2117,6 +2180,9 @@ Szukaj w %s + + Przełącz domyślną przeglądarkę + Ustaw automatyczne otwieranie odnośników z witryn, wiadomości e-mail i SMS-ów w Firefoksie. @@ -2206,6 +2272,8 @@ Tłumaczenie Trwa tłumaczenie + + Wybierz język Wystąpił problem przy tłumaczeniu. Spróbuj ponownie. @@ -2226,6 +2294,10 @@ Nigdy nie tłumacz tego języka (%1$s) Nigdy nie tłumacz tej witryny + + Zastępuje wszystkie pozostałe ustawienia + + Zastępuje propozycje tłumaczenia Ustawienia tłumaczenia diff --git a/fenix/app/src/main/res/values-rm/strings.xml b/fenix/app/src/main/res/values-rm/strings.xml index efa79cba3148..c5c40892d4d4 100644 --- a/fenix/app/src/main/res/values-rm/strings.xml +++ b/fenix/app/src/main/res/values-rm/strings.xml @@ -1698,20 +1698,32 @@ Infurmaziuns d\'annunzia memorisadas + + Pleds-clav memorisads Las infurmaziuns d\'annunzia che ti memoriseschas u sincroniseschas cun %s vegnan mussadas qua. + + Ils pleds-clav che ti memoriseschas en u sincroniseschas cun %s vegnan mussads qua. Tut ils pleds-clav che ti memoriseschas èn criptads. Vegnir a savair dapli davart Sync. + + Vegnir a savair dapli davart la sincronisaziun Excepziuns Las infurmaziuns d\'annunzia ed ils pleds-clav betg memorisads vegnan mussadas qua. + + %s na vegn betg a memorisar pleds-clav per websites inditgadas qua. Las infurmaziuns d\'annunzia ed ils pleds-clav na vegnan betg memorisads per questas paginas. + + %s na vegn betg a memorisar pleds-clav per questas websites. Stizzar tut las excepziuns Tschertgar datas d\'annunzia + + Tschertgar en ils pleds-clav Website @@ -1741,11 +1753,17 @@ Zuppentar il pled-clav Debloccar per vesair las infurmaziuns d\'annunzia memorisadas + + Debloccar per vesair tes pleds-clav memorisads Protegia las infurmaziuns d\'annunzia ed ils pleds-clav + + Protegia tes pleds-clav memorisads Definescha in muster per debloccar l\'apparat, in PIN u in pled-clav per proteger tias infurmaziuns d\'annunzia e tes pleds-clav da persunas che han access a tes apparat. + + Endrizza in muster per bloccar l’apparat, in PIN u pled-clav per evitar ch’ina autra persuna possia acceder a tes pleds-clav memorisads sch’ella ha tes apparat. Pli tard @@ -1764,6 +1782,9 @@ Zavrar il menu da las datas d\'annunzia + + Menu per zavrar ils pleds-clav + Endataziun automatica @@ -1771,10 +1792,16 @@ Adressas Cartas da credit + + Metodas da pajament Emplenir automaticamain las datas da la carta da credit + + Memorisar ed endatar automaticamain las metodas da pajament Las datas èn criptadas + + %s criptescha tut las metodas da pajament che ti memoriseschas Sincronisar las cartas tranter ils apparats @@ -1782,17 +1809,26 @@ Agiuntar ina carta da credit + + Agiuntar ina carta Administrar las cartas memorisadas + + Administrar las cartas Agiuntar ina adressa Administrar las adressas Memorisar ed emplenir automaticamain las adressas + + Memorisar ed endatar automaticamain las adressas Includer infurmaziuns sco numers, adressas dad e-mail ed adressas postalas + + Cuntegna numers da telefon ed adressas dad e-mail + Agiuntar ina carta @@ -1813,6 +1849,8 @@ Stizzar la carta Vuls ti propi stizzar questa carta da credit? + + Stizzar la carta? Stizzar @@ -1827,14 +1865,22 @@ Endatescha per plaschair in numer da carta da credit valid + + Endatescha in numer da carta valid Emplenescha per plaschair quest champ + + Agiuntescha in num Debloccar per vesair tias cartas memorisadas Protegia tias cartas da credit + + Protegia tias metodas da pajament memorisadas Endrizza in muster per bloccar l\'apparat, in PIN u pled-clav per evitar ch\'ina autra persuna possia acceder a tias cartas da credit memorisadas sch\'ella ha tes apparat. + + Endrizza in muster per bloccar l\'apparat, in PIN u pled-clav per evitar ch’ina autra persuna possia acceder a tias metodas da pajament memorisadas sch’ella ha tes apparat. Ussa endrizzar @@ -1845,6 +1891,8 @@ Debloccar per utilisar las datas da cartas da credit memorisadas + + Debloccar per utilisar las metodas da pajament memorisadas Agiuntar ina adressa @@ -1882,6 +1930,8 @@ Vuls ti propi stizzar questa adressa? + + Stizzar questa adressa? Stizzar @@ -1980,6 +2030,8 @@ Modifitgar Vuls ti propi stizzar questa infurmaziun d\'annunzia? + + Vuls ti propi stizzar quest pled-clav? Stizzar @@ -1987,24 +2039,44 @@ Interrumper Opziuns per datas d\'annunzia + + Opziuns da pleds-clav Il champ modifitgabel per l\'adressa web da las datas d\'annunzia. + + Il champ da text modifitgabel per l’adressa da la website. Il champ modifitgabel per il num d\'utilisader da las datas d\'annunzia. + + Il champ da text modifitgabel per il num d’utilisader. Il champ modifitgabel per il pled-clav da las datas d\'annunzia. + + Il champ da text modifitgabel per il pled-clav. Memorisar las midadas da las datas d\'annunzia. + + Memorisar las midadas. Modifitgar + + Modifitgar il pled-clav Agiuntar novas datas d\'annunzia + + Agiuntar in pled-clav Pled-clav obligatoric + + Endatar in pled-clav Num d\'utilisader obligatoric + + Endatar in num d’utilisader Num dal server obligatoric + + Endatar ina adressa web Tschertga vocala @@ -2099,6 +2171,9 @@ Tschertga %s + + + Mida tes navigatur standard Definescha che colliaziuns da websites, e-mails e messadis vegnan averts automaticamain en Firefox. @@ -2354,6 +2429,8 @@ Translatar Translaziun en elavuraziun + + Tscherner ina lingua Igl ha dà in problem cun translatar. Emprova per plaschair anc ina giada. @@ -2374,6 +2451,10 @@ Mai translatar %1$s Mai translatar questa website + + Remplazza tut ils auters parameters + + Remplazza las offertas da translaziun Parameters da translaziun diff --git a/fenix/app/src/main/res/values-tg/strings.xml b/fenix/app/src/main/res/values-tg/strings.xml index 4eaf14fdb39c..4ae0da3cfc30 100644 --- a/fenix/app/src/main/res/values-tg/strings.xml +++ b/fenix/app/src/main/res/values-tg/strings.xml @@ -1715,6 +1715,8 @@ Ниҳонвожаҳои нигоҳдошташуда Воридшавиҳое, ки шумо дар %s нигоҳ медоред ё ҳамоҳанг мекунед, дар ин ҷо нишон дода мешаванд. + + Ниҳонвожаҳоеро, ки шумо нигоҳ медоред ё бо «%s» ҳамоҳанг месозед, дар ин рӯйхат нишон дода мешаванд. Ҳамаи ниҳонвожаҳое, ки шумо нигоҳ медоред, рамзгузорӣ карда мешаванд. Маълумоти бештар дар бораи ҳамоҳангсозӣ @@ -1723,8 +1725,12 @@ Истисноҳо Воридшавиҳо ва ниҳонвожаҳое, ки нигоҳ дошта нашудаанд, дар ин ҷо нишон дошта мешаванд. + + «%s» барои сомонаҳое, ки дар ин рӯйхат нишон дода шудаанд, ниҳонвожаҳоро нигоҳ намедорад. Воридшавиҳо ва ниҳонвожаҳо барои сомонаҳои зерин нигоҳ дошта намешаванд. + + «%s» барои сомонаҳои зерин ниҳонвожаҳоро нигоҳ намедорад. Нест кардани ҳамаи истисноҳо @@ -1759,8 +1765,12 @@ Пинҳон кардани ниҳонвожа Барои дидани воридшавиҳои нигоҳдошташуда, қулфро кушоед + + Барои дидани ниҳонвожаҳои нигоҳдошташуда, қулфро кушоед Воридшавиҳо ва ниҳонвожаҳои худро муҳофизат намоед + + Ниҳонвожаҳои нигоҳдоштаро муҳофизат намоед Барои муҳофизат кардани воридшавиҳо ва ниҳонвожаҳои худ аз дастрасии озод, агар касе дигар аз дастгоҳи шумо истифода барад, шаклвораи қулфи экран, рамзи PIN ё ниҳонвожаеро барои дастгоҳи худ танзим намоед. @@ -1804,14 +1814,20 @@ Илова кардани корти кредитӣ + + Илова кардани корт Идора кардани кортҳои нигоҳдошташуда + + Идоракунии кортҳо Илова кардани нишонӣ Идоракунии нишониҳо Нигоҳ доштан ва ба таври худкор пур кардани нишониҳо + + Нигоҳ доштан ва пур кардани нишониҳо Илова кардани маълумот монанди рақамҳо, нишониҳои почтаи электронӣ ва бурдарасонӣ @@ -1836,6 +1852,8 @@ Нест кардани корт Шумо мутмаин ҳастед, ки мехоҳед ин корти кредитиро нест намоед? + + Кортро нест мекунед? Нест кардан @@ -1851,8 +1869,12 @@ Лутфан, рақами корти кредитии дурустро ворид намоед + + Рақами корти дурустро ворид намоед Лутфан, ин майдонро пур кунед + + Номеро ворид намоед Барои дидани кортҳои нигоҳдошташуда, қулфро кушоед @@ -1905,6 +1927,8 @@ Шумо мутмаин ҳастед, ки мехоҳед ин нишониро нест намоед? + + Ин нишониро нест мекунед? Нест кардан @@ -2002,12 +2026,16 @@ Таҳрир кардан Шумо мутмаин ҳастед, ки мехоҳед ин воридшавиро нест намоед? + + Шумо мутмаин ҳастед, ки мехоҳед ин ниҳонвожаро нест намоед? Нест кардан Бекор кардан Имконоти воридшавӣ + + Инконоти ниҳонвожа Майдони матни таҳриршаванда барои нишонии сомонаи воридшавӣ. @@ -2016,17 +2044,29 @@ Майдони матни таҳриршаванда барои ниҳонвожаи воридшавӣ. Нигоҳ доштани тағйирот барои воридшавӣ + + Тағийротро нигоҳ медорад. Таҳрир кардан + + Таҳрир кардани ниҳонвожа Илова кардани воридшавии нав + + Илова кардани ниҳонвожа Ниҳонвожа лозим аст + + Ниҳонвожаеро ворид намоед Номи корбар лозим аст + + Номи корбареро ворид намоед Номи сервер лозим аст + + Нишонии сомонаеро ворид намоед Ҷустуҷӯи овозӣ @@ -2123,6 +2163,9 @@ Ҷустуҷӯ дар «%s» + + Гузоштан ба браузери пешфарзи худ + Пайвандҳоеро, танзим кунед, то ки онҳо аз сомонаҳо, почтаи электронӣ ва паёмҳо дар браузери «Firefox» ба таври худкор кушода шаванд. @@ -2380,6 +2423,8 @@ Дар ҳоли тарҷума қарор дорад + + Забонеро интихоб кунед Ҳангоми тарҷума мушкилие ба миён омад. Лутфан, аз нав кӯшиш кунед. @@ -2401,6 +2446,10 @@ %1$s ҳеҷ вақт тарҷума карда нашавад Ин сомона ҳеҷ гоҳ тарҷума карда нашавад + + Ҳамаи танзимоти дигарро иваз мекунад + + Пешниҳодҳоро барои тарҷума иваз мекунад Танзимоти сомона diff --git a/fenix/app/src/main/res/values-tr/strings.xml b/fenix/app/src/main/res/values-tr/strings.xml index 927f22503d6f..c273ae92ea24 100644 --- a/fenix/app/src/main/res/values-tr/strings.xml +++ b/fenix/app/src/main/res/values-tr/strings.xml @@ -2177,6 +2177,9 @@ %s araması + + Varsayılan tarayıcınızı değiştirin + Web siteleri, e-postalar ve mesajlardaki bağlantılar otomatik olarak Firefox’ta açılsın. diff --git a/focus-android/app/src/main/res/values-eo/strings.xml b/focus-android/app/src/main/res/values-eo/strings.xml index 422afe3c34bd..66c8d9dc1735 100644 --- a/focus-android/app/src/main/res/values-eo/strings.xml +++ b/focus-android/app/src/main/res/values-eo/strings.xml @@ -54,7 +54,6 @@ Forigi el ŝparvojoj - Novaĵoj Agordoj Pri Helpo @@ -85,10 +84,9 @@ sharing an URL. --> Dividi per - + Ĉu viŝi retuman historion? + Tuŝetu aŭ viŝu tiun ĉi sciigon por sekure viŝi vian retuman historion. + Forviŝi retuman historion diff --git a/focus-android/app/src/main/res/values-pl/strings.xml b/focus-android/app/src/main/res/values-pl/strings.xml index ed2d1f76fae7..28c036d45641 100644 --- a/focus-android/app/src/main/res/values-pl/strings.xml +++ b/focus-android/app/src/main/res/values-pl/strings.xml @@ -53,7 +53,6 @@ Usuń ze skrótów - Co nowego Ustawienia O programie Pomoc @@ -84,10 +83,9 @@ sharing an URL. --> Udostępnij przez - + Usunąć historię przeglądania? + Stuknij lub wyczyść to powiadomienie, aby bezpiecznie usunąć historię przeglądania. + Usuń historię przeglądania @@ -290,7 +288,7 @@ Blokowanie śledzących reklam Niektóre reklamy (nawet niekliknięte) śledzą odwiedziny zawierających je stron Blokowanie śledzących statystyk - Używane do zbierania, analizowania i mierzenia działań użytkownika, takich jak kliknięcia i przewijanie + Używane do zbierania, analizowania i mierzenia działań użytkownika, takich jak stuknięcia i przewijanie Blokowanie śledzących społecznościowych Osadzane na stronach, aby śledzić ich odwiedziny i dodawać np. przyciski udostępniania Blokowanie pozostałych śledzących From d22515b8d250c05f81b65a717bc2f0e35834e6a0 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Mon, 12 Feb 2024 00:48:31 +0000 Subject: [PATCH 159/586] Update GeckoView (Nightly) to 124.0.20240211213657. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 6151e8e4691c..1d336b896ce4 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240211090343" + const val version = "124.0.20240211213657" /** * GeckoView channel From 3e2edae7de1ca04a3a2a11c73fda5fc366948d88 Mon Sep 17 00:00:00 2001 From: iorgamgabriel Date: Tue, 6 Feb 2024 15:06:58 +0200 Subject: [PATCH 160/586] Bug 1876140 - Translations UI Dropdown Checkmark --- .../java/org/mozilla/fenix/compose/Menu.kt | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/compose/Menu.kt b/fenix/app/src/main/java/org/mozilla/fenix/compose/Menu.kt index 68acd450bef8..2d1d5cbe148b 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/compose/Menu.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/compose/Menu.kt @@ -6,11 +6,15 @@ package org.mozilla.fenix.compose import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.DropdownMenu import androidx.compose.material.DropdownMenuItem +import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable @@ -24,8 +28,11 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.semantics.Role import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp +import org.mozilla.fenix.R import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.compose.button.PrimaryButton import org.mozilla.fenix.theme.FirefoxTheme @@ -62,14 +69,51 @@ private fun Menu( .background(color = FirefoxTheme.colors.layer2) .then(modifier), ) { + val hasCheckedItems = menuItems.any { it.isChecked } + for (item in menuItems) { + val checkmarkModifier = if (hasCheckedItems) { + Modifier.selectable( + selected = item.isChecked, + role = Role.Button, + onClick = { + onDismissRequest() + item.onClick() + }, + ) + } else { + Modifier + } + DropdownMenuItem( - modifier = Modifier.testTag(item.testTag), + modifier = Modifier + .testTag(item.testTag) + .align(alignment = Alignment.CenterHorizontally) + .then(checkmarkModifier), onClick = { onDismissRequest() item.onClick() }, ) { + if (hasCheckedItems) { + if (item.isChecked) { + Icon( + painter = painterResource(id = R.drawable.mozac_ic_checkmark_24), + modifier = Modifier + .size(24.dp), + contentDescription = null, + tint = FirefoxTheme.colors.iconPrimary, + ) + } else { + Spacer( + modifier = Modifier + .size(24.dp), + ) + } + + Spacer(modifier = Modifier.width(12.dp)) + } + Text( text = item.title, color = item.color ?: FirefoxTheme.colors.textPrimary, @@ -117,12 +161,14 @@ fun ContextualMenu( * * @property title Text the item should display. * @property color Color used to display the text. + * @property isChecked Whether a checkmark should appear next to the text. * @property testTag Tag used to identify the item in automated tests. * @property onClick Callback to be called when the item is clicked. */ data class MenuItem( val title: String, val color: Color? = null, + val isChecked: Boolean = false, val testTag: String = "", val onClick: () -> Unit, ) From cd5b5497c88e2a703f7a8734315d705de5dc472b Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Fri, 9 Feb 2024 11:02:40 +0200 Subject: [PATCH 161/586] Bug 1816066 - Fix verifyMultipleLoginsSelectionsTest UI test --- .../java/org/mozilla/fenix/helpers/TestAssetHelper.kt | 1 + .../java/org/mozilla/fenix/helpers/TestHelper.kt | 7 +++++++ .../androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt index d638e762f634..fb90e772f380 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt @@ -17,6 +17,7 @@ object TestAssetHelper { val waitingTime: Long = TimeUnit.SECONDS.toMillis(15) val waitingTimeLong = TimeUnit.SECONDS.toMillis(25) val waitingTimeShort: Long = TimeUnit.SECONDS.toMillis(3) + val waitingTimeVeryShort: Long = TimeUnit.SECONDS.toMillis(1) data class TestAsset(val url: Uri, val content: String, val title: String) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt index a1f415a5cfc4..2a06b0990458 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt @@ -39,6 +39,7 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort +import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeVeryShort import org.mozilla.fenix.helpers.ext.waitNotNull import org.mozilla.fenix.ui.robots.clickPageObject @@ -142,4 +143,10 @@ object TestHelper { assertFalse("Light theme not selected", expected) fun verifyDarkThemeApplied(expected: Boolean) = assertTrue("Dark theme not selected", expected) + + fun waitForAppWindowToBeUpdated() { + Log.i(TAG, "waitForAppWindowToBeUpdated: Waiting for $waitingTimeVeryShort ms for $packageName window to be updated") + mDevice.waitForWindowUpdate(packageName, waitingTimeVeryShort) + Log.i(TAG, "waitForAppWindowToBeUpdated: Waited for $waitingTimeVeryShort ms for $packageName window to be updated") + } } diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt index a725fd33dbb9..3dcdd96cdf4b 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt @@ -28,6 +28,7 @@ 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.TestHelper.verifySnackBarText +import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.clearTextFieldItem import org.mozilla.fenix.ui.robots.clickPageObject @@ -260,12 +261,16 @@ class LoginsTest { navigationToolbar { }.enterURLAndEnterToBrowser(loginPage.toUri()) { setPageObjectText(itemWithResId("username"), firstUser) + waitForAppWindowToBeUpdated() setPageObjectText(itemWithResId("password"), firstPass) + waitForAppWindowToBeUpdated() clickPageObject(itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() clickPageObject(itemWithText("Save")) setPageObjectText(itemWithResId("username"), secondUser) + waitForAppWindowToBeUpdated() setPageObjectText(itemWithResId("password"), secondPass) + waitForAppWindowToBeUpdated() clickPageObject(itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() clickPageObject(itemWithText("Save")) From 97fd5abb21c87f8856afcd657ba9014ac538f260 Mon Sep 17 00:00:00 2001 From: Jonathan Almeida Date: Thu, 18 Jan 2024 15:51:53 -0700 Subject: [PATCH 162/586] Bug 1875379 - Update Private notification description text --- .../org/mozilla/focus/session/SessionNotificationService.kt | 2 +- focus-android/app/src/main/res/values/strings.xml | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/focus-android/app/src/main/java/org/mozilla/focus/session/SessionNotificationService.kt b/focus-android/app/src/main/java/org/mozilla/focus/session/SessionNotificationService.kt index 875ec3b03635..0360d3017929 100644 --- a/focus-android/app/src/main/java/org/mozilla/focus/session/SessionNotificationService.kt +++ b/focus-android/app/src/main/java/org/mozilla/focus/session/SessionNotificationService.kt @@ -108,7 +108,7 @@ class SessionNotificationService : Service() { } val contentText = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - getString(R.string.notification_erase_text_android_14) + getString(R.string.notification_erase_text_android_14_1) } else { getString(R.string.notification_erase_text) } diff --git a/focus-android/app/src/main/res/values/strings.xml b/focus-android/app/src/main/res/values/strings.xml index fb0275eb5397..20aa1234291f 100644 --- a/focus-android/app/src/main/res/values/strings.xml +++ b/focus-android/app/src/main/res/values/strings.xml @@ -86,7 +86,11 @@ Share via Erase browsing history? - Tap or clear this notification to securely erase your browsing history. + Tap or clear this notification to securely erase your browsing history. + + + Tap or swipe this notification to securely erase your browsing history. Erase browsing history From 09592e559a82cd366243455624038ed3f8a3858d Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Wed, 26 Jul 2023 14:56:25 +0300 Subject: [PATCH 163/586] Bug 1845496 - Upgrade Kotlin and compose compiler. Also upgrade Kotlin related libraries: coroutines, serialisation and ksp. upgrade --- .../dependencies/src/main/java/DependenciesPlugin.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt index 44340909cd8d..878bea815397 100644 --- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt +++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt @@ -14,9 +14,9 @@ class DependenciesPlugin : Plugin { // Synchronized version numbers for dependencies used by (some) modules object Versions { - const val kotlin = "1.8.22" - const val coroutines = "1.7.2" - const val serialization = "1.5.1" + const val kotlin = "1.9.22" + const val coroutines = "1.7.3" + const val serialization = "1.6.0" const val python_envs_plugin = "0.0.31" const val junit = "4.13.2" @@ -47,13 +47,13 @@ object Versions { const val mozilla_glean = "56.1.0" const val material = "1.9.0" - const val ksp = "1.0.11" + const val ksp = "1.0.17" val ksp_plugin = "$kotlin-$ksp" // see https://android-developers.googleblog.com/2022/06/independent-versioning-of-Jetpack-Compose-libraries.html // for Jetpack Compose libraries versioning const val compose_version = "1.5.4" - const val compose_compiler = "1.4.8" + const val compose_compiler = "1.5.8" object AndroidX { const val activityCompose = "1.7.2" From 13ee3dfb4fdf9a9fb97d8ffdfecf2d8e547f158f Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Thu, 10 Aug 2023 18:51:42 +0300 Subject: [PATCH 164/586] Bug 1847999 - Upgrade Room to latest version. --- .../plugins/dependencies/src/main/java/DependenciesPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt index 878bea815397..18dcb3366171 100644 --- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt +++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt @@ -74,7 +74,7 @@ object Versions { const val test_ext = "1.1.5" const val test_runner = "1.5.2" const val espresso = "3.5.1" - const val room = "2.5.2" + const val room = "2.6.1" const val savedstate = "1.2.1" const val paging = "3.2.1" const val palette = "1.0.0" From 433bd7adbd35207595b4e884ef8ebcff0ab18b6b Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Thu, 10 Aug 2023 18:53:03 +0300 Subject: [PATCH 165/586] Bug 1847999 - Switch to generating Kotlin code for Room. --- android-components/components/feature/addons/build.gradle | 1 + android-components/components/feature/containers/build.gradle | 1 + android-components/components/feature/downloads/build.gradle | 1 + android-components/components/feature/logins/build.gradle | 1 + android-components/components/feature/pwa/build.gradle | 1 + .../components/feature/recentlyclosed/build.gradle | 1 + android-components/components/feature/share/build.gradle | 1 + .../components/feature/sitepermissions/build.gradle | 1 + .../components/feature/tab-collections/build.gradle | 1 + android-components/components/feature/top-sites/build.gradle | 1 + android-components/components/service/pocket/build.gradle | 1 + 11 files changed, 11 insertions(+) diff --git a/android-components/components/feature/addons/build.gradle b/android-components/components/feature/addons/build.gradle index 48dacf68b8b9..b6bd5641cd3b 100644 --- a/android-components/components/feature/addons/build.gradle +++ b/android-components/components/feature/addons/build.gradle @@ -18,6 +18,7 @@ android { ksp { arg("room.schemaLocation", "$projectDir/schemas".toString()) + arg("room.generateKotlin", "true") } javaCompileOptions { diff --git a/android-components/components/feature/containers/build.gradle b/android-components/components/feature/containers/build.gradle index f035e5dc27bf..9ebb3289dbd5 100644 --- a/android-components/components/feature/containers/build.gradle +++ b/android-components/components/feature/containers/build.gradle @@ -15,6 +15,7 @@ android { ksp { arg("room.schemaLocation", "$projectDir/schemas".toString()) + arg("room.generateKotlin", "true") } javaCompileOptions { diff --git a/android-components/components/feature/downloads/build.gradle b/android-components/components/feature/downloads/build.gradle index 4519d283ee72..1072c051b14f 100644 --- a/android-components/components/feature/downloads/build.gradle +++ b/android-components/components/feature/downloads/build.gradle @@ -19,6 +19,7 @@ android { ksp { arg("room.schemaLocation", "$projectDir/schemas".toString()) + arg("room.generateKotlin", "true") } } diff --git a/android-components/components/feature/logins/build.gradle b/android-components/components/feature/logins/build.gradle index 9e3cb034301d..fd4febbe3264 100644 --- a/android-components/components/feature/logins/build.gradle +++ b/android-components/components/feature/logins/build.gradle @@ -15,6 +15,7 @@ android { ksp { arg("room.schemaLocation", "$projectDir/schemas".toString()) + arg("room.generateKotlin", "true") } } diff --git a/android-components/components/feature/pwa/build.gradle b/android-components/components/feature/pwa/build.gradle index 0920617b1486..5d8b90b313fe 100644 --- a/android-components/components/feature/pwa/build.gradle +++ b/android-components/components/feature/pwa/build.gradle @@ -17,6 +17,7 @@ android { ksp { arg("room.schemaLocation", "$projectDir/schemas".toString()) + arg("room.generateKotlin", "true") } javaCompileOptions { diff --git a/android-components/components/feature/recentlyclosed/build.gradle b/android-components/components/feature/recentlyclosed/build.gradle index 8258b9471420..586afb1edc84 100644 --- a/android-components/components/feature/recentlyclosed/build.gradle +++ b/android-components/components/feature/recentlyclosed/build.gradle @@ -15,6 +15,7 @@ android { ksp { arg("room.schemaLocation", "$projectDir/schemas".toString()) + arg("room.generateKotlin", "true") } javaCompileOptions { diff --git a/android-components/components/feature/share/build.gradle b/android-components/components/feature/share/build.gradle index 103693cc6b99..a44df774e16c 100644 --- a/android-components/components/feature/share/build.gradle +++ b/android-components/components/feature/share/build.gradle @@ -15,6 +15,7 @@ android { ksp { arg("room.schemaLocation", "$projectDir/schemas".toString()) + arg("room.generateKotlin", "true") } javaCompileOptions { diff --git a/android-components/components/feature/sitepermissions/build.gradle b/android-components/components/feature/sitepermissions/build.gradle index 0215b84542cf..06fa58246b87 100644 --- a/android-components/components/feature/sitepermissions/build.gradle +++ b/android-components/components/feature/sitepermissions/build.gradle @@ -19,6 +19,7 @@ android { ksp { arg("room.schemaLocation", "$projectDir/schemas".toString()) + arg("room.generateKotlin", "true") } javaCompileOptions { diff --git a/android-components/components/feature/tab-collections/build.gradle b/android-components/components/feature/tab-collections/build.gradle index 9ad2d6f74384..74cd5c76b720 100644 --- a/android-components/components/feature/tab-collections/build.gradle +++ b/android-components/components/feature/tab-collections/build.gradle @@ -15,6 +15,7 @@ android { ksp { arg("room.schemaLocation", "$projectDir/schemas".toString()) + arg("room.generateKotlin", "true") } javaCompileOptions { diff --git a/android-components/components/feature/top-sites/build.gradle b/android-components/components/feature/top-sites/build.gradle index 0dbac23deef4..236137605152 100644 --- a/android-components/components/feature/top-sites/build.gradle +++ b/android-components/components/feature/top-sites/build.gradle @@ -15,6 +15,7 @@ android { ksp { arg("room.schemaLocation", "$projectDir/schemas".toString()) + arg("room.generateKotlin", "true") } javaCompileOptions { diff --git a/android-components/components/service/pocket/build.gradle b/android-components/components/service/pocket/build.gradle index 416ddaf8741f..2835723a988b 100644 --- a/android-components/components/service/pocket/build.gradle +++ b/android-components/components/service/pocket/build.gradle @@ -15,6 +15,7 @@ android { ksp { arg("room.schemaLocation", "$projectDir/schemas".toString()) + arg("room.generateKotlin", "true") } } From cadfde47b4a9729734b06fa9331ce62cc7edc2b5 Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Thu, 10 Aug 2023 18:58:30 +0300 Subject: [PATCH 166/586] Bug 1847999 - Rename param to match supertype. The supertype param was changed in Room 2.6.0 --- .../feature/downloads/db/DownloadsDatabase.kt | 18 ++++---- .../feature/pwa/db/ManifestDatabase.kt | 18 ++++---- .../feature/share/db/RecentAppsDatabase.kt | 6 +-- .../db/SitePermissionsDatabase.kt | 46 +++++++++---------- .../feature/top/sites/db/TopSiteDatabase.kt | 18 ++++---- .../db/PocketRecommendationsDatabase.kt | 32 ++++++------- 6 files changed, 69 insertions(+), 69 deletions(-) diff --git a/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/db/DownloadsDatabase.kt b/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/db/DownloadsDatabase.kt index 16405ef2c67f..9adabfe9cdb1 100644 --- a/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/db/DownloadsDatabase.kt +++ b/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/db/DownloadsDatabase.kt @@ -48,29 +48,29 @@ internal abstract class DownloadsDatabase : RoomDatabase() { @Suppress("MaxLineLength", "MagicNumber") internal object Migrations { val migration_1_2 = object : Migration(1, 2) { - override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL( + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL( "ALTER TABLE downloads ADD COLUMN is_private INTEGER NOT NULL DEFAULT 0", ) } } val migration_2_3 = object : Migration(2, 3) { - override fun migrate(database: SupportSQLiteDatabase) { + override fun migrate(db: SupportSQLiteDatabase) { // Create a temporal table - database.execSQL("CREATE TABLE temp_downloads (`id` TEXT NOT NULL, `url` TEXT NOT NULL, `file_name` TEXT, `content_type` TEXT, `content_length` INTEGER, `status` INTEGER NOT NULL, `destination_directory` TEXT NOT NULL, `created_at` INTEGER NOT NULL, PRIMARY KEY(`id`))") + db.execSQL("CREATE TABLE temp_downloads (`id` TEXT NOT NULL, `url` TEXT NOT NULL, `file_name` TEXT, `content_type` TEXT, `content_length` INTEGER, `status` INTEGER NOT NULL, `destination_directory` TEXT NOT NULL, `created_at` INTEGER NOT NULL, PRIMARY KEY(`id`))") // Copy the data - database.execSQL("INSERT INTO temp_downloads (id,url,file_name,content_type,content_length,status,destination_directory,created_at) SELECT id,url,file_name,content_type,content_length,status,destination_directory,created_at FROM downloads where is_private = 0") + db.execSQL("INSERT INTO temp_downloads (id,url,file_name,content_type,content_length,status,destination_directory,created_at) SELECT id,url,file_name,content_type,content_length,status,destination_directory,created_at FROM downloads where is_private = 0") // Remove the old table - database.execSQL("DROP TABLE downloads") + db.execSQL("DROP TABLE downloads") // Rename the table name to the correct one - database.execSQL("ALTER TABLE temp_downloads RENAME TO downloads") + db.execSQL("ALTER TABLE temp_downloads RENAME TO downloads") } } val migration_3_4 = object : Migration(3, 4) { - override fun migrate(database: SupportSQLiteDatabase) { + override fun migrate(db: SupportSQLiteDatabase) { // Clear any data urls. - database.execSQL("UPDATE downloads SET url='' WHERE url LIKE 'data:%' ") + db.execSQL("UPDATE downloads SET url='' WHERE url LIKE 'data:%' ") } } } diff --git a/android-components/components/feature/pwa/src/main/java/mozilla/components/feature/pwa/db/ManifestDatabase.kt b/android-components/components/feature/pwa/src/main/java/mozilla/components/feature/pwa/db/ManifestDatabase.kt index f47670c876b7..fdf36d57346b 100644 --- a/android-components/components/feature/pwa/src/main/java/mozilla/components/feature/pwa/db/ManifestDatabase.kt +++ b/android-components/components/feature/pwa/src/main/java/mozilla/components/feature/pwa/db/ManifestDatabase.kt @@ -27,28 +27,28 @@ internal abstract class ManifestDatabase : RoomDatabase() { @VisibleForTesting internal val MIGRATION_1_2: Migration = object : Migration(1, 2) { - override fun migrate(database: SupportSQLiteDatabase) { - val cursor = database.query("SELECT * FROM manifests LIMIT 0,1") + override fun migrate(db: SupportSQLiteDatabase) { + val cursor = db.query("SELECT * FROM manifests LIMIT 0,1") if (cursor.getColumnIndex("used_at") < 0) { - database.execSQL("ALTER TABLE manifests ADD COLUMN used_at INTEGER NOT NULL DEFAULT 0") + db.execSQL("ALTER TABLE manifests ADD COLUMN used_at INTEGER NOT NULL DEFAULT 0") } if (cursor.getColumnIndex("scope") < 0) { - database.execSQL("ALTER TABLE manifests ADD COLUMN scope TEXT") + db.execSQL("ALTER TABLE manifests ADD COLUMN scope TEXT") } - database.execSQL("CREATE INDEX IF NOT EXISTS index_manifests_scope ON manifests (scope)") - database.execSQL("UPDATE manifests SET used_at = updated_at WHERE used_at = 0") + db.execSQL("CREATE INDEX IF NOT EXISTS index_manifests_scope ON manifests (scope)") + db.execSQL("UPDATE manifests SET used_at = updated_at WHERE used_at = 0") } } @VisibleForTesting internal val MIGRATION_2_3: Migration = object : Migration(2, 3) { - override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("ALTER TABLE manifests ADD COLUMN has_share_targets INTEGER NOT NULL DEFAULT 0") + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL("ALTER TABLE manifests ADD COLUMN has_share_targets INTEGER NOT NULL DEFAULT 0") - database.execSQL( + db.execSQL( "CREATE INDEX IF NOT EXISTS index_manifests_has_share_targets ON manifests (has_share_targets)", ) } diff --git a/android-components/components/feature/share/src/main/java/mozilla/components/feature/share/db/RecentAppsDatabase.kt b/android-components/components/feature/share/src/main/java/mozilla/components/feature/share/db/RecentAppsDatabase.kt index bf648220a4fc..d554bd320986 100644 --- a/android-components/components/feature/share/src/main/java/mozilla/components/feature/share/db/RecentAppsDatabase.kt +++ b/android-components/components/feature/share/src/main/java/mozilla/components/feature/share/db/RecentAppsDatabase.kt @@ -45,9 +45,9 @@ internal abstract class RecentAppsDatabase : RoomDatabase() { internal object Migrations { val migration_1_2 = object : Migration(1, 2) { - override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("DROP TABLE RECENT_APPS_TABLE") - database.execSQL( + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL("DROP TABLE RECENT_APPS_TABLE") + db.execSQL( "CREATE TABLE IF NOT EXISTS " + RECENT_APPS_TABLE + "(" + "`activityName` TEXT NOT NULL, " + diff --git a/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDatabase.kt b/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDatabase.kt index ab474c763353..bdf82b53e53a 100644 --- a/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDatabase.kt +++ b/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDatabase.kt @@ -82,12 +82,12 @@ internal class StatusConverter { internal object Migrations { val migration_1_2 = object : Migration(1, 2) { - override fun migrate(database: SupportSQLiteDatabase) { + override fun migrate(db: SupportSQLiteDatabase) { // Version 1 is used in Nightly builds of Fenix, but not in production. Let's just skip actually migrating // anything and let's re-create the "site_permissions" table. - database.execSQL("DROP TABLE site_permissions") - database.execSQL( + db.execSQL("DROP TABLE site_permissions") + db.execSQL( "CREATE TABLE IF NOT EXISTS `site_permissions` (" + "`origin` TEXT NOT NULL, " + "`location` INTEGER NOT NULL, " + @@ -104,19 +104,19 @@ internal object Migrations { @Suppress("MagicNumber") val migration_2_3 = object : Migration(2, 3) { - override fun migrate(database: SupportSQLiteDatabase) { - val haveAutoPlayColumns = database.query("SELECT * FROM site_permissions").columnCount == 10 + override fun migrate(db: SupportSQLiteDatabase) { + val haveAutoPlayColumns = db.query("SELECT * FROM site_permissions").columnCount == 10 // We just want to apply this migration for user that do not have // the new autoplay fields autoplay_audible and autoplay_inaudible if (!haveAutoPlayColumns) { - database.execSQL( + db.execSQL( "ALTER TABLE site_permissions ADD COLUMN autoplay_audible INTEGER NOT NULL DEFAULT ''", ) - database.execSQL( + db.execSQL( "ALTER TABLE site_permissions ADD COLUMN autoplay_inaudible INTEGER NOT NULL DEFAULT ''", ) - database.execSQL( + db.execSQL( " UPDATE site_permissions" + " SET autoplay_audible = -1, " + // BLOCKED by default " `autoplay_inaudible` = 1", // ALLOWED by default @@ -127,33 +127,33 @@ internal object Migrations { @Suppress("MagicNumber") val migration_3_4 = object : Migration(3, 4) { - override fun migrate(database: SupportSQLiteDatabase) { - val hasEmeColumn = database.query("SELECT * FROM site_permissions").columnCount == 11 + override fun migrate(db: SupportSQLiteDatabase) { + val hasEmeColumn = db.query("SELECT * FROM site_permissions").columnCount == 11 if (!hasEmeColumn) { - database.execSQL( + db.execSQL( "ALTER TABLE site_permissions ADD COLUMN media_key_system_access INTEGER NOT NULL DEFAULT 0", ) // default is NO_DECISION - database.execSQL("UPDATE site_permissions SET media_key_system_access = 0") + db.execSQL("UPDATE site_permissions SET media_key_system_access = 0") } } } @Suppress("MagicNumber") val migration_4_5 = object : Migration(4, 5) { - override fun migrate(database: SupportSQLiteDatabase) { + override fun migrate(db: SupportSQLiteDatabase) { // Updating any previous autoplay sites with 0 (NO_DECISION) with the supported values // Autoplay permission doesn't support 0 (NO_DECISION), // it only supports 1 (ALLOWED) or -1 (BLOCKED) - database.execSQL("UPDATE site_permissions SET autoplay_audible = -1 WHERE autoplay_audible = 0 ") - database.execSQL("UPDATE site_permissions SET autoplay_inaudible = 1 WHERE autoplay_inaudible = 0 ") + db.execSQL("UPDATE site_permissions SET autoplay_audible = -1 WHERE autoplay_audible = 0 ") + db.execSQL("UPDATE site_permissions SET autoplay_inaudible = 1 WHERE autoplay_inaudible = 0 ") } } @Suppress("MagicNumber") val migration_5_6 = object : Migration(5, 6) { - override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL( + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL( "UPDATE site_permissions SET origin = 'https://'||origin||':443'", ) } @@ -161,12 +161,12 @@ internal object Migrations { @Suppress("MagicNumber") val migration_6_7 = object : Migration(6, 7) { - override fun migrate(database: SupportSQLiteDatabase) { + override fun migrate(db: SupportSQLiteDatabase) { // Update any site with our previous default value (block audio and video) to block audio only. // autoplay_audible BLOCKED (-1) and autoplay_inaudible BLOCKED (-1) to // autoplay_audible BLOCKED (-1) and autoplay_inaudible ALLOWED (1) // This match the default value of desktop block audio only. - database.execSQL( + db.execSQL( "UPDATE site_permissions SET autoplay_audible = -1, autoplay_inaudible= 1 " + "WHERE autoplay_audible = -1 AND autoplay_inaudible = -1", ) @@ -175,14 +175,14 @@ internal object Migrations { @Suppress("MagicNumber") val migration_7_8 = object : Migration(7, 8) { - override fun migrate(database: SupportSQLiteDatabase) { - val hasCrossOriginStorageAccessColumn = database.query("SELECT * FROM site_permissions").columnCount == 12 + override fun migrate(db: SupportSQLiteDatabase) { + val hasCrossOriginStorageAccessColumn = db.query("SELECT * FROM site_permissions").columnCount == 12 if (!hasCrossOriginStorageAccessColumn) { - database.execSQL( + db.execSQL( "ALTER TABLE site_permissions ADD COLUMN cross_origin_storage_access INTEGER NOT NULL DEFAULT 0", ) // default is NO_DECISION - database.execSQL("UPDATE site_permissions SET cross_origin_storage_access = 0") + db.execSQL("UPDATE site_permissions SET cross_origin_storage_access = 0") } } } diff --git a/android-components/components/feature/top-sites/src/main/java/mozilla/components/feature/top/sites/db/TopSiteDatabase.kt b/android-components/components/feature/top-sites/src/main/java/mozilla/components/feature/top/sites/db/TopSiteDatabase.kt index 78202bcf6097..59aa469f5463 100644 --- a/android-components/components/feature/top-sites/src/main/java/mozilla/components/feature/top/sites/db/TopSiteDatabase.kt +++ b/android-components/components/feature/top-sites/src/main/java/mozilla/components/feature/top/sites/db/TopSiteDatabase.kt @@ -43,15 +43,15 @@ internal abstract class TopSiteDatabase : RoomDatabase() { internal object Migrations { val migration_1_2 = object : Migration(1, 2) { - override fun migrate(database: SupportSQLiteDatabase) { + override fun migrate(db: SupportSQLiteDatabase) { // Add the new is_default column and set is_default to 0 (false) for every entry. - database.execSQL( + db.execSQL( "ALTER TABLE top_sites ADD COLUMN is_default INTEGER NOT NULL DEFAULT 0", ) // Prior to version 2, pocket top sites, wikipedia and youtube were added as default // sites in Fenix. Look for these entries and set is_default to 1 (true). - database.execSQL( + db.execSQL( "UPDATE top_sites " + "SET is_default = 1 " + "WHERE url IN " + @@ -64,9 +64,9 @@ internal object Migrations { @Suppress("MagicNumber") val migration_2_3 = object : Migration(2, 3) { - override fun migrate(database: SupportSQLiteDatabase) { + override fun migrate(db: SupportSQLiteDatabase) { // Create a temporary top sites table of version 1. - database.execSQL( + db.execSQL( "CREATE TABLE IF NOT EXISTS `top_sites_temp` (" + "`id` INTEGER PRIMARY KEY AUTOINCREMENT, " + "`title` TEXT NOT NULL, " + @@ -76,25 +76,25 @@ internal object Migrations { ) // Insert every entry from the old table into the temporary top sites table. - database.execSQL( + db.execSQL( "INSERT INTO top_sites_temp (title, url, created_at, is_default) " + "SELECT title, url, created_at, 0 FROM top_sites", ) // Assume there are consumers of version 2 with the mismatched isDefault and is_default // column name. Drop the old table. - database.execSQL( + db.execSQL( "DROP TABLE top_sites", ) // Rename the temporary table to top_sites. - database.execSQL( + db.execSQL( "ALTER TABLE top_sites_temp RENAME TO top_sites", ) // Prior to version 2, pocket top sites, wikipedia and youtube were added as default // sites in Fenix. Look for these entries and set isDefault to 1 (true). - database.execSQL( + db.execSQL( "UPDATE top_sites " + "SET is_default = 1 " + "WHERE url IN " + diff --git a/android-components/components/service/pocket/src/main/java/mozilla/components/service/pocket/stories/db/PocketRecommendationsDatabase.kt b/android-components/components/service/pocket/src/main/java/mozilla/components/service/pocket/stories/db/PocketRecommendationsDatabase.kt index 7f37091d5d2b..5a3e4f0efee4 100644 --- a/android-components/components/service/pocket/src/main/java/mozilla/components/service/pocket/stories/db/PocketRecommendationsDatabase.kt +++ b/android-components/components/service/pocket/src/main/java/mozilla/components/service/pocket/stories/db/PocketRecommendationsDatabase.kt @@ -62,8 +62,8 @@ internal abstract class PocketRecommendationsDatabase : RoomDatabase() { internal object Migrations { val migration_1_2 = object : Migration(1, 2) { - override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL( + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL( "CREATE TABLE IF NOT EXISTS " + "`${PocketRecommendationsDatabase.TABLE_NAME_SPOCS}` (" + "`url` TEXT NOT NULL, " + @@ -82,15 +82,15 @@ internal object Migrations { * Migration for when adding support for pacing sponsored stories. */ val migration_2_3 = object : Migration(2, 3) { - override fun migrate(database: SupportSQLiteDatabase) { + override fun migrate(db: SupportSQLiteDatabase) { // There are many new columns added. Drop the old table allowing to start fresh. // This migration is expected to only be needed in debug builds // with the feature not being live in any Fenix release. - database.execSQL( + db.execSQL( "DROP TABLE ${PocketRecommendationsDatabase.TABLE_NAME_SPOCS}", ) - database.createNewSpocsTables() + db.createNewSpocsTables() } } @@ -98,8 +98,8 @@ internal object Migrations { * Migration for when adding sponsored stories along with pacing support. */ val migration_1_3 = object : Migration(1, 3) { - override fun migrate(database: SupportSQLiteDatabase) { - database.createNewSpocsTables() + override fun migrate(db: SupportSQLiteDatabase) { + db.createNewSpocsTables() } } @@ -107,26 +107,26 @@ internal object Migrations { * Migration for when adding a new index to the spoc impression entity. */ val migration_3_4 = object : Migration(3, 4) { - override fun migrate(database: SupportSQLiteDatabase) { + override fun migrate(db: SupportSQLiteDatabase) { // Rename the old tables to allow creating new ones - database.execSQL( + db.execSQL( "ALTER TABLE `${PocketRecommendationsDatabase.TABLE_NAME_SPOCS}` " + "RENAME TO temp_spocs", ) - database.execSQL( + db.execSQL( "ALTER TABLE `${PocketRecommendationsDatabase.TABLE_NAME_SPOCS_IMPRESSIONS}` " + "RENAME TO temp_spocs_impressions", ) // Create new tables with the new schema - database.createNewSpocsTables() - database.execSQL( + db.createNewSpocsTables() + db.execSQL( "CREATE INDEX IF NOT EXISTS `index_spocs_impressions_spocId` " + "ON `${PocketRecommendationsDatabase.TABLE_NAME_SPOCS_IMPRESSIONS}` (`spocId`)", ) // Copy the old data to the new tables - database.execSQL( + db.execSQL( "INSERT INTO " + "'${PocketRecommendationsDatabase.TABLE_NAME_SPOCS}' (" + "id, url, title, imageUrl, sponsor, clickShim, impressionShim, " + @@ -136,7 +136,7 @@ internal object Migrations { "priority, lifetimeCapCount, flightCapCount, flightCapPeriod " + "FROM temp_spocs", ) - database.execSQL( + db.execSQL( "INSERT INTO " + "'${PocketRecommendationsDatabase.TABLE_NAME_SPOCS_IMPRESSIONS}' (" + "spocId, impressionId, impressionDateInSeconds" + @@ -146,8 +146,8 @@ internal object Migrations { ) // Cleanup - database.execSQL("DROP TABLE temp_spocs") - database.execSQL("DROP TABLE temp_spocs_impressions") + db.execSQL("DROP TABLE temp_spocs") + db.execSQL("DROP TABLE temp_spocs_impressions") } } From ad0a5144729b4f9823814681e6555b2df0f55666 Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Thu, 10 Aug 2023 20:40:46 +0300 Subject: [PATCH 167/586] Bug 1847999 - Switch to using non-deprecated constructor for MigrationTestHelper. --- .../feature/downloads/OnDeviceDownloadStorageTest.kt | 5 +---- .../components/feature/logins/LoginExceptionStorageTest.kt | 5 +---- .../feature/pwa/db/ManifestDatabaseMigrationTest.kt | 5 +---- .../sitepermissions/db/OnDeviceSitePermissionsStorageTest.kt | 5 +---- .../feature/top/sites/OnDevicePinnedSitesStorageTest.kt | 5 +---- .../pocket/stories/db/PocketRecommendationsDatabaseTest.kt | 5 +---- 6 files changed, 6 insertions(+), 24 deletions(-) diff --git a/android-components/components/feature/downloads/src/androidTest/java/mozilla/components/feature/downloads/OnDeviceDownloadStorageTest.kt b/android-components/components/feature/downloads/src/androidTest/java/mozilla/components/feature/downloads/OnDeviceDownloadStorageTest.kt index bcfd2577f2ed..e7c689b4f032 100644 --- a/android-components/components/feature/downloads/src/androidTest/java/mozilla/components/feature/downloads/OnDeviceDownloadStorageTest.kt +++ b/android-components/components/feature/downloads/src/androidTest/java/mozilla/components/feature/downloads/OnDeviceDownloadStorageTest.kt @@ -7,7 +7,6 @@ package mozilla.components.feature.downloads import android.content.Context import androidx.room.Room import androidx.room.testing.MigrationTestHelper -import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import androidx.test.core.app.ApplicationProvider import androidx.test.platform.app.InstrumentationRegistry import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -32,11 +31,9 @@ class OnDeviceDownloadStorageTest { private lateinit var database: DownloadsDatabase @get:Rule - @Suppress("DEPRECATION") val helper: MigrationTestHelper = MigrationTestHelper( InstrumentationRegistry.getInstrumentation(), - DownloadsDatabase::class.java.canonicalName, - FrameworkSQLiteOpenHelperFactory(), + DownloadsDatabase::class.java, ) @Before diff --git a/android-components/components/feature/logins/src/androidTest/java/mozilla/components/feature/logins/LoginExceptionStorageTest.kt b/android-components/components/feature/logins/src/androidTest/java/mozilla/components/feature/logins/LoginExceptionStorageTest.kt index 6ee5a3566b70..749ee0b82f15 100644 --- a/android-components/components/feature/logins/src/androidTest/java/mozilla/components/feature/logins/LoginExceptionStorageTest.kt +++ b/android-components/components/feature/logins/src/androidTest/java/mozilla/components/feature/logins/LoginExceptionStorageTest.kt @@ -8,7 +8,6 @@ import android.content.Context import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.room.Room import androidx.room.testing.MigrationTestHelper -import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import androidx.test.core.app.ApplicationProvider import androidx.test.platform.app.InstrumentationRegistry import kotlinx.coroutines.flow.first @@ -37,11 +36,9 @@ class LoginExceptionStorageTest { var instantTaskExecutorRule = InstantTaskExecutorRule() @get:Rule - @Suppress("DEPRECATION") val helper: MigrationTestHelper = MigrationTestHelper( InstrumentationRegistry.getInstrumentation(), - LoginExceptionStorage::class.java.canonicalName, - FrameworkSQLiteOpenHelperFactory(), + LoginExceptionDatabase::class.java, ) @Before diff --git a/android-components/components/feature/pwa/src/androidTest/java/mozilla/components/feature/pwa/db/ManifestDatabaseMigrationTest.kt b/android-components/components/feature/pwa/src/androidTest/java/mozilla/components/feature/pwa/db/ManifestDatabaseMigrationTest.kt index 7bfcfab6f528..00659e3af23d 100644 --- a/android-components/components/feature/pwa/src/androidTest/java/mozilla/components/feature/pwa/db/ManifestDatabaseMigrationTest.kt +++ b/android-components/components/feature/pwa/src/androidTest/java/mozilla/components/feature/pwa/db/ManifestDatabaseMigrationTest.kt @@ -6,7 +6,6 @@ package mozilla.components.feature.pwa.db import androidx.core.database.getStringOrNull import androidx.room.testing.MigrationTestHelper -import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import androidx.test.platform.app.InstrumentationRegistry import org.junit.Assert.assertEquals import org.junit.Assert.assertNull @@ -20,11 +19,9 @@ class ManifestDatabaseMigrationTest { @Rule @JvmField - @Suppress("DEPRECATION") val helper: MigrationTestHelper = MigrationTestHelper( InstrumentationRegistry.getInstrumentation(), - ManifestDatabase::class.java.canonicalName, - FrameworkSQLiteOpenHelperFactory(), + ManifestDatabase::class.java, ) @Test diff --git a/android-components/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/OnDeviceSitePermissionsStorageTest.kt b/android-components/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/OnDeviceSitePermissionsStorageTest.kt index cb057593b446..83b2a5a04250 100644 --- a/android-components/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/OnDeviceSitePermissionsStorageTest.kt +++ b/android-components/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/OnDeviceSitePermissionsStorageTest.kt @@ -8,7 +8,6 @@ import android.content.Context import androidx.core.net.toUri import androidx.room.Room import androidx.room.testing.MigrationTestHelper -import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import androidx.test.core.app.ApplicationProvider import androidx.test.platform.app.InstrumentationRegistry import kotlinx.coroutines.test.runTest @@ -34,11 +33,9 @@ class OnDeviceSitePermissionsStorageTest { private lateinit var database: SitePermissionsDatabase @get:Rule - @Suppress("DEPRECATION") val helper: MigrationTestHelper = MigrationTestHelper( InstrumentationRegistry.getInstrumentation(), - SitePermissionsDatabase::class.java.canonicalName, - FrameworkSQLiteOpenHelperFactory(), + SitePermissionsDatabase::class.java, ) @Before diff --git a/android-components/components/feature/top-sites/src/androidTest/java/mozilla/components/feature/top/sites/OnDevicePinnedSitesStorageTest.kt b/android-components/components/feature/top-sites/src/androidTest/java/mozilla/components/feature/top/sites/OnDevicePinnedSitesStorageTest.kt index a4d15b3c2742..ac5563190d6b 100644 --- a/android-components/components/feature/top-sites/src/androidTest/java/mozilla/components/feature/top/sites/OnDevicePinnedSitesStorageTest.kt +++ b/android-components/components/feature/top-sites/src/androidTest/java/mozilla/components/feature/top/sites/OnDevicePinnedSitesStorageTest.kt @@ -8,7 +8,6 @@ import android.content.Context import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.room.Room import androidx.room.testing.MigrationTestHelper -import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import androidx.test.core.app.ApplicationProvider import androidx.test.platform.app.InstrumentationRegistry import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -38,11 +37,9 @@ class OnDevicePinnedSitesStorageTest { var instantTaskExecutorRule = InstantTaskExecutorRule() @get:Rule - @Suppress("DEPRECATION") val helper: MigrationTestHelper = MigrationTestHelper( InstrumentationRegistry.getInstrumentation(), - TopSiteDatabase::class.java.canonicalName, - FrameworkSQLiteOpenHelperFactory(), + TopSiteDatabase::class.java, ) @Before diff --git a/android-components/components/service/pocket/src/androidTest/java/mozilla/components/service/pocket/stories/db/PocketRecommendationsDatabaseTest.kt b/android-components/components/service/pocket/src/androidTest/java/mozilla/components/service/pocket/stories/db/PocketRecommendationsDatabaseTest.kt index fed7f5ff6831..f31f41a31899 100644 --- a/android-components/components/service/pocket/src/androidTest/java/mozilla/components/service/pocket/stories/db/PocketRecommendationsDatabaseTest.kt +++ b/android-components/components/service/pocket/src/androidTest/java/mozilla/components/service/pocket/stories/db/PocketRecommendationsDatabaseTest.kt @@ -8,7 +8,6 @@ import android.content.Context import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.room.Room import androidx.room.testing.MigrationTestHelper -import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import androidx.test.core.app.ApplicationProvider import androidx.test.platform.app.InstrumentationRegistry import kotlinx.coroutines.runBlocking @@ -31,11 +30,9 @@ class PocketRecommendationsDatabaseTest { private lateinit var database: PocketRecommendationsDatabase @get:Rule - @Suppress("DEPRECATION") val helper: MigrationTestHelper = MigrationTestHelper( InstrumentationRegistry.getInstrumentation(), - PocketRecommendationsDatabase::class.java.canonicalName, - FrameworkSQLiteOpenHelperFactory(), + PocketRecommendationsDatabase::class.java, ) @get:Rule From 2917efdabbad9e4840b58ba3d248e8f433b0c20c Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Fri, 9 Feb 2024 15:14:40 +0200 Subject: [PATCH 168/586] Bug 1879539 - Remove redundant assertion functions from LibrarySubMenusMultipleSelectionToolbarRobot --- ...rySubMenusMultipleSelectionToolbarRobot.kt | 93 +++++++------------ 1 file changed, 31 insertions(+), 62 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt index a86f8802efab..3c675bf05e8b 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt @@ -34,27 +34,46 @@ import org.mozilla.fenix.tabstray.TabsTrayTestTag */ class LibrarySubMenusMultipleSelectionToolbarRobot { - fun verifyMultiSelectionCheckmark() = assertMultiSelectionCheckmark() - - fun verifyMultiSelectionCheckmark(url: Uri) = assertMultiSelectionCheckmark(url) + fun verifyMultiSelectionCheckmark() = onView(withId(R.id.checkmark)).check(matches(isDisplayed())) + + fun verifyMultiSelectionCheckmark(url: Uri) = + onView( + allOf( + withId(R.id.checkmark), + withParent(withParent(withChild(allOf(withId(R.id.url), withText(url.toString()))))), + + // This is used as part of the `multiSelectionToolbarItemsTest` test. Somehow, in the view hierarchy, + // the match above is finding two checkmark views - one visible, one hidden, which is throwing off + // the matcher. This 'isDisplayed' check is a hacky workaround for this, we're explicitly ignoring + // the hidden one. Why are there two to begin with, though? + isDisplayed(), + ), + ).check(matches(isDisplayed())) - fun verifyMultiSelectionCounter() = assertMultiSelectionCounter() + fun verifyMultiSelectionCounter() = onView(withText("1 selected")).check(matches(isDisplayed())) - fun verifyShareHistoryButton() = assertShareHistoryButton() + fun verifyShareHistoryButton() = shareHistoryButton().check(matches(isDisplayed())) - fun verifyShareBookmarksButton() = assertShareBookmarksButton() + fun verifyShareBookmarksButton() = shareBookmarksButton().check(matches(isDisplayed())) - fun verifyShareOverlay() = assertShareOverlay() + fun verifyShareOverlay() = onView(withId(R.id.shareWrapper)).check(matches(isDisplayed())) - fun verifyShareAppsLayout() = assertShareAppsLayout() + fun verifyShareAppsLayout() { + val sendToDeviceTitle = mDevice.findObject( + UiSelector() + .instance(0) + .className(TextView::class.java), + ) + sendToDeviceTitle.waitForExists(TestAssetHelper.waitingTime) + } - fun verifyShareTabFavicon() = assertShareTabFavicon() + fun verifyShareTabFavicon() = onView(withId(R.id.share_tab_favicon)).check(matches(isDisplayed())) - fun verifyShareTabTitle() = assertShareTabTitle() + fun verifyShareTabTitle() = onView(withId(R.id.share_tab_title)).check(matches(isDisplayed())) - fun verifyShareTabUrl() = assertShareTabUrl() + fun verifyShareTabUrl() = onView(withId(R.id.share_tab_url)) - fun verifyCloseToolbarButton() = assertCloseToolbarButton() + fun verifyCloseToolbarButton() = closeToolbarButton().check(matches(isDisplayed())) fun clickShareHistoryButton() { shareHistoryButton().click() @@ -157,53 +176,3 @@ private fun openInNewTabButton() = onView(withText("Open in new tab")) private fun openInPrivateTabButton() = onView(withText("Open in private tab")) private fun deleteButton() = onView(withText("Delete")) - -private fun assertMultiSelectionCheckmark() = - onView(withId(R.id.checkmark)) - .check(matches(isDisplayed())) - -private fun assertMultiSelectionCheckmark(url: Uri) = - onView( - allOf( - withId(R.id.checkmark), - withParent(withParent(withChild(allOf(withId(R.id.url), withText(url.toString()))))), - - // This is used as part of the `multiSelectionToolbarItemsTest` test. Somehow, in the view hierarchy, - // the match above is finding two checkmark views - one visible, one hidden, which is throwing off - // the matcher. This 'isDisplayed' check is a hacky workaround for this, we're explicitly ignoring - // the hidden one. Why are there two to begin with, though? - isDisplayed(), - ), - ) - .check(matches(isDisplayed())) - -private fun assertMultiSelectionCounter() = - onView(withText("1 selected")).check(matches(isDisplayed())) - -private fun assertShareHistoryButton() = - shareHistoryButton().check(matches(isDisplayed())) - -private fun assertShareBookmarksButton() = - shareBookmarksButton().check(matches(isDisplayed())) - -private fun assertShareOverlay() = - onView(withId(R.id.shareWrapper)).check(matches(isDisplayed())) - -private fun assertShareAppsLayout() = { - val sendToDeviceTitle = mDevice.findObject( - UiSelector() - .instance(0) - .className(TextView::class.java), - ) - sendToDeviceTitle.waitForExists(TestAssetHelper.waitingTime) -} - -private fun assertShareTabTitle() = - onView(withId(R.id.share_tab_title)).check(matches(isDisplayed())) - -private fun assertShareTabFavicon() = - onView(withId(R.id.share_tab_favicon)).check(matches(isDisplayed())) - -private fun assertShareTabUrl() = onView(withId(R.id.share_tab_url)) - -private fun assertCloseToolbarButton() = closeToolbarButton().check(matches(isDisplayed())) From 0a504515ce8e3d2ae66bf1933e1a92f0582cdfec Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Fri, 9 Feb 2024 15:41:26 +0200 Subject: [PATCH 169/586] Bug 1879539 - Add test logs to LibrarySubMenusMultipleSelectionToolbarRobot --- ...rySubMenusMultipleSelectionToolbarRobot.kt | 94 ++++++++++++++++--- 1 file changed, 83 insertions(+), 11 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt index 3c675bf05e8b..1e65807a09cb 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.ui.robots import android.net.Uri +import android.util.Log import android.widget.TextView import androidx.compose.ui.test.onNodeWithTag import androidx.test.espresso.Espresso.onView @@ -20,6 +21,8 @@ import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import org.hamcrest.Matchers.allOf import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.Constants +import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.HomeActivityComposeTestRule import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime @@ -34,13 +37,27 @@ import org.mozilla.fenix.tabstray.TabsTrayTestTag */ class LibrarySubMenusMultipleSelectionToolbarRobot { - fun verifyMultiSelectionCheckmark() = onView(withId(R.id.checkmark)).check(matches(isDisplayed())) + fun verifyMultiSelectionCheckmark() { + Log.i(TAG, "verifyMultiSelectionCheckmark: Trying to verify that the multi-selection checkmark is displayed") + onView(withId(R.id.checkmark)).check(matches(isDisplayed())) + Log.i(TAG, "verifyMultiSelectionCheckmark: Verified that the multi-selection checkmark is displayed") + } - fun verifyMultiSelectionCheckmark(url: Uri) = + fun verifyMultiSelectionCheckmark(url: Uri) { + Log.i(TAG, "verifyMultiSelectionCheckmark: Trying to verify that the multi-selection checkmark for item with url: $url is displayed") onView( allOf( withId(R.id.checkmark), - withParent(withParent(withChild(allOf(withId(R.id.url), withText(url.toString()))))), + withParent( + withParent( + withChild( + allOf( + withId(R.id.url), + withText(url.toString()), + ), + ), + ), + ), // This is used as part of the `multiSelectionToolbarItemsTest` test. Somehow, in the view hierarchy, // the match above is finding two checkmark views - one visible, one hidden, which is throwing off @@ -49,14 +66,32 @@ class LibrarySubMenusMultipleSelectionToolbarRobot { isDisplayed(), ), ).check(matches(isDisplayed())) + Log.i(Constants.TAG, "verifyMultiSelectionCheckmark: Verified that the multi-selection checkmark for item with url: $url is displayed") + } - fun verifyMultiSelectionCounter() = onView(withText("1 selected")).check(matches(isDisplayed())) + fun verifyMultiSelectionCounter() { + Log.i(TAG, "verifyMultiSelectionCounter: Trying to verify that the multi-selection toolbar containing: \"1 selected\" is displayed") + onView(withText("1 selected")).check(matches(isDisplayed())) + Log.i(TAG, "verifyMultiSelectionCounter: Verified that the multi-selection toolbar containing: \"1 selected\" is displayed") + } - fun verifyShareHistoryButton() = shareHistoryButton().check(matches(isDisplayed())) + fun verifyShareHistoryButton() { + Log.i(TAG, "verifyShareHistoryButton: Trying to verify that the multi-selection share history button is displayed") + shareHistoryButton().check(matches(isDisplayed())) + Log.i(TAG, "verifyShareHistoryButton: Verified that the multi-selection share history button is displayed") + } - fun verifyShareBookmarksButton() = shareBookmarksButton().check(matches(isDisplayed())) + fun verifyShareBookmarksButton() { + Log.i(TAG, "verifyShareBookmarksButton: Trying to verify that the multi-selection share bookmarks button is displayed") + shareBookmarksButton().check(matches(isDisplayed())) + Log.i(TAG, "verifyShareBookmarksButton: Verified that the multi-selection share bookmarks button is displayed") + } - fun verifyShareOverlay() = onView(withId(R.id.shareWrapper)).check(matches(isDisplayed())) + fun verifyShareOverlay() { + Log.i(TAG, "verifyShareOverlay: Trying to verify that the share overlay is displayed") + onView(withId(R.id.shareWrapper)).check(matches(isDisplayed())) + Log.i(TAG, "verifyShareOverlay: Verified that the share overlay is displayed") + } fun verifyShareAppsLayout() { val sendToDeviceTitle = mDevice.findObject( @@ -67,16 +102,34 @@ class LibrarySubMenusMultipleSelectionToolbarRobot { sendToDeviceTitle.waitForExists(TestAssetHelper.waitingTime) } - fun verifyShareTabFavicon() = onView(withId(R.id.share_tab_favicon)).check(matches(isDisplayed())) + fun verifyShareTabFavicon() { + Log.i(TAG, "verifyShareTabFavicon: Trying to verify that the shared tab favicon is displayed") + onView(withId(R.id.share_tab_favicon)).check(matches(isDisplayed())) + Log.i(TAG, "verifyShareTabFavicon: Verified that the shared tab favicon is displayed") + } - fun verifyShareTabTitle() = onView(withId(R.id.share_tab_title)).check(matches(isDisplayed())) + fun verifyShareTabTitle() { + Log.i(TAG, "verifyShareTabTitle: Trying to verify that the shared tab title is displayed") + onView(withId(R.id.share_tab_title)).check(matches(isDisplayed())) + Log.i(TAG, "verifyShareTabTitle: Verified that the shared tab title is displayed") + } - fun verifyShareTabUrl() = onView(withId(R.id.share_tab_url)) + fun verifyShareTabUrl() { + Log.i(TAG, "verifyShareTabUrl: Trying to verify that the shared tab url is displayed") + onView(withId(R.id.share_tab_url)).check(matches(isDisplayed())) + Log.i(TAG, "verifyShareTabUrl: Verified that the shared tab url is displayed") + } - fun verifyCloseToolbarButton() = closeToolbarButton().check(matches(isDisplayed())) + fun verifyCloseToolbarButton() { + Log.i(TAG, "verifyCloseToolbarButton: Trying to verify that the navigate up toolbar button is displayed") + closeToolbarButton().check(matches(isDisplayed())) + Log.i(TAG, "verifyCloseToolbarButton: Verified that the navigate up toolbar button is displayed") + } fun clickShareHistoryButton() { + Log.i(TAG, "clickShareHistoryButton: Trying to click the multi-selection share history button") shareHistoryButton().click() + Log.i(TAG, "clickShareHistoryButton: Clicked the multi-selection share history button") mDevice.waitNotNull( Until.findObject( @@ -87,7 +140,9 @@ class LibrarySubMenusMultipleSelectionToolbarRobot { } fun clickShareBookmarksButton() { + Log.i(TAG, "clickShareBookmarksButton: Trying to click the multi-selection share bookmarks button") shareBookmarksButton().click() + Log.i(TAG, "clickShareBookmarksButton: Clicked the multi-selection share bookmarks button") mDevice.waitNotNull( Until.findObject( @@ -98,7 +153,9 @@ class LibrarySubMenusMultipleSelectionToolbarRobot { } fun clickMultiSelectionDelete() { + Log.i(TAG, "clickMultiSelectionDelete: Trying to click the multi-selection delete button") deleteButton().click() + Log.i(TAG, "clickMultiSelectionDelete: Clicked the multi-selection delete button") } class Transition { @@ -108,21 +165,28 @@ class LibrarySubMenusMultipleSelectionToolbarRobot { } fun closeToolbarReturnToHistory(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { + Log.i(TAG, "closeToolbarReturnToHistory: Trying to click the navigate up toolbar button") closeToolbarButton().click() + Log.i(TAG, "closeToolbarReturnToHistory: Clicked the navigate up toolbar button") HistoryRobot().interact() return HistoryRobot.Transition() } fun closeToolbarReturnToBookmarks(interact: BookmarksRobot.() -> Unit): BookmarksRobot.Transition { + Log.i(TAG, "closeToolbarReturnToBookmarks: Trying to click the navigate up toolbar button") closeToolbarButton().click() + Log.i(TAG, "closeToolbarReturnToBookmarks: Clicked the navigate up toolbar button") BookmarksRobot().interact() return BookmarksRobot.Transition() } fun clickOpenNewTab(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + Log.i(TAG, "clickOpenNewTab: Trying to click the multi-select \"Open in a new tab\" context menu button") openInNewTabButton().click() + Log.i(TAG, "clickOpenNewTab: Clicked the multi-select \"Open in a new tab\" context menu button") + mDevice.waitNotNull( Until.findObject(By.res("$packageName:id/tab_layout")), waitingTime, @@ -133,15 +197,21 @@ class LibrarySubMenusMultipleSelectionToolbarRobot { } fun clickOpenNewTab(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition { + Log.i(TAG, "clickOpenNewTab: Trying to click the multi-select \"Open in a new tab\" context menu button") openInNewTabButton().click() + Log.i(TAG, "clickOpenNewTab: Clicked the multi-select \"Open in a new tab\" context menu button") + Log.i(TAG, "clickOpenNewTab: Trying to verify that the tabs tray exists") composeTestRule.onNodeWithTag(TabsTrayTestTag.tabsTray).assertExists() + Log.i(TAG, "clickOpenNewTab: Verified that the tabs tray exists") ComposeTabDrawerRobot(composeTestRule).interact() return ComposeTabDrawerRobot.Transition(composeTestRule) } fun clickOpenPrivateTab(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + Log.i(TAG, "clickOpenPrivateTab: Trying to click the multi-select \"Open in a private tab\" context menu button") openInPrivateTabButton().click() + Log.i(TAG, "clickOpenPrivateTab: Clicked the multi-select \"Open in a private tab\" context menu button") mDevice.waitNotNull( Until.findObject(By.res("$packageName:id/tab_layout")), waitingTime, @@ -152,7 +222,9 @@ class LibrarySubMenusMultipleSelectionToolbarRobot { } fun clickOpenPrivateTab(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition { + Log.i(TAG, "clickOpenPrivateTab: Trying to click the multi-select \"Open in a private tab\" context menu button") openInPrivateTabButton().click() + Log.i(TAG, "clickOpenPrivateTab: Clicked the multi-select \"Open in a private tab\" context menu button") ComposeTabDrawerRobot(composeTestRule).interact() return ComposeTabDrawerRobot.Transition(composeTestRule) From 95e9fa455f10bdc2bcc31ee99bf6a9b0fdb521f9 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Fri, 9 Feb 2024 15:42:54 +0200 Subject: [PATCH 170/586] Bug 1879539 - Remove unused functions from LibrarySubMenusMultipleSelectionToolbarRobot --- ...rarySubMenusMultipleSelectionToolbarRobot.kt | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt index 1e65807a09cb..b3b3d395c8ac 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt @@ -6,7 +6,6 @@ package org.mozilla.fenix.ui.robots import android.net.Uri import android.util.Log -import android.widget.TextView import androidx.compose.ui.test.onNodeWithTag import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches @@ -17,14 +16,12 @@ import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withParent import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.uiautomator.By -import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import org.hamcrest.Matchers.allOf import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.HomeActivityComposeTestRule -import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName @@ -93,15 +90,6 @@ class LibrarySubMenusMultipleSelectionToolbarRobot { Log.i(TAG, "verifyShareOverlay: Verified that the share overlay is displayed") } - fun verifyShareAppsLayout() { - val sendToDeviceTitle = mDevice.findObject( - UiSelector() - .instance(0) - .className(TextView::class.java), - ) - sendToDeviceTitle.waitForExists(TestAssetHelper.waitingTime) - } - fun verifyShareTabFavicon() { Log.i(TAG, "verifyShareTabFavicon: Trying to verify that the shared tab favicon is displayed") onView(withId(R.id.share_tab_favicon)).check(matches(isDisplayed())) @@ -159,11 +147,6 @@ class LibrarySubMenusMultipleSelectionToolbarRobot { } class Transition { - fun closeShareDialogReturnToPage(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - BrowserRobot().interact() - return BrowserRobot.Transition() - } - fun closeToolbarReturnToHistory(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { Log.i(TAG, "closeToolbarReturnToHistory: Trying to click the navigate up toolbar button") closeToolbarButton().click() From 9beaef6d805a0f286984b004d47c7d295cf5b0d4 Mon Sep 17 00:00:00 2001 From: William Durand Date: Mon, 12 Feb 2024 11:56:50 +0100 Subject: [PATCH 171/586] Bug 1879819 - Improve rating description in list of add-ons --- .../feature/addons/ui/AddonsManagerAdapter.kt | 2 +- .../addons/src/main/res/values/strings.xml | 4 +++- .../feature/addons/ui/AddonsManagerAdapterTest.kt | 2 +- .../fenix/addons/AddonDetailsBindingDelegate.kt | 15 +++++++++------ .../addons/AddonDetailsBindingDelegateTest.kt | 11 +++++++---- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt index 64c4df655d26..2b0ed6ed0225 100644 --- a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt +++ b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt @@ -260,7 +260,7 @@ class AddonsManagerAdapter( val reviewCount = context.getString(R.string.mozac_feature_addons_user_rating_count_2) val ratingContentDescription = String.format( - context.getString(R.string.mozac_feature_addons_rating_content_description), + context.getString(R.string.mozac_feature_addons_rating_content_description_2), it.average, ) holder.ratingView.contentDescription = ratingContentDescription diff --git a/android-components/components/feature/addons/src/main/res/values/strings.xml b/android-components/components/feature/addons/src/main/res/values/strings.xml index dc1c822e25ae..1a2efc89a0ac 100644 --- a/android-components/components/feature/addons/src/main/res/values/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values/strings.xml @@ -148,7 +148,9 @@ Reviews: %1$s - %1$.02f/5 + %1$.02f/5 + + Rating: %1$.02f out of 5 Add-ons diff --git a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonsManagerAdapterTest.kt b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonsManagerAdapterTest.kt index 41b8370cd0e1..6dac9c9f69df 100644 --- a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonsManagerAdapterTest.kt +++ b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonsManagerAdapterTest.kt @@ -170,7 +170,7 @@ class AddonsManagerAdapterTest { adapter.bindAddon(addonViewHolder, addon, appName, appVersion) - verify(ratingAccessibleView).setText("4.50/5") + verify(ratingAccessibleView).setText("Rating: 4.50 out of 5") verify(titleView).setText("name") verify(titleView).setTextColor(ContextCompat.getColor(testContext, style.addonNameTextColor!!)) verify(summaryView).setText("summary") diff --git a/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegate.kt b/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegate.kt index fef044b050c4..3cfcc9575c0f 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegate.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegate.kt @@ -64,9 +64,13 @@ class AddonDetailsBindingDelegate( private fun bindRating(addon: Addon) { addon.rating?.let { rating -> val resources = binding.root.resources - val ratingContentDescription = resources.getString(R.string.mozac_feature_addons_rating_content_description) + val ratingContentDescription = + resources.getString(R.string.mozac_feature_addons_rating_content_description_2) + binding.ratingLabel.contentDescription = String.format(ratingContentDescription, rating.average) binding.ratingView.rating = rating.average + val reviewCount = resources.getString(R.string.mozac_feature_addons_user_rating_count_2) + binding.reviewCount.contentDescription = String.format(reviewCount, numberFormatter.format(rating.reviews)) binding.reviewCount.text = numberFormatter.format(rating.reviews) if (addon.ratingUrl.isNotBlank()) { @@ -76,7 +80,6 @@ class AddonDetailsBindingDelegate( interactor.openWebsite(addon.ratingUrl.toUri()) } } - binding.ratingLabel.joinContextDescriptions(String.format(ratingContentDescription, rating.average)) } } @@ -103,7 +106,7 @@ class AddonDetailsBindingDelegate( val formattedDate = dateFormatter.format(addon.updatedAtDate) binding.lastUpdatedText.text = formattedDate - binding.lastUpdatedLabel.joinContextDescriptions(formattedDate) + binding.lastUpdatedLabel.joinContentDescriptions(formattedDate) } private fun bindVersion(addon: Addon) { @@ -121,7 +124,7 @@ class AddonDetailsBindingDelegate( } else { binding.versionText.setOnLongClickListener(null) } - binding.versionLabel.joinContextDescriptions(version) + binding.versionLabel.joinContentDescriptions(version) } private fun bindAuthor(addon: Addon) { @@ -142,7 +145,7 @@ class AddonDetailsBindingDelegate( interactor.openWebsite(author.url.toUri()) } } - binding.authorLabel.joinContextDescriptions(author.name) + binding.authorLabel.joinContentDescriptions(author.name) } private fun bindDetails(addon: Addon) { @@ -192,7 +195,7 @@ class AddonDetailsBindingDelegate( } @VisibleForTesting - internal fun TextView.joinContextDescriptions(text: String) { + internal fun TextView.joinContentDescriptions(text: String) { this.contentDescription = "${this.text} $text" } } diff --git a/fenix/app/src/test/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegateTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegateTest.kt index 91f27b9e9e7f..ca27f28c9bb0 100644 --- a/fenix/app/src/test/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegateTest.kt +++ b/fenix/app/src/test/java/org/mozilla/fenix/addons/AddonDetailsBindingDelegateTest.kt @@ -69,12 +69,15 @@ class AddonDetailsBindingDelegateTest { ) assertEquals(4.5f, binding.ratingView.rating) assertEquals("100", binding.reviewCount.text) - val ratingContentDescription = testContext.getString(R.string.mozac_feature_addons_rating_content_description) - val formattedRatting = String.format(ratingContentDescription, 4.3f) - val expectedContentDescription = binding.ratingLabel.text.toString() + " " + formattedRatting - assertEquals(expectedContentDescription, binding.ratingLabel.contentDescription) + val ratingContentDescription = testContext.getString(R.string.mozac_feature_addons_rating_content_description_2) + var formattedRatting = String.format(ratingContentDescription, 4.3f) + assertEquals(formattedRatting, binding.ratingLabel.contentDescription) assertEquals(IMPORTANT_FOR_ACCESSIBILITY_NO, binding.ratingView.importantForAccessibility) + + val reviewContentDescription = testContext.getString(R.string.mozac_feature_addons_user_rating_count_2) + formattedRatting = String.format(reviewContentDescription, 100) + assertEquals(formattedRatting, binding.reviewCount.contentDescription) } @Test From a26e21ee3b090843ed2bed110eb5e8529eb79149 Mon Sep 17 00:00:00 2001 From: Jonathan Almeida Date: Wed, 31 Jan 2024 17:25:08 -0500 Subject: [PATCH 172/586] Bug 1868469 - Update the url immediately for existing engineSession When we have an existing `engineSession` we use an optimized route to load the url without needing to dispatch the load action. This is still a valid performance improvement to make page loads faster. However, in this code path we do not end up update the url in the state until we get back a response from the Engine. This gives a perceived performance loss of slow browsing. Updating the url gives UI components an immediate update which reflects a change that would have been entered by the user. It was considered if we should do this in a middleware, but since this is an optimized route, we should not wait for the middleware to process the action before we perform the state update. --- .../mozilla/components/feature/session/SessionUseCases.kt | 8 ++++++++ .../components/feature/session/SessionUseCasesTest.kt | 4 ++++ docs/changelog.md | 5 ++++- .../java/org/mozilla/fenix/ui/CrashReportingTest.kt | 2 +- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/android-components/components/feature/session/src/main/java/mozilla/components/feature/session/SessionUseCases.kt b/android-components/components/feature/session/src/main/java/mozilla/components/feature/session/SessionUseCases.kt index 4c53f0d22f75..565ba3463218 100644 --- a/android-components/components/feature/session/src/main/java/mozilla/components/feature/session/SessionUseCases.kt +++ b/android-components/components/feature/session/src/main/java/mozilla/components/feature/session/SessionUseCases.kt @@ -4,6 +4,7 @@ package mozilla.components.feature.session +import mozilla.components.browser.state.action.ContentAction import mozilla.components.browser.state.action.CrashAction import mozilla.components.browser.state.action.EngineAction import mozilla.components.browser.state.action.LastAccessAction @@ -99,6 +100,13 @@ class SessionUseCases( flags = flags, additionalHeaders = additionalHeaders, ) + // Update the url in content immediately until the engine updates with any new changes to the state. + store.dispatch( + ContentAction.UpdateUrlAction( + loadSessionId, + url, + ), + ) store.dispatch( EngineAction.OptimizedLoadUrlTriggeredAction( loadSessionId, diff --git a/android-components/components/feature/session/src/test/java/mozilla/components/feature/session/SessionUseCasesTest.kt b/android-components/components/feature/session/src/test/java/mozilla/components/feature/session/SessionUseCasesTest.kt index 16a5fd3d626f..4461577d2595 100644 --- a/android-components/components/feature/session/src/test/java/mozilla/components/feature/session/SessionUseCasesTest.kt +++ b/android-components/components/feature/session/src/test/java/mozilla/components/feature/session/SessionUseCasesTest.kt @@ -11,6 +11,7 @@ import mozilla.components.browser.state.action.EngineAction import mozilla.components.browser.state.action.TabListAction import mozilla.components.browser.state.engine.EngineMiddleware import mozilla.components.browser.state.selector.findTab +import mozilla.components.browser.state.selector.selectedTab import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.state.createCustomTab @@ -80,6 +81,7 @@ class SessionUseCasesTest { assertEquals("mozilla", action.tabId) assertEquals("https://getpocket.com", action.url) } + assertEquals("https://getpocket.com", store.state.selectedTab?.content?.url) useCases.loadUrl("https://www.mozilla.org", LoadUrlFlags.select(LoadUrlFlags.EXTERNAL)) store.waitUntilIdle() @@ -93,6 +95,7 @@ class SessionUseCasesTest { assertEquals("https://www.mozilla.org", action.url) assertEquals(LoadUrlFlags.select(LoadUrlFlags.EXTERNAL), action.flags) } + assertEquals("https://www.mozilla.org", store.state.selectedTab?.content?.url) useCases.loadUrl("https://firefox.com", store.state.selectedTabId) store.waitUntilIdle() @@ -102,6 +105,7 @@ class SessionUseCasesTest { assertEquals("mozilla", action.tabId) assertEquals("https://firefox.com", action.url) } + assertEquals("https://firefox.com", store.state.selectedTab?.content?.url) useCases.loadUrl.invoke( "https://developer.mozilla.org", diff --git a/docs/changelog.md b/docs/changelog.md index 06a453a17cc4..c3de6235c869 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -19,7 +19,7 @@ permalink: /changelog/ * **all components** * All new usages of the `concept-fetch` component to make fetch requests now have conservative-mode off by default. Current features will continue to use conservative mode until individually updated. - + * **browser-toolbar** * Add `showMenuButton` and `hideMenuButton` API to `BrowserToolbar` and `DisplayToolbar` to allow hiding and showing of the menu button in the `BrowserToolbar` [Bug 1864760](https://bugzilla.mozilla.org/show_bug.cgi?id=1864760) @@ -27,6 +27,9 @@ permalink: /changelog/ * **feature-customtabs** * Fallback behaviour when failing to open a new window in custom tab will now be loading the URL directly in the same custom tab. [Bug 1832357](https://bugzilla.mozilla.org/show_bug.cgi?id=1832357) +* **feature-session** + * Update URL in the store immediately when using the optimized load URL code path. + # 123.0 * [Commits](https://github.com/mozilla-mobile/firefox-android/compare/releases_v122..releases_v123) * [Dependencies](https://github.com/mozilla-mobile/firefox-android/blob/releases_v123/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt index 84083e014ddf..be99ebe8af54 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt @@ -85,7 +85,7 @@ class CrashReportingTest : TestSetup() { verifyPageContent(tabCrashMessage) }.openTabDrawer { verifyExistingOpenTabs(firstWebPage.title) - verifyExistingOpenTabs(secondWebPage.title) + verifyExistingOpenTabs("about:crashcontent") }.closeTabDrawer { }.goToHomescreen { verifyExistingTopSitesList() From 5c0e0cacd88794befdb11d5a5898eac0d217a7f6 Mon Sep 17 00:00:00 2001 From: Ben Dean-Kawamura Date: Thu, 1 Feb 2024 16:57:01 -0500 Subject: [PATCH 173/586] Revert "Bug 1875294 - Record breadbcrumbs before crashing with UnsatsisfiedLinkError" This reverts commit 6fb061ce5efc1a3fb11dace06b826382e0b56736. These didn't work out in practice. The file lists were always empty, I think it might be a difference in permissions for release builds vs the debug builds that I was testing with. The package installer name was useful, but I realized there's Sentry tag for that which is even more useful. --- .../org/mozilla/fenix/FenixApplication.kt | 76 ++----------------- 1 file changed, 5 insertions(+), 71 deletions(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index b4f37a0af4db..6dfd7a06951f 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -112,11 +112,8 @@ import org.mozilla.fenix.session.VisibilityLifecycleCallback import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.utils.Settings.Companion.TOP_SITES_PROVIDER_MAX_THRESHOLD import org.mozilla.fenix.wallpapers.Wallpaper -import java.io.File -import java.io.FileInputStream import java.util.UUID import java.util.concurrent.TimeUnit -import java.util.zip.ZipInputStream import kotlin.math.roundToLong private const val RAM_THRESHOLD_MEGABYTES = 1024 @@ -525,76 +522,13 @@ open class FenixApplication : LocaleAwareApplication(), Provider { * thread, early in the app startup sequence. */ private fun beginSetupMegazord() { - try { - // Note: Megazord.init() must be called as soon as possible ... - Megazord.init() - - initializeRustErrors(components.analytics.crashReporter) - // ... but RustHttpConfig.setClient() and RustLog.enable() can be called later. + // Note: Megazord.init() must be called as soon as possible ... + Megazord.init() - RustLog.enable() - } catch (e: UnsatisfiedLinkError) { - @Suppress("TooGenericExceptionCaught") - try { - reportUnsatisfiedLinkErrorBreadcrumbs() - } catch (e: Throwable) { - // This shouldn't happen, but if it does it's better to ignore the exception from - // the breadcrumb code and rethrow the initial exception. - } - throw e - } - } + initializeRustErrors(components.analytics.crashReporter) + // ... but RustHttpConfig.setClient() and RustLog.enable() can be called later. - private fun reportUnsatisfiedLinkErrorBreadcrumbs() { - val breadcrumbStrings = mutableListOf() - val apkPath = applicationContext.getApplicationInfo().sourceDir - breadcrumbStrings.add("APK: $apkPath") - val apkDir = File(apkPath).getParentFile() - val installSourcePackage = if (SDK_INT >= Build.VERSION_CODES.R) { - packageManager.getInstallSourceInfo(packageName).installingPackageName - } else { - @Suppress("DEPRECATION") - packageManager.getInstallerPackageName(packageName) - } - breadcrumbStrings.add("Installer package name: $installSourcePackage") - - val installDirFileSet = if (apkDir != null) { - apkDir.walk() - .filter { it != apkDir && !it.isDirectory() } - .map { it.relativeTo(apkDir).toString() } - .filter { it.startsWith("lib/") } - .toHashSet() - } else { - HashSet() - } - val apkFileSet = ZipInputStream(FileInputStream(apkPath)).use { - generateSequence { it.nextEntry } - .map { it.name } - .filter { it.startsWith("lib/") } - .toHashSet() - } - fun formatFileSet(filenames: Set) = if (filenames.size > 0) { - filenames.joinToString(", ") - } else { - "" - } - val installDirOnly = formatFileSet(installDirFileSet - apkFileSet) - val apkFileOnly = formatFileSet(apkFileSet - installDirFileSet) - val both = formatFileSet(installDirFileSet union apkFileSet) - - breadcrumbStrings.add("Files only inside lib/ dir: $installDirOnly") - breadcrumbStrings.add("Files only inside APK lib/ dir: $apkFileOnly") - breadcrumbStrings.add("Files inside both lib/ dirs: $both") - - for (breadcrumbString in breadcrumbStrings) { - components.analytics.crashReporter.recordCrashBreadcrumb( - Breadcrumb( - category = "Startup", - message = breadcrumbString, - level = Breadcrumb.Level.INFO, - ), - ) - } + RustLog.enable() } @OptIn(DelicateCoroutinesApi::class) // GlobalScope usage From ab7cc9543b11710f8b7262d00d18f3f346089a39 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Mon, 12 Feb 2024 14:15:25 -0500 Subject: [PATCH 174/586] Bug 1873486 - Update mockk to version 1.13.9 --- .../fenixdependencies/src/main/java/FenixDependenciesPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt b/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt index e4a769a07c2a..efc00ff779f4 100644 --- a/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt +++ b/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt @@ -32,7 +32,7 @@ object FenixVersions { const val installreferrer = "2.2" const val junit = "5.9.3" - const val mockk = "1.13.8" + const val mockk = "1.13.9" const val google_ads_id_version = "16.0.0" From 82da77452ed8f24c1fdc164cb193877b353085ec Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 13 Feb 2024 00:03:47 +0000 Subject: [PATCH 175/586] Import translations from android-l10n --- .../addons/src/main/res/values-eu/strings.xml | 4 +- .../media/src/main/res/values-eu/strings.xml | 11 +- .../src/main/res/values-eu/strings.xml | 36 ++++ fenix/app/src/main/res/values-azb/strings.xml | 56 +++++++ fenix/app/src/main/res/values-eu/strings.xml | 154 +++++++++++++----- .../app/src/main/res/values-iw/strings.xml | 15 ++ 6 files changed, 230 insertions(+), 46 deletions(-) diff --git a/android-components/components/feature/addons/src/main/res/values-eu/strings.xml b/android-components/components/feature/addons/src/main/res/values-eu/strings.xml index 56985171df47..8c06d98ceeb5 100644 --- a/android-components/components/feature/addons/src/main/res/values-eu/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-eu/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Beste %1$d domeinutan zure datuak atzitzea + + %1$s, %2$d of %3$d Nabigatzailearen fitxak atzitzea @@ -75,7 +77,7 @@ Egilea - Egileak + Egileak Azken eguneraketa diff --git a/android-components/components/feature/media/src/main/res/values-eu/strings.xml b/android-components/components/feature/media/src/main/res/values-eu/strings.xml index f61dc91a9ca2..12d9fb39a8a2 100644 --- a/android-components/components/feature/media/src/main/res/values-eu/strings.xml +++ b/android-components/components/feature/media/src/main/res/values-eu/strings.xml @@ -1,5 +1,5 @@ - + Media @@ -21,9 +21,14 @@ Gogorarazlea: %1$s zure kamera ari da erabiltzen oraindik. Sakatu fitxa irekitzeko. - Gogorarazlea: %1$s zure mikrofonoa ari da erabiltzen oraindik. Sakatu fitxa irekitzeko + Gogorarazlea: %1$s zure mikrofonoa ari da erabiltzen oraindik. Sakatu fitxa irekitzeko + + Gogorarazlea: %1$s zure mikrofonoa ari da erabiltzen oraindik. Sakatu fitxa irekitzeko. + + Gogorarazlea: %1$s zure mikrofono eta kamera ari da erabiltzen oraindik. Sakatu fitxa irekitzeko + - Gogorarazlea: %1$s zure mikrofono eta kamera ari da erabiltzen oraindik. Sakatu fitxa irekitzeko + Gogorarazlea: %1$s zure mikrofono eta kamera ari da erabiltzen oraindik. Sakatu fitxa irekitzeko. Erreproduzitu diff --git a/android-components/components/feature/prompts/src/main/res/values-eu/strings.xml b/android-components/components/feature/prompts/src/main/res/values-eu/strings.xml index 95a210e5c1fd..3782fee0a216 100644 --- a/android-components/components/feature/prompts/src/main/res/values-eu/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-eu/strings.xml @@ -18,6 +18,8 @@ Pasahitza Ez gorde + + Une honetan ez Ez gorde inoiz @@ -26,16 +28,26 @@ Gorde Ez eguneratu + + Une honetan ez Eguneratu Pasahitzaren eremuak ezin du hutsik egon + Idatzi pasahitz bat + Ezin da saio-hasiera gorde + + Ezin da pasahitza gorde Gorde saio-hasiera hau? + + Gorde pasahitza? Eguneratu saio-hasiera hau? + + Eguneratu pasahitza? Gehitu erabiltzaile-izena gordetako pasahitzari? @@ -85,13 +97,22 @@ Ezarri denbora Kudeatu saio-hasierak + + Kudeatu pasahitzak Zabaldu iradokitako saio-hasierak + + Zabaldu gordetako pasahitzak Tolestu iradokitako saio-hasierak + + Tolestu gordetako pasahitzak Iradokitako saio-hasierak + + Gordetako pasahitzak + Gomendatu pasahitz sendoa @@ -110,12 +131,20 @@ Hautatu kreditu-txartela + + Erabili gordetako txartela Zabaldu iradokitako kreditu-txartelak + + Zabaldu gordetako txartelak Tolestu iradokitako kreditu-txartelak + + Tolestu gordetako txartelak Kudeatu kreditu-txartelak + + Kudeatu txartelak Gorde txartela modu seguruan? @@ -123,13 +152,20 @@ Txartel-zenbakia zifratu egingo da. Segurtasun-kodea ez da gordeko. + + %s(e)k zure txartel-zenbakia zifratzen du. Zure segurtasun-kodea ez da gordeko. + Hautatu helbidea Zabaldu iradokitako helbideak + + Zabaldu gordetako helbideak Tolestu iradokitako helbideak + + Tolestu gordetako helbideak Kudeatu helbideak diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml index 1c5e4b0c8767..796ef13cfb87 100644 --- a/fenix/app/src/main/res/values-azb/strings.xml +++ b/fenix/app/src/main/res/values-azb/strings.xml @@ -611,9 +611,16 @@ خاریجی یئندیرمه موْدیری. + + Gecko قیدلرینی گوجلندیر + + دگیشمه‌لری یئرینه سالماق اوچون اپلیکیشن‌دن چیْخیلیر... + تاخیلان‌لار + + تاخیلانیْ فایل‌دان قوْش بیلدیریش‌لر @@ -621,11 +628,30 @@ ایجازه وئریلمه‌دی + + + اؤزل تاخیْلان مجموعه‌سی تامام لغو + + مجموعه آدیْ + + مجموعه صاحیبی (قوللانیجیْ آیدی‌سی) + + تاخیْلان مجموعه‌‌سی ایصلاح اوْلدوُ. دگیشمه‌لری یئرینه سالماق اوچون اپلیکیشن‌دن چیْخیلیر... + + + + قاباقکی تاغ‌لارا قاییت + + سوْن بوکمارک‌لار + + سون باخیلان‌لار + آرتیق بیلین @@ -671,6 +697,36 @@ بوُکمارک‌لار + + گئچمیش + + یئنی تاغ + + تنظیم‌‎لر + + باغلا + + + + تاغ‌لار + + لیست + + هئچ زامان + + + آنایارپاق + + + + قالدیر + + + + لغو + + دوزه‌لیش + diff --git a/fenix/app/src/main/res/values-eu/strings.xml b/fenix/app/src/main/res/values-eu/strings.xml index ea6c22134a79..7f70955c968d 100644 --- a/fenix/app/src/main/res/values-eu/strings.xml +++ b/fenix/app/src/main/res/values-eu/strings.xml @@ -245,6 +245,7 @@ Pertsonalizatu hasiera-orria + Hasiera-pantaila @@ -252,6 +253,9 @@ Ezabatu nabigatze-historia + + Itzuli orria + Hautatutako hizkuntza @@ -263,8 +267,6 @@ Eskaneatu - - Bilaketa-motorra Bilaketa-motorren ezarpenak @@ -320,25 +322,30 @@ - Jakinarazpenek %s(r)i zuku gehiago ateratzen laguntzen dute + Jakinarazpenek %s(r)i zuku gehiago ateratzen laguntzen dute - Sinkronizatu zure fitxak gailuen artean, kudeatu deskargak, jaso aholkuak %s(r)en pribatutasun-babesari zuku gehien ateratzeko, eta gehiago. + Sinkronizatu zure fitxak gailuen artean, kudeatu deskargak, jaso aholkuak %s(r)en pribatutasun-babesari zuku gehien ateratzeko, eta gehiago. - Jarraitu + Jarraitu - Une honetan ez + Une honetan ez + + Firefoxen pribatutasun-oharra + Zu seguru mantentzea dugu xede - Irabazi asmorik gabeko erakundeak babestutako gure nabigatzaileak laguntzen du + Irabazi asmorik gabeko erakundeak babestutako gure nabigatzaileak laguntzen du eragozten enpresek zure webeko jarraipena sekretupean egin dezaten. + + Irabazi asmorik gabeko erakundeak babestutako gure nabigatzaileak laguntzen du eragozten enpresek zure webeko jarraipena sekretupean egin dezaten.\n\n Argibide gehiago gure pribatutasun-oharrean. - pribatutasun-oharrean + pribatutasun-oharrean Ezarri nabigatzaile lehenetsi gisa @@ -443,22 +450,11 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du. HTTPS-Only modua - - Cookie iragarki-banden murrizpena Cookie iragarki-banden blokeatzailea Cookie iragarki-banden blokeatzailea nabigatze pribatuan - - Murriztu cookie iragarki-bandak - - Desaktibatuta - - Aktibatuta - - - Cookie iragarki-bandetako eskaerak automatikoki ukatzen saiatzen da %1$s. Desaktibatuta gune honetarako @@ -476,35 +472,16 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du. Une honetan gune honetarako euskarririk ez - Aktibatu cookie iragarki-banden murrizpena %1$s gunerako? - Aktibatu cookie iragarki-banden blokeatzailea %1$s gunerako? - Desaktibatu cookie iragarki-banden murrizpena %1$s gunerako? - Desaktibatu cookie iragarki-banden blokeatzailea %1$s gunerako? %1$s(e)k ezin ditu cookie-eskaerak automatikoki baztertu gune honetan. Etorkizunean gune honetarako euskarria gehitzeko eskaera bidal dezakezu. - - %1$s(e)k gune honetako cookieak garbitu eta orria berrituko du. Cookie guztiak garbitzean, saioak amaitu edo erosketa-orgak hustu litezke. Desaktibatu eta %1$s(e)k gune honetako cookieak garbitu eta orria berrituko du. Saioa amaitu edo erosketa-orgak hustu litezke. - Cookie eskaerak automatikoki ukatzen saiatzen da %1$s. - Aktibatu eta %1$s gune honetako cookie iragarki-bandak automatikoki ukatzen saiatuko da. - - Baimendu %1$s(r)i cookie iragarki-bandak ukatzen? - - %1$s(e)k automatikoki uka ditzake cookie iragarki-bandetako eskaerak. - - Une honetan ez - - Cookie eskaera gutxiago ikusiko dituzu - - - Baimendu %1$s(e)k cookieak ukatu ditu zure partez @@ -721,6 +698,8 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du. Laster-markak Saio-hasierak + + Pasahitzak Irekitako fitxak @@ -748,6 +727,8 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du. Kreditu-txartelak + + Ordainketa metodoak Helbideak @@ -1290,8 +1271,6 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Baztertu - Ezin da inprimatu - Ezin da orria inprimatu Inprimatu @@ -1697,8 +1676,12 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Saio-hasierak eta pasahitzak + + Pasahitzak Gorde saio-hasierak eta pasahitzak + + Gorde pasahitzak Galdetu gorde aurretik @@ -1715,26 +1698,46 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Gehitu saio-hasiera + + Gehitu pasahitza + Sinkronizatu saio-hasierak + + Sinkronizatu pasahitzak Sinkronizatu saio-hasierak gailuen artean + + Sinkronizatu pasahitzak gailuen artean Gordetako saio-hasierak + + Gordetako pasahitzak %s(e)n gordetzen edo sinkronizatzen dituzun saio-hasierak hemen agertuko dira. + + %s(e)n gordetzen edo sinkronizatzen dituzun pasahitzak hemen agertuko dira. Gordetzen dituzun pasahitz guztiak zifratuta daude. + Sinkronizazioari buruzko argibide gehiago. + + Sinkronizazioari buruzko argibide gehiago Salbuespenak Gorde gabeko saio-hasiera eta pasahitzak hemen erakutsiko dira. + + %s(e)k ez du pasahitzik gordeko hemen zerrendatutako guneetarako. Gune hauetarako ez da saio-hasiera eta pasahitzik gordeko. + + %s(e)k ez du pasahitzik gordeko gune hauetarako. Ezabatu salbuespen guztiak Bilatu saio-hasierak + + Bilatu pasahitzak Gunea @@ -1763,10 +1766,16 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Ezkutatu pasahitza Desblokeatu gordetako saio-hasierak ikusteko + + Desblokeatu gordetako pasahitzak ikusteko Lortu zure saio-hasierak eta pasahitzak + + Bermatu gordetako zure pasahitzak Konfiguratu gailua blokeatzeko patroia, PINa edo pasahitza zure saio-hasierak eta pasahitzak babesteko zure gailua beste norbaitek izango balu. + + Konfiguratu gailua blokeatzeko patroia, PINa edo pasahitza zure gordetako pasahitzak babesteko zure gailua beste norbaitek izango balu. Geroago @@ -1786,6 +1795,9 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Ordenatu saio-hasieren menua + + Ordenatu pasahitzen menua + Betetze automatikoa @@ -1793,10 +1805,16 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Helbideak Kreditu-txartelak + + Ordainketa metodoak Gorde eta osatu automatikoki kreditu-txartelak + + Gorde eta bete ordainketa metodoak Datuak zifratuta daude + + Gordetzen dituzun ordainketa metodo guztiak zifratzen ditu %s(e)k Sinkronizatu txartelak gailuen artean @@ -1804,8 +1822,12 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Gehitu kreditu-txartela + + Gehitu txartela Kudeatu gordetako txartelak + + Kudeatu txartelak Gehitu helbidea @@ -1813,9 +1835,14 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Gorde eta osatu automatikoki helbideak + + Gorde eta osatu helbideak Kontuan izan zenbakiak, helbide elektronikoak eta bidalketa-helbideak + + Telefono zenbakiak eta helbide elektronikoak ere baditu + Gehitu txartela @@ -1836,6 +1863,8 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du. Ezabatu txartela Ziur zaude kreditu-txartel hau ezabatu nahi duzula? + + Ezabatu txartela? Ezabatu @@ -1849,15 +1878,23 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du. Idatzi baliozko kreditu-txartel zenbakia + + Idatzi baliozko txartel-zenbakia Bete eremu hau mesedez + + Gehitu izena Desblokeatu gordetako txartelak ikusteko Bermatu zure kreditu-txartelak + + Bermatu gordetako zure ordainketa metodoak Konfiguratu gailua blokeatzeko patroia, PINa edo pasahitza zure gordetako kreditu-txartelak babesteko zure gailua beste norbaitek izango balu. + + Konfiguratu gailua blokeatzeko patroia, PINa edo pasahitza gordetako zure ordainketa metodoak babesteko zure gailua beste norbaitek izango balu. Konfiguratu orain @@ -1867,6 +1904,8 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du. Desblokeatu gordetako kreditu txartelaren informazioa erabiltzeko + + Desblokeatu gordetako ordainketa metodoak erabiltzeko Gehitu helbidea @@ -1903,6 +1942,8 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du. Ezabatu helbidea Ziur zaude helbide hau ezabatu nahi duzula? + + Ezabatu helbidea? Ezabatu @@ -2001,30 +2042,52 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du. Editatu Ziur zaude saio-hasiera hau ezabatu nahi duzula? + + Ziur zaude pasahitz hau ezabatu nahi duzula? Ezabatu Utzi Saio-hasieren aukerak + + Pasahitzaren aukerak Saio-hasieraren web helbiderako testu-eremu editagarria. + + Webgunearen helbidearen testu-eremu editagarria. Saio-hasieraren erabiltzaile-izenerako testu-eremu editagarria. + + Erabiltzaile-izenaren testu-eremu editagarria. Saio-hasieraren pasahitzerako testu-eremu editagarria. + + Pasahitzaren testu-eremu editagarria. Gorde saio-hasieraren aldaketak. + + Gorde aldaketak. Editatu + + Editatu pasahitza Gehitu saio-hasiera berria + + Gehitu pasahitza Pasahitza behar da + + Idatzi pasahitz bat Erabiltzaile-izena behar da + + Idatzi erabiltzaile-izen bat Ostalari-izena behar da + + Idatzi web helbide bat Ahots bidezko bilaketa @@ -2121,6 +2184,9 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du. %s bilaketa + + Aldatu zure nabigatzaile lehenetsia + Ireki webgune, posta elektroniko eta mezuetako loturak Firefoxen automatikoki. @@ -2195,8 +2261,6 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du. Nabarmentzekoak %s(e)ko azken 80 egunetan fidagarriak direla uste ditugun balorazioak dira.]]> Argibide gehiago %s(r)i buruz. - - Mozillaren %s(e)k nola antzematen duen balorazioen kalitatea Nola antzematen duen %s(e)k balorazioen kalitatea @@ -2381,6 +2445,8 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du. Itzulpena burutzen + + Aukeratu hizkuntza Arazo bat gertatu da itzultzean. Saiatu berriro mesedez. @@ -2402,6 +2468,10 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du. Inoiz ez itzuli %1$s Inoiz ez itzuli gune hau + + Beste ezarpen guztiak baliogabetzen ditu + + Itzultzeko eskaintzak baliogabetzen ditu Itzulpenen ezarpenak diff --git a/focus-android/app/src/main/res/values-iw/strings.xml b/focus-android/app/src/main/res/values-iw/strings.xml index 0a1cf34e3a68..404587cd5062 100644 --- a/focus-android/app/src/main/res/values-iw/strings.xml +++ b/focus-android/app/src/main/res/values-iw/strings.xml @@ -724,6 +724,21 @@ ‏%1$s יכול לנסות לדחות באופן אוטומטי בקשות כרזות עוגיות. + + ביטול + + + בקשת תמיכה + + + הבקשה לתמיכה באתר הוגשה. + + + הבקשה לתמיכה באתר הוגשה. + + + הגדרות + ניגון אוטומטי From 0b277f1659452e08393e0394db6d9e73e911bc1a Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 13 Feb 2024 01:40:40 +0000 Subject: [PATCH 176/586] Update GeckoView (Nightly) to 124.0.20240212214644. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 1d336b896ce4..61f2182a2445 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240211213657" + const val version = "124.0.20240212214644" /** * GeckoView channel From 5648ec974f9d0f89ffb26e41addedcf4a9dc095d Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 13 Feb 2024 05:34:18 +0000 Subject: [PATCH 177/586] Update A-S to 124.20240213050313. --- .../plugins/dependencies/src/main/java/ApplicationServices.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt index 188a9b88fdf8..2ceca30e0b13 100644 --- a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt +++ b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // These lines are generated by android-components/automation/application-services-nightly-bump.py -val VERSION = "124.20240210050349" +val VERSION = "124.20240213050313" val CHANNEL = ApplicationServicesChannel.NIGHTLY object ApplicationServicesConfig { From 20b21b1fcb334cb95b313453427085ef8879d201 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Fri, 9 Feb 2024 16:13:15 +0200 Subject: [PATCH 178/586] Bug 1879886 - Remove unused functions from NavigationToolbarRobot --- .../fenix/ui/robots/NavigationToolbarRobot.kt | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt index 2cb5403242f2..51b4656f185c 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt @@ -61,16 +61,11 @@ class NavigationToolbarRobot { fun verifyUrl(url: String) = onView(withId(R.id.mozac_browser_toolbar_url_view)).check(matches(withText(url))) - fun verifyNoHistoryBookmarks() = assertNoHistoryBookmarks() - fun verifyTabButtonShortcutMenuItems() = assertTabButtonShortcutMenuItems() fun verifyReaderViewDetected(visible: Boolean = false) = assertReaderViewDetected(visible) - fun verifyCloseReaderViewDetected(visible: Boolean = false) = - assertCloseReaderViewDetected(visible) - fun toggleReaderView() { mDevice.findObject( UiSelector() @@ -379,13 +374,6 @@ fun openEditURLView() { Log.i(TAG, "openEditURLView: Edit URL bar displayed.") } -private fun assertNoHistoryBookmarks() { - onView(withId(R.id.container)) - .check(matches(not(hasDescendant(withText("Test_Page_1"))))) - .check(matches(not(hasDescendant(withText("Test_Page_2"))))) - .check(matches(not(hasDescendant(withText("Test_Page_3"))))) -} - private fun assertTabButtonShortcutMenuItems() { onView(withId(R.id.mozac_browser_menu_recyclerView)) .check(matches(hasDescendant(withText("Close tab")))) @@ -425,27 +413,6 @@ private fun assertReaderViewDetected(visible: Boolean) { ) } -private fun assertCloseReaderViewDetected(visible: Boolean) { - mDevice.findObject( - UiSelector() - .description("Close reader view"), - ) - .waitForExists(waitingTime) - - onView( - allOf( - withParent(withId(R.id.mozac_browser_toolbar_page_actions)), - withContentDescription("Close reader view"), - ), - ).check( - if (visible) { - matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)) - } else { - ViewAssertions.doesNotExist() - }, - ) -} - private val searchSelectorButton = mDevice.findObject(UiSelector().resourceId("$packageName:id/search_selector")) From 49d7033e145a740d63fca193545177733240a6ff Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Fri, 9 Feb 2024 16:15:03 +0200 Subject: [PATCH 179/586] Bug 1879886 - Convert private variables to functions so they don't get initialized --- .../org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt index 51b4656f185c..94af51d9ea85 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt @@ -114,7 +114,7 @@ class NavigationToolbarRobot { // New unified search UI selector fun verifyDefaultSearchEngine(engineName: String) = assertUIObjectExists( - searchSelectorButton.getChild(UiSelector().description(engineName)), + searchSelectorButton().getChild(UiSelector().description(engineName)), ) fun verifyTextSelectionOptions(vararg textSelectionOptions: String) { @@ -352,8 +352,8 @@ class NavigationToolbarRobot { } fun clickSearchSelectorButton(interact: SearchRobot.() -> Unit): SearchRobot.Transition { - searchSelectorButton.waitForExists(waitingTime) - searchSelectorButton.click() + searchSelectorButton().waitForExists(waitingTime) + searchSelectorButton().click() SearchRobot().interact() return SearchRobot.Transition() @@ -413,7 +413,7 @@ private fun assertReaderViewDetected(visible: Boolean) { ) } -private val searchSelectorButton = +private fun searchSelectorButton() = mDevice.findObject(UiSelector().resourceId("$packageName:id/search_selector")) inline fun runWithIdleRes(ir: IdlingResource?, pendingCheck: () -> Unit) { From 0a67838b6003eba618da0f132ec357abfdaac8f5 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Fri, 9 Feb 2024 16:18:33 +0200 Subject: [PATCH 180/586] Bug 1879886 - Remove redundant assertion functions from NavigationToolbarRobot --- .../fenix/ui/robots/NavigationToolbarRobot.kt | 57 +++++++++---------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt index 94af51d9ea85..2b2914e3ebe7 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt @@ -61,10 +61,33 @@ class NavigationToolbarRobot { fun verifyUrl(url: String) = onView(withId(R.id.mozac_browser_toolbar_url_view)).check(matches(withText(url))) - fun verifyTabButtonShortcutMenuItems() = assertTabButtonShortcutMenuItems() + fun verifyTabButtonShortcutMenuItems() { + onView(withId(R.id.mozac_browser_menu_recyclerView)) + .check(matches(hasDescendant(withText("Close tab")))) + .check(matches(hasDescendant(withText("New private tab")))) + .check(matches(hasDescendant(withText("New tab")))) + } - fun verifyReaderViewDetected(visible: Boolean = false) = - assertReaderViewDetected(visible) + fun verifyReaderViewDetected(visible: Boolean = false) { + mDevice.findObject( + UiSelector() + .description("Reader view"), + ) + .waitForExists(waitingTime) + + onView( + allOf( + withParent(withId(R.id.mozac_browser_toolbar_page_actions)), + withContentDescription("Reader view"), + ), + ).check( + if (visible) { + matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)) + } else { + ViewAssertions.doesNotExist() + }, + ) + } fun toggleReaderView() { mDevice.findObject( @@ -374,13 +397,6 @@ fun openEditURLView() { Log.i(TAG, "openEditURLView: Edit URL bar displayed.") } -private fun assertTabButtonShortcutMenuItems() { - onView(withId(R.id.mozac_browser_menu_recyclerView)) - .check(matches(hasDescendant(withText("Close tab")))) - .check(matches(hasDescendant(withText("New private tab")))) - .check(matches(hasDescendant(withText("New tab")))) -} - private fun urlBar() = mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar")) private fun awesomeBar() = mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_edit_url_view")) @@ -392,27 +408,6 @@ private fun clearAddressBarButton() = itemWithResId("$packageName:id/mozac_brows private fun readerViewToggle() = onView(withParent(withId(R.id.mozac_browser_toolbar_page_actions))) -private fun assertReaderViewDetected(visible: Boolean) { - mDevice.findObject( - UiSelector() - .description("Reader view"), - ) - .waitForExists(waitingTime) - - onView( - allOf( - withParent(withId(R.id.mozac_browser_toolbar_page_actions)), - withContentDescription("Reader view"), - ), - ).check( - if (visible) { - matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)) - } else { - ViewAssertions.doesNotExist() - }, - ) -} - private fun searchSelectorButton() = mDevice.findObject(UiSelector().resourceId("$packageName:id/search_selector")) From 7b5032183f7472c3f4395e16a3a15677e9e06812 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Mon, 12 Feb 2024 12:04:33 +0200 Subject: [PATCH 181/586] Bug 1879886 - Add test logs to NavigationToolbarRobot --- .../fenix/ui/robots/NavigationToolbarRobot.kt | 143 +++++++++++++----- 1 file changed, 109 insertions(+), 34 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt index 2b2914e3ebe7..cb6a8495639e 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt @@ -31,7 +31,6 @@ import androidx.test.uiautomator.By.textContains import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import org.hamcrest.CoreMatchers.allOf -import org.hamcrest.CoreMatchers.not import org.junit.Assert.assertTrue import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants @@ -58,23 +57,29 @@ import org.mozilla.fenix.tabstray.TabsTrayTestTag * Implementation of Robot Pattern for the URL toolbar. */ class NavigationToolbarRobot { - fun verifyUrl(url: String) = + fun verifyUrl(url: String) { + Log.i(TAG, "verifyUrl: Trying to verify toolbar text matches $url") onView(withId(R.id.mozac_browser_toolbar_url_view)).check(matches(withText(url))) + Log.i(TAG, "verifyUrl: Verified toolbar text matches $url") + } fun verifyTabButtonShortcutMenuItems() { + Log.i(TAG, "verifyTabButtonShortcutMenuItems: Trying to verify tab counter shortcut options") onView(withId(R.id.mozac_browser_menu_recyclerView)) .check(matches(hasDescendant(withText("Close tab")))) .check(matches(hasDescendant(withText("New private tab")))) .check(matches(hasDescendant(withText("New tab")))) + Log.i(TAG, "verifyTabButtonShortcutMenuItems: Verified tab counter shortcut options") } fun verifyReaderViewDetected(visible: Boolean = false) { + Log.i(TAG, "verifyReaderViewDetected: Waiting for $waitingTime ms for reader view button to exist") mDevice.findObject( UiSelector() .description("Reader view"), - ) - .waitForExists(waitingTime) - + ).waitForExists(waitingTime) + Log.i(TAG, "verifyReaderViewDetected: Waited for $waitingTime ms for reader view button to exist") + Log.i(TAG, "verifyReaderViewDetected: Trying to verify that the reader view button is visible") onView( allOf( withParent(withId(R.id.mozac_browser_toolbar_page_actions)), @@ -87,16 +92,20 @@ class NavigationToolbarRobot { ViewAssertions.doesNotExist() }, ) + Log.i(TAG, "verifyReaderViewDetected: Verified that the reader view button is visible") } fun toggleReaderView() { + Log.i(TAG, "toggleReaderView: Waiting for $waitingTime ms for reader view button to exist") mDevice.findObject( UiSelector() .resourceId("$packageName:id/mozac_browser_toolbar_page_actions"), ) .waitForExists(waitingTime) - + Log.i(TAG, "toggleReaderView: Waited for $waitingTime ms for reader view button to exist") + Log.i(TAG, "toggleReaderView: Trying to click the reader view button") readerViewToggle().click() + Log.i(TAG, "toggleReaderView: Clicked the reader view button") } fun verifyClipboardSuggestionsAreDisplayed(link: String = "", shouldBeDisplayed: Boolean) = @@ -109,28 +118,42 @@ class NavigationToolbarRobot { exists = shouldBeDisplayed, ) - fun longClickEditModeToolbar() = - mDevice.findObject(By.res("$packageName:id/mozac_browser_toolbar_edit_url_view")).click(LONG_CLICK_DURATION) + fun longClickEditModeToolbar() { + Log.i(TAG, "longClickEditModeToolbar: Trying to long click the edit mode toolbar") + mDevice.findObject(By.res("$packageName:id/mozac_browser_toolbar_edit_url_view")) + .click(LONG_CLICK_DURATION) + Log.i(TAG, "longClickEditModeToolbar: Long clicked the edit mode toolbar") + } fun clickContextMenuItem(item: String) { mDevice.waitNotNull( Until.findObject(By.text(item)), waitingTime, ) + Log.i(TAG, "clickContextMenuItem: Trying click context menu item: $item") mDevice.findObject(By.text(item)).click() + Log.i(TAG, "clickContextMenuItem: Clicked context menu item: $item") } - fun clickClearToolbarButton() = clearAddressBarButton().click() + fun clickClearToolbarButton() { + Log.i(TAG, "clickClearToolbarButton: Trying click the clear address button") + clearAddressBarButton().click() + Log.i(TAG, "clickClearToolbarButton: Clicked the clear address button") + } fun verifyToolbarIsEmpty() = - itemWithResIdContainingText( - "$packageName:id/mozac_browser_toolbar_edit_url_view", - getStringResource(R.string.search_hint), + assertUIObjectExists( + itemWithResIdContainingText( + "$packageName:id/mozac_browser_toolbar_edit_url_view", + getStringResource(R.string.search_hint), + ), ) // New unified search UI selector fun verifySearchBarPlaceholder(text: String) { + Log.i(TAG, "verifySearchBarPlaceholder: Waiting for $waitingTime ms for the toolbar to exist") urlBar().waitForExists(waitingTime) + Log.i(TAG, "verifySearchBarPlaceholder: Waited for $waitingTime ms for the toolbar to exist") assertItemTextEquals(urlBar(), expectedText = text) } @@ -156,19 +179,21 @@ class NavigationToolbarRobot { sessionLoadedIdlingResource = SessionLoadedIdlingResource() openEditURLView() - Log.i(TAG, "enterURLAndEnterToBrowser: Opened edit mode URL view") - + Log.i(TAG, "enterURLAndEnterToBrowser: Trying to set toolbar text to: $url") awesomeBar().setText(url.toString()) - Log.i(TAG, "enterURLAndEnterToBrowser: Set toolbar text to: $url") + Log.i(TAG, "enterURLAndEnterToBrowser: Toolbar text was set to: $url") + Log.i(TAG, "enterURLAndEnterToBrowser: Trying to press device enter button") mDevice.pressEnter() - Log.i(TAG, "enterURLAndEnterToBrowser: Clicked enter on keyboard, submitted query") + Log.i(TAG, "enterURLAndEnterToBrowser: Pressed device enter button") runWithIdleRes(sessionLoadedIdlingResource) { + Log.i(TAG, "enterURLAndEnterToBrowser: Trying to assert that home screen layout or download button or the total cookie protection contextual hint exist") assertTrue( itemWithResId("$packageName:id/browserLayout").waitForExists(waitingTime) || itemWithResId("$packageName:id/download_button").waitForExists(waitingTime) || itemWithResId("cfr.dismiss").waitForExists(waitingTime), ) + Log.i(TAG, "enterURLAndEnterToBrowser: Asserted that home screen layout or download button or the total cookie protection contextual hint exist") } BrowserRobot().interact() @@ -180,9 +205,12 @@ class NavigationToolbarRobot { interact: BrowserRobot.() -> Unit, ): BrowserRobot.Transition { openEditURLView() - + Log.i(TAG, "enterURLAndEnterToBrowserForTCPCFR: Trying to set toolbar text to: $url") awesomeBar().setText(url.toString()) + Log.i(TAG, "enterURLAndEnterToBrowserForTCPCFR: Toolbar text was set to: $url") + Log.i(TAG, "enterURLAndEnterToBrowserForTCPCFR: Trying to press device enter button") mDevice.pressEnter() + Log.i(TAG, "enterURLAndEnterToBrowserForTCPCFR: Pressed device enter button") BrowserRobot().interact() return BrowserRobot.Transition() @@ -194,12 +222,17 @@ class NavigationToolbarRobot { sessionLoadedIdlingResource = SessionLoadedIdlingResource() openEditURLView() - + Log.i(TAG, "openTabCrashReporter: Trying to set toolbar text to: $crashUrl") awesomeBar().setText(crashUrl) + Log.i(TAG, "openTabCrashReporter: Toolbar text was set to: $crashUrl") + Log.i(TAG, "openTabCrashReporter: Trying to press device enter button") mDevice.pressEnter() + Log.i(TAG, "openTabCrashReporter: Pressed device enter button") runWithIdleRes(sessionLoadedIdlingResource) { + Log.i(TAG, "openTabCrashReporter: Trying to find the tab crasher image") mDevice.findObject(UiSelector().resourceId("$packageName:id/crash_tab_image")) + Log.i(TAG, "openTabCrashReporter: Found the tab crasher image") } BrowserRobot().interact() @@ -208,15 +241,21 @@ class NavigationToolbarRobot { fun openThreeDotMenu(interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition { mDevice.waitNotNull(Until.findObject(By.res("$packageName:id/mozac_browser_toolbar_menu")), waitingTime) + Log.i(TAG, "openThreeDotMenu: Trying to click the main menu button") threeDotButton().click() + Log.i(TAG, "openThreeDotMenu: Clicked the main menu button") ThreeDotMenuMainRobot().interact() return ThreeDotMenuMainRobot.Transition() } fun openTabTray(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + Log.i(TAG, "openTabTray: Waiting for device to be idle for $waitingTime ms") mDevice.waitForIdle(waitingTime) + Log.i(TAG, "openTabTray: Waited for device to be idle for $waitingTime ms") + Log.i(TAG, "openTabTray: Trying to click the tabs tray button") tabTrayButton().click() + Log.i(TAG, "openTabTray: Clicked the tabs tray button") mDevice.waitNotNull( Until.findObject(By.res("$packageName:id/tab_layout")), waitingTime, @@ -229,6 +268,7 @@ class NavigationToolbarRobot { fun openComposeTabDrawer(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition { for (i in 1..Constants.RETRY_COUNT) { try { + Log.i(TAG, "openComposeTabDrawer: Started try #$i") mDevice.waitForObjects( mDevice.findObject( UiSelector() @@ -236,30 +276,40 @@ class NavigationToolbarRobot { ), waitingTime, ) - + Log.i(TAG, "openComposeTabDrawer: Trying to click the tabs tray button") tabTrayButton().click() - + Log.i(TAG, "openComposeTabDrawer: Clicked the tabs tray button") + Log.i(TAG, "openComposeTabDrawer: Trying to verify that the tabs tray exists") composeTestRule.onNodeWithTag(TabsTrayTestTag.tabsTray).assertExists() + Log.i(TAG, "openComposeTabDrawer: Verified that the tabs tray exists") break } catch (e: AssertionError) { + Log.i(TAG, "openComposeTabDrawer: AssertionError caught, executing fallback methods") if (i == Constants.RETRY_COUNT) { throw e } else { + Log.i(TAG, "openComposeTabDrawer: Waiting for device to be idle") mDevice.waitForIdle() + Log.i(TAG, "openComposeTabDrawer: Waited for device to be idle") } } } - + Log.i(TAG, "openComposeTabDrawer: Trying to verify the tabs tray new tab FAB button exists") composeTestRule.onNodeWithTag(TabsTrayTestTag.fab).assertExists() + Log.i(TAG, "openComposeTabDrawer: Verified the tabs tray new tab FAB button exists") ComposeTabDrawerRobot(composeTestRule).interact() return ComposeTabDrawerRobot.Transition(composeTestRule) } fun visitLinkFromClipboard(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "visitLinkFromClipboard: Waiting for $waitingTimeShort ms for clear address button to exist") if (clearAddressBarButton().waitForExists(waitingTimeShort)) { + Log.i(TAG, "visitLinkFromClipboard: Waited for $waitingTimeShort ms for clear address button to exist") + Log.i(TAG, "visitLinkFromClipboard: Trying to click the clear address button") clearAddressBarButton().click() + Log.i(TAG, "visitLinkFromClipboard: Clicked the clear address button") } mDevice.waitNotNull( @@ -275,26 +325,33 @@ class NavigationToolbarRobot { waitingTime, ) } - + Log.i(TAG, "visitLinkFromClipboard: Trying to click the fill link from clipboard button") fillLinkButton().click() + Log.i(TAG, "visitLinkFromClipboard: Clicked the fill link from clipboard button") BrowserRobot().interact() return BrowserRobot.Transition() } fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + Log.i(TAG, "goBackToHomeScreen: Trying to click the device back button") mDevice.pressBack() + Log.i(TAG, "goBackToHomeScreen: Clicked the device back button") + Log.i(TAG, "goBackToHomeScreen: Waiting for $waitingTimeShort ms for $packageName window to be updated") mDevice.waitForWindowUpdate(packageName, waitingTimeShort) + Log.i(TAG, "goBackToHomeScreen: Waited for $waitingTimeShort ms for $packageName window to be updated") HomeScreenRobot().interact() return HomeScreenRobot.Transition() } fun goBackToBrowserScreen(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "goBackToBrowserScreen: Trying to click the device back button") mDevice.pressBack() - Log.i(TAG, "goBackToBrowserScreen: Dismiss awesome bar using device back button") + Log.i(TAG, "goBackToBrowserScreen: Clicked the device back button") + Log.i(TAG, "goBackToBrowserScreen: Waiting for $waitingTimeShort ms for $packageName window to be updated") mDevice.waitForWindowUpdate(packageName, waitingTimeShort) - Log.i(TAG, "goBackToBrowserScreen: Waited $waitingTimeShort for window update") + Log.i(TAG, "goBackToBrowserScreen: Waited for $waitingTimeShort ms for $packageName window to be updated") BrowserRobot().interact() return BrowserRobot.Transition() @@ -302,16 +359,19 @@ class NavigationToolbarRobot { fun openTabButtonShortcutsMenu(interact: NavigationToolbarRobot.() -> Unit): Transition { mDevice.waitNotNull(Until.findObject(By.res("$packageName:id/counter_root"))) + Log.i(TAG, "openTabButtonShortcutsMenu: Trying to long click the tab counter button") tabsCounter().perform(longClick()) - Log.i(TAG, "Tabs counter long-click successful.") + Log.i(TAG, "openTabButtonShortcutsMenu: Long clicked the tab counter button") NavigationToolbarRobot().interact() return Transition() } fun closeTabFromShortcutsMenu(interact: NavigationToolbarRobot.() -> Unit): Transition { + Log.i(TAG, "closeTabFromShortcutsMenu: Waiting for device to be idle for $waitingTime ms") mDevice.waitForIdle(waitingTime) - + Log.i(TAG, "closeTabFromShortcutsMenu: Waited for device to be idle for $waitingTime ms") + Log.i(TAG, "closeTabFromShortcutsMenu: Trying to click the \"Close tab\" button") onView(withId(R.id.mozac_browser_menu_recyclerView)) .perform( RecyclerViewActions.actionOnItem( @@ -321,15 +381,17 @@ class NavigationToolbarRobot { ViewActions.click(), ), ) - Log.i(TAG, "Clicked the tab shortcut Close tab button.") + Log.i(TAG, "closeTabFromShortcutsMenu: Clicked the \"Close tab\" button") NavigationToolbarRobot().interact() return Transition() } fun openNewTabFromShortcutsMenu(interact: SearchRobot.() -> Unit): SearchRobot.Transition { + Log.i(TAG, "openNewTabFromShortcutsMenu: Waiting for device to be idle for $waitingTime ms") mDevice.waitForIdle(waitingTime) - Log.i(TAG, "Looking for tab shortcut New tab button.") + Log.i(TAG, "openNewTabFromShortcutsMenu: Waited for device to be idle for $waitingTime ms") + Log.i(TAG, "openNewTabFromShortcutsMenu: Trying to click the \"New tab\" button") onView(withId(R.id.mozac_browser_menu_recyclerView)) .perform( RecyclerViewActions.actionOnItem( @@ -339,15 +401,17 @@ class NavigationToolbarRobot { ViewActions.click(), ), ) - Log.i(TAG, "Clicked the tab shortcut New tab button.") + Log.i(TAG, "openNewTabFromShortcutsMenu: Clicked the \"New tab\" button") SearchRobot().interact() return SearchRobot.Transition() } fun openNewPrivateTabFromShortcutsMenu(interact: SearchRobot.() -> Unit): SearchRobot.Transition { + Log.i(TAG, "openNewPrivateTabFromShortcutsMenu: Waiting for device to be idle for $waitingTime ms") mDevice.waitForIdle(waitingTime) - Log.i(TAG, "Looking for tab shortcut New private tab button.") + Log.i(TAG, "openNewPrivateTabFromShortcutsMenu: Waited for device to be idle for $waitingTime ms") + Log.i(TAG, "openNewPrivateTabFromShortcutsMenu: Trying to click the \"New private tab\" button") onView(withId(R.id.mozac_browser_menu_recyclerView)) .perform( RecyclerViewActions.actionOnItem( @@ -357,26 +421,33 @@ class NavigationToolbarRobot { ViewActions.click(), ), ) - Log.i(TAG, "Clicked the tab shortcut New private tab button.") + Log.i(TAG, "openNewPrivateTabFromShortcutsMenu: Clicked the \"New private tab\" button") SearchRobot().interact() return SearchRobot.Transition() } fun clickUrlbar(interact: SearchRobot.() -> Unit): SearchRobot.Transition { + Log.i(TAG, "clickUrlbar: Trying to click the toolbar") urlBar().click() - + Log.i(TAG, "clickUrlbar: Clicked the toolbar") + Log.i(TAG, "clickUrlbar: Waiting for $waitingTime ms for the edit mode toolbar to exist") mDevice.findObject( UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_edit_url_view"), ).waitForExists(waitingTime) + Log.i(TAG, "clickUrlbar: Waited for $waitingTime ms for the edit mode toolbar to exist") SearchRobot().interact() return SearchRobot.Transition() } fun clickSearchSelectorButton(interact: SearchRobot.() -> Unit): SearchRobot.Transition { + Log.i(TAG, "clickSearchSelectorButton: Waiting for $waitingTime ms for the search selector button to exist") searchSelectorButton().waitForExists(waitingTime) + Log.i(TAG, "clickSearchSelectorButton: Waited for $waitingTime ms for the search selector button to exist") + Log.i(TAG, "clickSearchSelectorButton: Trying to click the search selector button") searchSelectorButton().click() + Log.i(TAG, "clickSearchSelectorButton: Clicked the search selector button") SearchRobot().interact() return SearchRobot.Transition() @@ -390,11 +461,15 @@ fun navigationToolbar(interact: NavigationToolbarRobot.() -> Unit): NavigationTo } fun openEditURLView() { + Log.i(TAG, "openEditURLView: Waiting for $waitingTime ms for the toolbar to exist") urlBar().waitForExists(waitingTime) + Log.i(TAG, "openEditURLView: Waited for $waitingTime ms for the toolbar to exist") + Log.i(TAG, "openEditURLView: Trying to click the toolbar") urlBar().click() - Log.i(TAG, "openEditURLView: URL bar clicked.") + Log.i(TAG, "openEditURLView: Clicked the toolbar") + Log.i(TAG, "openEditURLView: Waiting for $waitingTime ms for the edit mode toolbar to exist") itemWithResId("$packageName:id/mozac_browser_toolbar_edit_url_view").waitForExists(waitingTime) - Log.i(TAG, "openEditURLView: Edit URL bar displayed.") + Log.i(TAG, "openEditURLView: Waited for $waitingTime ms for the edit mode toolbar to exist") } private fun urlBar() = mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar")) From 11348a2e7f08e43e7aadd093c4e94309b18f4e09 Mon Sep 17 00:00:00 2001 From: DreVla Date: Wed, 10 Jan 2024 16:28:38 +0200 Subject: [PATCH 182/586] Bug 1870701 - Review Checker opt-in privacy policy link and text update Updated the Privacy Policy links and text to clearly explain the minimal nature of data that's collected and processed during Review Checker use in Firefox. --- .../middleware/ReviewQualityCheckNavigationMiddleware.kt | 3 ++- .../shopping/ui/ReviewQualityCheckContextualOnboarding.kt | 7 ++++--- fenix/app/src/main/res/values/strings.xml | 8 ++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/shopping/middleware/ReviewQualityCheckNavigationMiddleware.kt b/fenix/app/src/main/java/org/mozilla/fenix/shopping/middleware/ReviewQualityCheckNavigationMiddleware.kt index 91b846fcebc4..aaa1c4673cfb 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/shopping/middleware/ReviewQualityCheckNavigationMiddleware.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/shopping/middleware/ReviewQualityCheckNavigationMiddleware.kt @@ -13,7 +13,8 @@ import org.mozilla.fenix.shopping.store.ReviewQualityCheckState private const val POWERED_BY_URL = "https://www.fakespot.com/review-checker?utm_source=review-checker" + "&utm_campaign=fakespot-by-mozilla&utm_medium=inproduct&utm_term=core-sheet" -private const val PRIVACY_POLICY_URL = "https://www.fakespot.com/privacy-policy" +private const val PRIVACY_POLICY_URL = "https://www.mozilla.org/en-US/privacy/firefox/#review-checker" + + "?utm_source=review-checker&utm_campaign=privacy-policy&utm_medium=in-product&utm_term=opt-in-screen" private const val TERMS_OF_USE_URL = "https://www.fakespot.com/terms" /** diff --git a/fenix/app/src/main/java/org/mozilla/fenix/shopping/ui/ReviewQualityCheckContextualOnboarding.kt b/fenix/app/src/main/java/org/mozilla/fenix/shopping/ui/ReviewQualityCheckContextualOnboarding.kt index e5c53777b7d0..afa4da62dd4e 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/shopping/ui/ReviewQualityCheckContextualOnboarding.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/shopping/ui/ReviewQualityCheckContextualOnboarding.kt @@ -61,7 +61,7 @@ fun ReviewQualityCheckContextualOnboarding( val learnMoreText = stringResource(id = R.string.review_quality_check_contextual_onboarding_learn_more_link) val privacyPolicyText = - stringResource(id = R.string.review_quality_check_contextual_onboarding_privacy_policy) + stringResource(id = R.string.review_quality_check_contextual_onboarding_privacy_policy_3) val termsOfUseText = stringResource(id = R.string.review_quality_check_contextual_onboarding_terms_use) val titleContentDescription = @@ -113,9 +113,10 @@ fun ReviewQualityCheckContextualOnboarding( LinkText( text = stringResource( - id = R.string.review_quality_check_contextual_onboarding_caption, - stringResource(id = R.string.shopping_product_name), + id = R.string.review_quality_check_contextual_onboarding_caption_3, + stringResource(id = R.string.firefox), privacyPolicyText, + stringResource(id = R.string.shopping_product_name), termsOfUseText, ), linkTextStates = listOf( diff --git a/fenix/app/src/main/res/values/strings.xml b/fenix/app/src/main/res/values/strings.xml index 1796126135be..38148a49f80e 100644 --- a/fenix/app/src/main/res/values/strings.xml +++ b/fenix/app/src/main/res/values/strings.xml @@ -2247,13 +2247,17 @@ Learn more - By selecting “Yes, try it” you agree to %1$s by Mozilla’s %2$s and %3$s. + By selecting “Yes, try it” you agree to %1$s by Mozilla’s %2$s and %3$s. By selecting “Yes, try it” you agree to the following from %1$s: + + By selecting “Yes, try it” you agree to %1$s\'s %2$s and %3$s\'s %4$s. - privacy policy + privacy policy Privacy policy + + privacy notice terms of use From 1659b3bd1097e3a09dc52090e8538cfa56ff4728 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 13 Feb 2024 13:18:55 +0000 Subject: [PATCH 183/586] Update GeckoView (Nightly) to 124.0.20240213093751. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 61f2182a2445..63d33d2f3a30 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240212214644" + const val version = "124.0.20240213093751" /** * GeckoView channel From 7658c557554fd9c31c987ae5b2de4aea33de87c5 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Mon, 12 Feb 2024 15:04:48 -0500 Subject: [PATCH 184/586] Bug 1879944 - Update Compose Compiler to version 1.5.9 --- .../plugins/dependencies/src/main/java/DependenciesPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt index 18dcb3366171..f1daa633fbf8 100644 --- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt +++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt @@ -53,7 +53,7 @@ object Versions { // see https://android-developers.googleblog.com/2022/06/independent-versioning-of-Jetpack-Compose-libraries.html // for Jetpack Compose libraries versioning const val compose_version = "1.5.4" - const val compose_compiler = "1.5.8" + const val compose_compiler = "1.5.9" object AndroidX { const val activityCompose = "1.7.2" From 0c2a6aab6a678ae75a2195daf6734f24883be2cd Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 13 Feb 2024 13:31:12 +0200 Subject: [PATCH 185/586] Bug 1880047 - Add missing pairs of logs to NotificationRobot --- .../fenix/ui/robots/NotificationRobot.kt | 83 ++++++++++++------- 1 file changed, 54 insertions(+), 29 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt index 7398746e95c3..5a6acc9cbeac 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt @@ -29,10 +29,10 @@ class NotificationRobot { var notificationFound = mDevice.findObject(notification).waitForExists(waitingTime) while (!notificationFound) { + Log.i(TAG, "verifySystemNotificationExists: Waiting for $waitingTime ms for notification: $notification to exist") scrollToEnd() - Log.i(TAG, "verifySystemNotificationExists: Scrolling to the end of the notification tray") - Log.i(TAG, "verifySystemNotificationExists: Looking for $notificationMessage notification") notificationFound = mDevice.findObject(notification).waitForExists(waitingTime) + Log.i(TAG, "verifySystemNotificationExists: Waited for $waitingTime ms for notification: $notification to exist") } assertUIObjectExists(itemWithText(notificationMessage)) @@ -40,33 +40,37 @@ class NotificationRobot { fun clearNotifications() { if (clearButton.exists()) { - Log.i(TAG, "clearNotifications: Verified that clear notifications button exists") + Log.i(TAG, "clearNotifications:The clear notifications button exists") + Log.i(TAG, "clearNotifications: Trying to click the clear notifications button") clearButton.click() - Log.i(TAG, "clearNotifications: Clicked clear notifications button") + Log.i(TAG, "clearNotifications: Clicked the clear notifications button") } else { scrollToEnd() - Log.i(TAG, "clearNotifications: Scrolled to end of notifications tray") if (clearButton.exists()) { - Log.i(TAG, "clearNotifications: Verified that clear notifications button exists") + Log.i(TAG, "clearNotifications:The clear notifications button exists") + Log.i(TAG, "clearNotifications: Trying to click the clear notifications button") clearButton.click() - Log.i(TAG, "clearNotifications: Clicked clear notifications button") + Log.i(TAG, "clearNotifications: Clicked the clear notifications button") } else if (notificationTray().exists()) { + Log.i(TAG, "clearNotifications: The notifications tray is still displayed") + Log.i(TAG, "clearNotifications: Trying to click device back button") mDevice.pressBack() - Log.i(TAG, "clearNotifications: Dismiss notifications tray by clicking device back button") + Log.i(TAG, "clearNotifications: Clicked device back button") } } } fun cancelAllShownNotifications() { + Log.i(TAG, "cancelAllShownNotifications: Trying to cancel all system notifications") cancelAll() Log.i(TAG, "cancelAllShownNotifications: Canceled all system notifications") } fun verifySystemNotificationDoesNotExist(notificationMessage: String) { - Log.i(TAG, "verifySystemNotificationDoesNotExist: Waiting for $notificationMessage notification to be gone") + Log.i(TAG, "verifySystemNotificationDoesNotExist: Waiting for $waitingTime ms for notification: $notificationMessage to be gone") mDevice.findObject(UiSelector().textContains(notificationMessage)).waitUntilGone(waitingTime) + Log.i(TAG, "verifySystemNotificationDoesNotExist: Waited for $waitingTime ms for notification: $notificationMessage to be gone") assertUIObjectExists(itemContainingText(notificationMessage), exists = false) - Log.i(TAG, "verifySystemNotificationDoesNotExist: Verified that $notificationMessage notification does not exist") } fun verifyPrivateTabsNotification() { @@ -75,17 +79,22 @@ class NotificationRobot { } fun clickMediaNotificationControlButton(action: String) { + Log.i(TAG, "clickMediaNotificationControlButton: Waiting for $waitingTime ms for the system media control button: $action to exist") mediaSystemNotificationButton(action).waitForExists(waitingTime) + Log.i(TAG, "clickMediaNotificationControlButton: Waited for $waitingTime ms for the system media control button: $action to exist") + Log.i(TAG, "clickMediaNotificationControlButton: Trying to click the system media control button: $action") mediaSystemNotificationButton(action).click() + Log.i(TAG, "clickMediaNotificationControlButton: Clicked the system media control button: $action") } fun clickDownloadNotificationControlButton(action: String) { for (i in 1..RETRY_COUNT) { - Log.i(TAG, "clickPageObject: For loop i = $i") + Log.i(TAG, "clickDownloadNotificationControlButton: Started try #$i") try { assertUIObjectExists(downloadSystemNotificationButton(action)) + Log.i(TAG, "clickDownloadNotificationControlButton: Trying to click the download system notification: $action button and wait for $waitingTimeShort ms for a new window") downloadSystemNotificationButton(action).clickAndWaitForNewWindow(waitingTimeShort) - Log.i(TAG, "clickDownloadNotificationControlButton: Clicked app notification $action button and waits for a new window for $waitingTimeShort ms") + Log.i(TAG, "clickDownloadNotificationControlButton: Clicked the download system notification: $action button and waited for $waitingTimeShort ms for a new window") assertUIObjectExists( downloadSystemNotificationButton(action), exists = false, @@ -93,12 +102,13 @@ class NotificationRobot { break } catch (e: AssertionError) { - Log.i(TAG, "clickDownloadNotificationControlButton: Catch block") + Log.i(TAG, "clickDownloadNotificationControlButton: AssertionError caught, executing fallback methods") if (i == RETRY_COUNT) { throw e } + Log.i(TAG, "clickDownloadNotificationControlButton: Waiting for $waitingTimeShort ms for $packageName window to be updated") mDevice.waitForWindowUpdate(packageName, waitingTimeShort) - Log.i(TAG, "clickDownloadNotificationControlButton: Waited $waitingTimeShort ms for window update") + Log.i(TAG, "clickDownloadNotificationControlButton: Waited for $waitingTimeShort ms for $packageName window to be updated") } } } @@ -108,14 +118,16 @@ class NotificationRobot { fun expandNotificationMessage() { while (!notificationHeader.exists()) { + Log.i(TAG, "expandNotificationMessage: Waiting for $appName notification to exist") scrollToEnd() - Log.i(TAG, "expandNotificationMessage: Scrolled to end of notification tray") } if (notificationHeader.exists()) { + Log.i(TAG, "expandNotificationMessage: $appName notification exists") // expand the notification + Log.i(TAG, "expandNotificationMessage: Trying to click $appName notification") notificationHeader.click() - Log.i(TAG, "expandNotificationMessage: Clicked the app notification") + Log.i(TAG, "expandNotificationMessage: Clicked $appName notification") // double check if notification actions are viewable by checking for action existence; otherwise scroll again while (!mDevice.findObject(UiSelector().resourceId("android:id/action0")).exists() && @@ -123,7 +135,6 @@ class NotificationRobot { ) { Log.i(TAG, "expandNotificationMessage: App notification action buttons do not exist") scrollToEnd() - Log.i(TAG, "expandNotificationMessage: Scrolled to end of notification tray") } } } @@ -136,41 +147,46 @@ class NotificationRobot { ) { // In case it fails, retry max 3x the swipe action on download system notifications for (i in 1..RETRY_COUNT) { - Log.i(TAG, "swipeDownloadNotification: For loop i = $i") + Log.i(TAG, "swipeDownloadNotification: Started try #$i") try { - Log.i(TAG, "swipeDownloadNotification: Try block") var retries = 0 while (itemContainingText(appName).exists() && retries++ < 3) { - Log.i(TAG, "swipeDownloadNotification: While loop retries = $retries") // Swipe left the download system notification if (direction == "Left") { itemContainingText(appName) .also { + Log.i(TAG, "swipeDownloadNotification: Waiting for $waitingTime ms for $appName notification to exist") it.waitForExists(waitingTime) + Log.i(TAG, "swipeDownloadNotification: Waited for $waitingTime ms for $appName notification to exist") + Log.i(TAG, "swipeDownloadNotification: Trying to perform swipe left action on $appName notification") it.swipeLeft(3) + Log.i(TAG, "swipeDownloadNotification: Performed swipe left action on $appName notification") } - Log.i(TAG, "swipeDownloadNotification: Swiped left download notification") } else { // Swipe right the download system notification itemContainingText(appName) .also { + Log.i(TAG, "swipeDownloadNotification: Waiting for $waitingTime ms for $appName notification to exist") it.waitForExists(waitingTime) + Log.i(TAG, "swipeDownloadNotification: Waited for $waitingTime ms for $appName notification to exist") + Log.i(TAG, "swipeDownloadNotification: Trying to perform swipe right action on $appName notification") it.swipeRight(3) + Log.i(TAG, "swipeDownloadNotification: Performed swipe right action on $appName notification") } - Log.i(TAG, "swipeDownloadNotification: Swiped right download notification") } } // Not all download related system notifications can be dismissed if (shouldDismissNotification) { + Log.i(TAG, "swipeDownloadNotification: $appName notification can't be dismissed: $shouldDismissNotification") assertUIObjectExists(itemContainingText(appName), exists = false) } else { + Log.i(TAG, "swipeDownloadNotification: $appName notification can be dismissed: $shouldDismissNotification") assertUIObjectExists(itemContainingText(appName)) - Log.i(TAG, "swipeDownloadNotification: Verified that $appName notification exist") } break } catch (e: AssertionError) { - Log.i(TAG, "swipeDownloadNotification: Catch block") + Log.i(TAG, "swipeDownloadNotification: AssertionError caught, executing fallback methods") if (i == RETRY_COUNT) { throw e } else { @@ -179,11 +195,12 @@ class NotificationRobot { }.openNotificationShade { // The download complete system notification can't be expanded if (canExpandNotification) { + Log.i(TAG, "swipeDownloadNotification: $appName notification can be expanded: $canExpandNotification") // In all cases the download system notification title will be the app name verifySystemNotificationExists(appName) - Log.i(TAG, "swipeDownloadNotification: Verified that $appName notification exist") expandNotificationMessage() } else { + Log.i(TAG, "swipeDownloadNotification: $appName notification can't be expanded: $canExpandNotification") // Using the download completed system notification summary to bring in to view an properly verify it verifySystemNotificationExists("Download completed") } @@ -194,10 +211,12 @@ class NotificationRobot { } fun clickNotification(notificationMessage: String) { - Log.i(TAG, "clickNotification: Looking for $notificationMessage notification") + Log.i(TAG, "clickNotification: Waiting for $waitingTime ms for $notificationMessage notification to exist") mDevice.findObject(UiSelector().text(notificationMessage)).waitForExists(waitingTime) + Log.i(TAG, "clickNotification: Waited for $waitingTime ms for $notificationMessage notification to exist") + Log.i(TAG, "clickNotification: Trying to click the $notificationMessage notification and wait for $waitingTimeShort ms for a new window") mDevice.findObject(UiSelector().text(notificationMessage)).clickAndWaitForNewWindow(waitingTimeShort) - Log.i(TAG, "clickNotification: Clicked $notificationMessage notification and waiting for $waitingTimeShort ms for a new window") + Log.i(TAG, "clickNotification: Clicked the $notificationMessage notification and waited for $waitingTimeShort ms for a new window") } class Transition { @@ -206,18 +225,22 @@ class NotificationRobot { try { assertUIObjectExists(closePrivateTabsNotification()) } catch (e: AssertionError) { + Log.i(TAG, "clickClosePrivateTabsNotification: Trying to perform fling action to the end of the notification tray") notificationTray().flingToEnd(1) + Log.i(TAG, "clickClosePrivateTabsNotification: Performed fling action to the end of the notification tray") } - + Log.i(TAG, "clickClosePrivateTabsNotification: Trying to click the close private tabs notification") closePrivateTabsNotification().click() + Log.i(TAG, "clickClosePrivateTabsNotification: Clicked the close private tabs notification") HomeScreenRobot().interact() return HomeScreenRobot.Transition() } fun closeNotificationTray(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "closeNotificationTray: Trying to click device back button") mDevice.pressBack() - Log.i(TAG, "closeNotificationTray: Closed notification tray using device back button") + Log.i(TAG, "closeNotificationTray: Clicked device back button") BrowserRobot().interact() return BrowserRobot.Transition() @@ -259,7 +282,9 @@ private val notificationHeader = ) private fun scrollToEnd() { + Log.i(TAG, "scrollToEnd: Trying to perform scroll to the end of the notification tray action") notificationTray().scrollToEnd(1) + Log.i(TAG, "scrollToEnd: Performed scroll to the end of the notification tray action") } private val clearButton = mDevice.findObject(UiSelector().resourceId("com.android.systemui:id/dismiss_text")) From d947b10eaf6fbb4b761bc8d95460ceb4017586d4 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 13 Feb 2024 16:02:48 +0200 Subject: [PATCH 186/586] Bug 1880047 - Convert private variables to functions so they don't get initialised --- .../fenix/ui/robots/NotificationRobot.kt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt index 5a6acc9cbeac..99cbbf9a6906 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt @@ -39,17 +39,17 @@ class NotificationRobot { } fun clearNotifications() { - if (clearButton.exists()) { + if (clearButton().exists()) { Log.i(TAG, "clearNotifications:The clear notifications button exists") Log.i(TAG, "clearNotifications: Trying to click the clear notifications button") - clearButton.click() + clearButton().click() Log.i(TAG, "clearNotifications: Clicked the clear notifications button") } else { scrollToEnd() - if (clearButton.exists()) { + if (clearButton().exists()) { Log.i(TAG, "clearNotifications:The clear notifications button exists") Log.i(TAG, "clearNotifications: Trying to click the clear notifications button") - clearButton.click() + clearButton().click() Log.i(TAG, "clearNotifications: Clicked the clear notifications button") } else if (notificationTray().exists()) { Log.i(TAG, "clearNotifications: The notifications tray is still displayed") @@ -117,16 +117,16 @@ class NotificationRobot { assertUIObjectExists(mediaSystemNotificationButton(action)) fun expandNotificationMessage() { - while (!notificationHeader.exists()) { + while (!notificationHeader().exists()) { Log.i(TAG, "expandNotificationMessage: Waiting for $appName notification to exist") scrollToEnd() } - if (notificationHeader.exists()) { + if (notificationHeader().exists()) { Log.i(TAG, "expandNotificationMessage: $appName notification exists") // expand the notification Log.i(TAG, "expandNotificationMessage: Trying to click $appName notification") - notificationHeader.click() + notificationHeader().click() Log.i(TAG, "expandNotificationMessage: Clicked $appName notification") // double check if notification actions are viewable by checking for action existence; otherwise scroll again @@ -274,7 +274,7 @@ private fun notificationTray() = UiScrollable( UiSelector().resourceId("com.android.systemui:id/notification_stack_scroller"), ).setAsVerticalList() -private val notificationHeader = +private fun notificationHeader() = mDevice.findObject( UiSelector() .resourceId("android:id/app_name_text") @@ -287,7 +287,7 @@ private fun scrollToEnd() { Log.i(TAG, "scrollToEnd: Performed scroll to the end of the notification tray action") } -private val clearButton = mDevice.findObject(UiSelector().resourceId("com.android.systemui:id/dismiss_text")) +private fun clearButton() = mDevice.findObject(UiSelector().resourceId("com.android.systemui:id/dismiss_text")) private fun cancelAll() { val notificationManager: NotificationManager = From ed17a80811b9cba9902c015021f54c71d48d46bc Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 13 Feb 2024 14:21:00 +0200 Subject: [PATCH 187/586] Bug 1880064 - Add logs to PwaRobot --- .../java/org/mozilla/fenix/ui/robots/PwaRobot.kt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/PwaRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/PwaRobot.kt index f9e050526cd4..0de5dc465a3c 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/PwaRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/PwaRobot.kt @@ -4,24 +4,32 @@ package org.mozilla.fenix.ui.robots +import android.util.Log import androidx.test.uiautomator.UiSelector import org.junit.Assert.assertTrue import org.mozilla.fenix.helpers.AppAndSystemHelper.isExternalAppBrowserActivityInCurrentTask +import org.mozilla.fenix.helpers.Constants +import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists +import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName class PwaRobot { - fun verifyCustomTabToolbarIsNotDisplayed() = assertUIObjectExists(customTabToolbar(), exists = false) - fun verifyPwaActivityInCurrentTask() = assertTrue(isExternalAppBrowserActivityInCurrentTask()) + fun verifyCustomTabToolbarIsNotDisplayed() = assertUIObjectExists(itemWithResId("$packageName:id/toolbar"), exists = false) + fun verifyPwaActivityInCurrentTask() { + Log.i(TAG, "Trying to verify that the latest activity of the application is used for custom tabs or PWAs") + assertTrue(isExternalAppBrowserActivityInCurrentTask()) + Log.i(TAG, "Verified that the latest activity of the application is used for custom tabs or PWAs") + } class Transition } fun pwaScreen(interact: PwaRobot.() -> Unit): PwaRobot.Transition { + Log.i(TAG, "pwaScreen: Trying to find the engine view") mDevice.findObject(UiSelector().resourceId("$packageName:id/engineView")) + Log.i(Constants.TAG, "pwaScreen: Found the engine view") PwaRobot().interact() return PwaRobot.Transition() } - -private fun customTabToolbar() = mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar")) From 2763c7f3d8eec8e825e7a0e90cf70a37823d6f1b Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 13 Feb 2024 14:30:48 +0200 Subject: [PATCH 188/586] Bug 1880064 - Remove redundant assertion functions from ReaderViewRobot --- .../fenix/ui/robots/ReaderViewRobot.kt | 117 +++++++----------- 1 file changed, 45 insertions(+), 72 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ReaderViewRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ReaderViewRobot.kt index 89bd934fbe1b..910dd846e9a1 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ReaderViewRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ReaderViewRobot.kt @@ -25,31 +25,67 @@ import org.mozilla.fenix.helpers.click class ReaderViewRobot { fun verifyAppearanceFontGroup(visible: Boolean = false): ViewInteraction = - assertAppearanceFontGroup(visible) + onView( + withId(R.id.mozac_feature_readerview_font_group), + ).check( + matches(withEffectiveVisibility(visibleOrGone(visible))), + ) fun verifyAppearanceFontSansSerif(visible: Boolean = false): ViewInteraction = - assertAppearanceFontSansSerif(visible) + onView( + withId(R.id.mozac_feature_readerview_font_sans_serif), + ).check( + matches(withEffectiveVisibility(visibleOrGone(visible))), + ) fun verifyAppearanceFontSerif(visible: Boolean = false): ViewInteraction = - assertAppearanceFontSerif(visible) + onView( + withId(R.id.mozac_feature_readerview_font_serif), + ).check( + matches(withEffectiveVisibility(visibleOrGone(visible))), + ) fun verifyAppearanceFontDecrease(visible: Boolean = false): ViewInteraction = - assertAppearanceFontDecrease(visible) + onView( + withId(R.id.mozac_feature_readerview_font_size_decrease), + ).check( + matches(withEffectiveVisibility(visibleOrGone(visible))), + ) fun verifyAppearanceFontIncrease(visible: Boolean = false): ViewInteraction = - assertAppearanceFontIncrease(visible) + onView( + withId(R.id.mozac_feature_readerview_font_size_increase), + ).check( + matches(withEffectiveVisibility(visibleOrGone(visible))), + ) fun verifyAppearanceColorGroup(visible: Boolean = false): ViewInteraction = - assertAppearanceColorGroup(visible) + onView( + withId(R.id.mozac_feature_readerview_color_scheme_group), + ).check( + matches(withEffectiveVisibility(visibleOrGone(visible))), + ) fun verifyAppearanceColorSepia(visible: Boolean = false): ViewInteraction = - assertAppearanceColorSepia(visible) + onView( + withId(R.id.mozac_feature_readerview_color_sepia), + ).check( + matches(withEffectiveVisibility(visibleOrGone(visible))), + ) fun verifyAppearanceColorDark(visible: Boolean = false): ViewInteraction = - assertAppearanceColorDark(visible) + onView( + withId(R.id.mozac_feature_readerview_color_dark), + ).check( + matches(withEffectiveVisibility(visibleOrGone(visible))), + ) fun verifyAppearanceColorLight(visible: Boolean = false): ViewInteraction = - assertAppearanceColorLight(visible) + onView( + withId(R.id.mozac_feature_readerview_color_light), + ).check( + matches(withEffectiveVisibility(visibleOrGone(visible))), + ) fun verifyAppearanceFontIsActive(fontType: String) { val fontTypeKey: String = "mozac-readerview-fonttype" @@ -189,68 +225,5 @@ fun readerViewRobot(interact: ReaderViewRobot.() -> Unit): ReaderViewRobot.Trans return ReaderViewRobot.Transition() } -private fun assertAppearanceFontGroup(visible: Boolean) = - onView( - withId(R.id.mozac_feature_readerview_font_group), - ).check( - matches(withEffectiveVisibility(visibleOrGone(visible))), - ) - -private fun assertAppearanceFontSansSerif(visible: Boolean) = - onView( - withId(R.id.mozac_feature_readerview_font_sans_serif), - ).check( - matches(withEffectiveVisibility(visibleOrGone(visible))), - ) - -private fun assertAppearanceFontSerif(visible: Boolean) = - onView( - withId(R.id.mozac_feature_readerview_font_serif), - ).check( - matches(withEffectiveVisibility(visibleOrGone(visible))), - ) - -private fun assertAppearanceFontDecrease(visible: Boolean) = - onView( - withId(R.id.mozac_feature_readerview_font_size_decrease), - ).check( - matches(withEffectiveVisibility(visibleOrGone(visible))), - ) - -private fun assertAppearanceFontIncrease(visible: Boolean) = - onView( - withId(R.id.mozac_feature_readerview_font_size_increase), - ).check( - matches(withEffectiveVisibility(visibleOrGone(visible))), - ) - -private fun assertAppearanceColorDark(visible: Boolean) = - onView( - withId(R.id.mozac_feature_readerview_color_dark), - ).check( - matches(withEffectiveVisibility(visibleOrGone(visible))), - ) - -private fun assertAppearanceColorLight(visible: Boolean) = - onView( - withId(R.id.mozac_feature_readerview_color_light), - ).check( - matches(withEffectiveVisibility(visibleOrGone(visible))), - ) - -private fun assertAppearanceColorSepia(visible: Boolean) = - onView( - withId(R.id.mozac_feature_readerview_color_sepia), - ).check( - matches(withEffectiveVisibility(visibleOrGone(visible))), - ) - -private fun assertAppearanceColorGroup(visible: Boolean) = - onView( - withId(R.id.mozac_feature_readerview_color_scheme_group), - ).check( - matches(withEffectiveVisibility(visibleOrGone(visible))), - ) - private fun visibleOrGone(visibility: Boolean) = if (visibility) ViewMatchers.Visibility.VISIBLE else ViewMatchers.Visibility.GONE From 529d1ac674a8fb2e5d555e1f5aab37fc78329864 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 13 Feb 2024 15:01:48 +0200 Subject: [PATCH 189/586] Bug 1880064 - Add logs to ReaderViewRobot --- .../fenix/helpers/AppAndSystemHelper.kt | 1 + .../org/mozilla/fenix/ui/robots/PwaRobot.kt | 4 +- .../fenix/ui/robots/ReaderViewRobot.kt | 82 ++++++++++++++----- 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt index f9b95a2dc478..e3c4e532f164 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt @@ -226,6 +226,7 @@ object AppAndSystemHelper { * @return Boolean value that helps us know if the current activity supports custom tabs or PWAs. */ fun isExternalAppBrowserActivityInCurrentTask(): Boolean { + Log.i(TAG, "Trying to verify that the latest activity of the application is used for custom tabs or PWAs") val activityManager = TestHelper.appContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager mDevice.waitForIdle(TestAssetHelper.waitingTimeShort) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/PwaRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/PwaRobot.kt index 0de5dc465a3c..cd31c2fc8628 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/PwaRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/PwaRobot.kt @@ -18,9 +18,7 @@ import org.mozilla.fenix.helpers.TestHelper.packageName class PwaRobot { fun verifyCustomTabToolbarIsNotDisplayed() = assertUIObjectExists(itemWithResId("$packageName:id/toolbar"), exists = false) fun verifyPwaActivityInCurrentTask() { - Log.i(TAG, "Trying to verify that the latest activity of the application is used for custom tabs or PWAs") - assertTrue(isExternalAppBrowserActivityInCurrentTask()) - Log.i(TAG, "Verified that the latest activity of the application is used for custom tabs or PWAs") + assertTrue("$TAG: The latest activity of the application is not used for custom tabs or PWAs", isExternalAppBrowserActivityInCurrentTask()) } class Transition diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ReaderViewRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ReaderViewRobot.kt index 910dd846e9a1..30d87d72c985 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ReaderViewRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ReaderViewRobot.kt @@ -7,8 +7,8 @@ package org.mozilla.fenix.ui.robots import android.content.Context +import android.util.Log import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.ViewInteraction import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility @@ -16,6 +16,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.platform.app.InstrumentationRegistry import org.junit.Assert.assertEquals import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.click @@ -24,70 +25,98 @@ import org.mozilla.fenix.helpers.click */ class ReaderViewRobot { - fun verifyAppearanceFontGroup(visible: Boolean = false): ViewInteraction = + fun verifyAppearanceFontGroup(visible: Boolean = false) { + Log.i(TAG, "verifyAppearanceFontGroup: Trying to verify that the font group buttons are visible: $visible") onView( withId(R.id.mozac_feature_readerview_font_group), ).check( matches(withEffectiveVisibility(visibleOrGone(visible))), ) + Log.i(TAG, "verifyAppearanceFontGroup: Verified that the font group buttons are visible: $visible") + } - fun verifyAppearanceFontSansSerif(visible: Boolean = false): ViewInteraction = + fun verifyAppearanceFontSansSerif(visible: Boolean = false) { + Log.i(TAG, "verifyAppearanceFontSansSerif: Trying to verify that the sans serif font button is visible: $visible") onView( withId(R.id.mozac_feature_readerview_font_sans_serif), ).check( matches(withEffectiveVisibility(visibleOrGone(visible))), ) + Log.i(TAG, "verifyAppearanceFontSansSerif: Verified that the sans serif font button is visible: $visible") + } - fun verifyAppearanceFontSerif(visible: Boolean = false): ViewInteraction = + fun verifyAppearanceFontSerif(visible: Boolean = false) { + Log.i(TAG, "verifyAppearanceFontSerif: Trying to verify that the serif font button is visible: $visible") onView( withId(R.id.mozac_feature_readerview_font_serif), ).check( matches(withEffectiveVisibility(visibleOrGone(visible))), ) + Log.i(TAG, "verifyAppearanceFontSerif: Verified that the serif font button is visible: $visible") + } - fun verifyAppearanceFontDecrease(visible: Boolean = false): ViewInteraction = + fun verifyAppearanceFontDecrease(visible: Boolean = false) { + Log.i(TAG, "verifyAppearanceFontDecrease: Trying to verify that the decrease font button is visible: $visible") onView( withId(R.id.mozac_feature_readerview_font_size_decrease), ).check( matches(withEffectiveVisibility(visibleOrGone(visible))), ) + Log.i(TAG, "verifyAppearanceFontDecrease: Verified that the decrease font button is visible: $visible") + } - fun verifyAppearanceFontIncrease(visible: Boolean = false): ViewInteraction = + fun verifyAppearanceFontIncrease(visible: Boolean = false) { + Log.i(TAG, "verifyAppearanceFontIncrease: Trying to verify that the increase font button is visible: $visible") onView( withId(R.id.mozac_feature_readerview_font_size_increase), ).check( matches(withEffectiveVisibility(visibleOrGone(visible))), ) + Log.i(TAG, "verifyAppearanceFontIncrease: Verified that the increase font button is visible: $visible") + } - fun verifyAppearanceColorGroup(visible: Boolean = false): ViewInteraction = + fun verifyAppearanceColorGroup(visible: Boolean = false) { + Log.i(TAG, "verifyAppearanceColorGroup: Trying to verify that the color group buttons are visible: $visible") onView( withId(R.id.mozac_feature_readerview_color_scheme_group), ).check( matches(withEffectiveVisibility(visibleOrGone(visible))), ) + Log.i(TAG, "verifyAppearanceColorGroup: Verified that the color group buttons are visible: $visible") + } - fun verifyAppearanceColorSepia(visible: Boolean = false): ViewInteraction = + fun verifyAppearanceColorSepia(visible: Boolean = false) { + Log.i(TAG, "verifyAppearanceColorSepia: Trying to verify that the sepia color button is visible: $visible") onView( withId(R.id.mozac_feature_readerview_color_sepia), ).check( matches(withEffectiveVisibility(visibleOrGone(visible))), ) + Log.i(TAG, "verifyAppearanceColorSepia: Verified that the sepia color button is visible: $visible") + } - fun verifyAppearanceColorDark(visible: Boolean = false): ViewInteraction = + fun verifyAppearanceColorDark(visible: Boolean = false) { + Log.i(TAG, "verifyAppearanceColorDark: Trying to verify that the dark color button is visible: $visible") onView( withId(R.id.mozac_feature_readerview_color_dark), ).check( matches(withEffectiveVisibility(visibleOrGone(visible))), ) + Log.i(TAG, "verifyAppearanceColorDark: Verified that the dark color button is visible: $visible") + } - fun verifyAppearanceColorLight(visible: Boolean = false): ViewInteraction = + fun verifyAppearanceColorLight(visible: Boolean = false) { + Log.i(TAG, "verifyAppearanceColorLight: Trying to verify that the light color button is visible: $visible") onView( withId(R.id.mozac_feature_readerview_color_light), ).check( matches(withEffectiveVisibility(visibleOrGone(visible))), ) + Log.i(TAG, "verifyAppearanceColorLight: Verified that the light color button is visible: $visible") + } fun verifyAppearanceFontIsActive(fontType: String) { + Log.i(TAG, "verifyAppearanceFontIsActive: Trying to verify that the font type is: $fontType") val fontTypeKey: String = "mozac-readerview-fonttype" val prefs = InstrumentationRegistry.getInstrumentation() @@ -97,9 +126,11 @@ class ReaderViewRobot { ) assertEquals(fontType, prefs.getString(fontTypeKey, "")) + Log.i(TAG, "verifyAppearanceFontIsActive: Verified that the font type is: $fontType") } fun verifyAppearanceFontSize(expectedFontSize: Int) { + Log.i(TAG, "verifyAppearanceFontSize: Trying to verify that the font size is: $expectedFontSize") val fontSizeKey: String = "mozac-readerview-fontsize" val prefs = InstrumentationRegistry.getInstrumentation() @@ -111,9 +142,11 @@ class ReaderViewRobot { val fontSizeKeyValue = prefs.getInt(fontSizeKey, 3) assertEquals(expectedFontSize, fontSizeKeyValue) + Log.i(TAG, "verifyAppearanceFontSize: Verified that the font size is: $expectedFontSize") } fun verifyAppearanceColorSchemeChange(expectedColorScheme: String) { + Log.i(TAG, "verifyAppearanceColorSchemeChange: Trying to verify that the color scheme is: $expectedColorScheme") val colorSchemeKey: String = "mozac-readerview-colorscheme" val prefs = InstrumentationRegistry.getInstrumentation() @@ -123,12 +156,15 @@ class ReaderViewRobot { ) assertEquals(expectedColorScheme, prefs.getString(colorSchemeKey, "")) + Log.i(TAG, "verifyAppearanceColorSchemeChange: Verified that the color scheme is: $expectedColorScheme") } class Transition { fun closeAppearanceMenu(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "closeAppearanceMenu: Trying to click device back button") mDevice.pressBack() + Log.i(TAG, "closeAppearanceMenu: Clicked device back button") BrowserRobot().interact() return BrowserRobot.Transition() @@ -139,8 +175,9 @@ class ReaderViewRobot { onView( withId(R.id.mozac_feature_readerview_font_sans_serif), ) - + Log.i(TAG, "toggleSansSerif: Trying to click sans serif button") sansSerifButton().click() + Log.i(TAG, "toggleSansSerif: Clicked sans serif button") ReaderViewRobot().interact() return Transition() @@ -151,8 +188,9 @@ class ReaderViewRobot { onView( withId(R.id.mozac_feature_readerview_font_serif), ) - + Log.i(TAG, "toggleSerif: Trying to click serif button") serifButton().click() + Log.i(TAG, "toggleSerif: Clicked serif button") ReaderViewRobot().interact() return Transition() @@ -163,8 +201,9 @@ class ReaderViewRobot { onView( withId(R.id.mozac_feature_readerview_font_size_decrease), ) - + Log.i(TAG, "toggleFontSizeDecrease: Trying to click the decrease font button") fontSizeDecrease().click() + Log.i(TAG, "toggleFontSizeDecrease: Clicked the decrease font button") ReaderViewRobot().interact() return Transition() @@ -175,8 +214,9 @@ class ReaderViewRobot { onView( withId(R.id.mozac_feature_readerview_font_size_increase), ) - + Log.i(TAG, "toggleFontSizeIncrease: Trying to click the increase font button") fontSizeIncrease().click() + Log.i(TAG, "toggleFontSizeIncrease: Clicked the increase font button") ReaderViewRobot().interact() return Transition() @@ -187,8 +227,9 @@ class ReaderViewRobot { onView( withId(R.id.mozac_feature_readerview_color_light), ) - + Log.i(TAG, "toggleColorSchemeChangeLight: Trying to click the light color button") toggleLightColorSchemeButton().click() + Log.i(TAG, "toggleColorSchemeChangeLight: Clicked the light color button") ReaderViewRobot().interact() return Transition() @@ -199,8 +240,9 @@ class ReaderViewRobot { onView( withId(R.id.mozac_feature_readerview_color_dark), ) - + Log.i(TAG, "toggleColorSchemeChangeDark: Trying to click the dark color button") toggleDarkColorSchemeButton().click() + Log.i(TAG, "toggleColorSchemeChangeDark: Clicked the dark color button") ReaderViewRobot().interact() return Transition() @@ -211,8 +253,9 @@ class ReaderViewRobot { onView( withId(R.id.mozac_feature_readerview_color_sepia), ) - + Log.i(TAG, "toggleColorSchemeChangeSepia: Trying to click the sepia color button") toggleSepiaColorSchemeButton().click() + Log.i(TAG, "toggleColorSchemeChangeSepia: Clicked the sepia color button") ReaderViewRobot().interact() return Transition() @@ -220,10 +263,5 @@ class ReaderViewRobot { } } -fun readerViewRobot(interact: ReaderViewRobot.() -> Unit): ReaderViewRobot.Transition { - ReaderViewRobot().interact() - return ReaderViewRobot.Transition() -} - private fun visibleOrGone(visibility: Boolean) = if (visibility) ViewMatchers.Visibility.VISIBLE else ViewMatchers.Visibility.GONE From 27fdbc45b0120f82cfff0e1106ba39768ef9ef94 Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Wed, 30 Aug 2023 08:57:38 +0300 Subject: [PATCH 190/586] Bug 1850316 - Update androidx navigation. --- .../plugins/dependencies/src/main/java/DependenciesPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt index f1daa633fbf8..6d5ceb48b655 100644 --- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt +++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt @@ -81,7 +81,7 @@ object Versions { const val preferences = "1.2.1" const val lifecycle = "2.7.0" const val media = "1.7.0" - const val navigation = "2.5.3" + const val navigation = "2.7.7" const val work = "2.7.1" const val arch = "2.2.0" const val uiautomator = "2.2.0" From d79a60ca88841d208ba36b6768e2411cf44afdf6 Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Thu, 27 Jul 2023 13:30:14 +0300 Subject: [PATCH 191/586] Bug 1850316 - Remove navigation library duplication from FenixDependencies. --- .../plugins/dependencies/src/main/java/DependenciesPlugin.kt | 3 +++ fenix/app/build.gradle | 4 ++-- fenix/build.gradle | 2 +- .../src/main/java/FenixDependenciesPlugin.kt | 2 ++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt index 6d5ceb48b655..ceb34e7696c2 100644 --- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt +++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt @@ -129,6 +129,9 @@ object ComponentsDependencies { const val androidx_compose_foundation = "androidx.compose.foundation:foundation:${Versions.AndroidX.compose}" const val androidx_compose_material = "androidx.compose.material:material:${Versions.AndroidX.compose}" const val androidx_compose_runtime_livedata = "androidx.compose.runtime:runtime-livedata:${Versions.AndroidX.compose}" + const val androidx_safeargs = "androidx.navigation:navigation-safe-args-gradle-plugin:${Versions.AndroidX.navigation}" + const val androidx_navigation_fragment = "androidx.navigation:navigation-fragment-ktx:${Versions.AndroidX.navigation}" + const val androidx_navigation_ui = "androidx.navigation:navigation-ui:$${Versions.AndroidX.navigation}" const val androidx_compose_navigation = "androidx.navigation:navigation-compose:${Versions.AndroidX.navigation}" const val androidx_constraintlayout = "androidx.constraintlayout:constraintlayout:${Versions.AndroidX.constraintlayout}" const val androidx_core = "androidx.core:core:${Versions.AndroidX.core}" diff --git a/fenix/app/build.gradle b/fenix/app/build.gradle index bacca971143b..4a689a89a7ab 100644 --- a/fenix/app/build.gradle +++ b/fenix/app/build.gradle @@ -640,8 +640,8 @@ dependencies { implementation ComponentsDependencies.androidx_paging implementation ComponentsDependencies.androidx_preferences implementation ComponentsDependencies.androidx_fragment - implementation FenixDependencies.androidx_navigation_fragment - implementation FenixDependencies.androidx_navigation_ui + implementation ComponentsDependencies.androidx_navigation_fragment + implementation ComponentsDependencies.androidx_navigation_ui implementation ComponentsDependencies.androidx_compose_navigation implementation ComponentsDependencies.androidx_recyclerview diff --git a/fenix/build.gradle b/fenix/build.gradle index cb9ff542e225..bd002d017909 100644 --- a/fenix/build.gradle +++ b/fenix/build.gradle @@ -78,7 +78,7 @@ buildscript { classpath ComponentsDependencies.tools_androidgradle classpath ComponentsDependencies.tools_kotlingradle classpath FenixDependencies.tools_benchmarkgradle - classpath FenixDependencies.androidx_safeargs + classpath ComponentsDependencies.androidx_safeargs classpath FenixDependencies.osslicenses_plugin classpath "org.mozilla.telemetry:glean-gradle-plugin:${Versions.mozilla_glean}" classpath "${ApplicationServicesConfig.groupId}:tooling-nimbus-gradle:${ApplicationServicesConfig.version}" diff --git a/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt b/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt index efc00ff779f4..a8657de948a8 100644 --- a/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt +++ b/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt @@ -22,6 +22,7 @@ object FenixVersions { const val androidx_benchmark = "1.2.2" const val androidx_profileinstaller = "1.3.1" const val androidx_legacy = "1.0.0" + const val androidx_lifecycle = "2.6.1" const val androidx_navigation = "2.5.3" const val androidx_splash_screen = "1.0.1" const val androidx_transition = "1.4.1" @@ -55,6 +56,7 @@ object FenixDependencies { const val androidx_profileinstaller = "androidx.profileinstaller:profileinstaller:${FenixVersions.androidx_profileinstaller}" const val androidx_activity_ktx = "androidx.activity:activity-ktx:${FenixVersions.androidx_activity}" const val androidx_legacy = "androidx.legacy:legacy-support-v4:${FenixVersions.androidx_legacy}" + const val androidx_lifecycle_common = "androidx.lifecycle:lifecycle-common:${FenixVersions.androidx_lifecycle}" const val androidx_safeargs = "androidx.navigation:navigation-safe-args-gradle-plugin:${FenixVersions.androidx_navigation}" const val androidx_navigation_fragment = "androidx.navigation:navigation-fragment-ktx:${FenixVersions.androidx_navigation}" const val androidx_navigation_ui = "androidx.navigation:navigation-ui:${FenixVersions.androidx_navigation}" From 9df75c1ca170796d5cb9df47d175059902934135 Mon Sep 17 00:00:00 2001 From: mcarare <48995920+mcarare@users.noreply.github.com> Date: Thu, 27 Jul 2023 15:01:57 +0300 Subject: [PATCH 192/586] Bug 1850316 - Use alternative ways to get backQueue elements. backQueue is now private in NavController. --- .../src/main/java/org/mozilla/fenix/ext/NavController.kt | 2 +- .../java/org/mozilla/fenix/search/SearchDialogFragment.kt | 2 +- .../org/mozilla/fenix/search/SearchDialogFragmentTest.kt | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/ext/NavController.kt b/fenix/app/src/main/java/org/mozilla/fenix/ext/NavController.kt index 07e9713b98d8..e768d72f2a13 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/ext/NavController.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/ext/NavController.kt @@ -68,7 +68,7 @@ fun NavController.navigateWithBreadcrumb( */ @SuppressLint("RestrictedApi") fun NavController.hasTopDestination(fragmentClassName: String): Boolean { - return this.backQueue.lastOrNull()?.destination?.displayName?.contains( + return this.currentBackStackEntry?.destination?.displayName?.contains( fragmentClassName, true, ) == true diff --git a/fenix/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt index f6fd7de78d38..c41d5ea4c2af 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt @@ -959,7 +959,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { internal fun getPreviousDestination(): NavBackStackEntry? { // This duplicates the platform functionality for "previousBackStackEntry" but additionally skips this entry. - val descendingEntries = findNavController().backQueue.reversed().iterator() + val descendingEntries = findNavController().currentBackStack.value.reversed().iterator() // Throw the topmost destination away. if (descendingEntries.hasNext()) { descendingEntries.next() diff --git a/fenix/app/src/test/java/org/mozilla/fenix/search/SearchDialogFragmentTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/search/SearchDialogFragmentTest.kt index c7aa3e72bbe1..ff71df0ff1cd 100644 --- a/fenix/app/src/test/java/org/mozilla/fenix/search/SearchDialogFragmentTest.kt +++ b/fenix/app/src/test/java/org/mozilla/fenix/search/SearchDialogFragmentTest.kt @@ -50,14 +50,14 @@ internal class SearchDialogFragmentTest { @Test fun `GIVEN this is the only visible fragment WHEN asking for the previous destination THEN return null`() { - every { navController.backQueue } returns ArrayDeque(listOf(getDestination(fragmentName))) + every { navController.currentBackStack.value } returns ArrayDeque(listOf(getDestination(fragmentName))) assertNull(fragment.getPreviousDestination()) } @Test fun `GIVEN this and FragmentB on top of this are visible WHEN asking for the previous destination THEN return null`() { - every { navController.backQueue } returns ArrayDeque( + every { navController.currentBackStack.value } returns ArrayDeque( listOf( getDestination(fragmentName), getDestination("FragmentB"), @@ -70,7 +70,7 @@ internal class SearchDialogFragmentTest { @Test fun `GIVEN FragmentA, this and FragmentB are visible WHEN asking for the previous destination THEN return FragmentA`() { val fragmentADestination = getDestination("FragmentA") - every { navController.backQueue } returns ArrayDeque( + every { navController.currentBackStack.value } returns ArrayDeque( listOf( fragmentADestination, getDestination(fragmentName), @@ -84,7 +84,7 @@ internal class SearchDialogFragmentTest { @Test fun `GIVEN FragmentA and this on top of it are visible WHEN asking for the previous destination THEN return FragmentA`() { val fragmentADestination = getDestination("FragmentA") - every { navController.backQueue } returns ArrayDeque( + every { navController.currentBackStack.value } returns ArrayDeque( listOf( fragmentADestination, getDestination(fragmentName), From 7f7b326157a6174c3befd126b94543067e440479 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Mon, 12 Feb 2024 09:59:46 -0500 Subject: [PATCH 193/586] Bug 1851947 - Update Google Accompanist to version 0.32.0 --- .../fenixdependencies/src/main/java/FenixDependenciesPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt b/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt index a8657de948a8..6cce2f427b86 100644 --- a/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt +++ b/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt @@ -27,7 +27,7 @@ object FenixVersions { const val androidx_splash_screen = "1.0.1" const val androidx_transition = "1.4.1" const val androidx_datastore = "1.0.0" - const val google_accompanist = "0.30.1" + const val google_accompanist = "0.32.0" const val adjust = "4.35.1" const val installreferrer = "2.2" From 65efb284ebc1bd1ca01ec8076aed7ddd6ad5e336 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Fri, 5 Jan 2024 16:13:11 -0500 Subject: [PATCH 194/586] Bug 1879912 - Update OkHttp to version 4.12.0 --- .../plugins/dependencies/src/main/java/DependenciesPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt index ceb34e7696c2..39153acc4594 100644 --- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt +++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt @@ -24,7 +24,7 @@ object Versions { const val mockito = "5.10.0" const val maven_ant_tasks = "2.1.3" const val jacoco = "0.8.11" - const val okhttp = "4.11.0" + const val okhttp = "4.12.0" const val okio = "3.6.0" const val coil = "2.4.0" From 0df7d35a691c1a73d14a5dc7f3b6d71717e59c92 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Mon, 12 Feb 2024 12:36:47 -0500 Subject: [PATCH 195/586] Bug 1879912 - Update Okio to version 3.8.0 --- .../plugins/dependencies/src/main/java/DependenciesPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt index 39153acc4594..964a5cab5c44 100644 --- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt +++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt @@ -25,7 +25,7 @@ object Versions { const val maven_ant_tasks = "2.1.3" const val jacoco = "0.8.11" const val okhttp = "4.12.0" - const val okio = "3.6.0" + const val okio = "3.8.0" const val coil = "2.4.0" const val android_gradle_plugin = "8.2.2" From 179fff2e8a1a0e6c90ea15c490a52fe47de67cd4 Mon Sep 17 00:00:00 2001 From: Roger Yang Date: Tue, 13 Feb 2024 14:21:40 -0500 Subject: [PATCH 196/586] Bug 1880150 - Do not wait for attribution before dismissing splash screen --- fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 659c832c5c95..eb59219befd5 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -447,8 +447,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { var maxDurationReached = false val delay = FxNimbus.features.splashScreen.value().maximumDurationMs.toLong() splashScreen.setKeepOnScreenCondition { - val dataFetched = components.settings.utmParamsKnown && - components.settings.nimbusExperimentsFetched + val dataFetched = components.settings.nimbusExperimentsFetched + val keepOnScreen = !maxDurationReached && !dataFetched if (!keepOnScreen) { SplashScreen.firstLaunchExtended.record( From 33ca41956fa493d4aec22bc6d81e404350974f0b Mon Sep 17 00:00:00 2001 From: Cathy Lu Date: Sat, 10 Feb 2024 15:35:05 -0600 Subject: [PATCH 197/586] Bug 1878962 - Action to remove site from never translate list --- .../browser/state/action/BrowserAction.kt | 11 ++++ .../middleware/TranslationsMiddleware.kt | 47 +++++++++++++++ .../state/reducer/TranslationsStateReducer.kt | 11 ++++ .../state/action/TranslationsActionTest.kt | 25 ++++++++ .../middleware/TranslationsMiddlewareTest.kt | 57 +++++++++++++++++++ 5 files changed, 151 insertions(+) diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt index 53b72ac3b5ff..94707a735543 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt @@ -980,6 +980,17 @@ sealed class TranslationsAction : BrowserAction() { override val tabId: String, val neverTranslateSites: List, ) : TranslationsAction(), ActionWithTab + + /** + * Remove from the list of sites the user has opted to never translate. + * + * @property tabId The ID of the tab the [EngineSession] that requested the removal. + * @property origin A site origin URI that will have the specified never translate permission set. + */ + data class RemoveNeverTranslateSiteAction( + override val tabId: String, + val origin: String, + ) : TranslationsAction(), ActionWithTab } /** diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt index ab984747ef92..46abdc5289e5 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt @@ -61,6 +61,11 @@ class TranslationsMiddleware( -> Unit } } + is TranslationsAction.RemoveNeverTranslateSiteAction -> { + scope.launch { + removeNeverTranslateSite(context, action.tabId, action.origin) + } + } else -> { // no-op } @@ -143,6 +148,48 @@ class TranslationsMiddleware( ) } + /** + * Removes the site from the list of never translate sites using [scope] and dispatches the result to the + * store via [TranslationsAction.SetNeverTranslateSitesAction] or else dispatches the failure + * [TranslationsAction.TranslateExceptionAction]. + * + * @param context Context to use to dispatch to the store. + * @param tabId Tab ID associated with the request. + * @param origin A site origin URI that will have the specified never translate permission set. + */ + private fun removeNeverTranslateSite( + context: MiddlewareContext, + tabId: String, + origin: String, + ) { + engine.setNeverTranslateSpecifiedSite( + origin = origin, + setting = false, + onSuccess = { + logger.info("Success requesting never translate sites.") + + // Fetch page settings to ensure the state matches the engine. + context.store.dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tabId, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + ), + ) + }, + onError = { + logger.error("Error removing site from never translate list: ", it) + + // Fetch never translate sites to ensure the state matches the engine. + context.store.dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tabId, + operation = TranslationOperation.FETCH_NEVER_TRANSLATE_SITES, + ), + ) + }, + ) + } + /** * Retrieves the page settings using [scope] and dispatches the result to the * store via [TranslationsAction.SetPageSettingsAction] or else dispatches the failure diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt index 154ae8f4a99b..99656bf7953b 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt @@ -5,6 +5,7 @@ package mozilla.components.browser.state.reducer import mozilla.components.browser.state.action.TranslationsAction +import mozilla.components.browser.state.selector.findTab import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.TranslationsState import mozilla.components.concept.engine.translate.TranslationOperation @@ -190,6 +191,16 @@ internal object TranslationsStateReducer { ) } + is TranslationsAction.RemoveNeverTranslateSiteAction -> { + val neverTranslateSites = state.findTab(action.tabId)?.translationsState?.neverTranslateSites + val updatedNeverTranslateSites = neverTranslateSites?.filter { it != action.origin }?.toList() + state.copyWithTranslationsState(action.tabId) { + it.copy( + neverTranslateSites = updatedNeverTranslateSites, + ) + } + } + is TranslationsAction.OperationRequestedAction -> when (action.operation) { TranslationOperation.FETCH_SUPPORTED_LANGUAGES -> { diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt index 0eed569f0604..796b9f4927d6 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt @@ -221,6 +221,31 @@ class TranslationsActionTest { assertEquals(neverTranslateSites, tabState().translationsState.neverTranslateSites) } + @Test + fun `WHEN a RemoveNeverTranslateSiteAction is dispatched AND successful THEN update neverTranslateSites`() { + // Initial add to neverTranslateSites + assertEquals(null, tabState().translationsState.neverTranslateSites) + val neverTranslateSites = listOf("google.com") + store.dispatch( + TranslationsAction.SetNeverTranslateSitesAction( + tabId = tab.id, + neverTranslateSites = neverTranslateSites, + ), + ).joinBlocking() + assertEquals(neverTranslateSites, tabState().translationsState.neverTranslateSites) + + // Action started + store.dispatch( + TranslationsAction.RemoveNeverTranslateSiteAction( + tabId = tab.id, + origin = "google.com", + ), + ).joinBlocking() + + // Action success + assertEquals(listOf(), tabState().translationsState.neverTranslateSites) + } + @Test fun `WHEN a TranslateExceptionAction is dispatched due to an error THEN update the error condition according to the operation`() { // Initial state diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt index 237d69a5a85a..7f5503288dd3 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt @@ -34,6 +34,7 @@ import mozilla.components.support.test.whenever import org.junit.Before import org.junit.Rule import org.junit.Test +import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.Mockito.spy import org.mockito.Mockito.verify @@ -281,4 +282,60 @@ class TranslationsMiddlewareTest { ) waitForIdle() } + + @Test + fun `WHEN RemoveNeverTranslateSiteAction is dispatched AND removing is unsuccessful THEN FETCH_NEVER_TRANSLATE_SITES is dispatched`() = runTest { + val errorCallback = argumentCaptor<((Throwable) -> Unit)>() + whenever( + engine.setNeverTranslateSpecifiedSite( + origin = any(), + setting = anyBoolean(), + onSuccess = any(), + onError = errorCallback.capture(), + ), + ).thenAnswer { errorCallback.value.invoke(Throwable()) } + + val action = + TranslationsAction.RemoveNeverTranslateSiteAction( + tabId = tab.id, + origin = "google.com", + ) + translationsMiddleware.invoke(context, {}, action) + waitForIdle() + + // Verify Dispatch + verify(store).dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_NEVER_TRANSLATE_SITES, + ), + ) + } + + @Test + fun `WHEN RemoveNeverTranslateSiteAction is dispatched AND removing is successful THEN FETCH_PAGE_SETTINGS is dispatched`() = runTest { + val sitesCallback = argumentCaptor<(() -> Unit)>() + val action = + TranslationsAction.RemoveNeverTranslateSiteAction( + tabId = tab.id, + origin = "google.com", + ) + translationsMiddleware.invoke(context, {}, action) + verify(engine).setNeverTranslateSpecifiedSite( + origin = any(), + setting = anyBoolean(), + onSuccess = sitesCallback.capture(), + onError = any(), + ) + sitesCallback.value.invoke() + waitForIdle() + + // Verify Dispatch + verify(store).dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + ), + ) + } } From 486e9e21fbf0444eeaf51cbf2daeaffc85b6fa24 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Tue, 13 Feb 2024 15:32:51 -0500 Subject: [PATCH 198/586] Bug 1880152 - Update Firebase Cloud Messaging to version 23.4.1 --- .../plugins/dependencies/src/main/java/DependenciesPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt index 964a5cab5c44..8317fa7a7ceb 100644 --- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt +++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt @@ -91,7 +91,7 @@ object Versions { } object Firebase { - const val messaging = "23.4.0" + const val messaging = "23.4.1" } } From 1a01b8c156dbca7c01579edf292d3b21f62c4e03 Mon Sep 17 00:00:00 2001 From: ohall-m Date: Mon, 12 Feb 2024 12:17:59 -0500 Subject: [PATCH 199/586] Bug 1877203 - Update Translations Page Settings The goal of this bug is to have a way to update page settings. It adds: * A new action, `UpdatePageSettingAction` * This action has four options: * `UPDATE_ALWAYS_OFFER_POPUP` * `UPDATE_ALWAYS_TRANSLATE_LANGUAGE` * `UPDATE_NEVER_TRANSLATE_LANGUAGE` * `UPDATE_NEVER_TRANSLATE_SITE` * Each operation eagerly sets the new setting on the browser store, then sends the request to the engine. If setting on the engine fails, then they will re-request the page settings in order to remain in-sync. --- .../browser/state/action/BrowserAction.kt | 15 ++ .../middleware/TranslationsMiddleware.kt | 188 +++++++++++++++++- .../state/reducer/TranslationsStateReducer.kt | 49 +++++ .../state/action/TranslationsActionTest.kt | 106 ++++++++++ .../middleware/TranslationsMiddlewareTest.kt | 101 ++++++++++ .../TranslationPageSettingOperation.kt | 32 +++ .../translate/TranslationPageSettings.kt | 8 +- 7 files changed, 494 insertions(+), 5 deletions(-) create mode 100644 android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationPageSettingOperation.kt diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt index 94707a735543..cea4dddd5d54 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt @@ -49,6 +49,7 @@ import mozilla.components.concept.engine.translate.TranslationEngineState import mozilla.components.concept.engine.translate.TranslationError import mozilla.components.concept.engine.translate.TranslationOperation import mozilla.components.concept.engine.translate.TranslationOptions +import mozilla.components.concept.engine.translate.TranslationPageSettingOperation import mozilla.components.concept.engine.translate.TranslationPageSettings import mozilla.components.concept.engine.translate.TranslationSupport import mozilla.components.concept.engine.webextension.WebExtensionBrowserAction @@ -970,6 +971,20 @@ sealed class TranslationsAction : BrowserAction() { val pageSettings: TranslationPageSettings?, ) : TranslationsAction(), ActionWithTab + /** + * Updates the specified page setting operation on the translation engine and ensures the final + * state on the given [tabId]'s store remains in-sync. + * + * @property tabId The ID of the tab the [EngineSession] should be linked to. + * @property operation The page setting update operation to perform. + * @property setting The boolean value of the corresponding [operation]. + */ + data class UpdatePageSettingAction( + override val tabId: String, + val operation: TranslationPageSettingOperation, + val setting: Boolean, + ) : TranslationsAction(), ActionWithTab + /** * Sets the list of sites that the user has opted to never translate. * diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt index 46abdc5289e5..0ee5e36edd68 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddleware.kt @@ -15,6 +15,7 @@ import mozilla.components.concept.engine.EngineSession import mozilla.components.concept.engine.translate.LanguageSetting import mozilla.components.concept.engine.translate.TranslationError import mozilla.components.concept.engine.translate.TranslationOperation +import mozilla.components.concept.engine.translate.TranslationPageSettingOperation import mozilla.components.concept.engine.translate.TranslationPageSettings import mozilla.components.lib.state.Middleware import mozilla.components.lib.state.MiddlewareContext @@ -66,6 +67,47 @@ class TranslationsMiddleware( removeNeverTranslateSite(context, action.tabId, action.origin) } } + + is TranslationsAction.UpdatePageSettingAction -> { + when (action.operation) { + TranslationPageSettingOperation.UPDATE_ALWAYS_OFFER_POPUP -> + scope.launch { + updateAlwaysOfferPopupPageSetting( + setting = action.setting, + ) + } + + TranslationPageSettingOperation.UPDATE_ALWAYS_TRANSLATE_LANGUAGE -> + scope.launch { + updateLanguagePageSetting( + context = context, + tabId = action.tabId, + setting = action.setting, + settingType = LanguageSetting.ALWAYS, + ) + } + + TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_LANGUAGE -> + scope.launch { + updateLanguagePageSetting( + context = context, + tabId = action.tabId, + setting = action.setting, + settingType = LanguageSetting.NEVER, + ) + } + + TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_SITE -> + scope.launch { + updateNeverTranslateSitePageSetting( + context = context, + tabId = action.tabId, + setting = action.setting, + ) + } + } + } + else -> { // no-op } @@ -77,7 +119,7 @@ class TranslationsMiddleware( /** * Retrieves the list of supported languages using [scope] and dispatches the result to the - * store via [TranslationsAction.TranslateSetLanguagesAction] or else dispatches the failure + * store via [TranslationsAction.SetSupportedLanguagesAction] or else dispatches the failure * [TranslationsAction.TranslateExceptionAction]. * * @param context Context to use to dispatch to the store. @@ -287,4 +329,148 @@ class TranslationsMiddleware( ) } } + + /** + * Updates the always offer popup setting with the [Engine]. + * + * @param setting The value of the always offer setting to update. + */ + private fun updateAlwaysOfferPopupPageSetting( + setting: Boolean, + ) { + logger.info("Setting the always offer translations popup preference.") + engine.setTranslationsOfferPopup(setting) + } + + /** + * Updates the language settings with the [Engine]. + * + * If an error occurs, then the method will request the page settings be re-fetched and set on + * the browser store. + * + * @param context The context used to request the page settings. + * @param tabId Tab ID associated with the request. + * @param setting The value of the always offer setting to update. + * @param settingType If the boolean to update is from the + * [LanguageSetting.ALWAYS] or [LanguageSetting.NEVER] perspective. + */ + private fun updateLanguagePageSetting( + context: MiddlewareContext, + tabId: String, + setting: Boolean, + settingType: LanguageSetting, + ) { + logger.info("Preparing to update the translations language preference.") + + val pageLanguage = context.store.state.findTab(tabId) + ?.translationsState?.translationEngineState?.detectedLanguages?.documentLangTag + val convertedSetting = settingType.toLanguageSetting(setting) + + if (pageLanguage == null || convertedSetting == null) { + logger.info("An issue occurred while preparing to update the language setting.") + + // Fetch page settings to ensure the state matches the engine. + context.store.dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tabId, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + ), + ) + } else { + updateLanguageSetting(context, tabId, pageLanguage, convertedSetting) + } + } + + /** + * Updates the language settings with the [Engine]. + * + * If an error occurs, then the method will request the page settings be re-fetched and set on + * the browser store. + * + * @param context The context used to request the page settings. + * @param tabId Tab ID associated with the request. + * @param languageCode The BCP-47 language to update. + * @param setting The new language setting for the [languageCode]. + */ + private fun updateLanguageSetting( + context: MiddlewareContext, + tabId: String, + languageCode: String, + setting: LanguageSetting, + ) { + logger.info("Setting the translations language preference.") + + engine.setLanguageSetting( + languageCode = languageCode, + languageSetting = setting, + + onSuccess = { + logger.info("Successfully updated the language preference.") + }, + + onError = { + logger.error("Could not update the language preference.", it) + + // Fetch page settings to ensure the state matches the engine. + context.store.dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tabId, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + ), + ) + }, + ) + } + + /** + * Updates the never translate site settings with the [EngineSession] and ensures the global + * list of never translate sites remains in sync. + * + * If an error occurs, then the method will request the page settings be re-fetched and set on + * the browser store. + * + * Note: This method should be used when on the same page as the requested change. + * + * @param context The context used to request the page settings. + * @param tabId Tab ID associated with the request. + * @param setting The value of the site setting to update. + */ + private fun updateNeverTranslateSitePageSetting( + context: MiddlewareContext, + tabId: String, + setting: Boolean, + ) { + val engineSession = context.store.state.findTab(tabId) + ?.engineState?.engineSession + + if (engineSession == null) { + logger.error("Did not receive an engine session to set the never translate site preference.") + } else { + engineSession.setNeverTranslateSiteSetting( + setting = setting, + onResult = { + logger.info("Successfully updated the never translate site preference.") + + // Ensure the global sites store is in-sync with the page settings. + context.store.dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tabId, + operation = TranslationOperation.FETCH_NEVER_TRANSLATE_SITES, + ), + ) + }, + onException = { + logger.error("Could not update the never translate site preference.", it) + + // Fetch page settings to ensure the state matches the engine. + context.store.dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tabId, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + ), + ) + }, + ) + } + } } diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt index 99656bf7953b..df014ec1289a 100644 --- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt +++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/TranslationsStateReducer.kt @@ -9,6 +9,8 @@ import mozilla.components.browser.state.selector.findTab import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.TranslationsState import mozilla.components.concept.engine.translate.TranslationOperation +import mozilla.components.concept.engine.translate.TranslationPageSettingOperation +import mozilla.components.concept.engine.translate.TranslationPageSettings internal object TranslationsStateReducer { @@ -229,6 +231,53 @@ internal object TranslationsStateReducer { state } } + + is TranslationsAction.UpdatePageSettingAction -> { + var pageSettings = state.findTab(action.tabId)?.translationsState?.pageSettings + // Initialize page settings, if null. + if (pageSettings == null) { + pageSettings = TranslationPageSettings() + } + when (action.operation) { + TranslationPageSettingOperation.UPDATE_ALWAYS_OFFER_POPUP -> { + pageSettings.alwaysOfferPopup = action.setting + state.copyWithTranslationsState(action.tabId) { + it.copy( + pageSettings = pageSettings, + ) + } + } + TranslationPageSettingOperation.UPDATE_ALWAYS_TRANSLATE_LANGUAGE -> { + pageSettings.alwaysTranslateLanguage = action.setting + // Always and never translate sites are always opposites. + pageSettings.neverTranslateLanguage = !action.setting + + state.copyWithTranslationsState(action.tabId) { + it.copy( + pageSettings = pageSettings, + ) + } + } + TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_LANGUAGE -> { + pageSettings.neverTranslateLanguage = action.setting + // Always and never translate sites are always opposites. + pageSettings.alwaysTranslateLanguage = !action.setting + state.copyWithTranslationsState(action.tabId) { + it.copy( + pageSettings = pageSettings, + ) + } + } + TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_SITE -> { + pageSettings.neverTranslateSite = action.setting + state.copyWithTranslationsState(action.tabId) { + it.copy( + pageSettings = pageSettings, + ) + } + } + } + } } private inline fun BrowserState.copyWithTranslationsState( diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt index 796b9f4927d6..4aa5c8bc7fff 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/TranslationsActionTest.kt @@ -14,6 +14,7 @@ import mozilla.components.concept.engine.translate.Language import mozilla.components.concept.engine.translate.TranslationEngineState import mozilla.components.concept.engine.translate.TranslationError import mozilla.components.concept.engine.translate.TranslationOperation +import mozilla.components.concept.engine.translate.TranslationPageSettingOperation import mozilla.components.concept.engine.translate.TranslationPageSettings import mozilla.components.concept.engine.translate.TranslationPair import mozilla.components.concept.engine.translate.TranslationSupport @@ -412,4 +413,109 @@ class TranslationsActionTest { // Action success assertNull(tabState().translationsState.supportedLanguages) } + + @Test + fun `WHEN a UpdatePageSettingAction is dispatched for UPDATE_ALWAYS_OFFER_POPUP THEN set page settings for alwaysOfferPopup `() { + // Action started + store.dispatch( + TranslationsAction.UpdatePageSettingAction( + tabId = tab.id, + operation = TranslationPageSettingOperation.UPDATE_ALWAYS_OFFER_POPUP, + setting = true, + ), + ).joinBlocking() + + // Action success + assertTrue(tabState().translationsState.pageSettings?.alwaysOfferPopup!!) + } + + @Test + fun `WHEN a UpdatePageSettingAction is dispatched for UPDATE_ALWAYS_TRANSLATE_LANGUAGE THEN set page settings for alwaysTranslateLanguage `() { + // Action started + store.dispatch( + TranslationsAction.UpdatePageSettingAction( + tabId = tab.id, + operation = TranslationPageSettingOperation.UPDATE_ALWAYS_TRANSLATE_LANGUAGE, + setting = true, + ), + ).joinBlocking() + + // Action success + assertTrue(tabState().translationsState.pageSettings?.alwaysTranslateLanguage!!) + assertFalse(tabState().translationsState.pageSettings?.neverTranslateLanguage!!) + } + + @Test + fun `WHEN a UpdatePageSettingAction is dispatched for UPDATE_NEVER_TRANSLATE_LANGUAGE THEN set page settings for alwaysTranslateLanguage `() { + // Action started + store.dispatch( + TranslationsAction.UpdatePageSettingAction( + tabId = tab.id, + operation = TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_LANGUAGE, + setting = true, + ), + ).joinBlocking() + + // Action success + assertTrue(tabState().translationsState.pageSettings?.neverTranslateLanguage!!) + assertFalse(tabState().translationsState.pageSettings?.alwaysTranslateLanguage!!) + } + + @Test + fun `WHEN a UpdatePageSettingAction is dispatched for UPDATE_NEVER_TRANSLATE_SITE THEN set page settings for neverTranslateSite`() { + // Action started + store.dispatch( + TranslationsAction.UpdatePageSettingAction( + tabId = tab.id, + operation = TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_SITE, + setting = true, + ), + ).joinBlocking() + + // Action success + assertTrue(tabState().translationsState.pageSettings?.neverTranslateSite!!) + } + + @Test + fun `WHEN a UpdatePageSettingAction is dispatched for each option THEN the page setting is consistent`() { + // Action started + store.dispatch( + TranslationsAction.UpdatePageSettingAction( + tabId = tab.id, + operation = TranslationPageSettingOperation.UPDATE_ALWAYS_OFFER_POPUP, + setting = true, + ), + ).joinBlocking() + + store.dispatch( + TranslationsAction.UpdatePageSettingAction( + tabId = tab.id, + operation = TranslationPageSettingOperation.UPDATE_ALWAYS_TRANSLATE_LANGUAGE, + setting = true, + ), + ).joinBlocking() + + store.dispatch( + TranslationsAction.UpdatePageSettingAction( + tabId = tab.id, + operation = TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_LANGUAGE, + setting = true, + ), + ).joinBlocking() + + store.dispatch( + TranslationsAction.UpdatePageSettingAction( + tabId = tab.id, + operation = TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_SITE, + setting = true, + ), + ).joinBlocking() + + // Action success + assertTrue(tabState().translationsState.pageSettings?.alwaysOfferPopup!!) + // neverTranslateLanguage was posted last and will prevent a contradictory state on the alwaysTranslateLanguage state. + assertFalse(tabState().translationsState.pageSettings?.alwaysTranslateLanguage!!) + assertTrue(tabState().translationsState.pageSettings?.neverTranslateLanguage!!) + assertTrue(tabState().translationsState.pageSettings?.neverTranslateSite!!) + } } diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt index 7f5503288dd3..226724f5f47f 100644 --- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt +++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/middleware/TranslationsMiddlewareTest.kt @@ -21,6 +21,7 @@ import mozilla.components.concept.engine.translate.LanguageSetting import mozilla.components.concept.engine.translate.TranslationEngineState import mozilla.components.concept.engine.translate.TranslationError import mozilla.components.concept.engine.translate.TranslationOperation +import mozilla.components.concept.engine.translate.TranslationPageSettingOperation import mozilla.components.concept.engine.translate.TranslationPageSettings import mozilla.components.concept.engine.translate.TranslationSupport import mozilla.components.lib.state.MiddlewareContext @@ -240,6 +241,106 @@ class TranslationsMiddlewareTest { waitForIdle() } + @Test + fun `WHEN UpdatePageSettingAction is dispatched WITH UPDATE_ALWAYS_TRANSLATE_LANGUAGE AND updating the setting is unsuccessful THEN OperationRequestedAction with FETCH_PAGE_SETTINGS is dispatched`() = runTest { + // Setup + setupMockState() + val errorCallback = argumentCaptor<((Throwable) -> Unit)>() + whenever( + engine.setLanguageSetting( + languageCode = any(), + languageSetting = any(), + onSuccess = any(), + onError = errorCallback.capture(), + ), + ).thenAnswer { errorCallback.value.invoke(Throwable()) } + + // Send Action + val action = + TranslationsAction.UpdatePageSettingAction( + tabId = tab.id, + operation = TranslationPageSettingOperation.UPDATE_ALWAYS_TRANSLATE_LANGUAGE, + setting = true, + ) + translationsMiddleware.invoke(context, {}, action) + waitForIdle() + + // Verify Dispatch + verify(store).dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + ), + ) + } + + @Test + fun `WHEN UpdatePageSettingAction is dispatched WITH UPDATE_NEVER_TRANSLATE_LANGUAGE AND updating the setting is unsuccessful THEN OperationRequestedAction with FETCH_PAGE_SETTINGS is dispatched`() = runTest { + // Setup + setupMockState() + val errorCallback = argumentCaptor<((Throwable) -> Unit)>() + whenever( + engine.setLanguageSetting( + languageCode = any(), + languageSetting = any(), + onSuccess = any(), + onError = errorCallback.capture(), + ), + ) + .thenAnswer { errorCallback.value.invoke(Throwable()) } + + // Send Action + val action = + TranslationsAction.UpdatePageSettingAction( + tabId = tab.id, + operation = TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_LANGUAGE, + setting = true, + ) + translationsMiddleware.invoke(context, {}, action) + waitForIdle() + + // Verify Dispatch + verify(store).dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + ), + ) + } + + @Test + fun `WHEN UpdatePageSettingAction is dispatched WITH UPDATE_NEVER_TRANSLATE_SITE AND updating the setting is unsuccessful THEN OperationRequestedAction with FETCH_PAGE_SETTINGS is dispatched`() = runTest { + // Setup + setupMockState() + val errorCallback = argumentCaptor<((Throwable) -> Unit)>() + whenever( + engineSession.setNeverTranslateSiteSetting( + setting = anyBoolean(), + onResult = any(), + onException = errorCallback.capture(), + ), + ) + .thenAnswer { errorCallback.value.invoke(Throwable()) } + + // Send Action + val action = + TranslationsAction.UpdatePageSettingAction( + tabId = tab.id, + operation = TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_SITE, + setting = true, + ) + translationsMiddleware.invoke(context, {}, action) + waitForIdle() + + // Verify Dispatch + verify(store).dispatch( + TranslationsAction.OperationRequestedAction( + tabId = tab.id, + operation = TranslationOperation.FETCH_PAGE_SETTINGS, + ), + ) + } + @Test fun `WHEN OperationRequestedAction is dispatched to fetch never translate sites AND succeeds THEN SetNeverTranslateSitesAction is dispatched`() = runTest { val neverTranslateSites = listOf("google.com") diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationPageSettingOperation.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationPageSettingOperation.kt new file mode 100644 index 000000000000..82367408b365 --- /dev/null +++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationPageSettingOperation.kt @@ -0,0 +1,32 @@ +/* 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 mozilla.components.concept.engine.translate + +/** + * The container for referring to the different page settings. + * + * See [TranslationPageSettings] for the corresponding data model + */ +enum class TranslationPageSettingOperation { + /** + * The system should offer a translation on a page. + */ + UPDATE_ALWAYS_OFFER_POPUP, + + /** + * The page's always translate language setting. + */ + UPDATE_ALWAYS_TRANSLATE_LANGUAGE, + + /** + * The page's never translate language setting. + */ + UPDATE_NEVER_TRANSLATE_LANGUAGE, + + /** + * The page's never translate site setting. + */ + UPDATE_NEVER_TRANSLATE_SITE, +} diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationPageSettings.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationPageSettings.kt index 7c253d6af2cc..2cc9eb598098 100644 --- a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationPageSettings.kt +++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationPageSettings.kt @@ -19,8 +19,8 @@ package mozilla.components.concept.engine.translate * When true, the engine will not offer a translation on the current host site. */ data class TranslationPageSettings( - val alwaysOfferPopup: Boolean? = null, - val alwaysTranslateLanguage: Boolean? = null, - val neverTranslateLanguage: Boolean? = null, - val neverTranslateSite: Boolean? = null, + var alwaysOfferPopup: Boolean? = null, + var alwaysTranslateLanguage: Boolean? = null, + var neverTranslateLanguage: Boolean? = null, + var neverTranslateSite: Boolean? = null, ) From 97cf47376df1bd4dbbe888d81e2a66b1a6171f33 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 14 Feb 2024 00:03:31 +0000 Subject: [PATCH 200/586] Import translations from android-l10n --- .../addons/src/main/res/values-be/strings.xml | 4 +- .../src/main/res/values-cak/strings.xml | 14 +++ fenix/app/src/main/res/values-azb/strings.xml | 50 ++++++++ fenix/app/src/main/res/values-be/strings.xml | 112 +++++++++++------- fenix/app/src/main/res/values-cak/strings.xml | 108 ++++++++++------- .../src/main/res/values-es-rCL/strings.xml | 3 + fenix/app/src/main/res/values-it/strings.xml | 12 +- 7 files changed, 214 insertions(+), 89 deletions(-) diff --git a/android-components/components/feature/addons/src/main/res/values-be/strings.xml b/android-components/components/feature/addons/src/main/res/values-be/strings.xml index 9422059324ef..e8b8be200a4f 100644 --- a/android-components/components/feature/addons/src/main/res/values-be/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values-be/strings.xml @@ -22,6 +22,8 @@ then we will show another collapsed entry saying "Access your data on 2 other domains". This entry it's for the plural case, when the add-on is accessing more than one extra domain. %1$d will be replaced by an integer indicating the number of additional domains for which this web extension is requesting permission. --> Доступ да вашых дадзеных у %1$d іншых даменах + + %1$s, %2$d з %3$d Доступ да картак браўзера @@ -75,7 +77,7 @@ Аўтар - Аўтары + Аўтары Апошняе абнаўленне diff --git a/android-components/components/feature/prompts/src/main/res/values-cak/strings.xml b/android-components/components/feature/prompts/src/main/res/values-cak/strings.xml index 8f5c874dca8c..81a8705c8e0a 100644 --- a/android-components/components/feature/prompts/src/main/res/values-cak/strings.xml +++ b/android-components/components/feature/prompts/src/main/res/values-cak/strings.xml @@ -106,6 +106,16 @@ Chilab\'en taq molojri\'ïl + + Xeyak ewan taq tzij + + + Tichilab\'ëx ütz ewan tzij + + Tichilab\'ëx ütz ewan tzij + + Ke\'awokisaj ütz ewan taq tzij: %1$s + ¿La nitaq chik tzij chi re re ruxaq? Nisamajïx chik re ruxaq rik\'in jub\'a\' nukamuluj samaj k\'a jub\'a\' b\'anon, achi\'el nitaq jun tojïk o kamul nrelesaj rutzijol jun na\'oj. @@ -117,6 +127,8 @@ Ticha\' rutarjeta\' kre\'ito\' + + Tokisäx yakon tarjeta\' Kerik\' ri chilab\'en rutarjeta\' kre\ito\' @@ -124,6 +136,8 @@ Kenuk\'samajïx kikre\'ito\' taq tarjeta\' + + Kenuk\'samajïx taq tarjeta\' ¿Jikïl tayaka\' re tarjeta\' re\'? diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml index 796ef13cfb87..06f3ceeadf99 100644 --- a/fenix/app/src/main/res/values-azb/strings.xml +++ b/fenix/app/src/main/res/values-azb/strings.xml @@ -652,9 +652,40 @@ a section where users see a list of tabs that they have visited in the past few days --> سون باخیلان‌لار + + دوشوندوروجو ناغیل‌لار + + %sطرفیندن گوج آلینان مقاله‌لر + + اسپانسرلی ناغیل‌لار + + + دال پرده‌لر + + + + دال پرده: %1$s + + دال پرده گونجللندی! + + گؤستر + + دال پرده یئندیریلنمه‌دی + + گئنه چالیش + + دال پرده دگیشیله بیلمه‌دی آرتیق بیلین + + کلاسیک %s + + + هونرمند سئری‌سی + + باغیْمسیز سس‌لر مجموعه‌سی. %s + ایندی دؤنگل‌لندیر @@ -662,6 +693,8 @@ بوُکمارک‌لار + + گیریش‌لر رمز‌لر @@ -669,6 +702,23 @@ چیخیش + + جهاز آدی + + جهاز آدیْ بوْش اوْلمالیدیر + + دؤنگل‌لنیر... + + دؤنگل خطا وئردی. سوْن باشاریْ: %s + + + دؤنگل خطا وئردی. سوْن دؤنگل: یوْخدور + + سوْن دؤنگل: %s + + + سوْن دؤنگل: هئچ + اوست diff --git a/fenix/app/src/main/res/values-be/strings.xml b/fenix/app/src/main/res/values-be/strings.xml index 4351428f7519..d0e080a57306 100644 --- a/fenix/app/src/main/res/values-be/strings.xml +++ b/fenix/app/src/main/res/values-be/strings.xml @@ -242,6 +242,7 @@ Уладкаваць хатнюю старонку + Хатні экран @@ -249,6 +250,9 @@ Сцерці гісторыю аглядання + + Перакласці старонку + Абраная мова @@ -260,8 +264,6 @@ Сканаваць - - Пашукавік Налады пошукавых сістэм @@ -316,23 +318,28 @@ - Апавяшчэнні дапамогуць вам зрабіць больш з %s + Апавяшчэнні дапамогуць вам зрабіць больш з %s - Сінхранізуйце свае карткі паміж прыладамі, кіруйце сцягваннямі, атрымлівайце парады, як максімальна выкарыстоўваць ахову прыватнасці %s, і многае іншае. + Сінхранізуйце свае карткі паміж прыладамі, кіруйце сцягваннямі, атрымлівайце парады, як максімальна выкарыстоўваць ахову прыватнасці %s, і многае іншае. - Працягнуць + Працягнуць - Не зараз + Не зараз + + Паведамленне аб прыватнасці Firefox + Нам падабаецца забяспечваць вашу бяспеку - Наш браўзер, падтрыманы некамерцыйнай арганізацыяй, дапамагае абмяжоўваць кампаніі ад сачэння за вамі ў Інтэрнэце.\n\nДаведайцеся больш у нашым паведамленні аб прыватнасці. + Наш браўзер, падтрыманы некамерцыйнай арганізацыяй, дапамагае не даваць кампаніям таемна сачыць за вамі ў сеціве. + + Наш браўзер, падтрыманы некамерцыйнай арганізацыяй, дапамагае абмяжоўваць кампаніі ад сачэння за вамі ў Інтэрнэце.\n\nДаведайцеся больш у нашым паведамленні аб прыватнасці. - паведамленні аб прыватнасці + паведамленні аб прыватнасці Зрабіць прадвызначаным браўзерам @@ -435,21 +442,11 @@ Рэжым «Толькі HTTPS» - - Памяншэнне колькасці банераў кукі Блакіроўшчык банераў кукі Блакіроўшчык банераў кукі ў прыватным праглядзе - - Памяншаць колькасць банераў кукі - - Выключана - - Уключана - - - %1$s аўтаматычна спрабуе адхіліць запыты файлаў кукі на банерах кукі. + Выключана для гэтага сайта @@ -468,36 +465,17 @@ Сайт зараз не падтрымліваецца - Уключыць памяншэнне колькасці банераў кукі для %1$s? - Уключыць блакіроўшчык банераў кукі для %1$s? - - Выключыць памяншэнне колькасці банераў кукі для %1$s? Выключыць блакіроўшчык банераў кукі для %1$s? %1$s не можа аўтаматычна адхіляць запыты кукаў на гэтым сайце. Вы можаце адправіць запыт на падтрымку гэтага сайта ў будучыні. - - %1$s выдаліць файлы кукі гэтага сайта і абновіць старонку. Выдаленне ўсіх файлаў кукі можа прывесці да выхаду з сістэмы або ачышчэння кошыка для пакупак. Выключыць, і %1$s выдаліць файлы кукі і перазагрузіць гэты сайт. Гэта можа прывесці да выхаду з уліковага запісу або ачышчэння кошыка. - %1$s спрабуе аўтаматычна адхіляць усе запыты файлаў кукі на сайтах, якія падтрымліваюцца. - Уключыце, і %1$s паспрабуе аўтаматычна адхіляць банеры кукі на гэтым сайце. - - Дазволіць %1$s адхіляць банеры кукі? - - %1$s можа аўтаматычна адхіляць многія запыты банераў кукі. - - Не зараз - - Вы ўбачыце менш запытаў пра кукі - - - Дазволіць %1$s толькі што адмовіўся ад кукі для вас @@ -716,6 +694,8 @@ Закладкі Лагіны + + Паролі Адкрытыя карткі @@ -742,6 +722,8 @@ Крэдытныя карты + + Спосабы аплаты Адрасы @@ -1285,8 +1267,6 @@ Адхіліць - Немагчыма надрукаваць - Немагчыма надрукаваць гэту старонку Друкаваць @@ -1699,8 +1679,12 @@ Лагіны і паролі + + Паролі Захаванне лагінаў і пароляў + + Захоўваць паролі Пытаць пра захаванне @@ -1717,12 +1701,17 @@ Дадаць лагін + + Дадаць пароль + Сінхранізацыя лагінаў Сінхранізаваць лагіны паміж прыладамі Захаваныя лагіны + + Захаваныя паролі Лагіны, якія вы захаваеце альбо сінхранізуеце праз %s, з’явяцца тут. @@ -1738,6 +1727,8 @@ Выдаліць усе выключэнні Шукаць лагіны + + Пошук пароляў Сайт @@ -1767,9 +1758,13 @@ Схаваць пароль Разблакуйце, каб пабачыць захаваныя лагіны + + Разблакуйце, каб пабачыць захаваныя паролі Абараніце свае лагіны і паролі + + Абараніце захаваныя паролі Наладзьце графічны ключ, пін ці пароль для блакавання прылады, каб абараніць захаваныя лагіны і паролі ад крадзяжу, калі Вашай прыладай завалодае хтосьці іншы. @@ -1798,8 +1793,12 @@ Крэдытныя карты + + Спосабы аплаты Захоўваць і аўтаматычна запаўняць карты + + Захоўваць і запаўняць спосабы аплаты Дадзеныя зашыфраваны @@ -1808,9 +1807,13 @@ Сінхранізаваць карты Дадаць крэдытную карту + + Дадаць карту Кіраванне захаванымі картамі + + Кіраваць картамі Дадаць адрас @@ -1818,6 +1821,8 @@ Захоўваць і аўтаматычна запаўняць адрасы + + Захоўваць і запаўняць адрасы Уключаць звесткі, такія як нумары, адрасы электроннай пошты і дастаўкі @@ -1842,6 +1847,8 @@ Выдаліць карту Вы ўпэўнены, што жадаеце выдаліць гэту крэдытную карту? + + Выдаліць карту? Выдаліць @@ -1856,12 +1863,18 @@ Калі ласка, увядзіце сапраўдны нумар крэдытнай карты + + Увядзіце сапраўдны нумар карты Калі ласка, запоўніце гэтае поле + + Дадайце імя Разблакуйце, каб пабачыць захаваныя карты Абараніце свае крэдытныя карты + + Абараніце захаваныя спосабы аплаты Наладзьце графічны ключ, пін або пароль для блакавання прылады, каб абараніць захаваныя крэдытныя карты, калі хтось іншы атрымае доступ да вашай прылады. @@ -1911,6 +1924,8 @@ Вы ўпэўнены, што жадаеце выдаліць гэты адрас? + + Выдаліць гэты адрас? Выдаліць @@ -2029,16 +2044,26 @@ Тэкставае поле для рэдагавання пароля для ўваходу ў сістэму. Захаваць змены ва ўваходных даных. + + Захаваць змены. Рэдагаванне Дадаць новы лагін + + Дадаць пароль Патрабуецца пароль + + Увядзіце пароль Патрабуецца імя карыстальніка + + Увядзіце імя карыстальніка Патрабуецца імя хоста + + Увядзіце вэб-адрас Галасавы пошук @@ -2136,6 +2161,9 @@ Пошук %s + + Змяніць прадвызначаны браўзер + Наладзьце аўтаматычнае адкрыццё спасылак з сайтаў, пошты і паведамленняў у Firefox. @@ -2187,6 +2215,8 @@ Скарэктаваны рэйтынг Ненадзейныя водгукі выдалены + + На аснове надзейных водгукаў Асноўныя моманты з апошніх водгукаў @@ -2207,8 +2237,6 @@ Асноўныя моманты з водгукаў пра %s за апошнія 80 дзён, якія мы лічым надзейнымі.]]> Даведайцеся больш пра %s. - - як %s ад Mozilla вызначае якасць водгукаў як %s вызначае якасць водгукаў diff --git a/fenix/app/src/main/res/values-cak/strings.xml b/fenix/app/src/main/res/values-cak/strings.xml index 7b77ffa093a3..338cfa7d8682 100644 --- a/fenix/app/src/main/res/values-cak/strings.xml +++ b/fenix/app/src/main/res/values-cak/strings.xml @@ -248,6 +248,7 @@ Tawichinaj ri ruxaq atikirib\'al + Rutikirib\'al ruwäch @@ -255,6 +256,9 @@ Tiyuj runatab\'al okem pa k\'amaya\'l + + Titzalq\'omïx ruxaq + Xcha\' ch\'ab\'äl @@ -266,8 +270,6 @@ Tiwachib\'ëx - - Kanob\'äl Runuk\'ulem kanob\'äl @@ -322,23 +324,26 @@ - Ri taq rutzijol yatkito\' richin nasamajij ch\'aqa\' chik pa %s + Ri taq rutzijol yatkito\' richin nasamajij ch\'aqa\' chik pa %s - Ke\'axima\' ri taq ruwi\' chi kikojol ri taq okisaxel, ke\'anuk\'samajij taq qasanïk, ke\'ak\'ulu\' taq na\'oj chi rij rub\'eyal nawïl ri rutzil ruchajixik richinanem %s chuqa\' ch\'aqa\' chik. + Ke\'axima\' ri taq ruwi\' chi kikojol ri taq okisaxel, ke\'anuk\'samajij taq qasanïk, ke\'ak\'ulu\' taq na\'oj chi rij rub\'eyal nawïl ri rutzil ruchajixik richinanem %s chuqa\' ch\'aqa\' chik. - Titikïr chik el + Titikïr chik el - Wakami mani + Wakami mani + + Firefox ichinan rutzijol + Niqa chi qawäch chi atqajikib\'an - Ri qokik\'amaya\'l majun ch\'akoj rojqan, yatruto\' chi ri ajk\'ayij taq moloj yatkitzeqelb\'ej pa ewan pa ajk\'amaya\'l.\n\nCh\'aqa\' chik taq na\'oj pa ri rutzijol ichinanem. + Ri qokik\'amaya\'l majun ch\'akoj rojqan, yatruto\' chi ri ajk\'ayij taq moloj yatkitzeqelb\'ej pa ewan pa ajk\'amaya\'l.\n\nCh\'aqa\' chik taq na\'oj pa ri rutzijol ichinanem. - ichinan na\'oj + ichinan na\'oj Tiya\' kan achi\'el kanob\'äl k\'o wi @@ -435,20 +440,10 @@ HTTPS-Only B\'anikil - - Kech\'utinirisäx kitzijol kuki Kiq\'atöy kitzijol cookie Ruq\'atöy kitzijol taq cookie pan ichinan okem - - Kech\'utinär ri taq kib\'aner koki - - Tichup - - Titzij - - %1$s nutojtob\'ej yeruxutuj ruyonil ri kik\'utuxik kuki pa ri taq kinimawuj kuki. Chupül pa re ruxaq re\' @@ -467,32 +462,13 @@ Wakami man koch\'el ta re ruxaq re\' - ¿La nitzij ri kich\'utinisaxik rutzijol kuki richin %1$s? - ¿La nitzij ri kiq\'atik taq kitzijol cookie richin %1$s? - ¿La nichup ri kich\'utinisaxik rutzijol kuki richin %1$s? - ¿La nichup ri ruq\'atoj kitzijol taq cookie richin %1$s? Man yeruq\'ät ta ri %1$s pa ruyonil ri taq kik\'utuj taq cookie pa re ruxaq re\'. Yatikïr natäq un k\'utuj richin nito\' re ruxaq re\' ri chwa\'q kab\'ij. - - %1$s xkeruyüj ri taq rukuki re ruxaq chuqa\' xtuk\'ëx re ruxaq. Xkeruyüj ronojel ri taq kuki, nitikïr nutz\'apij ri molojri\'ïl o yerujäm ri taq ruch\'ich\' loq\'oj. - - %1$s nitikïr nutojtob\'ej yeruxutuj pa ruyonil ronojel ri kik\'utuxik taq kuki pa koch\'el taq ruxaq. Toq nitzij, ri %1$s xtutojtob\'ej xkeruxutuj pa ruyonil ri taq kitzijol taq cookie pa re ruxaq re\'. - - ¿La niya\' q\'ij chi %1$s yeruxutuj ri kik\'utuxik taq kuki? - - %1$s nitikïr yeruxutuj pa ruyonil k\'ïy kik\'utuxik taq kuki. - - Wakami mani - - Xtatz\'ët jub\'a kik\'utuxik kuki - - - Tiya\' q\'ij %1$s k\'a b\'a\' keruxutuj taq cookie @@ -702,6 +678,8 @@ Taq yaketal Ketikirisäx molojri\'ïl + + Ewan taq tzij Kejaq ruwi\' @@ -729,6 +707,8 @@ Rutarjeta\' kre\'ito\' + + Rub\'eyal tojïk Taq ochochib\'äl @@ -1269,8 +1249,6 @@ Tewäx - Man tikirel ta xtz\'ajb\'äx - Man tikirel ta nitz\'ajb\'äx re ruxaq re\' Titz\'ajb\'äx @@ -1316,6 +1294,10 @@ Ketz\'apïx ichinan taq ruwi\' + + + La yetz\'apïx ichinan taq ruwi\'? + Markentin @@ -1658,8 +1640,12 @@ Kitikirisaxik molojri\'ïl chuqa\' ewan taq tzij + + Ewan taq tzij Keyak kitikirisaxik molojri\'ïl chuqa\' ewan taq tzij + + Keyak ewan taq tzij Tik\'utüx chi niyak @@ -1672,16 +1658,25 @@ Tatz\'aqatisaj rutikirib\'al molojri\'ïl + + Titz\'aqatisäx ewan tzij + Sync tikirisanïk molojri\'ïl + + Kexim ewan taq tzij Sync rutikirib\'al molojri\'ïl rik\'in okisaxel Xeyak kitikirisaxik mojojri\'ïl + + Xeyak ewan taq tzij Wawe\' xkeq\'alajin ri taq tikirisanïk molojri\'ïl xke\'ayäk o xke\'axïm rik\'in %s. Tawetamaj ch\'aqa\' chik chi rij ri Sync. + + Tawetamaj ch\'aqa\' chik chi rij ri sync Taq man relik ta @@ -1692,6 +1687,8 @@ Tiyuj ronojel man relik ta Kekanöx tikirib\'äl taq molojri\'ïl + + Kekanöx ewan taq tzij Ruxaq k\'amaya\'l @@ -1721,10 +1718,14 @@ Tewäx ewan tzij Man tiq\'at chik richin ye\'atz\'ët ri tikirib\'äl amolojri\'ïl e\'ayakon + + Man tiq\'at chik richin ye\'atz\'ët ri ewan taq tzij e\'ayakon Ke\'ajikib\'a\' kitikirisaxik amolojri\'ïl chuqa\' ewan taq atzij Tab\'ana\' runuk\'ulem jun retal ruq\'atoj okisab\'äl, jun PIN o jun ewan tzij richin nachajij ri kitikirib\'al amolojri\'ïl chuqa\' ewan taq atzij e\'ayakon we xa ta k\'o xtichapo ri awokisab\'al. + + Tab\'ana\' runuk\'ulem jun retal ruq\'atoj okisab\'äl, jun PIN o jun ewan tzij richin nachajij ri ewan taq atzij e\'ayakon we xa ta k\'o xtichapo ri awokisab\'al. Jub\'a\' chik na @@ -1753,6 +1754,8 @@ Taq ochochib\'äl Rutarjeta\' kre\'ito\' + + Rub\'eyal tojïk Keyak chuqa\' ruyon kenojisäx ri tarjeta\' @@ -1765,9 +1768,13 @@ Titz\'aqatisäx rutarjeta\' kre\'ito\' + + Titz\'aqatisäx tarjeta\' Kenuk\'samajïx yakon taq tarjeta\' + + Kenuk\'samajïx taq tarjeta\' Titz\'aqatisäx ochochib\'äl @@ -1775,6 +1782,9 @@ Keyak chuqa\' ruyon kenojisäx ri ochochib\'äl + + Keyak chuqa\' kenojisäx ri ochochib\'äl + Titz\'aqatisäx tarjeta\' @@ -1795,6 +1805,8 @@ Tiyuj tarjeta\' Tiyuj tarjeta\' + + La niyuj tarjeta\'? Tiyuj @@ -1811,6 +1823,8 @@ Tanojisaj re k\'ojlem re\' + + Titz\'aqatisäx jun b\'i\'aj Man tiq\'at chik richin ye\'atz\'ët ri tarjeta\' e\'ayakon @@ -1959,16 +1973,28 @@ Achi\'el: \nhttps://www.google.com/search?q=%s Ruk\'ojlem nuk\'el rutz\'ib\'axik rub\'i\' winäq pa ri rutikirib\'al molojri\'ïl. Ruk\'ojlem nuk\'el rutz\'ib\'axik ewan tzij pa ri rutikirib\'al molojri\'ïl. + + Ruk\'ojlem nuk\'el rutz\'ib\'axik ewan tzij. Keyaj taq jaloj richin ri rutikirib\'al molojri\'ïl. + + Keyak taq jaloj. Tinuk\' + + Tinuk\' ewan tzij Titz\'aqatisäx k\'ak\'a\' rub\'i\' taqoya\'l + + Titz\'aqatisäx ewan tzij Najowäx ewan tzij + + Titz\'ib\'äx jun ewan tzij Najowäx rub\'i\' okisanel + + Titz\'ib\'äx jun ewan rutzij okisaxel Najowäx rub\'i\' ruk\'u\'x k\'amb\'ey @@ -2052,7 +2078,7 @@ Achi\'el: \nhttps://www.google.com/search?q=%s Tikanöx pa %s - + Nub\'än kinuk\'ulem ximonel ajk\'amaya\'l taq ruxaq, taq taqoya\'l chuqa\' taq rutzijol richin yejaq pa ruyonil pa Firefox. @@ -2072,6 +2098,8 @@ Achi\'el: \nhttps://www.google.com/search?q=%s B\'anob\'äl richin yach\'ob\'on Tilitäj ch\'aqa\' chik + + B\'anon ruma %s. Tetamäx ch\'aqa\' chik diff --git a/fenix/app/src/main/res/values-es-rCL/strings.xml b/fenix/app/src/main/res/values-es-rCL/strings.xml index 883e691fad29..db20b1724a5b 100644 --- a/fenix/app/src/main/res/values-es-rCL/strings.xml +++ b/fenix/app/src/main/res/values-es-rCL/strings.xml @@ -2167,6 +2167,9 @@ Buscar con %s + + Cambia tu navegador predeterminado + Configura enlaces de sitios web, correos electrónicos y mensajes para que se abran automáticamente en Firefox. diff --git a/fenix/app/src/main/res/values-it/strings.xml b/fenix/app/src/main/res/values-it/strings.xml index 3a6cd2169c9f..e7ee8061bdcb 100644 --- a/fenix/app/src/main/res/values-it/strings.xml +++ b/fenix/app/src/main/res/values-it/strings.xml @@ -2295,13 +2295,13 @@ Impostazioni - Mostra annunci nella verifica recensioni + Mostra annunci in Verifica recensioni Verranno visualizzati annunci occasionali per prodotti pertinenti. Promuoviamo solo prodotti con recensioni affidabili. %s Ulteriori informazioni - Disattiva verifica recensioni + Disattiva Verifica recensioni Altri prodotti da valutare @@ -2395,17 +2395,17 @@ Prima di acquistare, scopri se puoi fidarti delle recensioni di questo prodotto. - Prova verifica recensioni + Prova Verifica recensioni Queste recensioni sono affidabili? Controlla ora per vedere la valutazione rettificata. - Apri verifica recensioni + Apri Verifica recensioni Beta - Apri verifica recensioni + Apri Verifica recensioni - Chiudi verifica recensioni + Chiudi Verifica recensioni %1$s su 5 stelle From e2c59a3f8c1ea9ea6e2a34a7fa4539c964c35354 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 14 Feb 2024 01:25:41 +0000 Subject: [PATCH 201/586] Update GeckoView (Nightly) to 124.0.20240213210653. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index 63d33d2f3a30..e6ae5164f0d1 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240213093751" + const val version = "124.0.20240213210653" /** * GeckoView channel From d3e464e8e982e6e668169356c8c961155c5d0b03 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 13 Feb 2024 15:45:42 +0200 Subject: [PATCH 202/586] Bug 1880221 - Convert private variables to functions so they don't get initialised --- .../fenix/ui/robots/RecentlyClosedTabsRobot.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/RecentlyClosedTabsRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/RecentlyClosedTabsRobot.kt index d77962cfb1d9..2a3996fd9e37 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/RecentlyClosedTabsRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/RecentlyClosedTabsRobot.kt @@ -87,21 +87,21 @@ class RecentlyClosedTabsRobot { } fun clickOpenInNewTab(testRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition { - openInNewTabOption.click() + openInNewTabOption().click() ComposeTabDrawerRobot(testRule).interact() return ComposeTabDrawerRobot.Transition(testRule) } fun clickOpenInPrivateTab(testRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition { - openInPrivateTabOption.click() + openInPrivateTabOption().click() ComposeTabDrawerRobot(testRule).interact() return ComposeTabDrawerRobot.Transition(testRule) } fun clickShare(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { - multipleSelectionShareButton.click() + multipleSelectionShareButton().click() ShareOverlayRobot().interact() return ShareOverlayRobot.Transition() @@ -132,8 +132,8 @@ private fun recentlyClosedTabDeleteButton() = ), ) -private val openInNewTabOption = onView(withText("Open in new tab")) +private fun openInNewTabOption() = onView(withText("Open in new tab")) -private val openInPrivateTabOption = onView(withText("Open in private tab")) +private fun openInPrivateTabOption() = onView(withText("Open in private tab")) -private val multipleSelectionShareButton = onView(withId(R.id.share_history_multi_select)) +private fun multipleSelectionShareButton() = onView(withId(R.id.share_history_multi_select)) From e558d16f418be49bb0024bffb952b7be4319da36 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 13 Feb 2024 15:56:16 +0200 Subject: [PATCH 203/586] Bug 1880221 - Add logs to RecentlyClosedTabsRobot --- .../ui/robots/RecentlyClosedTabsRobot.kt | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/RecentlyClosedTabsRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/RecentlyClosedTabsRobot.kt index 2a3996fd9e37..8034e46745b5 100644 --- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/RecentlyClosedTabsRobot.kt +++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/RecentlyClosedTabsRobot.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.ui.robots import android.net.Uri +import android.util.Log import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.Visibility @@ -17,6 +18,7 @@ import androidx.test.uiautomator.UiSelector import org.hamcrest.Matchers import org.hamcrest.Matchers.allOf import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.HomeActivityComposeTestRule import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText @@ -32,28 +34,36 @@ import org.mozilla.fenix.helpers.click class RecentlyClosedTabsRobot { - fun waitForListToExist() = + fun waitForListToExist() { + Log.i(TAG, "waitForListToExist: Waiting for $waitingTime ms for recently closed tabs list to exist") mDevice.findObject(UiSelector().resourceId("$packageName:id/recently_closed_list")) .waitForExists(waitingTime) + Log.i(TAG, "waitForListToExist: Waited for $waitingTime ms for recently closed tabs list to exist") + } fun verifyRecentlyClosedTabsMenuView() { + Log.i(TAG, "verifyRecentlyClosedTabsMenuView: Trying to verify that the recently closed tabs menu view is visible") onView( allOf( withText("Recently closed tabs"), withParent(withId(R.id.navigationToolbar)), ), ).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + Log.i(TAG, "verifyRecentlyClosedTabsMenuView: Verified that the recently closed tabs menu view is visible") } fun verifyEmptyRecentlyClosedTabsList() { + Log.i(TAG, "verifyEmptyRecentlyClosedTabsList: Waiting for device to be idle") mDevice.waitForIdle() - + Log.i(TAG, "verifyEmptyRecentlyClosedTabsList: Waited for device to be idle") + Log.i(TAG, "verifyEmptyRecentlyClosedTabsList: Trying to verify that the empty recently closed tabs list is visible") onView( allOf( withId(R.id.recently_closed_empty_view), withText(R.string.recently_closed_empty_message), ), ).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + Log.i(TAG, "verifyEmptyRecentlyClosedTabsList: Verified that the empty recently closed tabs list is visible") } fun verifyRecentlyClosedTabsPageTitle(title: String) = @@ -62,6 +72,7 @@ class RecentlyClosedTabsRobot { ) fun verifyRecentlyClosedTabsUrl(expectedUrl: Uri) { + Log.i(TAG, "verifyRecentlyClosedTabsUrl: Trying to verify that the recently closed tab with url: $expectedUrl is visible") onView( allOf( withId(R.id.url), @@ -70,45 +81,64 @@ class RecentlyClosedTabsRobot { ), ), ).check(matches(withText(Matchers.containsString(expectedUrl.toString())))) + Log.i(TAG, "verifyRecentlyClosedTabsUrl: Verified that the recently closed tab with url: $expectedUrl is visible") } - fun clickDeleteRecentlyClosedTabs() = recentlyClosedTabDeleteButton().click() + fun clickDeleteRecentlyClosedTabs() { + Log.i(TAG, "clickDeleteRecentlyClosedTabs: Trying to click the recently closed tab item delete button") + recentlyClosedTabDeleteButton().click() + Log.i(TAG, "clickDeleteRecentlyClosedTabs: Clicked the recently closed tab item delete button") + } class Transition { fun clickRecentlyClosedItem(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { recentlyClosedTabsPageTitle(title).also { + Log.i(TAG, "clickRecentlyClosedItem: Waiting for $waitingTimeShort ms for recently closed tab with title: $title to exist") it.waitForExists(waitingTimeShort) + Log.i(TAG, "clickRecentlyClosedItem: Waited for $waitingTimeShort ms for recently closed tab with title: $title to exist") + Log.i(TAG, "clickRecentlyClosedItem: Trying to click the recently closed tab with title: $title") it.click() + Log.i(TAG, "clickRecentlyClosedItem: Clicked the recently closed tab with title: $title") } + Log.i(TAG, "clickRecentlyClosedItem: Waiting for device to be idle") mDevice.waitForIdle() + Log.i(TAG, "clickRecentlyClosedItem: Waited for device to be idle") BrowserRobot().interact() return BrowserRobot.Transition() } fun clickOpenInNewTab(testRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition { + Log.i(TAG, "clickOpenInNewTab: Trying to click the multi-select \"Open in a new tab\" context menu button") openInNewTabOption().click() + Log.i(TAG, "clickOpenInNewTab: Clicked the multi-select \"Open in a new tab\" context menu button") ComposeTabDrawerRobot(testRule).interact() return ComposeTabDrawerRobot.Transition(testRule) } fun clickOpenInPrivateTab(testRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition { + Log.i(TAG, "clickOpenInPrivateTab: Trying to click the multi-select \"Open in a private tab\" context menu button") openInPrivateTabOption().click() + Log.i(TAG, "clickOpenInPrivateTab: Clicked the multi-select \"Open in a private tab\" context menu button") ComposeTabDrawerRobot(testRule).interact() return ComposeTabDrawerRobot.Transition(testRule) } fun clickShare(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { + Log.i(TAG, "clickShare: Trying to click the share recently closed tabs button") multipleSelectionShareButton().click() + Log.i(TAG, "clickShare: Clicked the share recently closed tabs button") ShareOverlayRobot().interact() return ShareOverlayRobot.Transition() } fun goBackToHistoryMenu(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { + Log.i(TAG, "goBackToHistoryMenu: Trying to click navigate up toolbar button") onView(withContentDescription("Navigate up")).click() + Log.i(TAG, "goBackToHistoryMenu: Clicked navigate up toolbar button") HistoryRobot().interact() return HistoryRobot.Transition() From 1e5bb036370dae6a41547d1713a247ab853c5953 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 31 Jan 2024 21:29:21 -0500 Subject: [PATCH 204/586] Bug 1877888 - Update Adjust to version 4.38.1 --- .../fenixdependencies/src/main/java/FenixDependenciesPlugin.kt | 2 +- .../focusdependencies/src/main/java/FocusDependenciesPlugin.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt b/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt index 6cce2f427b86..0cdb5a6d12e4 100644 --- a/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt +++ b/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt @@ -29,7 +29,7 @@ object FenixVersions { const val androidx_datastore = "1.0.0" const val google_accompanist = "0.32.0" - const val adjust = "4.35.1" + const val adjust = "4.38.1" const val installreferrer = "2.2" const val junit = "5.9.3" diff --git a/focus-android/plugins/focusdependencies/src/main/java/FocusDependenciesPlugin.kt b/focus-android/plugins/focusdependencies/src/main/java/FocusDependenciesPlugin.kt index d426a32f5866..95f9326d6c31 100644 --- a/focus-android/plugins/focusdependencies/src/main/java/FocusDependenciesPlugin.kt +++ b/focus-android/plugins/focusdependencies/src/main/java/FocusDependenciesPlugin.kt @@ -14,7 +14,7 @@ class FocusDependenciesPlugin : Plugin { object FocusVersions { object Adjust { - const val adjust = "4.35.1" + const val adjust = "4.38.1" const val install_referrer = "2.2" } From 7ed2e0782444a8fb572d165e9533c43022cf0b7a Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 31 Jan 2024 21:23:12 -0500 Subject: [PATCH 205/586] Bug 1877887 - Update ZXing to version 3.5.3 --- .../plugins/dependencies/src/main/java/DependenciesPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt index 8317fa7a7ceb..acd18d71c8d8 100644 --- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt +++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt @@ -38,7 +38,7 @@ object Versions { const val sentry = "7.3.0" - const val zxing = "3.5.2" + const val zxing = "3.5.3" const val disklrucache = "2.0.2" const val leakcanary = "2.13" From 163501769705940eec8e9b58efd5888ceb5b08b3 Mon Sep 17 00:00:00 2001 From: DreVla Date: Wed, 14 Feb 2024 11:56:46 +0200 Subject: [PATCH 206/586] Bug 1870701 - Replace straight quotes with curly quotes in RC onboarding Due to straight quotes giving an error in pontoon, these have to be replaced with curly quotes. --- .../shopping/ui/ReviewQualityCheckContextualOnboarding.kt | 2 +- fenix/app/src/main/res/values/strings.xml | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/fenix/app/src/main/java/org/mozilla/fenix/shopping/ui/ReviewQualityCheckContextualOnboarding.kt b/fenix/app/src/main/java/org/mozilla/fenix/shopping/ui/ReviewQualityCheckContextualOnboarding.kt index afa4da62dd4e..0ab8bca523a5 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/shopping/ui/ReviewQualityCheckContextualOnboarding.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/shopping/ui/ReviewQualityCheckContextualOnboarding.kt @@ -113,7 +113,7 @@ fun ReviewQualityCheckContextualOnboarding( LinkText( text = stringResource( - id = R.string.review_quality_check_contextual_onboarding_caption_3, + id = R.string.review_quality_check_contextual_onboarding_caption_4, stringResource(id = R.string.firefox), privacyPolicyText, stringResource(id = R.string.shopping_product_name), diff --git a/fenix/app/src/main/res/values/strings.xml b/fenix/app/src/main/res/values/strings.xml index 38148a49f80e..486a5a0caf8d 100644 --- a/fenix/app/src/main/res/values/strings.xml +++ b/fenix/app/src/main/res/values/strings.xml @@ -2251,7 +2251,9 @@ By selecting “Yes, try it” you agree to the following from %1$s: - By selecting “Yes, try it” you agree to %1$s\'s %2$s and %3$s\'s %4$s. + By selecting “Yes, try it” you agree to %1$s\'s %2$s and %3$s\'s %4$s. + + By selecting “Yes, try it” you agree to %1$s\’s %2$s and %3$s\’s %4$s. privacy policy From 7eb4f3fb2b066be507a9d80e584272f48b1041d4 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 14 Feb 2024 13:44:11 +0000 Subject: [PATCH 207/586] Update GeckoView (Nightly) to 124.0.20240214094558. --- android-components/plugins/dependencies/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt index e6ae5164f0d1..7254baf0a556 100644 --- a/android-components/plugins/dependencies/src/main/java/Gecko.kt +++ b/android-components/plugins/dependencies/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "124.0.20240213210653" + const val version = "124.0.20240214094558" /** * GeckoView channel From a56dae01da335e2b827ff509bdfeaa4fa7a8a386 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 14 Feb 2024 13:44:11 +0000 Subject: [PATCH 208/586] Update Glean to 57.0.0. --- .../plugins/dependencies/src/main/java/DependenciesPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt index acd18d71c8d8..0e8be735cd80 100644 --- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt +++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt @@ -44,7 +44,7 @@ object Versions { const val leakcanary = "2.13" // DO NOT MODIFY MANUALLY. This is auto-updated along with GeckoView. - const val mozilla_glean = "56.1.0" + const val mozilla_glean = "57.0.0" const val material = "1.9.0" const val ksp = "1.0.17" From bd7a7e4ca01f20d7546b6ce99d7c5020938fc1f3 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 14 Feb 2024 05:21:33 +0000 Subject: [PATCH 209/586] Update A-S to 124.20240214150638. --- .../plugins/dependencies/src/main/java/ApplicationServices.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt index 2ceca30e0b13..3ab69f0d7432 100644 --- a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt +++ b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // These lines are generated by android-components/automation/application-services-nightly-bump.py -val VERSION = "124.20240213050313" +val VERSION = "124.20240214150638" val CHANNEL = ApplicationServicesChannel.NIGHTLY object ApplicationServicesConfig { From fb472ef6e96db30b7d1843d18b223509ad05c209 Mon Sep 17 00:00:00 2001 From: William Durand Date: Mon, 12 Feb 2024 17:23:44 +0100 Subject: [PATCH 210/586] Bug 1875229 - Add support for extensions not allowed in private windows --- .../gecko/webextension/GeckoWebExtension.kt | 2 + .../webextension/GeckoWebExtensionTest.kt | 50 ++++++++++++ .../gecko/webextension/MockWebExtension.kt | 3 + .../engine/webextension/WebExtension.kt | 41 ++++++++++ .../components/feature/addons/Addon.kt | 31 ++++++++ .../ui/AddonInstallationDialogFragment.kt | 9 ++- .../addons/src/main/res/values/strings.xml | 2 + .../feature/addons/src/test/java/AddonTest.kt | 3 + .../ui/AddonInstallationDialogFragmentTest.kt | 26 +++++++ .../webextensions/WebExtensionSupportTest.kt | 2 + .../addons/InstalledAddonDetailsFragment.kt | 78 +++++++++++-------- .../InstalledAddonDetailsFragmentTest.kt | 26 ++++++- 12 files changed, 233 insertions(+), 40 deletions(-) diff --git a/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/webextension/GeckoWebExtension.kt b/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/webextension/GeckoWebExtension.kt index ae574b6559a3..e55e745a2216 100644 --- a/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/webextension/GeckoWebExtension.kt +++ b/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/webextension/GeckoWebExtension.kt @@ -13,6 +13,7 @@ import mozilla.components.concept.engine.Settings import mozilla.components.concept.engine.webextension.Action import mozilla.components.concept.engine.webextension.ActionHandler import mozilla.components.concept.engine.webextension.DisabledFlags +import mozilla.components.concept.engine.webextension.Incognito import mozilla.components.concept.engine.webextension.MessageHandler import mozilla.components.concept.engine.webextension.Metadata import mozilla.components.concept.engine.webextension.Port @@ -373,6 +374,7 @@ class GeckoWebExtension( baseUrl = it.baseUrl, temporary = it.temporary, detailUrl = it.amoListingUrl, + incognito = Incognito.fromString(it.incognito), ) } } diff --git a/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/webextension/GeckoWebExtensionTest.kt b/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/webextension/GeckoWebExtensionTest.kt index 3658aea4bd12..9bf9ba7f493f 100644 --- a/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/webextension/GeckoWebExtensionTest.kt +++ b/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/webextension/GeckoWebExtensionTest.kt @@ -10,6 +10,7 @@ import mozilla.components.concept.engine.DefaultSettings import mozilla.components.concept.engine.webextension.Action import mozilla.components.concept.engine.webextension.ActionHandler import mozilla.components.concept.engine.webextension.DisabledFlags +import mozilla.components.concept.engine.webextension.Incognito import mozilla.components.concept.engine.webextension.MessageHandler import mozilla.components.concept.engine.webextension.Port import mozilla.components.concept.engine.webextension.TabHandler @@ -420,6 +421,7 @@ class GeckoWebExtensionTest { updateDate = "updateDate", reviewCount = 2, averageRating = 2.2, + incognito = "split", ), ) val extensionWithMetadata = GeckoWebExtension(nativeWebExtension, runtime) @@ -447,6 +449,7 @@ class GeckoWebExtensionTest { assertTrue(metadata.disabledFlags.contains(DisabledFlags.USER)) assertFalse(metadata.disabledFlags.contains(DisabledFlags.BLOCKLIST)) assertFalse(metadata.disabledFlags.contains(DisabledFlags.APP_SUPPORT)) + assertEquals(Incognito.SPLIT, metadata.incognito) } @Test @@ -463,6 +466,7 @@ class GeckoWebExtensionTest { baseUrl = "moz-extension://123c5c5b-cd03-4bea-b23f-ac0b9ab40257/", disabledFlags = DisabledFlags.USER, permissions = arrayOf("p1", "p2"), + incognito = null, ), ) val extensionWithMetadata = GeckoWebExtension(nativeWebExtension, runtime) @@ -484,6 +488,7 @@ class GeckoWebExtensionTest { assertNull(metadata.reviewUrl) assertNull(metadata.updateDate) assertNull(metadata.downloadUrl) + assertEquals(Incognito.SPANNING, metadata.incognito) } @Test @@ -583,4 +588,49 @@ class GeckoWebExtensionTest { webExtensionWithIcon.getIcon(48) verify(iconMock).getBitmap(48) } + + @Test + fun `incognito set to spanning`() { + val runtime: GeckoRuntime = mock() + val nativeWebExtension = mockNativeWebExtension( + id = "id", + location = "uri", + metaData = mockNativeWebExtensionMetaData(version = "1", incognito = "spanning"), + ) + val extensionWithMetadata = GeckoWebExtension(nativeWebExtension, runtime) + + val metadata = extensionWithMetadata.getMetadata() + assertNotNull(metadata) + assertEquals(Incognito.SPANNING, metadata.incognito) + } + + @Test + fun `incognito set to not_allowed`() { + val runtime: GeckoRuntime = mock() + val nativeWebExtension = mockNativeWebExtension( + id = "id", + location = "uri", + metaData = mockNativeWebExtensionMetaData(version = "1", incognito = "not_allowed"), + ) + val extensionWithMetadata = GeckoWebExtension(nativeWebExtension, runtime) + + val metadata = extensionWithMetadata.getMetadata() + assertNotNull(metadata) + assertEquals(Incognito.NOT_ALLOWED, metadata.incognito) + } + + @Test + fun `incognito set to split`() { + val runtime: GeckoRuntime = mock() + val nativeWebExtension = mockNativeWebExtension( + id = "id", + location = "uri", + metaData = mockNativeWebExtensionMetaData(version = "1", incognito = "split"), + ) + val extensionWithMetadata = GeckoWebExtension(nativeWebExtension, runtime) + + val metadata = extensionWithMetadata.getMetadata() + assertNotNull(metadata) + assertEquals(Incognito.SPLIT, metadata.incognito) + } } diff --git a/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/webextension/MockWebExtension.kt b/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/webextension/MockWebExtension.kt index 348c1646dc6c..e5b59c1b294b 100644 --- a/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/webextension/MockWebExtension.kt +++ b/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/webextension/MockWebExtension.kt @@ -55,6 +55,7 @@ fun mockNativeWebExtensionMetaData( updateDate: String? = null, reviewCount: Int = 0, averageRating: Double = 0.0, + incognito: String? = "spanning", ): WebExtension.MetaData { val metadata: WebExtension.MetaData = mock() ReflectionUtils.setField(metadata, "icon", icon) @@ -82,6 +83,8 @@ fun mockNativeWebExtensionMetaData( ReflectionUtils.setField(metadata, "updateDate", updateDate) ReflectionUtils.setField(metadata, "reviewCount", reviewCount) ReflectionUtils.setField(metadata, "averageRating", averageRating) + ReflectionUtils.setField(metadata, "averageRating", averageRating) + ReflectionUtils.setField(metadata, "incognito", incognito) return metadata } diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/webextension/WebExtension.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/webextension/WebExtension.kt index ede179ca937e..5fe7eb2ed0c4 100644 --- a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/webextension/WebExtension.kt +++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/webextension/WebExtension.kt @@ -470,6 +470,12 @@ data class Metadata( * The URL to the detail page of this extension. */ val detailUrl: String?, + + /** + * Indicates how this extension works with private browsing windows. + * https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/incognito + */ + val incognito: Incognito, ) /** @@ -516,6 +522,41 @@ class DisabledFlags internal constructor(val value: Int) { fun contains(flag: Int) = (value and flag) != 0 } +/** + * Incognito values that control how an extension works with private browsing windows. + */ +enum class Incognito { + /** + * The extension will see events from private and non-private windows and tabs. + */ + SPANNING, + + /** + * The extension will be split between private and non-private windows. + */ + SPLIT, + + /** + * Private tabs and windows are invisible to the extension. + */ + NOT_ALLOWED, + + ; + + companion object { + /** + * Safely returns an Incognito value based on the input nullable string. + */ + fun fromString(value: String?): Incognito { + return when (value) { + "split" -> SPLIT + "not_allowed" -> NOT_ALLOWED + else -> SPANNING + } + } + } +} + /** * Returns whether or not the extension is disabled because it is unsupported. */ diff --git a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/Addon.kt b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/Addon.kt index 64c6fc49333a..6046e04c7407 100644 --- a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/Addon.kt +++ b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/Addon.kt @@ -11,6 +11,7 @@ import android.os.Parcelable import androidx.annotation.VisibleForTesting import androidx.core.net.toUri import kotlinx.parcelize.Parcelize +import mozilla.components.concept.engine.webextension.Incognito import mozilla.components.concept.engine.webextension.WebExtension import mozilla.components.support.base.log.logger.Logger import java.text.ParseException @@ -18,6 +19,8 @@ import java.text.SimpleDateFormat import java.util.Locale import java.util.TimeZone +typealias GeckoIncognito = Incognito + val logger = Logger("Addon") /** @@ -46,6 +49,7 @@ val logger = Logger("Addon") * @property defaultLocale Indicates which locale will be always available to display translatable fields. * @property ratingUrl The link to the ratings page (user reviews) for this [Addon]. * @property detailUrl The link to the detail page for this [Addon]. + * @property incognito Indicates how the extension works with private browsing windows. */ @SuppressLint("ParcelCreator") @Parcelize @@ -68,6 +72,7 @@ data class Addon( val defaultLocale: String = DEFAULT_LOCALE, val ratingUrl: String = "", val detailUrl: String = "", + val incognito: Incognito = Incognito.SPANNING, ) : Parcelable { /** @@ -165,6 +170,26 @@ data class Addon( INCOMPATIBLE, } + /** + * Incognito values that control how an [Addon] works with private browsing windows. + */ + enum class Incognito { + /** + * The [Addon] will see events from private and non-private windows and tabs. + */ + SPANNING, + + /** + * The [Addon] will be split between private and non-private windows. + */ + SPLIT, + + /** + * Private tabs and windows are invisible to the [Addon]. + */ + NOT_ALLOWED, + } + /** * Returns a list of localized Strings per each item on the [permissions] list. * @param context A context reference. @@ -315,6 +340,11 @@ data class Addon( null } val detailUrl = metadata?.detailUrl.orEmpty() + val incognito = when (metadata?.incognito) { + GeckoIncognito.NOT_ALLOWED -> Incognito.NOT_ALLOWED + GeckoIncognito.SPLIT -> Incognito.SPLIT + else -> Incognito.SPANNING + } return Addon( id = extension.id, @@ -332,6 +362,7 @@ data class Addon( updatedAt = fromMetadataToAddonDate(metadata?.updateDate.orEmpty()), ratingUrl = ratingUrl, detailUrl = detailUrl, + incognito = incognito, installedState = installedState, ) } diff --git a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragment.kt b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragment.kt index 56ab680cfc39..095d6bf301c4 100644 --- a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragment.kt +++ b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragment.kt @@ -22,6 +22,7 @@ import android.widget.TextView import androidx.annotation.VisibleForTesting import androidx.appcompat.widget.AppCompatCheckBox import androidx.core.content.ContextCompat +import androidx.core.view.isVisible import androidx.fragment.app.FragmentManager import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.R @@ -153,8 +154,12 @@ class AddonInstallationDialogFragment : AddonDialogFragment() { loadIcon(addon = addon, iconView = binding.icon) val allowedInPrivateBrowsing = rootView.findViewById(R.id.allow_in_private_browsing) - allowedInPrivateBrowsing.setOnCheckedChangeListener { _, isChecked -> - allowPrivateBrowsing = isChecked + if (addon.incognito == Addon.Incognito.NOT_ALLOWED) { + allowedInPrivateBrowsing.isVisible = false + } else { + allowedInPrivateBrowsing.setOnCheckedChangeListener { _, isChecked -> + allowPrivateBrowsing = isChecked + } } val confirmButton = rootView.findViewById