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
+ PamilikPanungtung diropéa
@@ -114,8 +114,10 @@
RincianIdin
-
+
Piceun
+
+ LaporanTambahkeun %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 wachtwurdenDe 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ûnderingenNet-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 fuortsmiteOanmeldingen sykje
+
+ Wachtwurden sykjeWebsite
@@ -1736,10 +1745,16 @@
Wachtwurd ferstopjeUntskoattelje om jo bewarre oanmeldingen te besjen
+
+ Untskoattelje om jo bewarre wachtwurden te besjenBefeiligje jo oanmeldingen en wachtwurden
+
+ Befeiligje jo bewarre wachtwurdenStel 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 ynfoljeGegevens binne fersifere
+
+ %s fersiferet alle betellingsmetoaden dy’t jo bewarjeKaarten 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ûkenAdres tafoegje
@@ -2003,30 +2024,52 @@
BewurkjeBinne jo wis dat jo dizze oanmelding fuortsmite wolle?
+
+ Binne jo wis dat jo dit wachtwurd fuortsmite wolle?FuortsmiteAnnulearjeOanmeldopsjes
+
+ WachtwurdopsjesIt 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 bewurkjeNije oanmelding tafoegje
+
+ Wachtwurd tafoegjeWachtwurd fereaske
+
+ Folje in wachtwurd ynBrûkersnamme fereaske
+
+ Folje in brûkersnamme ynHostnamme fereaske
+
+ Fier in websiteadres ynSprutsen sykopdracht
@@ -2403,6 +2446,10 @@ Dizze analyze sil jo allinnich helpe om de beoardielingskwaliteit te beoardielen
%1$s nea oersetteDizze website nea oersette
+
+ Oerskriuwt alle oare ynstellingen
+
+ Negearret oersetoanbiedingenOersetynstellingen
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 AnyarSetélanNgeunaanPitulung
@@ -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 emptyEnter a password
-
+
Unable to save loginCan’t save password
@@ -100,19 +100,19 @@
Set timeManage logins
-
+
Manage passwordsExpand suggested logins
-
+
Expand saved passwordsCollapse suggested logins
-
+
Collapse saved passwordsSuggested 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 optionsThe 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$dAccess 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ḍanFren asaǧǧăw n unekcum
-
- Fren amiḍanQqen 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 cyfrineiriauMaes 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 iaithBu 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øgetjenesteIndstillinger 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æringAngiv som standard-browser
@@ -435,22 +435,11 @@
Tilstanden Kun-HTTPS
-
- Reduktion af cookie-bannereBlokering af cookie-bannereBlokering 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 sideUdskriv
@@ -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 anmeldelserhvordan %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
-
- SuchmaschineSuchmaschinen-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-BannernCookie-Banner-BlockerCookie-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 werdenDrucken
@@ -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-OptionenDas 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 feststelltWie %s die Qualität der Rezensionen bestimmt
@@ -2492,6 +2461,8 @@
Übersetzung läuft
+
+ Sprache auswählenBeim Ü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ś
-
- PytnicaNastajenja 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órgojowBlokěrowak cookiejowych chórgojowBlokě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 nastajenjaWobźěł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óstajakak %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ñaEl 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 idiomaHubo 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 maksutavatAseta 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 asetuksetMuokattava 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 kieliKää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 rechercheParamè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 cookiesBloqueur de bannières de cookiesBloqueur 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 impossibleImprimer
@@ -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 passeLe 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 avisla façon dont %s détermine la qualité d’un avis
@@ -2493,6 +2462,8 @@
Traduction en cours
+
+ Choisissez une langueUn 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 @@
WachtwurdopsjesIt 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 taalDer 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ć
-
- PytawaNastajenja 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 chorhojowBlokowak plackowych chorhojowBlokowak 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 nastajenjaWobdźěł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 postajakak %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ásKereső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éseSü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ésA %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ásokA 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éthogyan határozza meg a %s az értékelések minőségét
@@ -2477,6 +2446,8 @@
Fordítás folyamatban
+
+ Válasszon nyelvetHiba 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 recercaParametros 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 cookieBlocada 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 paginaImprimer
@@ -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 contrasignoLe 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 revisioncomo %s determina le qualitate del revision
@@ -2514,6 +2481,8 @@
Traduction in curso
+
+ Elige un linguaIl 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 @@
BreytaSé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élLeitarvé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íðuPrenta
@@ -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ðsBreytilegi 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 umsagnahvernig %s ákvarðar gæði umsagna
@@ -2453,6 +2422,8 @@
Þýðing í gangi
+
+ Veldu tungumálVandamá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 ricercaImpostazioni 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 cookieBlocco banner per i cookieBlocco 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 paginaStampa
@@ -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 passwordIl 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 recensionicome %s determina la qualità delle recensioni
@@ -2505,6 +2474,8 @@
Traduzione in corso
+
+ Scegli una linguaSi è 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 amtawiNadi deg usebter
+
+ Suqel asebterSekles ɣ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 unadiIɣ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 FirefoxNḥ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 tuqqnaAmsewḥel n yiɣarracen n yinagan n tuqqnaAmsewḥ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 ufayluIlɣa
@@ -711,6 +694,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Ticraḍ n yisebtarInekcam
+
+ Awalen uffirenAccaren 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-aSiggez
@@ -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 uffirenSekles inekcam d wawalen uffiren
+
+ Sekles awalen uffirenSuter asekles
@@ -1706,16 +1698,25 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Rnu anekcum
+
+ Rnu awal uffir
+
Mtawi inekcam
+
+ Mtawi awalen uffirenMtawi inekcam gqr yibenkanInekcam yettwakelsen
+
+ Awalen uffiren yettwakelsenAnekcum i tḥerzeḍ ɣer %s ad d-ittwasken da.Issin ugar ɣef umtawi.
+
+ Issin ugar ɣef umtawiTisuraf
@@ -1726,6 +1727,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Kkes akk tisurafNadi inekcam
+
+ Nadi awalen uffirenAsmel web
@@ -1785,6 +1788,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
TansiwinTikarḍ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ḍiwinRnu takarḍa n usmad
+
+ Rnu takarḍaSefrek tikerḍiwin yettwaskelsen
+
+ Sefrek tikarḍiwinRnu tansaSefrek tansiwinAsekles d taččart tawurmant n tansiwin
+
+ Sekles; teččareḍ tansiwinSeddu talɣut am wuṭṭunen, imayl akked tansiwin n usiweḍ
@@ -1826,6 +1837,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Kkes takarḍaTebɣ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ɣtuTtxil-k·m ččar urti-a
+
+ Rnu isemKkes 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 uffirRnu anekcum amaynut
+
+ Rnu awal uffirAwal uffir yettusra
+
+ Sekcem awal uffirIsem n useqdac yettwasra
+
+ Sekcem isem n useqdacAsenneftaɣ yettwasra
@@ -2317,6 +2346,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Suqqel
+
+ Fren tutlaytYella 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 yellaniţ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
-
- ZoekmachineInstellingen 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 cookiebannersBlokkering van cookiebannersBlokkering 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 afdrukkenAfdrukken
@@ -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 @@
WachtwoordoptiesHet 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 bepaalthoe %s de beoordelingskwaliteit bepaalt
@@ -2474,6 +2443,8 @@
Vertaling wordt uitgevoerd
+
+ Kies een taalEr 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 senhasO 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 idiomaHouve 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-passeO 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çãoTradução em curso
+
+ Escolha um idiomaOcorreu 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ösenordsalternativDet 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åkDet 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çenekleriHesabı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$dAccedir 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$dCael mynediad at dabiau’r porwyr
@@ -75,7 +77,7 @@
Awdur
- Awduron
+ AwduronDiweddarwyd 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$dAuf Browsertabs zugreifen
@@ -75,7 +77,7 @@
Autor
- Autoren
+ AutorenZuletzt 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$dMějśo pśistup k rejtarikam wobglědowaka
@@ -75,7 +77,7 @@
Awtor
- Awtory
+ AwtorySlě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$dAcceder 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$dAcceder 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$dKäytä selaimen välilehtiä
@@ -75,7 +77,7 @@
Tekijä
- Tekijät
+ TekijätViimeksi 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$dBrowserljepblêden benaderje
@@ -75,7 +77,7 @@
Auteur
- Skriuwers
+ SkriuwersLê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$dMějće přistup k rajtarkam wobhladowaka
@@ -75,7 +77,7 @@
Awtor
- Awtorojo
+ AwtorojoPoslednja 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$dAcceder al schedas del navigator
@@ -75,7 +77,7 @@
Autor
- Autores
+ AutoresUltime 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$dSkoða vafraflipa
@@ -75,7 +77,7 @@
Höfundur
- Höfundar
+ HöfundarSeinast 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$dAccedere alle schede del browser
@@ -75,7 +77,7 @@
Autore
- Autori
+ AutoriUltimo 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$dBrowsertabbladen benaderen
@@ -75,7 +77,7 @@
Schrijver
- Auteurs
+ AuteursLaatst 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$dAccedir als onglets del navegador
@@ -75,7 +77,7 @@
Autor
- Autors
+ AutorsDarriè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$dAcessar 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$dAceder 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
+ UtvecklareSenast 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 @@
ContrasenyaNo desis
+
+ Ara noNo desis mai
@@ -26,16 +28,26 @@
DesaNo actualitzis
+
+ Ara noActualitzaEl 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 contrasenyaVoleu 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’horaGestiona els inicis de sessió
+
+ Gestiona les contrasenyesAmplia els inicis de sessió suggerits
+
+ Amplia les contrasenyes desadesRedueix els inicis de sessió suggerits
+
+ Redueix les contrasenyes desadesInicis de sessió suggerits
+
+ Contrasenyes desades
+
Suggereix una contrasenya segura
@@ -110,12 +131,20 @@
Seleccioneu una targeta de crèdit
+
+ Usa una targeta desadaAmplia les targetes de crèdit suggerides
+
+ Amplia les targetes desadesRedueix les targetes de crèdit suggerides
+
+ Redueix les targetes desadesGestiona les targetes de crèdit
+
+ Gestiona les targetesVoleu 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çaAmplia les adreces suggerides
+
+ Amplia les adreces desadesRedueix les adreces suggerides
+
+ Redueix les adreces desadesGestiona 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 @@
CyfrinairPeidio â chadw
+
+ Nid nawrByth cadw
@@ -26,16 +28,26 @@
CadwPeidio â diweddaru
+
+ Nid nawrDiweddaruRhaid i faes cyfrinair beidio â bod yn wag
+ Rhowch gyfrinair
+
Methu cadw mewngofnod
+
+ Methu cadw cyfrinairCadw’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 amserRheoli mewngofnodion
+
+ Rheoli cyfrineiriauEhangu’r mewngofnodion
+
+ Ehangu cyfrineiriau sydd wedi\'u cadwLleihau’r mewngofnodion
+
+ Cau cyfrineiriau sydd wedi\'u cadwMewngofnodion
+
+ Cyfrineiriau wedi\'u cadw
+
Awgrym o gyfrinair cryf
@@ -110,12 +131,20 @@
Dewiswch gerdyn credyd
+
+ Defnyddio cerdyn sydd wedi\'i gadwEhangu awgrymiad y cardiau credyd
+
+ Ehangu cardiau sydd wedi\'u cadwLleihau awgrymiad y cardiau credyd
+
+ Cau cardiau sydd wedi\'u cadwRheoli cardiau credyd
+
+ Rheoli cardiauCadw’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 gyfeiriadEhangu awgrymiadau cyfeiriadau
+
+ Ehangu cyfeiriadau sydd wedi\'u cadwLleihau awgrymiadau cyfeiriadau
+
+ Cau cyfeiriadau sydd wedi\'u cadwRheoli 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 jetztNie speichern
@@ -34,16 +36,26 @@
SpeichernNicht aktualisieren
+
+ Nicht jetztAktualisierenDas Passwortfeld darf nicht leer bleiben
+ Passwort eingeben
+
Zugangsdaten konnten nicht gespeichert werden
+
+ Passwort kann nicht gespeichert werdenDiese Zugangsdaten speichern?
+
+ Passwort speichern?Diese Zugangsdaten aktualisieren?
+
+ Passwort aktualisieren?Benutzernamen zum gespeicherten Passwort hinzufügen?
@@ -97,13 +109,22 @@
Zeit einstellenZugangsdaten verwalten
+
+ Passwörter verwaltenVorgeschlagene Zugangsdaten ausklappen
+
+ Gespeicherte Passwörter ausklappenVorgeschlagene Zugangsdaten einklappen
+
+ Gespeicherte Passwörter einklappenVorgeschlagene Zugangsdaten
+
+ Gespeicherte Passwörter
+
Starkes Passwort vorschlagen
@@ -122,12 +143,20 @@
Kreditkarte auswählen
+
+ Eine gespeicherte Karte verwendenVorgeschlagene Kreditkarten ausklappen
+
+ Gespeicherte Karten ausklappenVorgeschlagene Kreditkarten einklappen
+
+ Gespeicherte Karten einklappenKreditkarten verwalten
+
+ Karten verwaltenSoll 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ählenVorgeschlagene Adressen ausklappen
+
+ Gespeicherte Adressen ausklappenVorgeschlagene Adressen einklappen
+
+ Gespeicherte Adressen einklappenAdressen 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łoNjeskładowaś
+
+ Nic něntoNigda njeskładowaś
@@ -26,16 +28,26 @@
SkładowaśNjeaktualizěrowaś
+
+ Nic něntoAktualizě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ñaNo guardar
+
+ No ahoraNo guardar nunca
@@ -26,16 +28,26 @@
GuardarNo actualizar
+
+ No ahoraActualizarEl 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 horaAdministrar inicios de sesión
+
+ Administrar contraseñasExpandir los inicios de sesión sugeridos
+
+ Expandir las contraseñas guardadasContraer los inicios de sesión sugeridos
+
+ Contraer contraseñas guardadasInicios de sesión sugeridos
+
+ Contraseñas guardadas
+
Sugerir contraseña segura
@@ -111,12 +132,20 @@
Seleccionar tarjeta de crédito
+
+ Usar tarjeta guardadaAmpliar las tarjetas de crédito sugeridas
+
+ Expandir tarjetas guardadasContraer tarjetas de crédito sugeridas
+
+ Contraer tarjetas guardadasAdministrar 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ónExpandir direcciones sugeridas
+
+ Expandir las direcciones guardadasContraer direcciones sugeridas
+
+ Contraer direcciones guardadasAdministrar 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ñaNo guardar
+
+ Ahora noNunca guardar
@@ -26,16 +28,26 @@
GuardarNo actualizar
+
+ Ahora noActualizarEl 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 horaAdministrar credenciales
+
+ Gestionar contraseñasExpandir credenciales sugeridas
+
+ Expandir contraseñas guardadasContraer credenciales sugeridas
+
+ Contraer contraseñas guardadasCredenciales sugeridas
+
+ Contraseñas guardadas
+
Sugerir contraseña segura
@@ -110,12 +131,20 @@
Seleccionar tarjeta de crédito
+
+ Usar tarjeta guardadaExpandir tarjetas de crédito sugeridas
+
+ Expandir tarjetas guardadasOcultar tarjetas de crédito sugeridas
+
+ Contraer tarjetas guardadasGestionar 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ónExpandir direcciones sugeridas
+
+ Expandir direcciones guardadasOcultar direcciones sugeridas
+
+ Contraer direcciones guardadasGestionar 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 nytPäivitäSalasanakenttä ei saa olla tyhjä
+ Kirjoita salasana
+
Kirjautumistietojen tallennus epäonnistui
+
+ Salasanaa ei voi tallentaaTallennetaanko 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 aikaHallitse kirjautumistietoja
+
+ Hallitse salasanojaLaajenna ehdotetut kirjautumistiedot
+
+ Laajenna tallennetut salasanatSupista ehdotetut kirjautumistiedot
+
+ Supista tallennetut salasanatEhdotetut kirjautumistiedot
+
+ Tallennetut salasanat
+
Ehdota vahvaa salasanaa
@@ -110,12 +131,20 @@
Valitse luottokortti
+
+ Käytä tallennettua korttiaLaajenna ehdotetut luottokortit
+
+ Laajenna tallennetut kortitSupista ehdotetut luottokortit
+
+ Supista tallennetut kortitHallitse luottokortteja
+
+ Hallitse korttejaTallennetaanko tämä kortti turvallisesti?
@@ -123,13 +152,20 @@
Kortin numero salataan. Suojakoodia ei tallenneta.
+
+ %s salaa korttisi numeron. Turvakoodiasi ei tallenneta.
+
Valitse osoiteLaajenna ehdotetut osoitteet
+
+ Laajenna tallennetut osoitteetSupista ehdotetut osoitteet
+
+ Supista tallennetut osoitteetHallitse 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 tardNe jamais enregistrer
@@ -32,16 +34,26 @@
EnregistrerNe pas mettre à jour
+
+ Plus tardMettre à jourLe 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 passeEnregistrer 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’heureGérer les identifiants
+
+ Gérer les mots de passeDé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éeDévelopper les cartes bancaires suggéréesRéduire les cartes bancaires suggéréesGérer les cartes bancaires
+
+ Gérer les cartesEnregistrer 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 @@
WachtwurdNet bewarje
+
+ No netNea bewarje
@@ -26,16 +28,26 @@
BewarjeNet bywurkje
+
+ No netBywurkjeWachtwurdfjild mei net leech wêze
+ Folje in wachtwurd yn
+
Kin oanmelding net bewarje
+
+ Kin wachtwurd net bewarjeDizze oanmelding bewarje?
+
+ Wachtwurd bewarje?Dizze oanmelding bywurkje?
+
+ Wachtwurd bywurkje?Brûkersnamme oan bewarre wachtwurd tafoegje?
@@ -85,13 +97,22 @@
Tiid ynstelleOanmeldingen beheare
+
+ Wachtwurden beheareFoarstelde oanmeldingen útklappe
+
+ Bewarre wachtwurden te útklappeFoarstelde oanmeldingen ynklappe
+
+ Bewarre wachtwurden ynklappeFoarstelde oanmeldingen
+
+ Bewarre wachtwurden
+
Sterk wachtwurd foarstelle
@@ -110,12 +131,20 @@
Selektearje creditcard
+
+ Bewarre kaart brûkeFoarstelde creditcards útklappe
+
+ Bewarre kaarten te útklappeFoarstelde creditcards ynklappe
+
+ Bewarre kaarten ynklappeCreditcards beheare
+
+ Kaarten beheareDizze 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 selektearjeFoarstelde adressen útklappe
+
+ Bewarre adressen útklappeFoarstelde adressen ynklappe
+
+ Bewarre adressen ynklappeAdressen 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łoNjeskładować
+
+ Nic nětkoŽenje njeskładować
@@ -26,16 +28,26 @@
SkładowaćNjeaktualizować
+
+ Nic nětkoAktualizować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 @@
ContrasignoNon salvar
+
+ Non oraNon salvar mais
@@ -26,16 +28,26 @@
SalvarNon actualisar
+
+ Non oraActualisarLe campo del contrasigno non debe esser vacue
+ Insere un contrasigno
+
Impossibile salvar le credentiales
+
+ Impossibile salvar le contrasignoSalvar 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 contrasignosExpander le credentiales suggerite
+
+ Expander le contrasignos salvateCollaber le credentiales suggerite
+
+ Comprimer le contrasignos salvateCredentiales suggerite
+
+ Contrasignos salvate
+
Suggerer contrasigno complexe
@@ -111,12 +132,20 @@
Eliger le carta de credito
+
+ Usar un carta salvateExpander le cartas de credito suggerite
+
+ Expander le cartas salvateCollaber le cartas de credito suggerite
+
+ Comprimer le cartas salvateGerer le cartas de credito
+
+ Gerer le cartasSecurmente 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 adressExpander adresses suggerite
+
+ Expander adresses salvateCollaber adresses suggerite
+
+ Collaber adresses salvateGerer 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únaAldrei vista
@@ -26,16 +28,26 @@
VistaEkki uppfæra
+
+ Ekki núnaUppfæraLykilorð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ð kortFletta út tillögum að greiðslukortum
+
+ Fletta út vistuð greiðslukortFella saman tillögur að greiðslukortum
+
+ Fella saman vistuð greiðslukortSýsla með greiðslukort
+
+ Sýsla með greiðslukortVista þ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óstfangFletta út tillögum að póstföngum
+
+ Fletta út vistuðum heimilisföngumFella saman tillögur að póstföngum
+
+ Fella saman vistuð heimilisföngSý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 @@
PasswordNon salvare
+
+ Non adessoNon salvare mai
@@ -26,16 +28,26 @@
SalvaNon aggiornare
+
+ Non adessoAggiornaÈ necessario inserire una password
+ Inserisci una password
+
Impossibile salvare le credenziali
+
+ Impossibile salvare la passwordSalvare queste credenziali?
+
+ Salvare la password?Aggiornare queste credenziali?
+
+ Aggiornare la password?Aggiungere il nome utente alle credenziali salvate?
@@ -85,13 +97,22 @@
Imposta oraGestione credenziali
+
+ Gestisci passwordEspandi le credenziali suggerite
+
+ Espandi le password salvateComprimi le credenziali suggerite
+
+ Comprimi le password salvateCredenziali suggerite
+
+ Password salvate
+
Suggerisci password complessa
@@ -110,12 +131,20 @@
Seleziona carta di credito
+
+ Utilizza carta salvataEspandi l’elenco delle carte di credito suggerite
+
+ Espandi le carte salvateComprimi l’elenco delle carte di credito suggerite
+
+ Comprimi le carte salvateGestisci carte di credito
+
+ Gestisci carteSalvare 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 indirizzoEspandi gli indirizzi suggeriti
+
+ Espandi gli indirizzi salvatiComprimi gli indirizzi suggeriti
+
+ Comprimi gli indirizzi salvatiGestisci 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 @@
WachtwoordNiet opslaan
+
+ Niet nuNooit opslaan
@@ -26,16 +28,26 @@
OpslaanNiet bijwerken
+
+ Niet nuBijwerkenWachtwoordveld mag niet leeg zijn
+ Vul een wachtwoord in
+
Kan aanmelding niet opslaan
+
+ Kan wachtwoord niet opslaanDeze aanmelding opslaan?
+
+ Wachtwoord opslaan?Deze aanmelding bijwerken?
+
+ Wachtwoord bijwerken?Gebruikersnaam aan opgeslagen wachtwoord toevoegen?
@@ -85,13 +97,22 @@
Tijd instellenAanmeldingen beheren
+
+ Wachtwoorden beherenVoorgestelde aanmeldingen uitvouwen
+
+ Opgeslagen wachtwoorden uitvouwenVoorgestelde aanmeldingen inklappen
+
+ Opgeslagen wachtwoorden inklappenVoorgestelde aanmeldingen
+
+ Opgeslagen wachtwoorden
+
Sterk wachtwoord voorstellen
@@ -110,12 +131,20 @@
Selecteer creditcard
+
+ Opgeslagen kaart gebruikenVoorgestelde creditcards uitbreiden
+
+ Opgeslagen kaarten uitvouwenVoorgestelde creditcards inklappen
+
+ Opgeslagen kaarten inklappenCreditcards beheren
+
+ Kaarten beherenDeze 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 selecterenVoorgestelde adressen uitvouwen
+
+ Opgeslagen adressen uitvouwenVoorgestelde adressen inklappen
+
+ Opgeslagen adressen inklappenAdressen 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 @@
SenhalEnregistrar pas
+
+ Pas araEnregistrar pas jamai
@@ -26,16 +28,26 @@
EnregistrarMetre pas a jorn
+
+ Pas araMetre a jornLo camp senhal pòt pas èsser void
+ Picatz un senhal
+
Impossible d’enregistrar l’identificant
+
+ Enregistrament de senhal impossibleSalvar 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 tempsGerir los identificants
+
+ Gerir los senhalsEspandir los identificants suggerits
+
+ Desplegar los senhals salvatsPlegar los identificants suggerits
+
+ Plegar los senhals salvatsIdentificants recomandats
+
+ Senhals salvats
+
Suggerir un senhal fòrt
@@ -110,12 +131,16 @@
Seleccionar carta de crèdit
+
+ Utilizar una carta enregistradaEspandir las cartas de crèdit suggeridasPlegar las cartas de crèdit suggeridasGerir las cartas de crèdit
+
+ Gerir las cartasSalvar 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 @@
SenhaNão salvar
+
+ Agora nãoNunca salvar
@@ -26,16 +28,26 @@
SalvarNão atualizar
+
+ Agora nãoAtualizarO 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 senhaSalvar esta conta?
+
+ Salvar senha?Atualizar esta conta?
+
+ Atualizar senha?Adicionar nome de usuário à senha salva?
@@ -85,13 +97,22 @@
Ajustar horaGerenciar contas
+
+ Gerenciar senhasExpandir sugestão de contas
+
+ Expandir senhas salvasRecolher sugestão de contas
+
+ Recolher senhas salvasSugestão de contas
+
+ Senhas salvas
+
Sugerir senha forte
@@ -110,12 +131,20 @@
Selecionar cartão de crédito
+
+ Usar cartão salvoExpandir sugestões de cartão de crédito
+
+ Expandir cartões salvosRecolher sugestões de cartão de crédito
+
+ Recolher cartões salvosGerenciar cartões de crédito
+
+ Gerenciar cartõesSalvar 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çoExpandir endereços sugeridos
+
+ Expandir endereços salvosRecolher endereços sugeridos
+
+ Recolher endereços salvosGerenciar 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-passeNão guardar
+
+ Agora nãoNunca guardar
@@ -26,16 +28,26 @@
GuardarNão atualizar
+
+ Agora nãoAtualizarO 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-passeGuardar esta credencial?
+
+ Guardar palavra-passe?Atualizar esta credencial?
+
+ Atualizar palavra-passe?Adicionar nome de utilizador à palavra-passe guardada?
@@ -85,13 +97,22 @@
Definir horaGerir credenciais
+
+ Gerir palavras-passeExpandir credenciais sugeridas
+
+ Expandir palavras-passe guardadasColapsar credenciais sugeridas
+
+ Colapsar palavras-passe guardadasCredenciais sugeridas
+
+ Palavras-passe guardadas
+
Sugerir palavra-passe forte
@@ -111,12 +132,20 @@
Selecionar cartão de crédito
+
+ Utilizar cartão guardadoExpandir os cartões de créditos sugeridos
+
+ Expandir cartões guardadosColapsar os cartões de crédito sugeridos
+
+ Colapsar cartões guardadosGerir cartões de crédito
+
+ Gerir cartõesGuardar 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çoExpandir endereços sugeridos
+
+ Expandir endereços guardadosColapsar endereços sugeridas
+
+ Colapsar endereços guardadosGerir 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ösenordSpara inte
+
+ Inte nuSpara aldrig
@@ -26,16 +28,26 @@
SparaUppdatera inte
+
+ Inte nuUppdateraLösenordsfältet får inte vara tomt
+ Ange ett lösenord
+
Kunde inte spara inloggningsuppgifter
+
+ Det går inte att spara lösenordetSpara 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 tidHantera inloggningar
+
+ Hantera lösenordExpandera föreslagna inloggningar
+
+ Expandera sparade lösenordKomprimera föreslagna inloggningar
+
+ Komprimera sparade lösenordFöreslagna inloggningar
+
+ Sparade lösenord
+
Föreslå ett starkt lösenord
@@ -110,12 +131,20 @@
Välj kreditkort
+
+ Använd sparat kortExpandera föreslagna kreditkort
+
+ Expandera sparade kortKomprimera föreslagna kreditkort
+
+ Komprimera sparade kortHantera kreditkort
+
+ Hantera kortVill 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 adressExpandera föreslagna adresser
+
+ Expandera sparade adresserKomprimera föreslagna adresser
+
+ Komprimera sparade adresserHantera 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$sCerca a la pàgina
+
+ Tradueix la pàginaDesa 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 cercaParà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 privadesaDefineix com a navegador per defecteAra 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 FirefoxLes 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 alternatiusEditeu els motors visibles al menú de cerca
@@ -427,8 +411,6 @@
Motors de cercaSuggeriments dels motors de cerca
-
- Barra d’adreces
@@ -463,21 +445,11 @@
Mode només HTTPS
-
- Reducció de bàners de galetesBlocador de bàners de galetesBlocador 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
-
-
- PermetEl %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 personalitzatServidor de comptes de Mozilla personalitzatServidor 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 MozillaTorneu-vos a connectar per reprendre la sincronització
@@ -590,8 +536,6 @@
Recollida de dadesDepuració remota per USB
-
- Mostra els motors de cercaMostra 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èsInicis de sessió
+
+ ContrasenyesPestanyes obertes
@@ -780,6 +720,8 @@
Targetes de crèdit
+
+ Formes de pagamentAdreces
@@ -1316,8 +1258,6 @@
Descarta
- No s’ha pogut imprinir
-
No s’ha pogut imprimir aquesta pàginaImprimeix
@@ -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 dadesContingut que fa seguiment
@@ -1717,9 +1663,13 @@
Inicis de sessió i contrasenyes
+
+ ContrasenyesDesa els inicis de sessió i contrasenyes
+
+ Desa les contrasenyesDemana-m’ho
@@ -1736,16 +1686,30 @@
Afegeix un inici de sessió
+
+ Afegeix una contrasenya
+
Sincronitza els inicis de sessió
+
+ Sincronitza les contrasenyesSincronitza els inicis de sessió entre dispositius
+
+ Sincronitza les contrasenyes entre dispositiusInicis de sessió desats
+
+ Contrasenyes desadesAquí 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 pagamentDesa i emplena automàticament les targetes
@@ -1825,8 +1791,12 @@
Sincronitza les targetesAfegeix una targeta de crèdit
+
+ Afegeix una targetaGestiona les targetes desades
+
+ Gestiona les targetesAfegeix una adreça
@@ -1834,9 +1804,14 @@
Desa i emplena automàticament les adreces
+
+ Desa i emplena automàticament les adrecesInclou 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 targetaSegur que voleu suprimir aquesta targeta de crèdit?
+
+ Voleu suprimir la targeta?Suprimeix
@@ -1869,8 +1846,12 @@
Targetes desadesIntroduïu un número de targeta de crèdit vàlid
+
+ Introduïu un número de targeta vàlidEmpleneu aquest camp
+
+ Afegiu un nomDesbloqueu 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 cercaEdita el motor de cerca
-
- Afegeix
-
- DesaEditaSuprimeix
-
- AltresNom
-
- NomNom del motor de cercaURL de la cadena de cerca
- Cadena de cerca que s’utilitzarà
-
URL s’utilitzarà per a la cercaSubstituïu la consulta per «%s». Per exemple:\nhttps://www.google.com/search?q=%s
@@ -2038,6 +2011,8 @@
Cancel·laOpcions d’inici de sessió
+
+ Opcions de la contrasenyaCamp 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 contrasenyaAfegeix un inici de sessió nou
+
+ Afegeix una contrasenyaCal una contrasenya
+
+ Escriviu una contrasenyaCal el nom d’usuari
+
+ Escriviu un nom d\'usuariCal el nom del servidor
+
+ Escriviu una adreça webCerca per veu
@@ -2190,8 +2177,6 @@
- Verificador de ressenyes
-
Verificador de ressenyesRessenyes fiables
@@ -2205,7 +2190,7 @@
Valoració ajustada
- S’han eliminat les ressenyes poc fiables
+ S’han eliminat les ressenyes poc fiablesPunts 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 ressenyacom 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. %sMé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 ressenyaAixò 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\'úsSí, 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úsquedaAjustes 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 cookiesBloqueador de anuncios de cookiesBloqueador de anuncios de cookies en navegación privada
-
- Reducir los anuncios de cookies
-
- No
-
- Sí
-
-
- %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áginaImprimir
@@ -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ñaEl 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ñascómo %s determina la calidad de las reseñas
@@ -2455,6 +2424,8 @@
Traducción en proceso
+
+ Elige un idiomaHubo 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 enregistratsConfiguratz 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 senhalLo 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 lengaI 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_themepref_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 SettingsSecret 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_listpref_multiselect_search_engine_list
+ pref_key_remote_server_prod
+
pref_privacy_block_adspref_privacy_block_analyticspref_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$dAccess browser tabs
@@ -75,7 +77,7 @@
Author
- Authors
+ AuthorsLast 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$dBöngészőlapok elérése
@@ -75,7 +77,7 @@
Szerző
- Szerzők
+ SzerzőkLegutó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 @@
PasswordDon’t save
+
+ Not nowNever save
@@ -26,16 +28,26 @@
SaveDon’t update
+
+ Not nowUpdatePassword field must not be empty
+ Enter a password
+
Unable to save login
+
+ Can’t save passwordSave this login?
+
+ Save password?Update this login?
+
+ Update password?Add username to saved password?
@@ -85,13 +97,22 @@
Set timeManage logins
+
+ Manage passwordsExpand suggested logins
+
+ Expand saved passwordsCollapse suggested logins
+
+ Collapse saved passwordsSuggested logins
+
+ Saved passwords
+
Suggest strong password
@@ -110,12 +131,20 @@
Select credit card
+
+ Use saved cardExpand suggested credit cards
+
+ Expand saved cardsCollapse suggested credit cards
+
+ Collapse saved cardsManage credit cards
+
+ Manage cardsSecurely 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 addressExpand suggested addresses
+
+ Expand saved addressesCollapse suggested addresses
+
+ Collapse saved addressesManage 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 nemSose mentse
@@ -26,16 +28,26 @@
MentésNe frissítse
+
+ Most nemFrissítésA 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ásaBejelentkezések kezelése
+
+ Jelszavak kezeléseJavasolt bejelentkezések kibontása
+
+ Mentett jelszavak kibontásaJavasolt bejelentkezések összecsukása
+
+ Mentett jelszavak összecsukásaJavasolt bejelentkezések
+
+ Mentett jelszavak
+
Erős jelszó javaslata
@@ -110,12 +131,20 @@
Válasszon bankkártyát
+
+ Mentett kártya használataJavasolt bankkártyák kibontása
+
+ Mentett kártyák kibontásaJavasolt bankkártyák összecsukása
+
+ Mentett kártyák összecsukásaBankkártyák kezelése
+
+ Kártyák kezeléseElmenti 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ásaJavasolt címek kibontása
+
+ Mentett címek kibontásaJavasolt címek összecsukása
+
+ Mentett címek összecsukásaCí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 @@
GesloNe shrani
+
+ Ne zdajNikoli ne shranjuj
@@ -26,12 +28,18 @@
ShraniNe posodobi
+
+ Ne zdajPosodobiPolje za geslo ne sme biti prazno
+ Vnesite geslo
+
Ni mogoče shraniti povezave
+
+ Gesla ni mogoče shranitiShranim to prijavo?
@@ -92,6 +100,9 @@
Predlagane prijave
+
+ Shranjena gesla
+
Predlagaj močno geslo
@@ -110,12 +121,16 @@
Izberite kreditno kartico
+
+ Uporabi shranjeno karticoRazširi predlagane kreditne karticeStrni predlagane kreditne karticeUpravljanje 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 engineSearch 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 ReductionCookie Banner BlockerCookie 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 pagePrint
@@ -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 optionsThe 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 qualityhow %s determines review quality
@@ -2449,6 +2418,8 @@
Translation in Progress
+
+ Choose a languageThere 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
-
- IskalnikNastavitve 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škotkiZavračanje pasic s piškotkiZavrač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 natisnitiNatisni
@@ -2049,12 +2020,8 @@
Možnosti geselBesedilno 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 mnenjkako %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$dPristup tabovima browsera
@@ -75,7 +77,7 @@
Autor
- Autori
+ AutoriZadnje 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$dAcedi aes schedis dal navigadôr
@@ -75,7 +77,7 @@
Autôr
- Autôrs
+ AutôrsUltin 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$dTarayıcı sekmelerine erişme
@@ -75,7 +77,7 @@
Geliştiren
- Yazarlar
+ YazarlarSon 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$dTruy 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-tremenNa enrollañ
+
+ Diwezhatoc’hNa enrollañ biken
@@ -26,16 +28,26 @@
EnrollañNa hizivaat
+
+ Diwezhatoc’hHizivaatAr 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-tremenEnrollañ 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 eurArdoer titouroù kennaskañ
+
+ Merañ ar gerioù-tremenBrasaat an titouroù kennaskañ aliet
+
+ Dispakañ ar gerioù-tremen enrolletBerraat an titouroù kennaskañ aliet
+
+ Kuzhat ar gerioù-tremen enrolletTitouroù 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 gredAstenn ar cʼhartennoù kred kinniget
+
+ Dispakañ ar c’hartennoù enrolletBihanaat ar cʼhartennoù kred kinniget
+
+ Kuzhat ar c’hartennoù enrolletMerañ ar cʼhartennoù kred
+
+ Merañ ar c’hartennoùEnrollañ ar gartenn-mañ en surentez?
@@ -122,8 +149,12 @@
Dibab ur chomlec’hDisplegañ ar chomlec’hioù kinniget
+
+ Dispakañ ar chomlec’hioù enrolletPlegañ ar chomlec’hioù kinniget
+
+ Kuzhat ar chomlec’hioù enrolletMerañ 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 @@
LozinkaNemoj spasiti
+
+ Ne sadaNikad ne spašavaj
@@ -26,16 +28,26 @@
SpasiNemoj ažurirati
+
+ Ne sadaAžurirajPolje za lozinku ne smije biti prazno
+ Unesite lozinku
+
Ne mogu spasiti prijavu
+
+ Nije moguće sačuvati lozinkuSpasi 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 vrijemeUpravljanje prijavama
+
+ Upravljajte lozinkamaProširi predložene prijave
+
+ Proširi sačuvane lozinkeSažmi predložene prijave
+
+ Sažmi sačuvane lozinkePredložene prijave
+
+ Sačuvane lozinke
+
Predloži jaku lozinku
@@ -110,12 +131,20 @@
Odaberite kreditnu karticu
+
+ Koristi sačuvanu karticuProširite predložene kreditne kartice
+
+ Proširi sačuvane karticeSažmi predložene kreditne kartice
+
+ Sažmi sačuvane karticeUpravljaj kreditnim karticama
+
+ Upravljajte karticamaSigurno 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 adresuProširite predložene adrese
+
+ Proširi sačuvane adreseSažmi predložene adrese
+
+ Sažmi sačuvane adreseUpravljaj 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 @@
PasswordNo sta salvâ
+
+ No cumòNo sta salvâ mai
@@ -26,17 +28,27 @@
SalveNo sta inzornâ
+
+ No cumòInzorneIl cjamp de password nol à di sei vueit
+ Inserìs une password
+
Impussibil salvâ lis credenziâls
+
+ Impussibil salvâ la passwordSalvâ 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 passwordsSlargje lis credenziâls sugjeridis
+
+ Slargje lis passwords salvadisComprim lis credenziâls sugjeridis
+
+ Strenç lis passwords salvadisCredenziâls sugjeridis
+
+ Passwords salvadis
+
Sugjerìs password complesse
@@ -112,13 +133,21 @@
Selezione cjarte di credit
+
+ Dopre cjarte salvadeSlargje la liste des cjartis di credit sugjeridis
+
+ Slargje lis cjartis salvadisComprim la liste des cjartis di credit sugjeridis
+
+ Strenç lis cjartis salvadisGjestìs cjartis di credit
+
+ Gjestìs cjartisSalvâ 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 recapitSlargje i recapits sugjerîts
+
+ Slargje lis direzions salvadisComprim recapits sugjerîts
+
+ Strenç lis direzions salvadisGjestì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 enregistradaEspandir las cartas de crèdit suggeridas
+
+ Desplegar las cartas enregistradasPlegar las cartas de crèdit suggeridas
+
+ Plegar las cartas enregistradasGerir 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çaEspandir las adreças suggeridas
+
+ Desplegar las adreças enregistradasPlegar las adreças suggeridas
+
+ Plegar las adreças enregistradasGestion 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 @@
ParolaKaydetme
+
+ Şimdi değilAsla kaydetme
@@ -26,16 +28,26 @@
KaydetGüncelleme
+
+ Şimdi değilGüncelleParola alanı boş olmamalıdır
+ Parola girin
+
Hesap kaydedilemedi
+
+ Parola kaydedilemediBu 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ı ayarlaHesapları 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ı daraltKredi kartlarını yönet
+
+ Kartları yönetBu 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 daraltAdresleri 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ẩuKhô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ậtTrườ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ẩuLư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 gianQuản lý đăng nhập
+
+ Quản lý mật khẩuMở rộng thông tin đăng nhập được đề xuất
+
+ Mở rộng mật khẩu đã lưuThu gọn thông tin đăng nhập được đề xuất
+
+ Thu gọn mật khẩu đã lưuThô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ưuMở rộng thẻ tín dụng được đề xuất
+
+ Mở rộng thẻ đã lưuThu gọn thẻ tín dụng được đề xuất
+
+ Thu gọn thẻ đã lưuQuản lý thẻ tín dụng
+
+ Quản lý thẻ tín dụngLư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ưuThu gọn các địa chỉ được đề xuất
+
+ Thu gọn địa chỉ đã lưuQuả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 enklaskArventennoù 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 kasetN’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 @@
UrediPrilagodi početnu stranicu
+
Početni ekranIzbriš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ćaBlokiranje pojavljivanja dijaloga kolačićaSmanjivanje 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 lozinkeIzmjenjivo 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 recenzijekako %s određuje kvalitet recenzije
@@ -2430,6 +2400,8 @@
Prevođenje u toku
+
+ Odaberi jezikDoš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 @@
ModifichePersonalize 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 passwordIl 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 lengheAl è 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 enregistratsConfiguratz 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 senhalLo 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ếmCà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ữ cookieTrình chặn biểu ngữ cookieTrì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àyIn
@@ -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ẩuTrườ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$dPřistupovat k panelům prohlížeče
@@ -75,7 +77,7 @@
Autor
- Autor
+ AutorPoslední 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$dKcem γ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$dPrístup ku kartám prehliadača
@@ -75,7 +77,7 @@
Autor
- Autori
+ AutoriPosledná 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 @@
HesloNeukládat
+
+ Teď neNikdy neukládat
@@ -26,16 +28,26 @@
UložitNeaktualizovat
+
+ Teď neAktualizovatHeslo nesmí být prázdné
+ Zadejte heslo
+
Přihlašovací údaje nelze uložit
+
+ Heslo není možné uložitUlož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 časSpráva přihlašovacích údajů
+
+ Správa přihlašovacích údajůZobrazit navrhované přihlašovací údaje
+
+ Rozbalit uložená heslaSkýt navrhované přihlašovací údaje
+
+ Sbalit uložená heslaNavrhované přihlašovací údaje
+
+ Uložená hesla
+
Navrhnout silné heslo
@@ -110,12 +131,20 @@
Vyberte platební kartu
+
+ Použít uloženou kartuZobrazit návrhy platebních karet
+
+ Rozbalit uložené kartySkrýt návrhy platebních karet
+
+ Sbalit uložené kartySpráva platebních karet
+
+ Spravovat kartyBezpeč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 uffirUr seklas ara
+
+ Mačči turaUrǧin sekles
@@ -26,16 +28,24 @@
SeklesUr leqqem ara
+
+ Mačči turaLeqqemUrti n wawal uffir ur ilaq ara ad yili d ilem
+ Sekcem awal uffir
+
Ur yezmir ara ad isekles anekcumSekles anekcum-agi?
+
+ Sekles awal uffir?Leqqem anekcum-agi?
+
+ Leqqem awal uffir?Rnu isem n useqdac ɣer wawal uffir yettwaskelsen?
@@ -85,6 +95,8 @@
Sbadu akudSefrek inekcam
+
+ Sefrek awalen uffirenSken-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 yettwaskelsenSemɣer tikerḍiwin n usmad i d-yettusumrenFneẓ tikerḍiwin n usmad i d-yettusumrenSefrektikarḍiwin n usmad
+
+ Sefrek tikarḍiwinAsekles 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 @@
HesloNeuložiť
+
+ Teraz nieNikdy neukladať
@@ -26,16 +28,26 @@
UložiťNeaktualizovať
+
+ Teraz nieAktualizovať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ť časSpravovať 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ú kartuRozbaliť navrhované platobné karty
+
+ Rozbaliť uložené kartyZbaliť navrhované platobné karty
+
+ Zbaliť uložené kartySpravovať platobné karty
+
+ Spravovať kartyBezpeč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 adresuRozbaliť navrhované adresy
+
+ Rozbaliť uložené adresyZbaliť navrhované adresy
+
+ Zbaliť uložené adresySpravovať 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á heslaUlož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á heslaNastavte 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ů platbyPř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řekladPrávě probíhá překlad
+
+ Vyberte jazykPři překladu došlo k chybě. Zkuste to prosím znovu.
@@ -2450,6 +2468,8 @@
Nikdy nepřekládat tuto stránkuPřepíše všechna ostatní nastavení
+
+ Přepíše nabídky k překladuNastavení 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
SefsexIɣewwaren n unekcum
+
+ Tixtiṛiyin n wawal uffirUrti 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ɣaAdenqed 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$sWerǧ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 tikkeltWerǧin attsuqleḍ
+
+
+ Ur suqqul ara ismal-aKkes %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 suqqelSefsex
@@ -2425,6 +2449,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Inig ar deffirIfecka n yiccer
+
+ Amḍan n waccarenUrmid
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 cookieBlokovanie bannerov k súborom cookieBlokovať 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 hesielUpraviteľ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 recenzieako %s určuje kvalitu recenzie
@@ -2470,6 +2440,8 @@
Práve prebieha preklad
+
+ Zvoľte jazykPri 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$sNikdy neprekladať z jazyka %1$sNikdy 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 prekladovInformá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átNastavenia prekladania obsahuAutomatický preklad
- Nikdy neprekladať tieto stránky
+ Neprekladať tieto stránkyStiahnuť 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 karticeShrani in samodejno izpolni kartice
+
+ Shranjuj in izpolnjuj načine plačilaPodatki 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 jezikPri prevajanju je prišlo do težave. Poskusite znova.
@@ -2498,6 +2505,8 @@
Prekliči
+
+ Vedno prenesi tudi ob varčevanju s podatkiPrenesi
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éhoNastaveníO násNá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$dAccéder aux onglets du navigateur
@@ -75,7 +77,7 @@
Auteur
- Auteurs
+ AuteursDerniè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$dAtzè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 abertasVersione
+
+ Autoria
- Autoria
+ AutoriaÙrtima atualizatzione
@@ -80,6 +84,8 @@
Àteras informatziones subra de is permissosValutatzione
+
+ Àteru in pitzus de custu cumplementuCunfiguratzione
@@ -108,26 +114,44 @@
DetàlliosPermissos
-
+
Boga
+
+ SinnalaBoles agiùnghere %1$s?
+
+ %1$s rechedet permissos agiuntivos.Rechedet su permissu tuo pro:
+
+ Bolet:Agiunghe
+
+ Permite
+
+ RefudaAnnullaInstalla su cumplementuAnnulla
+
+ Retzensiones: %1$s%1$.02f/5CumplementosGestore de cumplementos
+
+ Is cumplementos sunt istados disativados in manera temporànea
+
+ Torra a aviare is cumplementos
+
+ Agata àteros cumplementosPermite
@@ -152,6 +176,8 @@
Agiunghe %1$s e %2$s a %3$sAgiunghe·ddos a %1$s
+
+ Iscarrighende e verifichende su cumplementu…Impossìbile otènnere sa lista de cumplementos.
@@ -160,6 +186,18 @@
%1$s installaduFaddina 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 adresuZobrazit navrhované adresy
+
+ Rozbalit uložené adresySkrýt navrhované adresy
+
+ Sbalit uložené adresySprá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 passeDévelopper les identifiants suggérés
+
+ Développer les mots de passe enregistrésRéduire les identifiants suggérés
+
+ Réduire les mots de passe enregistrésIdentifiants suggérés
@@ -140,8 +144,12 @@
Utiliser une carte enregistréeDévelopper les cartes bancaires suggérées
+
+ Développer les cartes enregistréesRéduire les cartes bancaires suggérées
+
+ Réduire les cartes enregistréesGérer les cartes bancaires
@@ -161,8 +169,12 @@
Sélectionner une adresseDévelopper les adresses suggérées
+
+ Développer les adresses enregistréesRéduire les adresses suggérées
+
+ Réduire les adresses enregistréesGé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 @@
CraeNon sarves
+
+ Immoe nonoNon sarves mai
@@ -26,16 +28,26 @@
SarvaNo atualizes
+
+ Immoe nonoAtualizaSa crae non podet èssere bòida
+ Inserta una crae
+
Impossìbile sarvare is credentziales
+
+ Impossìbile sarvare sa craeBoles 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’oraGesti is credentziales
+
+ Gesti is craesIsmà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 sarvadaIsmànnia is cartas de crèditu cussigiadasMìnima is cartas de crèditu cussigiadasGesti is cartas de crèditu
+
+ Gesti is cartasBoles 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$sImprea %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 prijavRazširi predlagane prijave
+
+ Prikaži shranjena geslaStrni predlagane prijave
+
+ Skrij shranjena geslaPredlagane prijave
@@ -125,8 +129,12 @@
Uporabi shranjeno karticoRazširi predlagane kreditne kartice
+
+ Prikaži shranjene karticeStrni predlagane kreditne kartice
+
+ Skrij shranjene karticeUpravljanje kreditnih kartic
@@ -146,8 +154,12 @@
Izbira naslovaRazširi predlagane naslove
+
+ Prikaži shranjene nasloveStrni predlagane naslove
+
+ Skrij shranjene nasloveUpravljanje 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 @@
BibliotecaSitu de iscrivania
+
+ Aberi in un’ischeda normaleAgiunghe a s’ischermu printzipale
@@ -177,6 +193,8 @@
Torra a sincronizareChirca in sa pàgina
+
+ Tradue sa pàginaSarva 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 chircaCunfiguratzione de su motore de chirca
@@ -254,6 +276,8 @@
Ti donamus su benebènnidu a un’internet mègiusPrus 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 maiCumintza
@@ -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 riservadesaCunfigura comente navigadore predefiniduImmoe nono
+
+ Abarra amparadu cun su tzifradu cando passas dae unu dispositivu a s’àteruIdentìfica·tiImmoe 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ìficasImmoe 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 alternativosModìfica is motores visìbiles in su menù de chirca
@@ -312,8 +360,16 @@
Motore de chirca predefiniduChirca
-
- 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 FirefoxAvalora in Google PlayModalidade «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 privadaDisativadu pro custu situAnnulla
+
+ Imbia una rechesta
+
+ Boles preguntare agiudu pro custu situ?
+
+ Rechesta imbiadaAtivu pro custu situ
+
+ Rechesta de agiudu imbiadaSitu 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 personalizaduSerbidore de Sync personalizadu
@@ -401,7 +462,7 @@
Intra pro sincronizare ischedas, sinnalibros, craes e àteru.
- Contu de Firefox
+ Contu de MozillaTorra a connètere pro sighire cun sa sincronizatzione
@@ -412,8 +473,6 @@
Còllida de datosCurretzione de faddinas pro mèdiu de USB
-
- Ammustra is motores de chircaAmmustra cussìgios de chirca
@@ -432,13 +491,33 @@
Cunfiguratzione de su contuCumpletamentu 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 tuaAberi is ligòngios in is aplicatziones
+
+ Semper
+
+ Pregunta prima de abèrrere
+
+ MaiGestore de iscarrigamentos esternu
+
+ Ativa is registros de Gecko
+
+ Serrende s’aplicatzione pro aplicare is modìficas…
+
Cumplementos
+
+ Installa unu cumplementu dae un’archìviuNotì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 contuSincroniza immoe
@@ -523,6 +615,8 @@
SinnalibrosCredentziales
+
+ CraesIschedas abertas
@@ -549,6 +643,8 @@
%1$s in %2$s %3$sCartas de crèditu
+
+ Mètodos de pagamentuIndiritzos
@@ -786,10 +882,10 @@
Aberi is ischedasNòmine de sa colletzione
-
- Torra a nominare
-
- Boga
+
+ Torra a nominare
+
+ BogaCantzella dae sa cronologia
@@ -1032,6 +1128,12 @@
Sarva comente PDFImpossìbile generare su PDF
+
+ Iscarta
+
+ Impossìbile imprentare custa pàgina
+
+ ImprentaImbia a su dispositivu
@@ -1054,8 +1156,12 @@
In foras de lìniaConnete 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 aplicatzioneImbia 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 predefiniduProva sa navigatzione privada
+
+ Nàviga chene sighidurasFaghe sa prima chirca
+
+ No, gràtzias
+
Colletzione cantzellada
@@ -1091,6 +1213,8 @@
Ischeda privada serradaIschedas privadas serradas
+
+ Datos de sa navigatzione privada cantzelladosISCONTZA
@@ -1112,6 +1236,8 @@
Boles cantzellare %1$s?Cantzella
+
+ Intrende a sa modalidade de ischermu cumpletuURL 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àneaPermissos 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·tiSincronizatzione 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
+
+ CraesSarva credentziales e craes
+
+ Sarva is craesPregunta·mi·ddu
@@ -1353,16 +1466,27 @@
Agiunghe credentziale
+
+ Agiunghe crae
+
Sincronizatzione de credentziales
+
+ Sincroniza is craesSincronizatzione de credentziales intre dispositivos
+
+ Sincroniza is craes intre dispositivosCredentziales sarvadas
+
+ Craes sarvadasIs 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 sincronizatzioneEtzetziones
@@ -1373,6 +1497,8 @@
Cantzella totu is etzetzionesChirca credentziales
+
+ Chirca craesSitu
@@ -1421,18 +1547,28 @@
IndiritzosCartas de crèditu
+
+ Mètodos de pagamentuSarva e cumpleta in automàticu is cartas
+
+ Sarva e cumpleta cun is mètodos de pagamentuIs datos sunt tzifrados
+
+ %s tzifrat totu is mètodos de pagamentu chi sarvesSincronizatzione de cartas intre dispositivosSincronizatzione de cartasAgiunghe una carta de crèditu
+
+ Agiunghe una cartaGesti is cartas
+
+ Gesti is cartasAgiunghe un’indiritzu
@@ -1440,9 +1576,14 @@
Sarva e cumpleta in automàticu is indiritzos
+
+ Sarva e cumpleta cun is indiritzosInclude 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 cartaSeguru chi boles cantzellare custa carta de crèditu?
+
+ Boles cantzellare sa carta?Cantzella
@@ -1475,16 +1618,32 @@
Cartas sarvadasInserta unu nùmeru de carta vàlidu
+
+ Inserta unu nùmeru de carta vàliduCumpila custu campu
+
+ Agiunghe unu nòmineIsbloca 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 immoeA pustisIsbloca su disposivitu tuo
+
+ Isbloca pro impreare informatzione sarvada de una carta de crèditu
+
+ Isbloca pro impreare is mètodos de pagamentu sarvadosAgiunghe un’indiritzu
@@ -1521,6 +1680,8 @@
Cantzella s’indiritzuSeguru chi boles cantzellare custu indiritzu?
+
+ Boles cantzellare custu indiritzu?Cantzella
@@ -1536,26 +1697,16 @@
Agiunghe unu motore de chirca nouModìfica motore de chirca
-
- Agiunghe
-
- SarvaModìficaCantzella
-
- ÀteruNòmine
-
- NòmineNòmine de su motore de chirca
- Cadena de chirca
-
URL de impreare in sa chircaSostitui 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=%sSarva
@@ -1628,22 +1778,38 @@ Esempru: \nhttp://suggestqueries.google.com/complete/search?client=firefox&q
ModìficaSeguru chi boles cantzellare custa credentziale?
+
+ Seguru chi boles cantzellare custa crae?CantzellaAnnullaOptziones de credentziales
+
+ Optziones de is craesSarva is modìficas a sa credentziale.
+
+ Sarva is modìficas.Modìfica
+
+ Modìfica sa craeAgiunghe una credentziale noa
+
+ Agiunghe una craeCrae rechesta
+
+ Inserta una craeNòmine de utente rechestu
+
+ Inserta unu nòmine de utente
+
+ Inserta un’indiritzu webChirca 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 syncNissuna 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èndiduCurtzadòrgios
-
- Nòmine
+
+ NòmineNòmine de su curtzadòrgiu
-
- AB
-
- Annulla
+
+ AB
+
+ AnnullaCunfiguratzione
@@ -1725,6 +1904,8 @@ Esempru: \nhttp://suggestqueries.google.com/complete/search?client=firefox&q
Artìculos pro temaIscoberi·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
+
+ minimaduismànnia
+
+ ismanniadu
+
+ aberi su ligòngiu pro àteras informatziones in pitzus de custa colletzioneleghe 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 @@
IzjemeTu 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 prijavZavarujte svoje prijave in gesla
+
+ Zavarujte shranjena geslaNastavite 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čilaPodatki so šifrirani
+
+ %s šifrira vse načine plačila, ki jih shraniteSinhroniziraj kartice med napravami
@@ -2025,8 +2037,12 @@
Možnosti geselBesedilno 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$sNikoli ne prevajaj tega spletnega mesta
+
+ Preglasi vse druge nastavitveNastavitve prevajanja
@@ -2479,6 +2497,9 @@
Prekliči
+
+
+ Prenesi jezikeVeč 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$dTilgå 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 ponukeOk, 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 @@
AdgangskodeGem ikke
+
+ Ikke nuGem aldrig
@@ -26,16 +28,26 @@
GemOpdater ikke
+
+ Ikke nuOpdaterFeltet Adgangskode må ikke være tomt
+ Indtast en adgangskode
+
Kunne ikke gemme login
+
+ Kan ikke gemme adgangskodeGem dette login?
+
+ Gem adgangskode?Opdater dette login?
+
+ Opdater adgangskode?Føj brugernavn til gemt adgangskode?
@@ -85,13 +97,22 @@
Vælg tidspunktHåndter logins
+
+ Håndter adgangskoderUdvid foreslåede logins
+
+ Udvid gemte adgangskoderSammenfold foreslåede logins
+
+ Sammenfold gemte adgangskoderForeslåede logins
+
+ Gemte adgangskoder
+
Foreslå stærk adgangskode
@@ -110,12 +131,20 @@
Vælg betalingskort
+
+ Brug gemt kortUdvid foreslåede betalingskort
+
+ Udvid gemte kortSammenfold foreslåede betalingskort
+
+ Sammenfold gemte kortHåndter betalingskort
+
+ Håndter kortGem 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 adresseUdvid foreslåede adresser
+
+ Udvid gemte adresserSammenfold foreslåede adresser
+
+ Sammenfold gemte adresserHå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 FirefoxVi 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ærkerLogins
+
+ AdgangskoderÅbne faneblade
@@ -708,6 +718,8 @@
Betalingskort
+
+ BetalingsmetoderAdresser
@@ -1643,8 +1655,12 @@
Logins og adgangskoder
+
+ AdgangskoderGem logins og adgangskoder
+
+ Gem adgangskoderBed om at gemme
@@ -1661,26 +1677,46 @@
Tilføj login
+
+ Tilføj adgangskode
+
Synkroniser logins
+
+ Synkroniser adgangskoderSynkroniser logins på tværs af enheder
+
+ Synkroniser adgangskoder på tværs af enhederGemte logins
+
+ Gemte adgangskoderDe 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 synkroniseringUndtagelserLogins 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 undtagelserSøg efter logins
+
+ Søg efter adgangskoderWebsted
@@ -1709,10 +1745,16 @@
Skjul adgangskodeLås op for at se dine gemte logins
+
+ Lås op for at se dine gemte adgangskoderGør dine logins og adgangskoder sikre
+
+ Gør dine gemte adgangskoder sikreIndstil 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 @@
AdresserBetalingskort
+
+ BetalingsmetoderGem og autofyld betalingskort
+
+ Gem og udfyld betalingsmetoderData er krypteret
+
+ %s krypterer alle betalingsmetoder, du gemmerSynkroniser kort på tværs af enhederSynkroniser kortTilføj betalingskort
+
+ Tilføj kortHåndter gemte kort
+
+ Håndter kortTilføj adresseHåndter adresserGem og autofyld adresser
+
+ Gem og udfyld adresserInkluderer oplysninger såsom telefonnumre, mail- og forsendelsesadresser
+
+ Inkluderer telefonnumre og mailadresser
+
Tilføj kort
@@ -1780,6 +1840,8 @@
Slet kortEr du sikker på, at du vil slette dette betalingskort?
+
+ Slet kort?Slet
@@ -1795,14 +1857,22 @@
Indtast et gyldigt betalingskortnummer
+
+ Indtast et gyldigt kortnummerUdfyld dette felt
+
+ Tilføj navnLås op for at se dine gemte betalingskortBeskyt dine betalingskort
+
+ Gør dine gemte betalingsmetoder sikreIndstil 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 betalingsmetoderTilføj adresse
@@ -1848,6 +1920,8 @@
Slet adresseEr du sikker på, at du vil slette denne adresse?
+
+ Slet denne adresse?Slet
@@ -1947,30 +2021,52 @@
RedigerEr du sikker på, at du vil slette dette login?
+
+ Er du sikker på, at du vil slette denne adgangskode?SletAnnullerLogin-indstillinger
+
+ Adgangskode-indstillingerDet 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 adgangskodeTilføj nyt login
+
+ Tilføj adgangskodeAdgangskode påkrævet
+
+ Indtast en adgangskodeBrugernavn påkrævet
+
+ Indtast et brugernavnVærtsnavn påkrævet
+
+ Indtast en webadresseStemme-søgning
@@ -2325,6 +2421,8 @@
Oversættelse i gang
+
+ Vælg et sprogDer opstod et problem med at oversætte. Prøv igen.
@@ -2345,6 +2443,10 @@
Oversæt aldrig %1$sOversæt aldrig dette websted
+
+ Tilsidesætter alle andre indstillinger
+
+ Tilsidesætter tilbud om oversættelseOversæ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-wAgbur n uḍfaṛ
@@ -1759,6 +1761,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Serreḥ akken ad tsekneḍ inekcam-ik yettwaskelsenMmesten inekcam d wawalen uffiren
+
+ Seɣles awalen-ik·im uffiren i yettwaskelsenSbadu 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
- NyhederIndstillingerOmHjæ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
- NobedadeakEzarpenakHoni buruzLaguntza
@@ -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$ddostop do zavihkov brskalnika
@@ -75,7 +77,7 @@
Avtor
- Avtorji
+ AvtorjiZadnja 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 @@
PassordIkkje lagre
+
+ Ikkje noLagre aldri
@@ -26,16 +28,24 @@
LagreIkkje oppdater
+
+ Ikkje noOppdaterPassordfeltet kan ikkje stå tomt
+ Skriv inn passord
+
Klarte ikkje å lagre innloggingaLagre denne innlogginga?
+
+ Lagre passord?Vil du oppdatere denne innlogginga?
+
+ Oppdatere passord?Leggje brukarnamn til lagra passord?
@@ -85,6 +95,8 @@
Oppgi tidHandsam innloggingar
+
+ Handsam passordUtvid 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 kortUtvid føreslått betalingskortMinimer føreslått betalingskortHandsam betalingskort
+
+ Handsam kortLagre 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åkDet 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 @@
UrediAli 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$sCancel
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 @@
LisadLisade 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 @@
SuplimenteManager 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$dTok 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älustandmete sisestamine vahemällu
+
+ Lehitsemise ajaloo lugeminefailide allalaadimine ja allalaaditud failide ajaloo vaatamine ning muutmine
@@ -68,8 +70,10 @@
arendajate tööriistade laiendamine, et pääseda ligi avatud kaartide andmeteleVersioon
+
+ Autor
- Autorid
+ AutoridViimati uuendatud
@@ -106,14 +110,24 @@
ÜksikasjadÕigused
-
+
Eemalda
+
+ RaporteeriKas paigaldada lisa %1$s?
+
+ %1$s nõuab täiendavaid õigusi.See lisa nõuab järgmisi õigusi:
+
+ Nõutavad õigused:Paigalda
+
+ Luba
+
+ KeelduLoobu
@@ -128,6 +142,8 @@
LisadLisade haldur
+
+ Avasta veel lisasidLuba
@@ -166,6 +182,16 @@
Lisa %1$s paigaldamine õnnestusLisa %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üüsOlgu, 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 tzijMan tiyak
+
+ Wakami maniMajub\'ey tiyak
@@ -26,16 +28,26 @@
TiyakMan tik\'ex ruwäch
+
+ Wakami maniTik\'exMan 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 wakamiTinuk\'samajïx rutikirib\'al molojri\'ïl
+
+ Kenuk\'samajïx ewan taq tzijKerik\' 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 StandardbrowserStellen 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 predeterminadoConfigurar 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 @@
MuudaKohanda avalehte
+
Avaleht
@@ -208,8 +209,6 @@
Skanni
-
- OtsingumootorOtsingumootori sätted
@@ -223,7 +222,7 @@
%s jagab vaikeotsingumootoriga kõike, mida aadressiribale sisestad.
-
+
Otsi otsingumootoriga %sOtsi otse aadressiribalt
@@ -231,6 +230,9 @@
Otsingusätted
+
+ Otsi seekord järgneva otsingumootoriga:
+
Ava uus kaart %1$sis
@@ -253,8 +255,6 @@
VaikeotsingumootorOtsimine
-
- AadressiribaHinda Google PlaysAinult HTTPS-režiim
+
+ Sellel saidil väljas
+
+ Sellel saidil sees
+
Kõrgendatud turvalisuse nimel üritatakse saitidega ühenduda ainult HTTPSi krüptitud protokolli vahendusel.
-
- SeesVä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 serverKohandatud sünkroonimise server
-
- Firefoxi konto/sünkroniseerimise server muutus. Muudatuste rakendumiseks väljutakse äpist…Konto
@@ -321,8 +320,6 @@
ŽestidKohandamine
-
- Firefoxi kontoSünkroniseerimise jätkamiseks loo ühendus uuesti
@@ -334,8 +331,6 @@
Andmete kogumineRemote debugging via USB
-
- Kuvatakse otsingumootoreidKuvatakse otsingu soovitusi
@@ -364,6 +359,7 @@
Mitte kunagiKasutatakse 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 kaardidKollektsiooni nimi
-
- Muuda nime
-
- Eemalda
+
+ Muuda nime
+
+ EemaldaKustuta ajaloost
@@ -879,10 +861,10 @@
Keelatud Androidi pooltErandid
-
- SeesVäljas
+
+ TavalineRange
@@ -971,7 +953,7 @@
JagaSalvesta PDFina
-
+
PDFi loomine pole võimalikEdasta seadmele
@@ -1080,13 +1062,9 @@
Avatud kaardid%d kaarti
-
- Lehitsemise ajalugu ja saitide andmed%d aadressi
-
- KüpsisedSind 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ättedTä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 teavetTavaline (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 pooltRange
- 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 jagamaJälitav sisu
@@ -1252,8 +1204,12 @@
Saitideülesed jälitamisküpsised
+
+ Saidiülesed küpsisedBlokib 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 lisamineOtsingumootori muutmine
-
- Lisa
-
- SalvestaMuudaKustuta
-
- Muu
-
- Nimi
-
- Kasutatav otsingustringPäringu asendamiseks kasuta “%s”. Näiteks \nhttps://www.google.com/search?q=%s
@@ -1702,14 +1648,14 @@
Olgu, sain aruOtseteed
-
- Nimi
+
+ NimiOtsetee nimi
-
- Olgu
-
- Loobu
+
+ Olgu
+
+ LoobuSä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 startNu, 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 startInstaleazăCaută în pagină
+
+ Tradu paginaSalvează în colecție
@@ -131,6 +171,10 @@
Editează
+
+ Șterge istoricul de navigare
+
Limbă selectată
@@ -142,8 +186,6 @@
Scanează
-
- Motor de căutareSetă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 acumCăutare
@@ -181,12 +246,22 @@
GeneralitățiDespre
+
+ 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ăutareMotor de căutare implicitCăutare
-
- Bară de adrese
+
+ Motoare de căutare
+
+ Sugestii de la motoarele de căutareEvaluează pe Google PlayAccesibilitate
-
- Server personalizat pentru contul FirefoxServer personalizat de sincronizare
-
- Server de cont Firefox/sincronizare modificat. Se închide aplicația pentru implementarea modificărilor…ContBară de unelteTemă
+
+ Pagină de startPersonalizare
-
- Cont FirefoxReconectează-te pentru a continua sincronizarea
@@ -237,8 +308,6 @@
Colectare de dateDepanare de la distanță prin USB
-
- Afișează motoare de căutareAfișează sugestii de căutare
@@ -257,6 +326,7 @@
Deschide linkuri în aplicațiiManager 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-uriVei 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țieProtecț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ăutareEditează 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 ManagerNavigate 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 upClose
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
+ OKLearn 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$dAcceder 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 LawrDiddymu
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-clavBetg memorisar
+
+ Betg ussaMai memorisar
@@ -26,16 +28,26 @@
MemorisarBetg actualisar
+
+ Betg ussaActualisarIl 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-clavMemorisar 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\'uraAdministrar las datas d\'annunzia
+
+ Administrar ils pleds-clavExpander las datas d\'annunzia proponidas
+
+ Extender ils pleds-clav memorisadsReducir las datas d\'annunzia proponidas
+
+ Reducir ils pleds-clav memorisadsDatas d\'annunzia proponidas
+
+ Pleds-clav memorisads
+
Proponer in ferm pled-clav
@@ -110,12 +131,20 @@
Tscherner ina carta da credit
+
+ Utilisar ina carta memorisadaExpander las cartas da credit proponidas
+
+ Extender las cartas memorisadasReducir las cartas da credit proponidas
+
+ Reducir las cartas memorisadasAdministrar las cartas da credit
+
+ Administrar las cartasMemorisar 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\'adressaExpander las adressas proponidas
+
+ Extender las adressas proponidasCumprimer las adressas proponidas
+
+ Reducir las adressas memorisadasAdministrar 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 veebilehitsemineOtsi või sisesta aadress
+
+ Otsi veebist
+
+ Otsi ajaloost
+
+ Otsi järjehoidjatest
+
+ Otsi kaartidestSisesta otsitav fraas
@@ -39,6 +47,9 @@
Valitud
+
+
+ Hiljuti salvestatudKuva 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 avaekraanileTä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 kaarteSünkroniseeritud seade
+
+ EemaldaEemalda
@@ -140,6 +187,8 @@
PeataLisad
+
+ Konto andmedLisad puuduvad
@@ -153,6 +202,8 @@
KogumikTöölaua versioon
+
+ Ava tavalisel kaardilLisa avaekraanile
@@ -163,6 +214,8 @@
Otsi lehelt
+
+ Tõlgi lehtSalvesta 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, azwelIseɣwan
+
+ Iseɣwan i yellan
+
Suqqel asebter-a?
+
+ Ԑreḍ tisuqilin tusligin n %1$sIssin ugar
@@ -2354,13 +2361,20 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Suqqel
+
+ Asuqel itedduFren tutlaytYella wugur deg usuqqel. Ttxil-k ɛreḍ tikkelt niḍen.
+
+ Nesḥassef, mazal ur nessefrak ara tutlayt %1$s.Issin ugar
+
+
+ Tixtiṛiyin n usuqelSumer 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 tschertgarParameters 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 datasDefinir sco navigatur da standard
@@ -432,21 +439,11 @@
Modus mo HTTPS
-
- Reducziun da bandieras da cookiesBloccada da bandieras da cookiesBloccada 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 @@
SegnapaginasInfurmaziuns d\'annunzia
+
+ Pleds-clavTabs averts
@@ -733,6 +714,8 @@
Cartas da credit
+
+ Metodas da pajamentAdressas
@@ -1266,8 +1249,6 @@
Serrar
- Impussibel da stampar
-
Impussibel da stampar questa paginaStampar
@@ -1680,8 +1661,12 @@
Infurmaziuns d\'annunzia e pleds-clav
+
+ Pleds-clavMemorisar las infurmaziuns d\'annunzia ed ils pleds-clav
+
+ Memorisar ils pleds-clavDumandar per memorisar
@@ -1699,10 +1684,17 @@
Agiuntar infurmaziuns d\'annunzia
+
+ Agiuntar in pled-clav
+
Sincronisar las infurmaziuns d\'annunzia
+
+ Sincronisar ils pleds-clavSincronisar las datas d\'annunzia tranter tes apparats
+
+ Sincronisar ils pleds-clav sin tut ils apparatsInfurmaziuns 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 recensiunsco %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$dAccede à l’unghjette di u navigatore
@@ -75,7 +77,7 @@
Autore
- Autori
+ AutoriUltima 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 rhagorWedi’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$dFå tilgang til faner
@@ -75,7 +77,7 @@
Utvikler
- Utviklere
+ UtviklereSist 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 subituPiglià in contuU 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’intesaArregistrà 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’oraUrganizà l’identificazioni di cunnessione
+
+ Amministrà e parolle d’intesaSpiegà l’identificazioni di cunnessione suggerite
+
+ Spiegà e parolle d’intesa arregistrateRipiegà l’identificazioni di cunnessione suggerite
+
+ Ripiegà e parolle d’intesa arregistrateIdentificazioni di cunnessione suggerite
+
+ Parolle d’intesa arregistrate
+
Suggerisce una parolla d’intesa forte
@@ -110,12 +131,20 @@
Selezziunà una carta bancaria
+
+ Impiegà una carta arregistrataSpiegà e carte bancarie suggerite
+
+ Spiegà e carte arregistrateRipiegà e carte bancarie suggerite
+
+ Ripiegà e carte arregistrateUrganizà e carte bancarie
+
+ Amministrà e carteArregistrà 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 indirizzuSpiegà l’indirizzi suggeriti
+
+ Spiegà l’indirizzi arregistratiRipiegà l’indirizzi suggeriti
+
+ Ripiegà l’indirizzi arregistratiUrganizà 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 praeguUuendaParooli väli ei tohi olla tühi
+ Sisesta parool
+
Kasutajatunnuste salvestamine pole võimalik
+
+ Parooli ei saa salvestadaKas salvestada need kasutajatunnused?
+
+ Salvesta parool?Kas uuendada kasutajatunnused?
+
+ Uuenda parool?Kas lisada salvestatud paroolile kasutajanimi?
@@ -81,15 +93,34 @@
novdets
+
+ Aja määramineHalda kasutajakontosid
+
+ Halda parooleLaienda soovitatud kasutajakontosid
+
+ Laienda salvestatud paroolid
- Ahenda soovitatud kasutajakontosid
+ Ahenda soovitatud kasutajakontod
+
+ Ahenda salvestatud paroolidSoovitatud 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 kaartiLaienda soovitatud krediitkaarte
+
+ Laienda salvestatud kaardidAhenda soovitatud krediitkaarte
+
+ Ahenda salvestatud kaardidHalda krediitkaarte
+
+ Halda kaarteKas salvestada see kaart turvaliselt?
@@ -114,13 +153,28 @@
Kaardi number krüptitakse. Turvakoodi ei salvestata.
+
+ %s krüpteerib kaardi numbri. Turvakoodi ei salvestata.
+
Vali aadressLaienda soovitatud aadressid
+
+ Laienda salvestatud aadressidAhenda soovitatud aadressid
+
+ Ahenda salvestatud aadressidHalda 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 @@
PassordIkke lagre
+
+ Ikke nåLagre aldri
@@ -26,16 +28,26 @@
LagreIkke oppdater
+
+ Ikke nåOppdaterPassordfeltet kan ikke stå tomt
+ Skriv inn et passord
+
Klarte ikke å lagre innloggingen
+
+ Kan ikke lagre passordetLagre denne innloggingen?
+
+ Lagre passord?Vil du oppdatere denne innloggingen?
+
+ Oppdatere passord?Vil du legge til brukernavn til lagret passord?
@@ -85,13 +97,29 @@
Angi tidBehandle innlogginger
+
+ Behandle passordUtvid foreslåtte innlogginger
+
+ Utvid lagrede passordSlå sammen foreslåtte innlogginger
+
+ Skjul lagrede passordForeslå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 kortUtvid foreslåtte betalingskort
+
+ Utvid lagrede kortSlå sammen foreslåtte betalingskort
+
+ Skjul lagrede kortBehandle betalingskort
+
+ Behandle kortLagre 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 adresseUtvid foreslåtte adresser
+
+ Utvid lagrede adresserSlå sammen foreslåtte adresser
+
+ Skjul lagrede adresserBehandle 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 ricercaPreferenze 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 cannistrelliBlucchime di e striscie di cannistrelliBlucchime 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 @@
IndetteIdentificazioni di cunnessione
+
+ Parolle d’intesaApre l’unghjette
@@ -757,6 +731,8 @@
Carte bancarie
+
+ Metode di pagamentuIndirizzi
@@ -1300,8 +1276,6 @@
Chjode
- Impussibule di stampà
-
Impussibule di stampà sta paginaStampà
@@ -1702,8 +1676,12 @@
Identificazioni è parolle d’intesa
+
+ Parolle d’intesaArregistrà l’identificazioni è e parolle d’intesa
+
+ Arregistrà e parolle d’intesaDumandà 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’apparechjiIdentificazioni di cunnessione arregistrate
+
+ Parolle d’intesa arregistrateL’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 sincrunizazioneEccezzioniL’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’eccezzioniRicercà identificazioni di cunnessione
+
+ Ricercà parolle d’intesaSitu
@@ -1771,10 +1768,16 @@
Piattà a parolla d’intesaSpalancate per affissà l’identificazioni di cunnessione arregistrate
+
+ Spalancate per affissà e vostre parolle d’intesa arregistratePrutigite e vostre identificazioni di cunnessione è parolle d’intesa
+
+ Prutigite e vostre parolle d’intesa arregistrateDefinite 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 @@
IndirizziCarte bancarie
+
+ Metode di pagamentuArregistrà è riempie autumaticamente e carte
+
+ Arregistrà è rinsignà e metode di pagamentuI dati sò cifrati
+
+ %s cifra tutte e metode di pagamentu chì vo arregistrateSincrunizate e carte trà i vostri apparechjiSincrunizà e carteAghjunghje una carta bancaria
+
+ Aghjunghje una cartaAmministrà e carte arregistrate
+
+ Amministrà e carteAghjunghje un indirizzu
@@ -1820,9 +1836,14 @@
Arregistrà è riempie autumaticamente l’indirizzi
+
+ Arregistrà è rinsignà l’indirizziInclude 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 cartaVulete 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 accettevuleCi vole à riempie stu campu
+
+ Aghjunghje un nomeSpalancate per affissà e vostre carte arregistratePrutege e vostre carte bancarie
+
+ Prutigite e vostre metode di pagamentu arregistrateDefinite 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 arregistrateAghjunghje un indirizzu
@@ -1913,6 +1946,8 @@
Squassà l’indirizzuVulete 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’intesaU 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’intesaAghjunghje una nova identificazione di cunnessione
+
+ Aghjunghje una parolla d’intesaParolla d’intesa richiesta
+
+ Stampittate una parolla d’intesaU nome d’utilizatore hè richiestu
+
+ Stampittate un nome d’utilizatoreU nome d’ospite hè richiestu
+
+ Stampittate un indirizzu webRicerca 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’avisicumu %s determineghja a qualità di l’avisi
@@ -2402,6 +2460,8 @@
Traduzzione in corsu
+
+ Sciglite una linguaUn 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 traduzzionePreferenze 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 rhagorGalluogi 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 rhagorData defnydd a thechnegol
@@ -913,7 +913,7 @@
Gall %1$s osod a rhedeg astudiaethau o bryd i’w gilydd.
- Dysgu rhagor
+ Darllen rhagorBydd 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 rhagorSafonol (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 gyfrinairMae angen enw defnyddiwr
@@ -2199,7 +2199,7 @@
Rhan o deulu Firefox. %s
- Dysgu rhagor
+ Darllen rhagorNoddwyd
@@ -2423,7 +2423,7 @@
Cyfieithu
- Ceisio eto
+ Ceisiwch EtoYn 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 hynI 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 maksutavatAseta 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 asetuksetMuokattava 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 useqdacAsenneftaɣ yettwasra
+
+ Sekcem tansa webAnadi s taɣect
@@ -2150,6 +2152,9 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara
Anadi %s
+
+
+ Beddel iminig-ik·im amezwerSbadu 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å nyttFinn på siden
+
+ Oversett sidenLagre 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økemotorInnstillinger 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æringBruk som standard nettleser
@@ -435,21 +444,11 @@
Kun-HTTPS-modus
-
- Redusering av infokapselbannereBlokkering av infokapselbannerBlokkering av infokapselbanner i privat nettlesing
-
- Reduser infokapselbannere
-
- Av
-
- På
-
-
- %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 @@
BokmerkerInnlogginger
+
+ PassordÅpne faner
@@ -738,6 +720,8 @@
Betalingskort
+
+ BetalingsmetoderAdresser
@@ -1280,8 +1264,6 @@
Ignorer
- Kan ikke å skrive ut
-
Kan ikke å skrive ut denne sidenSkriv 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
+
+ PassordLagre innlogginger og passord
+
+ Lagre passordSpør om å lagre
@@ -1701,27 +1692,46 @@
Legg til innlogging
+
+ Legg til passord
+
Synkroniser innlogginger
+
+ Synkroniser passordSynkroniser innlogginger på tvers av enheter
+
+ Synkroniser passord på tvers av enheterLagrede innlogginger
+
+ Lagrede passordDe 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 synkroniseringUnntakInnlogginger 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 unntakSøk innlogginger
+
+ Søk etter passordNettsted
@@ -1751,8 +1761,12 @@
Skjul passordLås opp for å se dine lagrede innlogginger
+
+ Lås opp for å se dine lagrede passordSikre dine innlogginger og passord
+
+ Sikre dine lagrede passordKonfigurer 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 vurderingskvalitethvordan %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 brukJa, 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 alternativosEditar 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 rhagorYchwanegu a rheoli URLs awtogwblhau cyfaddas.
@@ -344,7 +344,7 @@
Anfon data defnydd
- Dysgu rhagor
+ Darllen rhagorMae 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 rhagorBydd 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 nyttInnstillingerOmHjelp
@@ -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$dAliri 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$dDostęp do kart przeglądarki
@@ -75,7 +77,7 @@
Autor
- Autorzy
+ AutorzyOstatnia 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 @@
PasvortoNe konservi
+
+ Ne nunNeniam konservi
@@ -26,16 +28,26 @@
KonserviNe ĝisdatigi
+
+ Ne nunĜisdatigiLa 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 horonAdministri legitimilojn
+
+ Administri pasvortojnMalfaldi sugestitajn legitimilojn
+
+ Malfaldi konservitajn pasvortojnFaldi sugestitajn legitimilojn
+
+ Faldi konservitajn pasvortojnSugestitaj legitimiloj
+
+ Konservitaj pasvortoj
+
Sugesti fortan pasvorton
@@ -110,12 +131,20 @@
Elekti kreditkarton
+
+ Uzi konservitan kartonMalfaldi sugestitajn kreditkartojn
+
+ Elporti konservitajn pasvortojnFaldi sugestitajn kreditkartojn
+
+ Faldi konservitajn kartojnAdministri 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 adresojnMalfaldi sugestitajn adresojn
+
+ Malfaldi konservitajn adresojnFaldi sugestitajn adresojn
+
+ Faldi konservitajn adresojnAdministri 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łoNie zachowuj
+
+ Nie terazNigdy nie zachowuj
@@ -26,16 +28,26 @@
ZachowajNie aktualizuj
+
+ Nie terazAktualizujPole hasła nie może być puste
+ Wpisz hasło
+
Nie można zachować danych logowania
+
+ Nie można zachować hasłaCzy 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 czasZarządzaj danymi logowania
+
+ Zarządzaj hasłamiRozwiń podpowiadane dane logowania
+
+ Rozwiń zachowane hasłaZwiń podpowiadane dane logowania
+
+ Zwiń zachowane hasłaPodpowiadane dane logowania
+
+ Zachowane hasła
+
Zaproponuj silne hasło
@@ -110,12 +131,20 @@
Wybierz kartę płatniczą
+
+ Użyj zachowanej kartyRozwiń podpowiadane karty płatnicze
+
+ Rozwiń zachowane kartyZwiń podpowiadane karty płatnicze
+
+ Zwiń zachowane kartyZarządzaj kartami płatniczymi
+
+ Zarządzaj kartamiCzy 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 adresRozwiń podpowiadane adresy
+
+ Rozwiń zachowane adresyZwiń podpowiadane adresy
+
+ Zwiń zachowane adresyZarzą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’indirizziInclude 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ĉiloAgordoj 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 privatecoDifini kiel norman retumilon
@@ -432,21 +439,11 @@
HTTPS-nura reĝimo
-
- Redukto de kuketaj anoncojBlokilo de kuketaj anoncojBlokilo 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 senditaRetejo 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 @@
legosignojnlegitimilojn
+
+ PasvortojMalfermitaj langetoj
@@ -738,6 +718,8 @@
Kreditkartoj
+
+ PagmetodojAdresoj
@@ -1282,8 +1264,6 @@
Ignori
- Ne eblas presi
-
Ne eblas presi tiun ĉi paĝonPresi
@@ -1691,8 +1671,12 @@
Legitimiloj kaj pasvortoj
+
+ PasvortojKonservi legitimilojn kaj pasvortojn
+
+ Konservi pasvortojnDemandi antaŭ ol konservi
@@ -1709,27 +1693,46 @@
Aldoni legitimilon
+
+ Aldoni pasvorton
+
Speguli legitimilojn
+
+ Speguli pasvortojnSpeguli legitimilojn inter aparatoj
+
+ Speguli pasvortojn inter aparatojKonservitaj legitimiloj
+
+ Konservitaj pasvortojLa 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 speguladoEsceptojNekonservitaj 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 esceptojnSerĉi legitimilojn
+
+ Serĉi pasvortojnRetejo
@@ -1759,10 +1762,16 @@
Malŝlosu por vidi viajn konservitajn legitimilojn
+
+ Malŝlosi por vidi viajn konservitajn pasvortojnProtektu viajn legitimilojn kaj pasvortojn
+
+ Protektu viajn konservitajn pasvortojnDifinu 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 @@
AdresojKreditkartoj
+
+ PagmetodojKonservi kaj aŭtomate plenigi kreditkartojn
+
+ Konservi kaj aŭtomate plenigi pagmetodojnLa datumoj estas ĉifritaj
+
+ %s ĉifras ĉiujn pagmetodojn, kiujn vi konservisSpeguli kreditkartojn inter aparatojSpeguli kreditkartojnAldoni kreditkarton
+
+ Aldoni kreditkartonAdministri konservitajn kreditkartojn
+
+ Administri kartojnAldoni adresonAdministri adresojnKonservi kaj aŭtomate plenigi adresojn
+
+ Konservi kaj aŭtomate plenigi adresojnInkluzivi 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 kartoBonvolu plenigi tiun ĉi kampon
+
+ Aldoni nomonMalŝlosu por vidi viajn konservitajn kreditkartojnSekurigu viajn kreditkartojn
+
+ Protektu viajn konservitajn pagmetodojnDifinu 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 pagmetodojnAldoni 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?ForigiNuligiPreferoj de komenco de seanco
+
+ Pasvortaj elekteblojLa 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 pasvortonAldoni novan legitimilon
+
+ Aldoni pasvortonPasvorto postulata
+
+ Tajpu pasvortonNomo de uzanto postulata
+
+ Tajpu nomon de uzantoNomo de servilo postulata
+
+ Tajpu retadresonVoĉ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 recenzojkiel %s determinas la kvaliton de recenzoj
@@ -2378,6 +2442,8 @@
TradukoTraduko okazas
+
+ Elektu lingvonOkazis problemo dum traduko. Bonvolu provi denove.
@@ -2398,6 +2464,10 @@
Neniam traduki %1$sNeniam traduki tiun ĉi retejon
+
+ Superregi ĉiujn aliajn agordojn
+
+ Superregi tradukproponojnTradukaj 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
-
- WyszukiwarkaUstawienia 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ściUstaw jako domyślną przeglądarkę
@@ -438,21 +445,11 @@
Tryb używania wyłącznie protokołu HTTPS
-
- Ograniczanie informacji o ciasteczkachBlokowanie informacji o ciasteczkachBlokowanie 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ładkiDane logowania
+
+ HasłaOtwarte karty
@@ -746,6 +726,8 @@
Karty płatnicze
+
+ Metody płatnościAdresy
@@ -1284,8 +1266,6 @@
Zamknij
- Nie można wydrukować
-
Nie można wydrukować tej stronyDrukuj
@@ -1693,8 +1673,12 @@
Dane logowania i hasła
+
+ HasłaZachowywanie 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ądzeniamiZachowane dane logowania
+
+ Zachowane hasłaZachowane 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 synchronizacjiWyjątkiTutaj 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ątkiSzukaj danych logowania
+
+ Szukaj hasełWitryna
@@ -1759,10 +1762,16 @@
Ukryj hasłoOdblokuj, aby wyświetlić zachowane dane logowania
+
+ Odblokuj, aby wyświetlić zachowane hasłaZabezpiecz dane logowania i hasła
+
+ Zabezpiecz zachowane hasłaSkonfiguruj 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ściZachowywanie i automatyczne wypełnianie kart
+
+ Zachowywanie i wypełnianie metod płatnościDane są zaszyfrowane
+
+ %s szyfruje wszystkie zachowywane metody płatnościSynchronizuj karty między urządzeniami
@@ -1800,8 +1818,12 @@
Dodaj kartę płatniczą
+
+ Dodaj kartęZarządzaj zachowanymi kartami
+
+ Zarządzaj kartamiDodaj adres
@@ -1809,9 +1831,14 @@
Zachowywanie i automatyczne wypełnianie adresów
+
+ Zachowywanie i wypełnianie adresówZawiera 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 kartyWypełnij to pole
+
+ Dodaj imię i nazwiskoOdblokuj, aby wyświetlić zachowane kartyZabezpiecz karty płatnicze
+
+ Zabezpiecz zachowane metody płatnościSkonfiguruj 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ściDodaj adres
@@ -1900,6 +1939,8 @@
Usuń adresCzy na pewno usunąć ten adres?
+
+ Czy usunąć ten adres?Usuń
@@ -1998,30 +2039,52 @@
EdytujCzy na pewno usunąć te dane logowania?
+
+ Czy na pewno usunąć to hasło?UsuńAnulujOpcje 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łaDodanie nowych danych logowania
+
+ Dodanie hasłaHasło jest wymagane
+
+ Wpisz hasłoNazwa użytkownika jest wymagana
+
+ Wpisz nazwę użytkownikaAdres jest wymagany
+
+ Wpisz adres witrynyWyszukiwanie 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łumaczenieTrwa tłumaczenie
+
+ Wybierz językWystą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łumaczeniaUstawienia 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 memorisadsLas 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 sincronisaziunExcepziunsLas 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 excepziunsTschertgar datas d\'annunzia
+
+ Tschertgar en ils pleds-clavWebsite
@@ -1741,11 +1753,17 @@
Zuppentar il pled-clavDebloccar per vesair las infurmaziuns d\'annunzia memorisadas
+
+ Debloccar per vesair tes pleds-clav memorisadsProtegia las infurmaziuns d\'annunzia ed ils pleds-clav
+
+ Protegia tes pleds-clav memorisadsDefinescha 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 @@
AdressasCartas da credit
+
+ Metodas da pajamentEmplenir automaticamain las datas da la carta da credit
+
+ Memorisar ed endatar automaticamain las metodas da pajamentLas datas èn criptadas
+
+ %s criptescha tut las metodas da pajament che ti memoriseschasSincronisar las cartas tranter ils apparats
@@ -1782,17 +1809,26 @@
Agiuntar ina carta da credit
+
+ Agiuntar ina cartaAdministrar las cartas memorisadas
+
+ Administrar las cartasAgiuntar ina adressaAdministrar las adressasMemorisar ed emplenir automaticamain las adressas
+
+ Memorisar ed endatar automaticamain las adressasIncluder 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 cartaVuls 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 validEmplenescha per plaschair quest champ
+
+ Agiuntescha in numDebloccar per vesair tias cartas memorisadasProtegia tias cartas da credit
+
+ Protegia tias metodas da pajament memorisadasEndrizza 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 memorisadasAgiuntar ina adressa
@@ -1882,6 +1930,8 @@
Vuls ti propi stizzar questa adressa?
+
+ Stizzar questa adressa?Stizzar
@@ -1980,6 +2030,8 @@
ModifitgarVuls ti propi stizzar questa infurmaziun d\'annunzia?
+
+ Vuls ti propi stizzar quest pled-clav?Stizzar
@@ -1987,24 +2039,44 @@
InterrumperOpziuns per datas d\'annunzia
+
+ Opziuns da pleds-clavIl 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-clavAgiuntar novas datas d\'annunzia
+
+ Agiuntar in pled-clavPled-clav obligatoric
+
+ Endatar in pled-clavNum d\'utilisader obligatoric
+
+ Endatar in num d’utilisaderNum dal server obligatoric
+
+ Endatar ina adressa webTschertga vocala
@@ -2099,6 +2171,9 @@
Tschertga %s
+
+
+ Mida tes navigatur standardDefinescha che colliaziuns da websites, e-mails e messadis vegnan averts automaticamain en Firefox.
@@ -2354,6 +2429,8 @@
TranslatarTranslaziun en elavuraziun
+
+ Tscherner ina linguaIgl ha dà in problem cun translatar. Emprova per plaschair anc ina giada.
@@ -2374,6 +2451,10 @@
Mai translatar %1$sMai translatar questa website
+
+ Remplazza tut ils auters parameters
+
+ Remplazza las offertas da translaziunParameters 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ĵojAgordojPriHelpo
@@ -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 nowegoUstawieniaO programiePomoc
@@ -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 reklamNiektóre reklamy (nawet niekliknięte) śledzą odwiedziny zawierających je stronBlokowanie ś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 przewijanieBlokowanie śledzących społecznościowychOsadzane na stronach, aby śledzić ich odwiedziny i dodawać np. przyciski udostępnianiaBlokowanie 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 viaErase 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 5Add-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$dNabigatzailearen fitxak atzitzea
@@ -75,7 +77,7 @@
Egilea
- Egileak
+ EgileakAzken 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 @@
PasahitzaEz gorde
+
+ Une honetan ezEz gorde inoiz
@@ -26,16 +28,26 @@
GordeEz eguneratu
+
+ Une honetan ezEguneratuPasahitzaren eremuak ezin du hutsik egon
+ Idatzi pasahitz bat
+
Ezin da saio-hasiera gorde
+
+ Ezin da pasahitza gordeGorde saio-hasiera hau?
+
+ Gorde pasahitza?Eguneratu saio-hasiera hau?
+
+ Eguneratu pasahitza?Gehitu erabiltzaile-izena gordetako pasahitzari?
@@ -85,13 +97,22 @@
Ezarri denboraKudeatu saio-hasierak
+
+ Kudeatu pasahitzakZabaldu iradokitako saio-hasierak
+
+ Zabaldu gordetako pasahitzakTolestu iradokitako saio-hasierak
+
+ Tolestu gordetako pasahitzakIradokitako saio-hasierak
+
+ Gordetako pasahitzak
+
Gomendatu pasahitz sendoa
@@ -110,12 +131,20 @@
Hautatu kreditu-txartela
+
+ Erabili gordetako txartelaZabaldu iradokitako kreditu-txartelak
+
+ Zabaldu gordetako txartelakTolestu iradokitako kreditu-txartelak
+
+ Tolestu gordetako txartelakKudeatu kreditu-txartelak
+
+ Kudeatu txartelakGorde 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 helbideaZabaldu iradokitako helbideak
+
+ Zabaldu gordetako helbideakTolestu iradokitako helbideak
+
+ Tolestu gordetako helbideakKudeatu 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-motorraBilaketa-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-oharreanEzarri nabigatzaile lehenetsi gisa
@@ -443,22 +450,11 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.HTTPS-Only modua
-
- Cookie iragarki-banden murrizpenaCookie iragarki-banden blokeatzaileaCookie 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-markakSaio-hasierak
+
+ PasahitzakIrekitako fitxak
@@ -748,6 +727,8 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.Kreditu-txartelak
+
+ Ordainketa metodoakHelbideak
@@ -1290,8 +1271,6 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Baztertu
- Ezin da inprimatu
-
Ezin da orria inprimatuInprimatu
@@ -1697,8 +1676,12 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Saio-hasierak eta pasahitzak
+
+ PasahitzakGorde saio-hasierak eta pasahitzak
+
+ Gorde pasahitzakGaldetu gorde aurretik
@@ -1715,26 +1698,46 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Gehitu saio-hasiera
+
+ Gehitu pasahitza
+
Sinkronizatu saio-hasierak
+
+ Sinkronizatu pasahitzakSinkronizatu saio-hasierak gailuen artean
+
+ Sinkronizatu pasahitzak gailuen arteanGordetako 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 gehiagoSalbuespenakGorde 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 guztiakBilatu saio-hasierak
+
+ Bilatu pasahitzakGunea
@@ -1763,10 +1766,16 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Ezkutatu pasahitzaDesblokeatu gordetako saio-hasierak ikusteko
+
+ Desblokeatu gordetako pasahitzak ikustekoLortu zure saio-hasierak eta pasahitzak
+
+ Bermatu gordetako zure pasahitzakKonfiguratu 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.
HelbideakKreditu-txartelak
+
+ Ordainketa metodoakGorde eta osatu automatikoki kreditu-txartelak
+
+ Gorde eta bete ordainketa metodoakDatuak zifratuta daude
+
+ Gordetzen dituzun ordainketa metodo guztiak zifratzen ditu %s(e)kSinkronizatu txartelak gailuen artean
@@ -1804,8 +1822,12 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Gehitu kreditu-txartela
+
+ Gehitu txartelaKudeatu gordetako txartelak
+
+ Kudeatu txartelakGehitu helbidea
@@ -1813,9 +1835,14 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Gorde eta osatu automatikoki helbideak
+
+ Gorde eta osatu helbideakKontuan 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 txartelaZiur 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-zenbakiaBete eremu hau mesedez
+
+ Gehitu izenaDesblokeatu gordetako txartelak ikustekoBermatu zure kreditu-txartelak
+
+ Bermatu gordetako zure ordainketa metodoakKonfiguratu 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 erabiltzekoGehitu helbidea
@@ -1903,6 +1942,8 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Ezabatu helbideaZiur zaude helbide hau ezabatu nahi duzula?
+
+ Ezabatu helbidea?Ezabatu
@@ -2001,30 +2042,52 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
EditatuZiur zaude saio-hasiera hau ezabatu nahi duzula?
+
+ Ziur zaude pasahitz hau ezabatu nahi duzula?EzabatuUtziSaio-hasieren aukerak
+
+ Pasahitzaren aukerakSaio-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 pasahitzaGehitu saio-hasiera berria
+
+ Gehitu pasahitzaPasahitza behar da
+
+ Idatzi pasahitz batErabiltzaile-izena behar da
+
+ Idatzi erabiltzaile-izen batOstalari-izena behar da
+
+ Idatzi web helbide batAhots 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 kalitateaNola antzematen duen %s(e)k balorazioen kalitatea
@@ -2381,6 +2445,8 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Itzulpena burutzen
+
+ Aukeratu hizkuntzaArazo bat gertatu da itzultzean. Saiatu berriro mesedez.
@@ -2402,6 +2468,10 @@ zure pasahitzak, laster-markak eta gehiago zifratzen du.
Inoiz ez itzuli %1$sInoiz ez itzuli gune hau
+
+ Beste ezarpen guztiak baliogabetzen ditu
+
+ Itzultzeko eskaintzak baliogabetzen dituItzulpenen 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 policyPrivacy policy
+
+ privacy noticeterms 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\'älRunuk\'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\'ojTiya\' kan achi\'el kanob\'äl k\'o wi
@@ -435,20 +440,10 @@
HTTPS-Only B\'anikil
-
- Kech\'utinirisäx kitzijol kukiKiq\'atöy kitzijol cookieRuq\'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 yaketalKetikirisäx molojri\'ïl
+
+ Ewan taq tzijKejaq ruwi\'
@@ -729,6 +707,8 @@
Rutarjeta\' kre\'ito\'
+
+ Rub\'eyal tojïkTaq 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 tzijKeyak kitikirisaxik molojri\'ïl chuqa\' ewan taq tzij
+
+ Keyak ewan taq tzijTik\'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 tzijSync rutikirib\'al molojri\'ïl rik\'in okisaxelXeyak kitikirisaxik mojojri\'ïl
+
+ Xeyak ewan taq tzijWawe\' 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 syncTaq man relik ta
@@ -1692,6 +1687,8 @@
Tiyuj ronojel man relik taKekanöx tikirib\'äl taq molojri\'ïl
+
+ Kekanöx ewan taq tzijRuxaq k\'amaya\'l
@@ -1721,10 +1718,14 @@
Tewäx ewan tzijMan 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\'ayakonKe\'ajikib\'a\' kitikirisaxik amolojri\'ïl chuqa\' ewan taq atzijTab\'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\'älRutarjeta\' kre\'ito\'
+
+ Rub\'eyal tojïkKeyak 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\'ajMan tiq\'at chik richin ye\'atz\'ët ri tarjeta\' e\'ayakon
@@ -1959,16 +1973,28 @@ Achi\'el: \nhttps://www.google.com/search?q=%sRuk\'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 tzijTitz\'aqatisäx k\'ak\'a\' rub\'i\' taqoya\'l
+
+ Titz\'aqatisäx ewan tzijNajowäx ewan tzij
+
+ Titz\'ib\'äx jun ewan tzijNajowäx rub\'i\' okisanel
+
+ Titz\'ib\'äx jun ewan rutzij okisaxelNajowäx rub\'i\' ruk\'u\'x k\'amb\'ey
@@ -2052,7 +2078,7 @@ Achi\'el: \nhttps://www.google.com/search?q=%sTikanö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\'onTilitä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 recensioniVerranno visualizzati annunci occasionali per prodotti pertinenti. Promuoviamo solo prodotti con recensioni affidabili. %sUlteriori informazioni
- Disattiva verifica recensioni
+ Disattiva Verifica recensioniAltri prodotti da valutare
@@ -2395,17 +2395,17 @@
Prima di acquistare, scopri se puoi fidarti delle recensioni di questo prodotto.
- Prova verifica recensioni
+ Prova Verifica recensioniQueste recensioni sono affidabili? Controlla ora per vedere la valutazione rettificata.
- Apri verifica recensioni
+ Apri Verifica recensioniBeta
- 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
diff --git a/android-components/components/browser/menu/src/main/res/values-bs/strings.xml b/android-components/components/browser/menu/src/main/res/values-bs/strings.xml
index ab954accf9d9..4e61450eb100 100644
--- a/android-components/components/browser/menu/src/main/res/values-bs/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-bs/strings.xml
@@ -10,4 +10,6 @@
Upravnik add-onimaIdi prema gore
+
+ Dodaci, idite gore
diff --git a/android-components/components/browser/menu/src/main/res/values-cy/strings.xml b/android-components/components/browser/menu/src/main/res/values-cy/strings.xml
index f89049f0d7e5..496c299482af 100644
--- a/android-components/components/browser/menu/src/main/res/values-cy/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-cy/strings.xml
@@ -10,4 +10,6 @@
Rheolwr YchwanegionLlywio i fyny
+
+ Ychwanegion, llywiwch i fyny
diff --git a/android-components/components/browser/menu/src/main/res/values-de/strings.xml b/android-components/components/browser/menu/src/main/res/values-de/strings.xml
index 09552bfe01f5..f37f959a9204 100644
--- a/android-components/components/browser/menu/src/main/res/values-de/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-de/strings.xml
@@ -10,4 +10,6 @@
Add-ons-VerwaltungNach oben navigieren
+
+ Add-ons, nach oben navigieren
diff --git a/android-components/components/browser/menu/src/main/res/values-dsb/strings.xml b/android-components/components/browser/menu/src/main/res/values-dsb/strings.xml
index 6dbf82c91b70..cf3b524bed6e 100644
--- a/android-components/components/browser/menu/src/main/res/values-dsb/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-dsb/strings.xml
@@ -10,4 +10,6 @@
Zastojnik dodankowGórjej
+
+ Dodanki, górjej nawigěrowaś
diff --git a/android-components/components/browser/menu/src/main/res/values-el/strings.xml b/android-components/components/browser/menu/src/main/res/values-el/strings.xml
index 8d77b333ac8f..40850b600276 100644
--- a/android-components/components/browser/menu/src/main/res/values-el/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-el/strings.xml
@@ -10,4 +10,6 @@
Διαχείριση προσθέτωνΠλοήγηση προς τα πάνω
+
+ Πρόσθετα, πλοήγηση προς τα πάνω
diff --git a/android-components/components/browser/menu/src/main/res/values-en-rGB/strings.xml b/android-components/components/browser/menu/src/main/res/values-en-rGB/strings.xml
index 5149a623ea46..781cea7ab0b0 100644
--- a/android-components/components/browser/menu/src/main/res/values-en-rGB/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-en-rGB/strings.xml
@@ -10,4 +10,6 @@
Add-ons ManagerNavigate up
+
+ Add-ons, navigate up
diff --git a/android-components/components/browser/menu/src/main/res/values-es-rAR/strings.xml b/android-components/components/browser/menu/src/main/res/values-es-rAR/strings.xml
index 06d3f3f85570..f53a8c947dd4 100644
--- a/android-components/components/browser/menu/src/main/res/values-es-rAR/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-es-rAR/strings.xml
@@ -10,4 +10,6 @@
Administrador de complementosNavegar hacia arriba
+
+ Complementos, navegar hacia arriba
diff --git a/android-components/components/browser/menu/src/main/res/values-es-rCL/strings.xml b/android-components/components/browser/menu/src/main/res/values-es-rCL/strings.xml
index cf011aeda850..9ac7896b0abc 100644
--- a/android-components/components/browser/menu/src/main/res/values-es-rCL/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-es-rCL/strings.xml
@@ -10,4 +10,6 @@
Administrador de complementosNavegar hacia arriba
+
+ Complementos, navegar hacia arriba
diff --git a/android-components/components/browser/menu/src/main/res/values-fi/strings.xml b/android-components/components/browser/menu/src/main/res/values-fi/strings.xml
index bbe8ade06663..3467756ea11c 100644
--- a/android-components/components/browser/menu/src/main/res/values-fi/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-fi/strings.xml
@@ -10,4 +10,6 @@
Lisäosien hallintaLiiku ylöspäin
+
+ Lisäosat, liiku ylös
diff --git a/android-components/components/browser/menu/src/main/res/values-fr/strings.xml b/android-components/components/browser/menu/src/main/res/values-fr/strings.xml
index 6e632e9af7e5..71c9b98962a6 100644
--- a/android-components/components/browser/menu/src/main/res/values-fr/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-fr/strings.xml
@@ -10,4 +10,6 @@
Gestionnaire de modulesRemonter
+
+ Modules complémentaires, remonter
diff --git a/android-components/components/browser/menu/src/main/res/values-fy-rNL/strings.xml b/android-components/components/browser/menu/src/main/res/values-fy-rNL/strings.xml
index 91f907fdbe07..3569cf24e334 100644
--- a/android-components/components/browser/menu/src/main/res/values-fy-rNL/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-fy-rNL/strings.xml
@@ -10,4 +10,6 @@
Add-onbehearderOmheech
+
+ Add-ons, omheech navigearje
diff --git a/android-components/components/browser/menu/src/main/res/values-hsb/strings.xml b/android-components/components/browser/menu/src/main/res/values-hsb/strings.xml
index c4d14947af6e..c4e47d18ef70 100644
--- a/android-components/components/browser/menu/src/main/res/values-hsb/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-hsb/strings.xml
@@ -10,4 +10,6 @@
Zrjadowak přidatkowHorje
+
+ Přidatki, horje nawigěrować
diff --git a/android-components/components/browser/menu/src/main/res/values-it/strings.xml b/android-components/components/browser/menu/src/main/res/values-it/strings.xml
index f083cdaed9ee..6a3864c63970 100644
--- a/android-components/components/browser/menu/src/main/res/values-it/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-it/strings.xml
@@ -10,4 +10,6 @@
Gestore comp. aggiuntiviPassa a livello superiore
+
+ Componenti aggiuntivi, torna indietro
diff --git a/android-components/components/browser/menu/src/main/res/values-iw/strings.xml b/android-components/components/browser/menu/src/main/res/values-iw/strings.xml
index 030716e387cb..11cd70d12371 100644
--- a/android-components/components/browser/menu/src/main/res/values-iw/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-iw/strings.xml
@@ -10,4 +10,6 @@
מנהל התוספותניווט למעלה
+
+ תוספות, ניווט למעלה
diff --git a/android-components/components/browser/menu/src/main/res/values-kk/strings.xml b/android-components/components/browser/menu/src/main/res/values-kk/strings.xml
index 4d955984b6a4..2f73285d38b9 100644
--- a/android-components/components/browser/menu/src/main/res/values-kk/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-kk/strings.xml
@@ -10,4 +10,6 @@
Қосымшалар басқарушысыЖоғары жылжу
+
+ Қосымшалар, жоғары өту
diff --git a/android-components/components/browser/menu/src/main/res/values-ko/strings.xml b/android-components/components/browser/menu/src/main/res/values-ko/strings.xml
index bb8582ab12c9..ad9461fb6244 100644
--- a/android-components/components/browser/menu/src/main/res/values-ko/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-ko/strings.xml
@@ -10,4 +10,6 @@
부가 기능 관리자위로 이동
+
+ 부가 기능, 위로 이동
diff --git a/android-components/components/browser/menu/src/main/res/values-nl/strings.xml b/android-components/components/browser/menu/src/main/res/values-nl/strings.xml
index 24eeeb8d44a2..64d1ef3b259a 100644
--- a/android-components/components/browser/menu/src/main/res/values-nl/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-nl/strings.xml
@@ -10,4 +10,6 @@
Add-onbeheerderOmhoog
+
+ Add-ons, omhoog navigeren
diff --git a/android-components/components/browser/menu/src/main/res/values-pt-rBR/strings.xml b/android-components/components/browser/menu/src/main/res/values-pt-rBR/strings.xml
index 80b85fa9a6c0..fbc47cac1f63 100644
--- a/android-components/components/browser/menu/src/main/res/values-pt-rBR/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-pt-rBR/strings.xml
@@ -10,4 +10,6 @@
Gerenciador de extensõesIr para o topo
+
+ Extensões, voltar
diff --git a/android-components/components/browser/menu/src/main/res/values-pt-rPT/strings.xml b/android-components/components/browser/menu/src/main/res/values-pt-rPT/strings.xml
index 467721fb1427..5727a92550cd 100644
--- a/android-components/components/browser/menu/src/main/res/values-pt-rPT/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-pt-rPT/strings.xml
@@ -10,4 +10,6 @@
Gestor de extrasNavegar para cima
+
+ Extras, navegar para cima
diff --git a/android-components/components/browser/menu/src/main/res/values-ru/strings.xml b/android-components/components/browser/menu/src/main/res/values-ru/strings.xml
index 2247a8a93689..41894420502d 100644
--- a/android-components/components/browser/menu/src/main/res/values-ru/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-ru/strings.xml
@@ -10,4 +10,6 @@
Менеджер дополненийПерейти наверх
+
+ Дополнения, перейти вверх
diff --git a/android-components/components/browser/menu/src/main/res/values-sk/strings.xml b/android-components/components/browser/menu/src/main/res/values-sk/strings.xml
index 905edfabb208..c2231f6afc9f 100644
--- a/android-components/components/browser/menu/src/main/res/values-sk/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-sk/strings.xml
@@ -10,4 +10,6 @@
Správca doplnkovPrejsť nahor
+
+ Doplnky, prejsť nahor
diff --git a/android-components/components/browser/menu/src/main/res/values-sv-rSE/strings.xml b/android-components/components/browser/menu/src/main/res/values-sv-rSE/strings.xml
index 673ca8f580c5..bcb5ffb8c92a 100644
--- a/android-components/components/browser/menu/src/main/res/values-sv-rSE/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-sv-rSE/strings.xml
@@ -9,5 +9,7 @@
Tilläggshanterare
- Navigera upp
+ Navigera uppåt
+
+ Tillägg, navigera uppåt
diff --git a/android-components/components/browser/menu/src/main/res/values-tg/strings.xml b/android-components/components/browser/menu/src/main/res/values-tg/strings.xml
index 8ef3f20e65a7..0852a61c5dd8 100644
--- a/android-components/components/browser/menu/src/main/res/values-tg/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-tg/strings.xml
@@ -10,4 +10,6 @@
Мудири ҷузъи иловагӣБа боло гузаред
+
+ Ҷузъҳои иловагӣ, гузариш ба боло
diff --git a/android-components/components/browser/menu/src/main/res/values-tr/strings.xml b/android-components/components/browser/menu/src/main/res/values-tr/strings.xml
index 848597df182b..72ea0eb61427 100644
--- a/android-components/components/browser/menu/src/main/res/values-tr/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-tr/strings.xml
@@ -10,4 +10,6 @@
Eklenti yöneticisiYukarı git
+
+ Eklentiler, yukarı git
diff --git a/android-components/components/browser/menu/src/main/res/values-ug/strings.xml b/android-components/components/browser/menu/src/main/res/values-ug/strings.xml
index 060395149041..dc0ff4e665e5 100644
--- a/android-components/components/browser/menu/src/main/res/values-ug/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-ug/strings.xml
@@ -10,4 +10,6 @@
قىستۇرما باشقۇرغۇچئۈستىگە يول باشلا
+
+ قوشۇلما، ئۈستىگە يول باشلا
diff --git a/android-components/components/browser/menu/src/main/res/values-vi/strings.xml b/android-components/components/browser/menu/src/main/res/values-vi/strings.xml
index cc7cfb6d5e99..32ed556662fd 100644
--- a/android-components/components/browser/menu/src/main/res/values-vi/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-vi/strings.xml
@@ -10,4 +10,6 @@
Quản lí tiện íchĐiều hướng lên
+
+ Tiện ích, điều hướng lên
diff --git a/android-components/components/browser/menu/src/main/res/values-zh-rCN/strings.xml b/android-components/components/browser/menu/src/main/res/values-zh-rCN/strings.xml
index 7c96c6b976e2..6eb039e3182f 100644
--- a/android-components/components/browser/menu/src/main/res/values-zh-rCN/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-zh-rCN/strings.xml
@@ -10,4 +10,6 @@
附加组件管理器向上导航
+
+ 附加组件,向上导航
diff --git a/android-components/components/browser/menu/src/main/res/values-zh-rTW/strings.xml b/android-components/components/browser/menu/src/main/res/values-zh-rTW/strings.xml
index dfa5ee40ca5b..eb2eb5f69eb6 100644
--- a/android-components/components/browser/menu/src/main/res/values-zh-rTW/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-zh-rTW/strings.xml
@@ -10,4 +10,6 @@
附加元件管理員向上導航
+
+ 附加元件,向上導航
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 4669bf57bf02..af3651fcf4f8 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
@@ -137,13 +137,13 @@
لغو
- تاخیلانی قور
+ تاخیلانی قورلغونظرلر: %1$s
- %1$.02f/5
+ %1$.02f/5تاخیلانلار
@@ -244,10 +244,10 @@
دوروم:%1$s، %2$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 c1bbe47b67b9..503ecb6b72b0 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
@@ -137,13 +137,17 @@
Отказ
- Инсталиране на добавка
+ Инсталиране на добавка
+
+ Инсталиране на %1$sОтказОтзиви: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Оценка: %1$.02f от 5Добавки
@@ -244,10 +248,14 @@
Състояние:Добавката „%1$s“ е добавена към %2$s
-
- Отворете я от менюто
+
+ Отворете я от менюто
+
+ Достъп до %1$s от менюто на %2$s.
+
+ Да, разбрах
- Да, разбрах
+ ДобреНаучете повече
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 61fed10d22ff..884830a8d1aa 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
@@ -137,13 +137,17 @@
Otkaži
- Instaliraj add-on
+ Instaliraj add-on
+
+ Instaliraj %1$sOtkažiRecenzije: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Ocjena: %1$.02f od 5Add-oni
@@ -244,10 +248,14 @@
Status:%1$s je dodan u %2$s
-
- Otvori ga u meniju
+
+ Otvori ga u meniju
+
+ Pristupite %1$s iz %2$s menija.
+
+ OK, razumijem
- OK, razumijem
+ OKSaznajte više
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 5d431f3afef4..446c4a9bdbc2 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
@@ -137,13 +137,15 @@
Abbandunà
- Installà u modulu
+ Installà u modulu
+
+ Installà %1$sAbbandunàVoti : %1$s
- %1$.02f/5
+ %1$.02f/5Moduli addiziunali
@@ -244,10 +246,14 @@
Statu :%1$s hè statu aghjuntu à %2$s
-
- Apritelu da u listinu
+
+ Apritelu da u listinu
+
+ Accidite à %1$s via u listinu di %2$s.
+
+ Iè, aghju capitu
- Iè, aghju capitu
+ VaiSapene di più
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 fbde39f7c1c5..4f5462975122 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
@@ -137,13 +137,17 @@
Diddymu
- Gosod Ychwanegyn
+ Gosod Ychwanegyn
+
+ Gosod %1$sDiddymuSgôr: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Sgôr: %1$.02f allan o 5Ychwanegion
@@ -244,10 +248,14 @@
Statws:Mae %1$s wedi ei ychwanegu at %2$s.
-
- Agorwch ef yn y ddewislen
+
+ Agorwch ef yn y ddewislen
+
+ Mynediad %1$s o ddewislen %2$s.
+
+ Iawn, rwy’n deall
- Iawn, rwy’n deall
+ IawnDarllen rhagor
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 ff1dc3cfe6e9..a766891b677d 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
@@ -137,13 +137,17 @@
Annuller
- Installer tilføjelse
+ Installer tilføjelse
+
+ Installer %1$sAnnullerAnmeldelser: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Bedømmelse: %1$.02f ud af 5 Tilføjelser
@@ -244,10 +248,14 @@
Status:%1$s er blevet føjet til %2$s
-
- Åbn den i menuen
+
+ Åbn den i menuen
+
+ Tilgå %1$s fra %2$s-menuen.
+
+ Ok, forstået
- Ok, forstået
+ OKLæs mere
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 99b9d7da22fc..c62975dca758 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
@@ -137,13 +137,17 @@
Abbrechen
- Add-on installieren
+ Add-on installieren
+
+ %1$s installierenAbbrechenBewertungen: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Bewertung: %1$.02f von 5Add-ons
@@ -244,10 +248,14 @@
Status:%1$s wurde zu %2$s hinzugefügt
-
- Im Menü öffnen
+
+ Im Menü öffnen
+
+ Greifen Sie über das %2$s-Menü auf %1$s zu.
+
+ OK
- OK
+ OKWeitere Informationen
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 f1975e4088ba..936713d81595 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
@@ -137,13 +137,17 @@
Pśetergnuś
- Dodank instalěrowaś
+ Dodank instalěrowaś
+
+ %1$s instalěrowaśPśetergnuśPógódnośenja: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Pógódnośenje: %1$.02f z 5Dodanki
@@ -244,10 +248,14 @@
Status:%1$s jo se %2$s pśidał.
-
- W meniju wócyniś
+
+ W meniju wócyniś
+
+ Mějśo pśistup k %1$s z menija %2$s.
+
+ W pórěźe, som zrozměł
- W pórěźe, som zrozměł
+ W pórěźeDalšne informacije
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 9687e5e82de5..a5a1a4aeb18b 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
@@ -137,13 +137,17 @@
Ακύρωση
- Εγκατάσταση προσθέτου
+ Εγκατάσταση προσθέτου
+
+ Εγκατάσταση %1$sΑκύρωσηΚριτικές: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Βαθμολογία: %1$.02f από 5Πρόσθετα
@@ -244,10 +248,14 @@
Κατάσταση:Το %1$s έχει προστεθεί στο %2$s
-
- Άνοιγμα στο μενού
+
+ Άνοιγμα στο μενού
+
+ Αποκτήστε πρόσβαση στο %1$s από το μενού του %2$s.
+
+ Εντάξει
- Εντάξει
+ ΟΚΜάθετε περισσότερα
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 78b5a8f9f8c4..f2f95d1471e2 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
@@ -137,13 +137,17 @@
Cancel
- Install Add-on
+ Install Add-on
+
+ Install %1$sCancelReviews: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Rating: %1$.02f out of 5Add-ons
@@ -244,10 +248,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
+ OKLearn more
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 1682f9966043..1bc6c1c5b1c3 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
@@ -137,13 +137,17 @@
Cancelar
- Instalar complemento
+ Instalar complemento
+
+ Instalar %1$sCancelarRevisiones: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Calificación: %1$.02f de 5Complementos
@@ -244,10 +248,14 @@
Estado:Se agregó %1$s a %2$s
-
- Abrirlo en el menú
+
+ Abrirlo en el menú
+
+ Acceder a %1$s desde el menú de %2$s.
+
+ Listo, entendido
- Listo, entendido
+ AceptarConocer más
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 f3a8750dc35c..894606736690 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
@@ -137,13 +137,17 @@
Cancelar
- Instalar complemento
+ Instalar complemento
+
+ Instalar %1$sCancelarReseñas: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Calificación: %1$.02f de 5Complementos
@@ -244,10 +248,14 @@
Estado:%1$s ha sido añadido a %2$s
-
- Ábrelo en el menú
+
+ Ábrelo en el menú
+
+ Accede a %1$s desde el menú %2$s.
+
+ Ok, ¡ya caché!
- Ok, ¡ya caché!
+ AceptarAprender más
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 9c1dc35c874d..294422dd51b5 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
@@ -137,13 +137,17 @@
Peruuta
- Asenna lisäosa
+ Asenna lisäosa
+
+ Asenna %1$sPeruutaArvosteluja: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Arvostelu: %1$.02f/5Lisäosat
@@ -244,10 +248,14 @@
Tila:%1$s on lisätty %2$siin
-
- Avaa valikossa
+
+ Avaa valikossa
+
+ Käytä lisäosaa %1$s %2$sin valikosta.
+
+ Selvä
- Selvä
+ OKLue lisää
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 ab62d4e19074..b06ef39e07ac 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
@@ -137,13 +137,17 @@
Annuler
- Installer le module
+ Installer le module
+
+ Installer %1$sAnnulerAvis : %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Note : %1$.02f sur 5Modules complémentaires
@@ -244,10 +248,14 @@
État :%1$s a été ajouté à %2$s
-
- Ouvrez-le depuis le menu
+
+ Ouvrez-le depuis le menu
+
+ Accédez à %1$s depuis le menu %2$s.
+
+ J’ai compris
- J’ai compris
+ OKEn savoir plus
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 a167df46711b..9bcdf8520974 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
@@ -137,13 +137,17 @@
Annulearje
- Add-on ynstallearje
+ Add-on ynstallearje
+
+ %1$s ynstallearjeAnnulearjeBeoardielingen: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Wurdearring: %1$.02f fan 5Add-ons
@@ -244,10 +248,14 @@
Steat:%1$s is oan %2$s tafoege
-
- Yn it menu iepenje
+
+ Yn it menu iepenje
+
+ Benaderje %1$s fan it %2$s-menu út.
+
+ Oké, begrepen
- Oké, begrepen
+ OKMear ynfo
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 3dfe7a45ecab..9b6cbc4f1af5 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
@@ -137,13 +137,17 @@
Přetorhnyć
- Přidatk instalować
+ Přidatk instalować
+
+ %1$s instalowaćPřetorhnyćPohódnoćenja: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Pohódnoćenje: %1$.02f z 5Přidatki
@@ -244,10 +248,14 @@
Status:%1$s je so %2$s přidał.
-
- W meniju wočinić
+
+ W meniju wočinić
+
+ Mějće přistup k %1$s z menija %2$s.
+
+ W porjadku, sym zrozumił
- W porjadku, sym zrozumił
+ W porjadkuDalše informacije
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 148ade38e458..39a41b5100b2 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
@@ -137,13 +137,17 @@
Annulla
- Installa componente aggiuntivo
+ Installa componente aggiuntivo
+
+ Installa %1$sAnnullaRecensioni: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Valutazione: %1$.02f su 5Componenti aggiuntivi
@@ -244,10 +248,14 @@
Stato:%1$s è stato aggiunto a %2$s
-
- Apri nel menu
+
+ Apri nel menu
+
+ Accedi a %1$s dal menu di %2$s.
+
+ OK
- OK
+ OKUlteriori informazioni
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 2a662f98a16d..290acb190ead 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
@@ -137,13 +137,17 @@
ביטול
- התקנת תוספת
+ התקנת תוספת
+
+ התקנת %1$sביטולסקירות: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ דירוג: %1$.02f מתוך 5תוספות
@@ -244,10 +248,14 @@
מצב:%1$s נוספה אל %2$s
-
- ניתן לפתוח אותה בתפריט
+
+ ניתן לפתוח אותה בתפריט
+
+ ניתן לגשת ל־%1$s מהתפריט של %2$s.
+
+ בסדר, הבנתי
- בסדר, הבנתי
+ אישורמידע נוסף
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 5e6da873770d..c1363aadcdd5 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
@@ -137,13 +137,17 @@
Бас тарту
- Қосымшаны орнату
+ Қосымшаны орнату
+
+ %1$s орнатуБас тартуПікірлер: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Рейтинг: %1$.02f, 5 ішіненҚосымшалар
@@ -244,10 +248,14 @@
Қалып-күйі:%1$s %2$s ішіне қосылды
-
- Мәзірде ашу
+
+ Мәзірде ашу
+
+ %2$s мәзірінен %1$s қосымшасына қол жеткізу.
+
+ Жақсы, түсіндім
- Жақсы, түсіндім
+ ОККөбірек білу
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 f0a7144960b9..5048edba07df 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
@@ -137,13 +137,17 @@
취소
- 부가 기능 설치
+ 부가 기능 설치
+
+ %1$s 설치취소리뷰: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ 평점: %1$.02f / 5부가 기능
@@ -244,10 +248,14 @@
상태:%2$s에 %1$s 부가 기능이 추가되었습니다
-
- 메뉴에서 열기
+
+ 메뉴에서 열기
+
+ %2$s 메뉴에서 %1$s에 액세스하세요.
+
+ 확인
- 확인
+ 확인더 알아보기
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 4b9745f5ad10..ae5236dd1f86 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
@@ -137,13 +137,17 @@
Annuleren
- Add-on installeren
+ Add-on installeren
+
+ %1$s installerenAnnulerenBeoordelingen: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Waardering: %1$.02f van 5Add-ons
@@ -244,10 +248,14 @@
Status:%1$s is aan %2$s toegevoegd
-
- In het menu openen
+
+ In het menu openen
+
+ Benader %1$s vanuit het %2$s-menu.
+
+ Oké, begrepen
- Oké, begrepen
+ OKMeer info
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 5df2c679e757..49f9cd103e59 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
@@ -137,13 +137,17 @@
Cancelar
- Instalar extensão
+ Instalar extensão
+
+ Instalar %1$sCancelarAvaliações: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Avaliação: %1$.02f de 5Extensões
@@ -244,10 +248,14 @@
Status:%1$s foi adicionado ao %2$s
-
- Abra opções da extensão no menu
+
+ Abra opções da extensão no menu
+
+ Acesse %1$s pelo menu do %2$s.
+
+ OK, entendi
- OK, entendi
+ OKSaiba mais
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 93bc453ff789..9a7bdaf7b454 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
@@ -137,13 +137,17 @@
Cancelar
- Instalar extra
+ Instalar extra
+
+ Instalar %1$sCancelarAvaliações: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Avaliação: %1$.02f de 5Extras
@@ -244,10 +248,14 @@
Estado:%1$s foi adicionado ao %2$s.
-
- Abrir no menu
+
+ Abrir no menu
+
+ Aceda a %1$s a partir do menu %2$s.
+
+ Ok, entendi
- Ok, entendi
+ OKSaber mais
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 1db019c56a81..54618d79cfa5 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
@@ -137,13 +137,17 @@
Отмена
- Установить дополнение
+ Установить дополнение
+
+ Установить %1$sОтменаОтзывов: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Оценка: %1$.02f из 5Дополнения
@@ -244,10 +248,14 @@
Состояние:%1$s было добавлено в %2$s
-
- Открыть его в меню
+
+ Открыть его в меню
+
+ Получить доступ к %1$s из меню %2$s.
+
+ Ок, понятно
- Ок, понятно
+ OKПодробнее
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 572330224a76..153fafe94e66 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
@@ -137,13 +137,17 @@
Zrušiť
- Inštalovať doplnok
+ Inštalovať doplnok
+
+ Nainštalovať %1$sZrušiťPočet recenzií: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Hodnotenie: %1$.02f z 5Doplnky
@@ -244,10 +248,14 @@
Stav:Doplnok %1$s bol pridaný do aplikácie %2$s
-
- Nájdete ho v ponuke
+
+ Nájdete ho v ponuke
+
+ Prístup k doplnku %1$s získate z ponuky %2$su.
+
+ Ok, rozumiem
- Ok, rozumiem
+ OKĎalšie informácie
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 da77caa578be..d19e83bc9d5c 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
@@ -137,13 +137,13 @@
Prekliči
- Namesti dodatek
+ Namesti dodatekPrekličiOcen: %1$s
- %1$.02f/5
+ %1$.02f/5Dodatki
@@ -244,10 +244,12 @@
Stanje:%1$s je bil dodan v %2$s
-
- Odprite ga v meniju
+
+ Odprite ga v meniju
- Razumem
+ Razumem
+
+ V reduVeč o tem
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 0ae3f20e3db0..dc6ac0706e72 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
@@ -137,13 +137,17 @@
Avbryt
- Installera tillägg
+ Installera tillägg
+
+ Installera %1$sAvbrytRecensioner: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Betyg: %1$.02f av 5Tillägg
@@ -244,10 +248,14 @@
Status:%1$s har lagts till %2$s
-
- Öppna den i menyn
+
+ Öppna den i menyn
+
+ Öppna %1$s från menyn %2$s.
+
+ Ok, jag förstår
- Ok, jag förstår
+ OKLäs mer
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 cce6e4e95177..2f59a7381e49 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
@@ -137,13 +137,17 @@
Бекор кардан
- Насб кардани ҷузъи иловагӣ
+ Насб кардани ҷузъи иловагӣ
+
+ «%1$s»-ро насб намоедБекор карданТақризҳо: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Баҳодиҳӣ: %1$.02f аз 5Ҷузъҳои иловагӣ
@@ -244,10 +248,14 @@
Вазъият:%1$s ба %2$s илова карда шуд
-
- Онро дар меню кушоед
+
+ Онро дар меню кушоед
+
+ Ба «%1$s» аз менюи «%2$s» дастрасӣ пайдо намоед.
+
+ Хуб, фаҳмидам
- Хуб, фаҳмидам
+ ХУБМаълумоти бештар
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 58f296540fd1..0ce97dd83cff 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
@@ -137,13 +137,17 @@
İptal
- Eklentiyi yükle
+ Eklentiyi yükle
+
+ %1$s eklentisini yükleİptalİnceleme: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Puan: 5 üzerinden %1$.02fEklentiler
@@ -244,10 +248,14 @@
Durum:%1$s %2$s tarayıcınıza eklendi
-
- Menüden açabilirsiniz
+
+ Menüden açabilirsiniz
+
+ %1$s eklentisine %2$s menüsünden erişebilirsiniz.
+
+ Tamam
- Tamam
+ TamamDaha fazla bilgi alın
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 a86fdf69e740..2fbc935821c5 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
@@ -137,13 +137,17 @@
بىكار قىلىش
- قىستۇرما قاچىلاش
+ قىستۇرما قاچىلاش
+
+ %1$sنى ئورناتبىكار قىلىشباھا: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ باھالاش: %1$.02f (تولۇق 5 نومۇر)قىستۇرمىلار
@@ -244,10 +248,14 @@
ھالىتى:%2$s غا %1$s قوشۇلدى
-
- تىزىملىكتىن ئېچىش
+
+ تىزىملىكتىن ئېچىش
+
+ %2$s تىزىملىكىدىن %1$s نى زىيارەت قىلىڭ.
+
+ ماقۇل
- ماقۇل
+ جەزملەتەپسىلاتى
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 a256a6172f0d..22eb0e6280e2 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
@@ -137,13 +137,17 @@
Hủy bỏ
- Cài đặt tiện ích
+ Cài đặt tiện ích
+
+ Cài đặt %1$sHủy bỏĐánh giá: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Xếp hạng: %1$.02f trên 5Tiện ích mở rộng
@@ -244,10 +248,14 @@
Trạng thái:%1$s đã được thêm vào %2$s
-
- Mở nó trong menu
+
+ Mở nó trong menu
+
+ Truy cập %1$s từ menu %2$s.
+
+ OK, đã hiểu
- OK, đã hiểu
+ OKTìm hiểu thêm
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 a0b6ca60deae..b6061e1ea1d4 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
@@ -137,13 +137,17 @@
取消
- 安装附加组件
+ 安装附加组件
+
+ 安装“%1$s”取消评价数:%1$s
- %1$.02f/5
+ %1$.02f/5
+
+ 评分:%1$.02f(满分 5 分)附加组件
@@ -244,10 +248,14 @@
状态:%1$s 已添加到 %2$s
-
- 在菜单中打开
+
+ 在菜单中打开
+
+ 可在 %2$s 菜单中使用“%1$s”。
+
+ 好的
- 好的
+ 确定详细了解
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 4d8bc57b6ec8..783c139327d5 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
@@ -137,13 +137,17 @@
取消
- 安裝附加元件
+ 安裝附加元件
+
+ 安裝 %1$s取消評價: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ 評分:%1$.02f 分,滿分 5 分附加元件
@@ -244,10 +248,14 @@
狀態:已安裝 %1$s 至 %2$s。
-
- 到選單開啟
+
+ 到選單開啟
+
+ 從 %2$s 選單使用 %1$s。
+
+ 好的,知道了
- 好的,知道了
+ 確定了解更多
diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml
index 06f3ceeadf99..596ba46384de 100644
--- a/fenix/app/src/main/res/values-azb/strings.xml
+++ b/fenix/app/src/main/res/values-azb/strings.xml
@@ -544,7 +544,7 @@
اؤزل دؤنگل سرور
- موْزیلا حسابیْ/دؤنگل سروری دگیشدیریلدی. دگیشمهلری یئرینه سالماق اوچون اپلیکیشندن چیخیلیر...
+ موْزیلا حسابیْ/دؤنگل سروری دگیشدیریلدی. دگیشمهلری یئرینه سالماق اوچون اپلیکیشندن چیخیلیر…حساب
@@ -614,7 +614,7 @@
Gecko قیدلرینی گوجلندیر
- دگیشمهلری یئرینه سالماق اوچون اپلیکیشندن چیْخیلیر...
+ دگیشمهلری یئرینه سالماق اوچون اپلیکیشندن چیْخیلیر…تاخیلانلار
@@ -641,7 +641,7 @@
مجموعه صاحیبی (قوللانیجیْ آیدیسی)
- تاخیْلان مجموعهسی ایصلاح اوْلدوُ. دگیشمهلری یئرینه سالماق اوچون اپلیکیشندن چیْخیلیر...
+ تاخیْلان مجموعهسی ایصلاح اوْلدوُ. دگیشمهلری یئرینه سالماق اوچون اپلیکیشندن چیْخیلیر…
@@ -662,6 +662,9 @@
دال پردهلر
+
+ اسپانسرلی شوْرتکاتلار
+
دال پرده: %1$s
@@ -686,6 +689,37 @@
باغیْمسیز سسلر مجموعهسی. %s
+
+ باغیْمسیز سسلر مجموعهسی.
+
+ بیر رنگ سپمهسی ایمتیحان ائلهیین
+
+ سیزینله دانیشان بیر دال پرده سئچین.
+
+ داها چوْخ دال پردهلری آراشدیْرین
+
+
+
+ ایندی یئنی تاخیْلانلار وار
+
+ فایرفاکسیْ اؤزوُنوز ائتمک ایمکانیْ وئرن 100 دن چوْخ یئنی اوُزانتیا باخیْن.
+
+ تاخیلانلاریْ آراشدیْر
+
+
+
+ تاخیلانلار گئچیجی اوْلاراق گوُجدن سالیْنمیش.
+
+
+ بیر و یا نئچه تاخیْلانین ایشی دایاندیریلدیْ، بوُدا سیستمیزی ثابیتسیز ائلهدی. %1$s تاخیلانی(لاریْ) یئنیدن باشلاتماغا باشاریْسیز اوْلدو. \n\n تاخیلانلار ایندیکی اوتورومونوزدا یئنیدن ایشه سالیْنمیاجاق. \n\n تاخیلانی(لار)ین سیلینمهسی و یا ایشدن سالینماسیْ بو موُشکولو حل ائلیه بیلر.
+
+ تاخیلانلاریْ یئنیدن باشلاتماغا چالیْشین
+
+ تاخیلانلاریْ گوُجسوز ائتمهگه ایدامه وئرین
+
+
+
+ حساب مودیریتیایندی دؤنگللندیر
@@ -707,7 +741,7 @@
جهاز آدیْ بوْش اوْلمالیدیر
- دؤنگللنیر...
+ دؤنگللنیر…دؤنگل خطا وئردی. سوْن باشاریْ: %s
diff --git a/fenix/app/src/main/res/values-bs/strings.xml b/fenix/app/src/main/res/values-bs/strings.xml
index 819e7f7a9700..053b30d784fc 100644
--- a/fenix/app/src/main/res/values-bs/strings.xml
+++ b/fenix/app/src/main/res/values-bs/strings.xml
@@ -2141,6 +2141,9 @@
%s pretraga
+
+ Promijenite svoj zadani pretraživač
+
Postavi automatsko otvaranje linkova web stranica, e-maila i poruka u Firefoxu.
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 2c2948d36c06..3a89ca170e63 100644
--- a/fenix/app/src/main/res/values-fy-rNL/strings.xml
+++ b/fenix/app/src/main/res/values-fy-rNL/strings.xml
@@ -2171,6 +2171,9 @@
Sykje mei %s
+
+ Jo standertbrowser wikselje
+
Keppelingen fan websites, e-mail en berjochten automatysk yn Firefox iepenje.
diff --git a/fenix/app/src/main/res/values-it/strings.xml b/fenix/app/src/main/res/values-it/strings.xml
index e7ee8061bdcb..a7bbe317cbcf 100644
--- a/fenix/app/src/main/res/values-it/strings.xml
+++ b/fenix/app/src/main/res/values-it/strings.xml
@@ -98,7 +98,7 @@
- La funzione per la protezione della privacy più potente che abbiamo mai realizzato isola gli elementi traccianti tra i siti.
+ La funzione per la protezione della privacy più potente che abbiamo mai realizzato: isola gli elementi che ti tracciano attraverso siti diversi.Ulteriori informazioni sulla Protezione totale per i cookie
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 247d17f85b8b..8e192a27d7c3 100644
--- a/fenix/app/src/main/res/values-zh-rCN/strings.xml
+++ b/fenix/app/src/main/res/values-zh-rCN/strings.xml
@@ -2223,6 +2223,9 @@
%s · 搜索
+
+ 切换默认浏览器
+
将网站、电子邮件及聊天工具中的链接设为在 Firefox 中自动打开。
From ccb01963f03f3963d8bb531448e56f610c423c28 Mon Sep 17 00:00:00 2001
From: Ryan VanderMeulen
Date: Wed, 24 Jan 2024 16:09:04 -0500
Subject: [PATCH 226/586] Bug 1876385 - Update AndroidX Benchmark to version
1.2.3
---
.../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 5916113c331a..39ed6cf1defe 100644
--- a/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt
+++ b/fenix/plugins/fenixdependencies/src/main/java/FenixDependenciesPlugin.kt
@@ -19,7 +19,7 @@ object FenixVersions {
const val fastlane = "2.1.1"
const val androidx_activity = "1.7.2"
- const val androidx_benchmark = "1.2.2"
+ const val androidx_benchmark = "1.2.3"
const val androidx_profileinstaller = "1.3.1"
const val androidx_legacy = "1.0.0"
const val androidx_lifecycle = "2.6.1"
From 09ab951ae6e9220136f0187322dce87d9c17e2bd Mon Sep 17 00:00:00 2001
From: github-actions
Date: Fri, 16 Feb 2024 00:03:28 +0000
Subject: [PATCH 227/586] Import translations from android-l10n
---
.../addons/src/main/res/values-bg/strings.xml | 2 +
.../addons/src/main/res/values-cy/strings.xml | 2 +
.../addons/src/main/res/values-de/strings.xml | 2 +
.../src/main/res/values-es-rAR/strings.xml | 2 +
.../src/main/res/values-kab/strings.xml | 14 +-
.../src/main/res/values-pt-rPT/strings.xml | 2 +
.../src/main/res/values-sv-rSE/strings.xml | 2 +
.../src/main/res/values-kab/strings.xml | 2 +
fenix/app/src/main/res/values-azb/strings.xml | 138 ++++++++++++++++++
9 files changed, 161 insertions(+), 5 deletions(-)
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 503ecb6b72b0..e16db4552651 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
@@ -98,6 +98,8 @@
Разрешаване в поверителни разделиРаботи в поверителни раздели
+
+ Не е разрешено в поверителни прозорциВключени
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 4f5462975122..b420dd55493e 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
@@ -98,6 +98,8 @@
Caniatáu yn y pori preifatRhedeg yn y pori preifat
+
+ Ni chaniateir mewn ffenestri preifatGalluogwyd
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 c62975dca758..9b8a66b73554 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
@@ -98,6 +98,8 @@
Im privaten Modus erlaubenIm privaten Modus ausführen
+
+ In privaten Fenstern nicht erlaubtAktiviert
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 1bc6c1c5b1c3..b02be32db705 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
@@ -98,6 +98,8 @@
Permitir en navegación privadaEjecutar en navegación privada
+
+ No permitido en ventanas privadasHabilitado
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 a11aa586d76a..1bef9a913070 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
@@ -137,13 +137,15 @@
Sefsex
- Asebded n uzegrir
+ Asebded n uzegrir
+
+ Sebded %1$sSefsexCegger: %1$s
- %1$.02f/55
+ %1$.02f/55Izegrar
@@ -242,10 +244,12 @@
Addaden:%1$s yettwarna ɣer %2$s
-
- Ldi-t deg wumuɣ
+
+ Ldi-t deg wumuɣ
- Ih, awi-t-id
+ Ih, awi-t-id
+
+ IHIssin ugar
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 9a7bdaf7b454..46e17c443f0c 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
@@ -98,6 +98,8 @@
Permitir na navegação privadaExecutar na navegação privada
+
+ Não permitido em janelas privadasAtivado
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 dc6ac0706e72..2ecddc5510b5 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
@@ -98,6 +98,8 @@
Tillåt i privat surfningKör i privat surfning
+
+ Inte tillåtet i privata fönsterAktiverad
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 0da6d4656b34..e38a77f8680f 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
@@ -38,6 +38,8 @@
Sekcem awal uffirUr yezmir ara ad isekles anekcum
+
+ Ur sseklas ara awal uffirSekles anekcum-agi?
diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml
index 596ba46384de..8bf0f3303cce 100644
--- a/fenix/app/src/main/res/values-azb/strings.xml
+++ b/fenix/app/src/main/res/values-azb/strings.xml
@@ -720,8 +720,12 @@
حساب مودیریتی
+
+ رمزینیزی دگیشدیرین، دیتا یئغمایی ایداره ائدین ویا حسابینیزی سیلین.ایندی دؤنگللندیر
+
+ نهیین دؤنگل ائدیلهجهگینی سئچینگئچمیش
@@ -753,6 +757,52 @@
سوْن دؤنگل: هئچ
+
+ %1$s - %2$s %3$s
+
+ اعتباری کارتلار
+
+
+ اؤدمه آپاریْلاری
+
+ آدرسلر
+
+
+
+ آلیْنان تاغلار
+
+ آیریْ فایرفاکس جهازلاریندان آلینان تاغلارا اوچون بیلدیریشلر
+
+ تاغ آلیندیْ
+
+
+ %s-دن آلینان تاغ
+
+
+
+ آیریْ توُتمالار
+
+ بوتون سایتلار اوچون آچیْن
+
+ آیریْ توتمالار سئچیلمیش سایتلار اوچون ایزلنمه قوْروماسینیْ ایشدن سالماغا ایمکان وئریر.
+
+ آرتیق بیلین
+
+
+ ایشه آلما و فنی دیتالار
+
+ بازارلاما دیتاسیْ
+
+ آراشدیرمالار
+
+
+
+ دیتالارینیزیْ دؤنگل ائدین و ساخلایین
+
+ حساب قالدیْر
+
اوست
@@ -781,6 +831,10 @@
بوُکمارکلار
+
+ دستکتاپ بوکمارکلاریْ
+
+ بوکمارک منوسوگئچمیش
@@ -790,22 +844,106 @@
باغلا
+
+ تاغلاریْ آچ
+
+ لغو
+
+
+ %d صفحه
+
+ %d صفحه
+
+
+ سوْن باغلانان تاغلار
+
+ بوتون گئچمیشی گؤستر
+
+ %d تاغ
+
+ %d تاغ
+
+ بو یاخین زاماندا باغلانان تاغ یوخ
+
تاغلار
+
+ تاغ گؤروُنوشولیست
+
+ شبکهلی
+
+ تاغلاریْ باغلاهئچ زامان
+
+ بیر گوندن سوْنرا
+
+ بیر هفتهدن سوْنرا
+
+ بیر آیدان سوْنرا
+
+ آچیق تاغلاریْ اوْتوماتیک باغلا
+
آنایارپاق
+
+ ال ایله باغلاییْن
+
+
+ بیر گۆندن سوْنرا باغلایین
+
قالدیر
+
+ سیل
+
+ %1$d سئچیلیدی
+
+ بوگون
+
+ دوُنن
+
+ سوْن 7 گون
+
+ سوْن 30 گون
+
+
+
+ داها قدیمی
+
+ گئچمیش یوخدور
+
+
+
+ یئندیرمهلر فالدیریلدیْ
+
+ %1$s قالدیریلدیْ
+
+ هئچ یئندیریلمیش فایل یوخدور
+
+ %1$d سئچیلیدی
+
+ قالدیر
+
+
+
+
+ باغیشلایین، %1$s بو صفحهنی دولدورا بیلمهدی.
+
لغو
From 33bfc8c94ef33e1ceb998843cdf53d5e275f3e35 Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Fri, 16 Feb 2024 01:25:06 +0000
Subject: [PATCH 228/586] Update GeckoView (Nightly) to 124.0.20240215210102.
---
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 665ea1184099..9b3afbde14d0 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.20240215095551"
+ const val version = "124.0.20240215210102"
/**
* GeckoView channel
From d1ab497a628b65f3ae29696ff16d6bc7507e02ae Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Fri, 16 Feb 2024 05:33:47 +0000
Subject: [PATCH 229/586] Update A-S to 125.20240216050339.
---
.../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 3da655c0580c..0048a6223ee9 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.20240215050333"
+val VERSION = "125.20240216050339"
val CHANNEL = ApplicationServicesChannel.NIGHTLY
object ApplicationServicesConfig {
From 047e8019a1c74266f3f211c34ddc0f85d7845963 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Wed, 14 Feb 2024 13:29:42 +0200
Subject: [PATCH 230/586] Bug 1815651 - Fix verifyAutofillToggleTest UI test
---
.../src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt | 6 ++++++
1 file changed, 6 insertions(+)
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 3dcdd96cdf4b..394c449eb557 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
@@ -510,9 +510,13 @@ class LoginsTest {
navigationToolbar {
}.enterURLAndEnterToBrowser(loginPage.toUri()) {
+ waitForPageToLoad()
setPageObjectText(itemWithResId("username"), "mozilla")
+ waitForAppWindowToBeUpdated()
setPageObjectText(itemWithResId("password"), "firefox")
+ waitForAppWindowToBeUpdated()
clickPageObject(itemWithResId("submit"))
+ waitForPageToLoad()
verifySaveLoginPromptIsDisplayed()
clickPageObject(itemWithText("Save"))
}.openTabDrawer {
@@ -521,6 +525,8 @@ class LoginsTest {
navigationToolbar {
}.enterURLAndEnterToBrowser(loginPage.toUri()) {
+ waitForPageToLoad()
+ clickPageObject(itemWithResId("togglePassword"))
verifyPrefilledLoginCredentials("mozilla", "firefox", true)
}.openTabDrawer {
closeTab()
From 256735cab481478cf0f838d0d8aa593e79d453ff Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Fri, 16 Feb 2024 13:04:48 +0000
Subject: [PATCH 231/586] Update GeckoView (Nightly) to 124.0.20240216094648.
---
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 9b3afbde14d0..b403375f2501 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.20240215210102"
+ const val version = "124.0.20240216094648"
/**
* GeckoView channel
From 72418f93b2b175e3e4ba20fbde7333999e8859da Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Fri, 16 Feb 2024 12:09:11 +0200
Subject: [PATCH 232/586] Bug 1880620 - Add logs to
SettingsSubMenuAddonsManagerAddonDetailedMenuRobot
---
...tingsSubMenuAddonsManagerAddonDetailedMenuRobot.kt | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.kt
index 799f3a991353..43aceae29f7f 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.kt
@@ -5,6 +5,7 @@
package org.mozilla.fenix.ui.robots
+import android.util.Log
import android.view.View
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
@@ -17,6 +18,7 @@ import org.hamcrest.CoreMatchers.allOf
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources
+import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource
import org.mozilla.fenix.helpers.click
@@ -28,8 +30,9 @@ class SettingsSubMenuAddonsManagerAddonDetailedMenuRobot {
class Transition {
fun goBack(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition {
- fun goBackButton() = onView(allOf(withContentDescription("Navigate up")))
- goBackButton().click()
+ Log.i(TAG, "goBack: Trying to click the navigate up button")
+ onView(allOf(withContentDescription("Navigate up"))).click()
+ Log.i(TAG, "goBack: Clicked the navigate up button")
SettingsSubMenuAddonsManagerRobot().interact()
return SettingsSubMenuAddonsManagerRobot.Transition()
@@ -42,8 +45,12 @@ class SettingsSubMenuAddonsManagerAddonDetailedMenuRobot {
View.VISIBLE,
),
) {
+ Log.i(TAG, "removeAddon: Trying to verify that the remove add-on button is visible")
removeAddonButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
+ Log.i(TAG, "removeAddon: Verified that the remove add-on button is visible")
+ Log.i(TAG, "removeAddon: Trying to click the remove add-on button")
removeAddonButton().click()
+ Log.i(TAG, "removeAddon: Clicked the remove add-on button")
}
SettingsSubMenuAddonsManagerRobot().interact()
From 865f7f05b306f5c8020c08b7cdd3f3e6eb2854d4 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Fri, 16 Feb 2024 12:19:12 +0200
Subject: [PATCH 233/586] Bug 1880620 - Remove redundant assertion functions
from SettingsSubMenuAddonsManagerRobot
---
.../SettingsSubMenuAddonsManagerRobot.kt | 113 ++++++++----------
1 file changed, 47 insertions(+), 66 deletions(-)
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 7847051388eb..9b41d345f2b6 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
@@ -139,7 +139,13 @@ class SettingsSubMenuAddonsManagerRobot {
fun verifyAddonIsInstalled(addonName: String) {
scrollToElementByText(addonName)
- assertAddonIsInstalled(addonName)
+ onView(
+ allOf(
+ withId(R.id.add_button),
+ isDescendantOfA(withId(R.id.add_on_item)),
+ hasSibling(hasDescendant(withText(addonName))),
+ ),
+ ).check(matches(withEffectiveVisibility(Visibility.INVISIBLE)))
}
fun verifyEnabledTitleDisplayed() {
@@ -149,8 +155,46 @@ class SettingsSubMenuAddonsManagerRobot {
fun cancelInstallAddon() = cancelInstall()
fun acceptPermissionToInstallAddon() = allowPermissionToInstall()
- fun verifyAddonsItems() = assertAddonsItems()
- fun verifyAddonCanBeInstalled(addonName: String) = assertAddonCanBeInstalled(addonName)
+ fun verifyAddonsItems() {
+ onView(allOf(withId(R.id.title), withText("Recommended")))
+ .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+
+ onView(
+ allOf(
+ isAssignableFrom(RelativeLayout::class.java),
+ withId(R.id.add_on_item),
+ hasDescendant(allOf(withId(R.id.add_on_icon), isCompletelyDisplayed())),
+ hasDescendant(
+ allOf(
+ withId(R.id.details_container),
+ hasDescendant(withText("uBlock Origin")),
+ hasDescendant(withText("Finally, an efficient wide-spectrum content blocker. Easy on CPU and memory.")),
+ hasDescendant(withId(R.id.rating)),
+ hasDescendant(withId(R.id.review_count)),
+ ),
+ ),
+ hasDescendant(withId(R.id.add_button)),
+ ),
+ ).check(matches(isCompletelyDisplayed()))
+ }
+ fun verifyAddonCanBeInstalled(addonName: String) {
+ scrollToElementByText(addonName)
+ mDevice.waitNotNull(Until.findObject(By.text(addonName)), waitingTime)
+
+ onView(
+ allOf(
+ withId(R.id.add_button),
+ hasSibling(
+ hasDescendant(
+ allOf(
+ withId(R.id.add_on_name),
+ withText(addonName),
+ ),
+ ),
+ ),
+ ),
+ ).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ }
fun selectAllowInPrivateBrowsing() {
assertUIObjectExists(itemWithText("Allow in private browsing"), waitingTime = waitingTimeLong)
@@ -210,16 +254,6 @@ class SettingsSubMenuAddonsManagerRobot {
),
)
- private fun assertAddonIsInstalled(addonName: String) {
- onView(
- allOf(
- withId(R.id.add_button),
- isDescendantOfA(withId(R.id.add_on_item)),
- hasSibling(hasDescendant(withText(addonName))),
- ),
- ).check(matches(withEffectiveVisibility(Visibility.INVISIBLE)))
- }
-
private fun cancelInstall() {
onView(allOf(withId(R.id.deny_button), withText("Cancel")))
.check(matches(isCompletelyDisplayed()))
@@ -233,59 +267,6 @@ class SettingsSubMenuAddonsManagerRobot {
.check(matches(isCompletelyDisplayed()))
.perform(click())
}
-
- private fun assertAddonsItems() {
- assertRecommendedTitleDisplayed()
- assertAddons()
- }
-
- private fun assertRecommendedTitleDisplayed() {
- onView(allOf(withId(R.id.title), withText("Recommended")))
- .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
- }
-
- private fun assertAddons() {
- assertAddonUblock()
- }
-
- private fun assertAddonUblock() {
- onView(
- allOf(
- isAssignableFrom(RelativeLayout::class.java),
- withId(R.id.add_on_item),
- hasDescendant(allOf(withId(R.id.add_on_icon), isCompletelyDisplayed())),
- hasDescendant(
- allOf(
- withId(R.id.details_container),
- hasDescendant(withText("uBlock Origin")),
- hasDescendant(withText("Finally, an efficient wide-spectrum content blocker. Easy on CPU and memory.")),
- hasDescendant(withId(R.id.rating)),
- hasDescendant(withId(R.id.review_count)),
- ),
- ),
- hasDescendant(withId(R.id.add_button)),
- ),
- ).check(matches(isCompletelyDisplayed()))
- }
-
- private fun assertAddonCanBeInstalled(addonName: String) {
- scrollToElementByText(addonName)
- mDevice.waitNotNull(Until.findObject(By.text(addonName)), waitingTime)
-
- onView(
- allOf(
- withId(R.id.add_button),
- hasSibling(
- hasDescendant(
- allOf(
- withId(R.id.add_on_name),
- withText(addonName),
- ),
- ),
- ),
- ),
- ).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
- }
}
fun addonsMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition {
From 7e91cbaee5f431120812fcbeaa762ad2c46e7b66 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Fri, 16 Feb 2024 13:01:39 +0200
Subject: [PATCH 234/586] Bug 1880620 - Add logs to
SettingsSubMenuAddonsManagerRobot
---
.../SettingsSubMenuAddonsManagerRobot.kt | 96 +++++++++++++------
1 file changed, 66 insertions(+), 30 deletions(-)
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 9b41d345f2b6..95ea5f4c431c 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
@@ -55,12 +55,15 @@ class SettingsSubMenuAddonsManagerRobot {
fun verifyAddonsListIsDisplayed(shouldBeDisplayed: Boolean) =
assertUIObjectExists(addonsList(), exists = shouldBeDisplayed)
- fun verifyAddonDownloadOverlay() =
+ fun verifyAddonDownloadOverlay() {
+ Log.i(TAG, "verifyAddonDownloadOverlay: Trying to verify that the \"Downloading and verifying add-on\" prompt is displayed")
onView(withText(R.string.mozac_add_on_install_progress_caption)).check(matches(isDisplayed()))
+ Log.i(TAG, "verifyAddonDownloadOverlay: Verified that the \"Downloading and verifying add-on\" prompt is displayed")
+ }
fun verifyAddonPermissionPrompt(addonName: String) {
mDevice.waitNotNull(Until.findObject(By.text("Add $addonName?")), waitingTime)
-
+ Log.i(TAG, "verifyAddonPermissionPrompt: Trying to verify that the add-ons permission prompt items are displayed")
onView(
allOf(
withText("Add $addonName?"),
@@ -71,11 +74,14 @@ class SettingsSubMenuAddonsManagerRobot {
)
.inRoot(isDialog())
.check(matches(isDisplayed()))
+ Log.i(TAG, "verifyAddonPermissionPrompt: Verified that the add-ons permission prompt items are displayed")
}
fun clickInstallAddon(addonName: String) {
- Log.i(TAG, "clickInstallAddon: Looking for $addonName install button")
+ Log.i(TAG, "clickInstallAddon: Waiting for $waitingTime ms for add-ons list to exist")
addonsList().waitForExists(waitingTime)
+ Log.i(TAG, "clickInstallAddon: Waited for $waitingTime ms for add-ons list to exist")
+ Log.i(TAG, "clickInstallAddon: Trying to scroll into view the install $addonName button")
addonsList().scrollIntoView(
mDevice.findObject(
UiSelector()
@@ -83,6 +89,8 @@ class SettingsSubMenuAddonsManagerRobot {
.childSelector(UiSelector().text(addonName)),
),
)
+ Log.i(TAG, "clickInstallAddon: Scrolled into view the install $addonName button")
+ Log.i(TAG, "clickInstallAddon: Trying to ensure the full visibility of the the install $addonName button")
addonsList().ensureFullyVisible(
mDevice.findObject(
UiSelector()
@@ -90,22 +98,24 @@ class SettingsSubMenuAddonsManagerRobot {
.childSelector(UiSelector().text(addonName)),
),
)
- Log.i(TAG, "clickInstallAddon: Found $addonName install button")
+ Log.i(TAG, "clickInstallAddon: Ensured the full visibility of the the install $addonName button")
+ Log.i(TAG, "clickInstallAddon: Trying to click the install $addonName button")
installButtonForAddon(addonName).click()
- Log.i(TAG, "clickInstallAddon: Clicked Install $addonName button")
+ Log.i(TAG, "clickInstallAddon: Clicked the install $addonName button")
}
fun verifyAddonInstallCompleted(addonName: String, activityTestRule: HomeActivityIntentTestRule) {
for (i in 1..RETRY_COUNT) {
+ Log.i(TAG, "verifyAddonInstallCompleted: Started try #$i")
try {
assertUIObjectExists(itemWithText("OK"), waitingTime = waitingTimeLong)
break
} catch (e: AssertionError) {
+ Log.i(TAG, "verifyAddonInstallCompleted: AssertionError caught, executing fallback methods")
if (i == RETRY_COUNT) {
throw e
} else {
- Log.i(TAG, "verifyAddonInstallCompleted: $addonName failed to install on try #$i")
restartApp(activityTestRule)
homeScreen {
}.openThreeDotMenu {
@@ -121,6 +131,7 @@ class SettingsSubMenuAddonsManagerRobot {
}
fun verifyAddonInstallCompletedPrompt(addonName: String) {
+ Log.i(TAG, "verifyAddonInstallCompletedPrompt: Trying to verify that completed add-on install prompt items are visible")
onView(
allOf(
withText("OK"),
@@ -131,14 +142,18 @@ class SettingsSubMenuAddonsManagerRobot {
),
)
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ Log.i(TAG, "verifyAddonInstallCompletedPrompt: Verified that completed add-on install prompt items are visible")
}
fun closeAddonInstallCompletePrompt() {
+ Log.i(TAG, "closeAddonInstallCompletePrompt: Trying to click the \"OK\" button from the completed add-on install prompt")
onView(withText("OK")).click()
+ Log.i(TAG, "closeAddonInstallCompletePrompt: Clicked the \"OK\" button from the completed add-on install prompt")
}
fun verifyAddonIsInstalled(addonName: String) {
scrollToElementByText(addonName)
+ Log.i(TAG, "verifyAddonIsInstalled: Trying to verify that the $addonName add-on was installed")
onView(
allOf(
withId(R.id.add_button),
@@ -146,19 +161,24 @@ class SettingsSubMenuAddonsManagerRobot {
hasSibling(hasDescendant(withText(addonName))),
),
).check(matches(withEffectiveVisibility(Visibility.INVISIBLE)))
+ Log.i(TAG, "verifyAddonIsInstalled: Verified that the $addonName add-on was installed")
}
fun verifyEnabledTitleDisplayed() {
+ Log.i(TAG, "verifyEnabledTitleDisplayed: Trying to verify that the \"Enabled\" heading is displayed")
onView(withText("Enabled"))
.check(matches(isCompletelyDisplayed()))
+ Log.i(TAG, "verifyEnabledTitleDisplayed: Verified that the \"Enabled\" heading is displayed")
}
fun cancelInstallAddon() = cancelInstall()
fun acceptPermissionToInstallAddon() = allowPermissionToInstall()
fun verifyAddonsItems() {
+ Log.i(TAG, "verifyAddonsItems: Trying to verify that the \"Recommended\" heading is visible")
onView(allOf(withId(R.id.title), withText("Recommended")))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyAddonsItems: Verified that the \"Recommended\" heading is visible")
+ Log.i(TAG, "verifyAddonsItems: Trying to verify that all uBlock Origin items are completely displayed")
onView(
allOf(
isAssignableFrom(RelativeLayout::class.java),
@@ -176,11 +196,12 @@ class SettingsSubMenuAddonsManagerRobot {
hasDescendant(withId(R.id.add_button)),
),
).check(matches(isCompletelyDisplayed()))
+ Log.i(TAG, "verifyAddonsItems: Verified that all uBlock Origin items are completely displayed")
}
fun verifyAddonCanBeInstalled(addonName: String) {
scrollToElementByText(addonName)
mDevice.waitNotNull(Until.findObject(By.text(addonName)), waitingTime)
-
+ Log.i(TAG, "verifyAddonCanBeInstalled: Trying to verify that the install $addonName button is visible")
onView(
allOf(
withId(R.id.add_button),
@@ -194,11 +215,14 @@ class SettingsSubMenuAddonsManagerRobot {
),
),
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ Log.i(TAG, "verifyAddonCanBeInstalled: Verified that the install $addonName button is visible")
}
fun selectAllowInPrivateBrowsing() {
assertUIObjectExists(itemWithText("Allow in private browsing"), waitingTime = waitingTimeLong)
+ Log.i(TAG, "selectAllowInPrivateBrowsing: Trying to click the \"Allow in private browsing\" check box")
onView(withId(R.id.allow_in_private_browsing)).click()
+ Log.i(TAG, "selectAllowInPrivateBrowsing: Clicked the \"Allow in private browsing\" check box")
}
fun installAddon(addonName: String, activityTestRule: HomeActivityIntentTestRule) {
@@ -214,8 +238,9 @@ class SettingsSubMenuAddonsManagerRobot {
class Transition {
fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
- fun goBackButton() = onView(allOf(withContentDescription("Navigate up")))
- goBackButton().click()
+ Log.i(TAG, "goBack: Trying to click navigate up toolbar button")
+ onView(allOf(withContentDescription("Navigate up"))).click()
+ Log.i(TAG, "goBack: Clicked the navigate up toolbar button")
HomeScreenRobot().interact()
return HomeScreenRobot.Transition()
@@ -226,19 +251,12 @@ class SettingsSubMenuAddonsManagerRobot {
interact: SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.() -> Unit,
): SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.Transition {
scrollToElementByText(addonName)
-
- onView(
- allOf(
- withId(R.id.add_on_item),
- hasDescendant(
- allOf(
- withId(R.id.add_on_name),
- withText(addonName),
- ),
- ),
- ),
- ).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
- .perform(click())
+ Log.i(TAG, "openDetailedMenuForAddon: Trying to verify that the $addonName add-on is visible")
+ addonItem(addonName).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ Log.i(TAG, "openDetailedMenuForAddon: Verified that the $addonName add-on is visible")
+ Log.i(TAG, "openDetailedMenuForAddon: Trying to click the $addonName add-on")
+ addonItem(addonName).perform(click())
+ Log.i(TAG, "openDetailedMenuForAddon: Clicked the $addonName add-on")
SettingsSubMenuAddonsManagerAddonDetailedMenuRobot().interact()
return SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.Transition()
@@ -255,17 +273,22 @@ class SettingsSubMenuAddonsManagerRobot {
)
private fun cancelInstall() {
- onView(allOf(withId(R.id.deny_button), withText("Cancel")))
- .check(matches(isCompletelyDisplayed()))
- .perform(click())
+ Log.i(TAG, "cancelInstall: Trying to verify that the \"Cancel\" button is completely displayed")
+ onView(allOf(withId(R.id.deny_button), withText("Cancel"))).check(matches(isCompletelyDisplayed()))
+ Log.i(TAG, "cancelInstall: Verified that the \"Cancel\" button is completely displayed")
+ Log.i(TAG, "cancelInstall: Trying to click the \"Cancel\" button")
+ onView(allOf(withId(R.id.deny_button), withText("Cancel"))).perform(click())
+ Log.i(TAG, "cancelInstall: Clicked the \"Cancel\" button")
}
private fun allowPermissionToInstall() {
mDevice.waitNotNull(Until.findObject(By.text("Add")), waitingTime)
-
- onView(allOf(withId(R.id.allow_button), withText("Add")))
- .check(matches(isCompletelyDisplayed()))
- .perform(click())
+ Log.i(TAG, "allowPermissionToInstall: Trying to verify that the \"Add\" button is completely displayed")
+ onView(allOf(withId(R.id.allow_button), withText("Add"))).check(matches(isCompletelyDisplayed()))
+ Log.i(TAG, "allowPermissionToInstall: Verified that the \"Add\" button is completely displayed")
+ Log.i(TAG, "allowPermissionToInstall: Trying to click the \"Add\" button")
+ onView(allOf(withId(R.id.allow_button), withText("Add"))).perform(click())
+ Log.i(TAG, "allowPermissionToInstall: Clicked the \"Add\" button")
}
}
@@ -274,5 +297,18 @@ fun addonsMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): Settings
return SettingsSubMenuAddonsManagerRobot.Transition()
}
+private fun addonItem(addonName: String) =
+ onView(
+ allOf(
+ withId(R.id.add_on_item),
+ hasDescendant(
+ allOf(
+ withId(R.id.add_on_name),
+ withText(addonName),
+ ),
+ ),
+ ),
+ )
+
private fun addonsList() =
UiScrollable(UiSelector().resourceId("$packageName:id/add_ons_list")).setAsVerticalList()
From 29a03ae52c5400a5771955d601b6847c2b5321ad Mon Sep 17 00:00:00 2001
From: github-actions
Date: Sat, 17 Feb 2024 00:03:19 +0000
Subject: [PATCH 235/586] Import translations from android-l10n
---
.../menu/src/main/res/values-eu/strings.xml | 2 ++
.../addons/src/main/res/values-cs/strings.xml | 18 ++++++++---
.../src/main/res/values-es-rCL/strings.xml | 2 ++
.../addons/src/main/res/values-eu/strings.xml | 20 +++++++++---
.../src/main/res/values-hsb/strings.xml | 2 ++
.../addons/src/main/res/values-it/strings.xml | 2 ++
.../addons/src/main/res/values-iw/strings.xml | 2 ++
.../addons/src/main/res/values-kk/strings.xml | 2 ++
.../addons/src/main/res/values-ko/strings.xml | 2 ++
.../addons/src/main/res/values-nl/strings.xml | 2 ++
.../src/main/res/values-pt-rBR/strings.xml | 2 ++
.../addons/src/main/res/values-ru/strings.xml | 2 ++
.../addons/src/main/res/values-si/strings.xml | 14 ++++++---
.../addons/src/main/res/values-sk/strings.xml | 2 ++
.../addons/src/main/res/values-sl/strings.xml | 4 +++
.../addons/src/main/res/values-ug/strings.xml | 2 ++
.../addons/src/main/res/values-vi/strings.xml | 2 ++
.../src/main/res/values-zh-rTW/strings.xml | 2 ++
fenix/app/src/main/res/values-azb/strings.xml | 31 +++++++++++++++++++
fenix/app/src/main/res/values-hu/strings.xml | 3 ++
20 files changed, 103 insertions(+), 15 deletions(-)
diff --git a/android-components/components/browser/menu/src/main/res/values-eu/strings.xml b/android-components/components/browser/menu/src/main/res/values-eu/strings.xml
index 5af09d05063f..10454c5e30e9 100644
--- a/android-components/components/browser/menu/src/main/res/values-eu/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-eu/strings.xml
@@ -10,4 +10,6 @@
Gehigarrien kudeatzaileaNabigatu gora
+
+ Gehigarriak, nabigatu gora
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 cbe8ac84b286..cbeb480b6608 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
@@ -137,13 +137,17 @@
Zrušit
- Nainstalovat doplněk
+ Nainstalovat doplněk
+
+ Nainstalovat %1$sZrušitRecenze: %1$s
- %1$.02f z 5
+ %1$.02f z 5
+
+ Hodnocení: %1$.02f z 5Doplňky
@@ -244,10 +248,14 @@
Stav:Doplněk %1$s byl přidán do aplikace %2$s
-
- Otevřete ho v nabídce
+
+ Otevřete ho v nabídce
+
+ Přístup k doplňku %1$s získáte z nabídky %2$s.
+
+ Ok, rozumím
- Ok, rozumím
+ OKZjistit více
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 894606736690..07f83182eacc 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
@@ -98,6 +98,8 @@
Permitir en navegación privadaEjecutar en navegación privada
+
+ No permitido en ventanas privadasActivado
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 8c06d98ceeb5..44fdf123234f 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
@@ -98,6 +98,8 @@
Baimendu nabigatze pribatuanExekutatu nabigatze pribatuan
+
+ Ez da leiho pribatuetan onartzenGaituta
@@ -137,13 +139,17 @@
Utzi
- Instalatu gehigarria
+ Instalatu gehigarria
+
+ Instalatu %1$sUtziBalorazioak: %1$s
- 5/%1$.02f
+ 5/%1$.02f
+
+ Balorazioa: 5etik %1$.02fGehigarriak
@@ -244,10 +250,14 @@
Egoera:%1$s hedapena %2$s(e)ra gehitu da
-
- Ireki hedapena menuan
+
+ Ireki hedapena menuan
+
+ Atzitu %1$s %2$s menutik.
+
+ Ados, ulertuta
- Ados, ulertuta
+ AdosArgibide gehiago
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 9b6cbc4f1af5..a578697560cc 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
@@ -98,6 +98,8 @@
W priwatnym modusu dowolićW priwatnym modusu wuwjesć
+
+ W priwatnych woknach njedowolenyZmóžnjeny
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 39a41b5100b2..64303a70c771 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
@@ -98,6 +98,8 @@
Consenti in navigazione anonimaEsegui in navigazione anonima
+
+ Disattivata in finestre anonimeAttivi
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 290acb190ead..3b5bf7f93608 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
@@ -98,6 +98,8 @@
לאפשר בגלישה פרטיתהפעלה בגלישה פרטית
+
+ לא מופעלת בחלונות פרטייםמופעל
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 c1363aadcdd5..9816650d4381 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
@@ -98,6 +98,8 @@
Жекелік шолу режимінде рұқсат етуЖекелік шолу режимінде жөнелту
+
+ Жекелік шолу терезелерінде рұқсат етілмегенІске қосылған
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 5048edba07df..fddc301ec414 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
@@ -98,6 +98,8 @@
사생활 보호 모드에서 허용사생활 보호 모드에서 실행
+
+ 사생활 보호 창에서 허용 안 됨사용함
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 ae5236dd1f86..4cb320a4d623 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
@@ -98,6 +98,8 @@
Toestaan tijdens privénavigatieUitvoeren tijdens privénavigatie
+
+ Niet toegestaan in privévenstersIngeschakeld
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 49f9cd103e59..657c1b488473 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
@@ -98,6 +98,8 @@
Permitir na navegação privativaAtivar na navegação privativa
+
+ Não permitido em janelas privativasAtivado
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 54618d79cfa5..85deeecc6422 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
@@ -98,6 +98,8 @@
Разрешено в приватных окнахЗапуск в приватных окнах
+
+ Не разрешено в приватных окнахВключено
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 a98bbc4f23eb..5aa89f9fe570 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
@@ -135,13 +135,15 @@
අවලංගු
- එක්කහුව ස්ථාපනය
+ එක්කහුව ස්ථාපනය
+
+ %1$s ස්ථාපනය කරන්නඅවලංගුසමාලෝචන: %1$s
- %1$.02f/5
+ %1$.02f/5එක්කහු
@@ -242,10 +244,12 @@
තත්වය:%2$s වෙත %1$s එක් කර ඇත
-
- වට්ටෝරුවෙහි එය අරින්න
+
+ වට්ටෝරුවෙහි එය අරින්න
- හරි, තේරුණා
+ හරි, තේරුණා
+
+ හරිතව දැනගන්න
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 153fafe94e66..d3ca7c4b7ee6 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
@@ -98,6 +98,8 @@
Povoliť v súkromnom prehliadaníSpustiť v súkromnom prehliadaní
+
+ Doplnok nie je povolený v súkromných oknáchPovolené
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 d19e83bc9d5c..41c8811d9693 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
@@ -98,6 +98,8 @@
Dovoli v zasebnem brskanjuZaženi v zasebnem brskanju
+
+ Ni dovoljeno v zasebnih oknihOmogočeno
@@ -144,6 +146,8 @@
Ocen: %1$s%1$.02f/5
+
+ Ocena: %1$.02f od 5Dodatki
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 2fbc935821c5..5ae9e80b1f1a 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
@@ -98,6 +98,8 @@
شەخسىي زىيارەت ھالىتىگە يول قويىدۇشەخسىي زىيارەت ھالىتىنى قوزغىتىدۇ
+
+ شەخسىي كۆزنەكتە ئىجرا قىلىشقا يول قويمايدۇقوزغىتىلدى
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 22eb0e6280e2..e1056994a4d9 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
@@ -98,6 +98,8 @@
Cho phép trong duyệt web riêng tưCho phép trong thẻ riêng tư
+
+ Không được phép trong cửa sổ riêng tưĐã bật
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 783c139327d5..68197e947e4c 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
@@ -98,6 +98,8 @@
允許在隱私瀏覽模式執行在隱私瀏覽模式執行
+
+ 不允許於隱私視窗運作啟用
diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml
index 8bf0f3303cce..033094275637 100644
--- a/fenix/app/src/main/res/values-azb/strings.xml
+++ b/fenix/app/src/main/res/values-azb/strings.xml
@@ -792,17 +792,30 @@
ایشه آلما و فنی دیتالار
+
+ %1$s داها یاخچیْ ائتمک اوچون موُروچونوز حاقیندا ایشلهییش،ایشه آلما، دوْنانیم و اؤزللشدیرمه دیتالارینی موزیلا ایله پایلاشیر.بازارلاما دیتاسیْ
+
+ اساس ایشه آلما بیلگیلرینی موبایل بازارلاما ایش اوْرتاغیمیز Adjust ایله پایلاشیر.آراشدیرمالار
+
+ موزیلایا آراشدیرمالار قوْشماغینا و ایجرا ائتمهسینه ایجازه وئریر.
+
دیتالارینیزیْ دؤنگل ائدین و ساخلایین
+
+ یئنیدن باغلانماق اوچون گیریش ائدینحساب قالدیْر
+
+
+ firefox.com/pair آدرسینه گؤرونن QR کوْدونو اسکن ائلهیین]]>
+
اوست
@@ -817,6 +830,9 @@
باتری ساخلیان طرفیندن تنظیملنیر
+
+ جهاز تمینی نظره آل
+
رفرش اوچون چک
@@ -824,6 +840,11 @@
آلتلر چوبوغونو گیزلتمک اوچون اسکرول ائله
+
+ تاغلاریْ دگیشدیرمک اوچون ادوات چوُبوغونو یانالار طرف چکین
+
+ تاغلاریْ آچماق اوچون ادوات چوُبوغونو یوخاریا چکین
+
یئندیرنلر
@@ -835,6 +856,10 @@
دستکتاپ بوکمارکلاریْبوکمارک منوسو
+
+ بوکمارکلار ادوات چوبوغو
+
+ باشقا بوکمارکلارگئچمیش
@@ -844,6 +869,12 @@
باغلا
+
+ %d آچیلسین؟
+
+ چوْخلو تاغلاریْن آچیلماسیْ صفحهلر دوْلورکن %s سوُرعتینی یاواشلاتا بیلر. ایدامه وئرمهگه آرخایینسیز؟تاغلاریْ آچ
diff --git a/fenix/app/src/main/res/values-hu/strings.xml b/fenix/app/src/main/res/values-hu/strings.xml
index 3ffd638ea8a7..fad21e3e8ee2 100644
--- a/fenix/app/src/main/res/values-hu/strings.xml
+++ b/fenix/app/src/main/res/values-hu/strings.xml
@@ -2184,6 +2184,9 @@
%s keresés
+
+ Az alapértelmezett böngésző módosítása
+
Állítsa be a webhelyek, e-mailek és üzenetek hivatkozásait, hogy azok automatikusan a Firefoxban nyíljanak meg.
From 78f966cd69a9c2eb18c28203c1e7648b5ac42aeb Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Sat, 17 Feb 2024 02:22:41 +0000
Subject: [PATCH 236/586] Update GeckoView (Nightly) to 124.0.20240216212328.
---
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 b403375f2501..033ebfb6ab84 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.20240216094648"
+ const val version = "124.0.20240216212328"
/**
* GeckoView channel
From 041854d19189ecbf5ab96711e21cedc78ca11ac0 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Sun, 18 Feb 2024 00:03:49 +0000
Subject: [PATCH 237/586] Import translations from android-l10n
---
.../src/main/res/values-pa-rIN/strings.xml | 2 ++
.../menu/src/main/res/values-sq/strings.xml | 2 ++
.../src/main/res/values-dsb/strings.xml | 2 ++
.../addons/src/main/res/values-fi/strings.xml | 2 ++
.../addons/src/main/res/values-ia/strings.xml | 16 ++++++---
.../src/main/res/values-pa-rIN/strings.xml | 20 ++++++++---
.../src/main/res/values-pt-rPT/strings.xml | 2 +-
.../addons/src/main/res/values-sq/strings.xml | 22 +++++++++---
.../addons/src/main/res/values-tg/strings.xml | 2 ++
.../addons/src/main/res/values-tr/strings.xml | 2 ++
.../media/src/main/res/values-sq/strings.xml | 11 ++++--
.../src/main/res/values-pt-rPT/strings.xml | 2 +-
.../src/main/res/values-sq/strings.xml | 36 +++++++++++++++++++
.../src/main/res/values-pt-rPT/strings.xml | 2 +-
fenix/app/src/main/res/values-sq/strings.xml | 19 +++++++---
fenix/app/src/main/res/values-tg/strings.xml | 2 ++
.../app/src/main/res/values-sq/strings.xml | 7 ++--
17 files changed, 121 insertions(+), 30 deletions(-)
diff --git a/android-components/components/browser/menu/src/main/res/values-pa-rIN/strings.xml b/android-components/components/browser/menu/src/main/res/values-pa-rIN/strings.xml
index 10a249568719..f3de60c315c6 100644
--- a/android-components/components/browser/menu/src/main/res/values-pa-rIN/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-pa-rIN/strings.xml
@@ -10,4 +10,6 @@
ਐਡ-ਆਨ ਮੈਨੇਜਰਉੱਤੇ ਜਾਓ
+
+ ਐਡ-ਆਨ, ਉੱਤੇ
diff --git a/android-components/components/browser/menu/src/main/res/values-sq/strings.xml b/android-components/components/browser/menu/src/main/res/values-sq/strings.xml
index 0e804ee33c97..3347a1e66ef5 100644
--- a/android-components/components/browser/menu/src/main/res/values-sq/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-sq/strings.xml
@@ -10,4 +10,6 @@
Përgjegjës ShtesashLëvizni për sipër
+
+ Shtesa, shkoni sipër
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 936713d81595..f8802aebffc7 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
@@ -98,6 +98,8 @@
W priwatnem modusu dowóliśW priwatnem modusu wuwjasć
+
+ W priwatnych woknach njedowólonyZmóžnjony
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 294422dd51b5..b5498092f353 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
@@ -98,6 +98,8 @@
Salli yksityisessä selauksessaSuorita yksityisessä selauksessa
+
+ Ei sallittu yksityisissä ikkunoissaKäytössä
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 c8c8a5cf6e62..25558ed54892 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
@@ -98,6 +98,8 @@
Permitter in navigation privateExequer in navigation private
+
+ Non permittite in fenestras privateActivate
@@ -137,13 +139,15 @@
Cancellar
- Installar additivo
+ Installar additivo
+
+ Installar %1$sCancellarRecensiones: %1$s
- %1$.02f/5
+ %1$.02f/5Additivos
@@ -244,10 +248,12 @@
Stato:%1$s ha essite addite a %2$s.
-
- Aperi lo in le menu
+
+ Aperi lo in le menu
- OK, io lo comprende
+ OK, io lo comprende
+
+ OKPro saper plus
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 9c057cc095bb..0f6bca88d477 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
@@ -98,6 +98,8 @@
ਨਿੱਜੀ ਬਰਾਊਜ਼ਿੰਗ ਵਿੱਚ ਮਨਜ਼ੂਰ ਕਰੋਨਿੱਜੀ ਬਰਾਊਜ਼ਿੰਗ ਚ ਚਲਾਓ
+
+ ਪ੍ਰਾਈਵੇਟ ਵਿੰਡੋਆਂ ਵਿੱਚ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈਸਮਰੱਥ ਹੈ
@@ -137,13 +139,17 @@
ਰੱਦ ਕਰੋ
- ਐਡ-ਆਨ ਇੰਸਟਾਲ ਕਰੋ
+ ਐਡ-ਆਨ ਇੰਸਟਾਲ ਕਰੋ
+
+ %1$s ਨੂੰ ਇੰਸਟਾਲ ਕਰੋਰੱਦ ਕਰੋਰੀਵਿਊ: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ ਰੇਟਿੰਗ: 5 ਵਿੱਚੋਂ %1$.02fਐਡ-ਆਨ
@@ -244,10 +250,14 @@
ਹਾਲਤ:%1$s ਨੂੰ %2$s ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ ਹੈ
-
- ਇਸਨੂੰ ਮੇਨੂ ਵਿੱਚ ਖੋਲ੍ਹੋ
+
+ ਇਸਨੂੰ ਮੇਨੂ ਵਿੱਚ ਖੋਲ੍ਹੋ
+
+ %2$s ਮੇਨੂ ਵਿੱਚੋਂ %1$s ਪਹੁੰਚ
+
+ ਠੀਕ ਹੈ, ਸਮਝ ਗਏ
- ਠੀਕ ਹੈ, ਸਮਝ ਗਏ
+ ਠੀਕ ਹੈਹੋਰ ਜਾਣੋ
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 46e17c443f0c..5caa370b58cd 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
@@ -257,7 +257,7 @@
Ok, entendi
- OK
+ OkSaber mais
diff --git a/android-components/components/feature/addons/src/main/res/values-sq/strings.xml b/android-components/components/feature/addons/src/main/res/values-sq/strings.xml
index d4ca1007753b..343de2bbebe7 100644
--- a/android-components/components/feature/addons/src/main/res/values-sq/strings.xml
+++ b/android-components/components/feature/addons/src/main/res/values-sq/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. -->
Të hyjë në të dhënat tuaja te %1$d përkatësi të tjera
+
+ %1$s, %2$d nga %3$dTë hyjë në skeda shfletuesi
@@ -96,6 +98,8 @@
Lejoje në shfletim privatXhiroje në shfletim privat
+
+ Nuk lejohet në dritare privateE aktivizuar
@@ -135,13 +139,17 @@
Anuloje
- Instaloni Shtesë
+ Instaloni Shtesë
+
+ Instaloni %1$sAnulojeShqyrtime: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Vlerësim: %1$.02f nga 5 gjithsejShtesa
@@ -242,10 +250,14 @@
Gjendje:%1$s u shtua te %2$s
-
- Hape te menuja
+
+ Hape te menuja
+
+ Përdoreni %1$s që nga menuja %2$s.
+
+ OK, E Mora Vesh
- OK, E Mora Vesh
+ OKMësoni më tepër
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 2f59a7381e49..414a51f83aa5 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
@@ -98,6 +98,8 @@
Иҷозат додан дар тамошокунии хусусӣИҷро кардан дар тамошокунии хусусӣ
+
+ Дар равзанаҳои хусусӣ иҷозат дода намешавадФаъол аст
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 0ce97dd83cff..e290797f50ff 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
@@ -98,6 +98,8 @@
Gizli gezintide izin verGizli gezintide çalıştır
+
+ Gizli pencerelerde izin verilmiyorEtkin
diff --git a/android-components/components/feature/media/src/main/res/values-sq/strings.xml b/android-components/components/feature/media/src/main/res/values-sq/strings.xml
index 5b52ac9bd2ea..dc685d267b93 100644
--- a/android-components/components/feature/media/src/main/res/values-sq/strings.xml
+++ b/android-components/components/feature/media/src/main/res/values-sq/strings.xml
@@ -1,5 +1,5 @@
-
+Media
@@ -21,9 +21,14 @@
Kujtues: %1$s ende po përdor kamerën tuaj. Prekeni që të hapet skeda.
- Kujtues: %1$s ende po përdor mikrofonin tuaj. Prekeni që të hapet skeda
+ Kujtues: %1$s ende po përdor mikrofonin tuaj. Prekeni që të hapet skeda
+
+ Kujtues: %1$s ende po përdor mikrofonin tuaj. Prekeni që të hapet skeda.
+
+ Kujtues: %1$s ende po përdor mikrofonin dhe skedën tuaj. Prekeni që të hapet skeda
+
- Kujtues: %1$s ende po përdor mikrofonin dhe skedën tuaj. Prekeni që të hapet skeda
+ Kujtues: %1$s ende po përdor mikrofonin dhe skedën tuaj. Prekeni që të hapet skeda.Luaje
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 72001b57aee7..42564fdfe1f2 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
@@ -98,7 +98,7 @@
Gerir credenciais
- Gerir palavras-passe
+ Gerir palavras-passesExpandir credenciais sugeridas
diff --git a/android-components/components/feature/prompts/src/main/res/values-sq/strings.xml b/android-components/components/feature/prompts/src/main/res/values-sq/strings.xml
index a18417ac6bd7..8a5a8bcaff61 100644
--- a/android-components/components/feature/prompts/src/main/res/values-sq/strings.xml
+++ b/android-components/components/feature/prompts/src/main/res/values-sq/strings.xml
@@ -18,6 +18,8 @@
FjalëkalimMos e ruaj
+
+ Jo taniMos e ruaj kurrë
@@ -26,16 +28,26 @@
RuajeMos e përditëso
+
+ Jo taniPërditësojeFusha e fjalëkalimit s’duhet të jetë e zbrazët
+ Jepni një fjalëkalim
+
S’arrihet të ruhen kredenciale hyrjesh
+
+ S’ruhet dot fjalëkalimiTë ruhen këto kredenciale hyrjesh?
+
+ Të ruhet fjalëkalimi?Të përditësohen këto kredenciale hyrjesh?
+
+ Të përditësohet fjalëkalimi?Të shtohet emri i përdoruesit te fjalëkalimi i ruajtur?
@@ -85,13 +97,22 @@
Ujdisni kohënAdministroni kredenciale hyrjesh
+
+ Administroni fjalëkalimeZgjeroji kredencialet e sugjeruara të hyrjeve
+
+ Zgjero fjalëkalimet e ruajturTkurri kredencialet e sugjeruara të hyrjeve
+
+ Tkurri fjalëkalimet e ruajturKredenciale të sugjeruara hyrjesh
+
+ Fjalëkalime të ruajtur
+
Sugjero fjalëkalim të fuqishëm
@@ -110,13 +131,21 @@
Përzgjidhni kartë krediti
+
+ Përdor kartë të ruajturZgjero karta kreditit të sugjeruara
+
+ Zgjero karta të ruajturaTkurri kartat e kreditit të sugjeruara
+
+ Tkurri kartat e ruajturaAdministroni karta krediti
+
+ Administroni kartaTë ruhet në mënyrë të sigurt kjo kartë?
@@ -124,13 +153,20 @@
Numri i kartës do të fshehtëzohet. Kodi i sigurisë s’do të ruhet.
+
+ %s-i e fshehtëzon numrin e kartës tuaj. Kodi juaj i sigurisë s’do të ruhet.
+
Përzgjidhni adresëZgjeroji adresat e sugjeruara
+
+ Zgjeroji adresat e ruajturaTkurri adresat e sugjeruara
+
+ Tkurri adresat e ruajturaAdministroni adresa
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 1885805a741c..374c48d065e6 100644
--- a/fenix/app/src/main/res/values-pt-rPT/strings.xml
+++ b/fenix/app/src/main/res/values-pt-rPT/strings.xml
@@ -2439,7 +2439,7 @@
Tradução em curso
- Escolha um idioma
+ Escolher um idiomaOcorreu um problema com a tradução. Por favor, tente novamente.
diff --git a/fenix/app/src/main/res/values-sq/strings.xml b/fenix/app/src/main/res/values-sq/strings.xml
index ea099419b54e..84f7179329e1 100644
--- a/fenix/app/src/main/res/values-sq/strings.xml
+++ b/fenix/app/src/main/res/values-sq/strings.xml
@@ -242,6 +242,7 @@
Përshtatni faqe hyrëse
+
Skena e kreut
@@ -249,6 +250,9 @@
Fshi historik shfletimesh
+
+ Përktheje faqen
+
Gjuha e përzgjedhur
@@ -1875,7 +1879,7 @@
Ujdisni një rregullsi, PIN, ose fjalëkalim kyçjeje pajisjeje për të mbrojtur nga hyrja në to kartat tuaja kreditit të ruajturar, nëse pajisjen tuaj e ka dikush tjetër.
- Ujdisni një rregullsi, PIN, ose fjalëkalim kyçjeje pajisjeje për të mbrojtur prej hyrjes në to hollësitë e ruajtura për kartat tuaja, nëse pajisjen tuaj e ka dikush tjetër.
+ Ujdisni një rregullsi, PIN, ose fjalëkalim kyçjeje pajisjeje për të mbrojtur prej hyrjes në to hollësitë e ruajtura për metodat tuaja të pagesave, nëse pajisjen tuaj e ka dikush tjetër.Ujdiseni tani
@@ -2035,12 +2039,12 @@
Mundësi fjalëkalimeshFusha e përpunueshme e teksteve për adresën web të kredencialeve të hyrjes.
-
- Fusha e përpunueshme e teksteve për adresën web të fjalëkalimit.
+
+ Fusha e përpunueshme e teksteve për adresën e sajtit.Fusha e përpunueshme e teksteve për emrin e përdoruesit të kredencialeve të hyrjes.
-
- Fusha e përpunueshme e teksteve për emrin e përdoruesit të fjalëkalimit.
+
+ Fusha e përpunueshme e teksteve për emrin e përdoruesit.Fusha e përpunueshme e teksteve për fjalëkalimin e kredencialeve të hyrjes.
@@ -2165,6 +2169,9 @@
Kërkim me %s
+
+ Ndërroni shfletuesin tuaj parazgjedhje
+
Caktoni lidhje prej sajtesh, email-esh dhe mesazhezh për hapje të automatizuar në Firefox.
@@ -2423,6 +2430,8 @@
Përkthim Në Kryerje e Sipër
+
+ Zgjidhni një gjuhëPati një problem me përkthimin. Ju lutemi, riprovoni.
diff --git a/fenix/app/src/main/res/values-tg/strings.xml b/fenix/app/src/main/res/values-tg/strings.xml
index 4ae0da3cfc30..72a7668f9f53 100644
--- a/fenix/app/src/main/res/values-tg/strings.xml
+++ b/fenix/app/src/main/res/values-tg/strings.xml
@@ -1773,6 +1773,8 @@
Ниҳонвожаҳои нигоҳдоштаро муҳофизат намоедБарои муҳофизат кардани воридшавиҳо ва ниҳонвожаҳои худ аз дастрасии озод, агар касе дигар аз дастгоҳи шумо истифода барад, шаклвораи қулфи экран, рамзи PIN ё ниҳонвожаеро барои дастгоҳи худ танзим намоед.
+
+ Барои муҳофизат кардани ниҳонвожаҳои нигоҳдошташудаи худ аз дастрасии озод, агар касе дигар аз дастгоҳи шумо истифода барад, шаклвораи қулфи экран, рамзи PIN ё ниҳонвожаеро барои дастгоҳи худ танзим намоед.Дертар
diff --git a/focus-android/app/src/main/res/values-sq/strings.xml b/focus-android/app/src/main/res/values-sq/strings.xml
index 7a0572918fad..ae4fa6fe3a18 100644
--- a/focus-android/app/src/main/res/values-sq/strings.xml
+++ b/focus-android/app/src/main/res/values-sq/strings.xml
@@ -83,10 +83,9 @@
sharing an URL. -->
Ndajeni përmes
-
+ Të fshihet historik shfletimesh?
+ Që të fshihet në mënyrë të siguruar historiku juaj i shfletimit, prekeni, ose spastrojeni këtë njoftim.
+
Fshini historik shfletimesh
From 2efded92c125169293c09a2ec9667f35ac5ab0e4 Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Sun, 18 Feb 2024 01:51:21 +0000
Subject: [PATCH 238/586] Update GeckoView (Nightly) to 124.0.20240217214641.
---
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 033ebfb6ab84..8408f36ce312 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.20240216212328"
+ const val version = "124.0.20240217214641"
/**
* GeckoView channel
From ba6beea45bb884bc4faab05eea8e9ecc9f7d6c76 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Mon, 19 Feb 2024 00:03:26 +0000
Subject: [PATCH 239/586] Import translations from android-l10n
---
.../src/main/res/values-es-rES/strings.xml | 2 +
.../menu/src/main/res/values-is/strings.xml | 2 +
.../menu/src/main/res/values-oc/strings.xml | 2 +
.../addons/src/main/res/values-br/strings.xml | 16 ++-
.../src/main/res/values-es-rES/strings.xml | 22 ++-
.../addons/src/main/res/values-is/strings.xml | 20 ++-
.../addons/src/main/res/values-oc/strings.xml | 20 ++-
.../src/main/res/values-es-rES/strings.xml | 11 +-
.../src/main/res/values-es-rES/strings.xml | 36 +++++
.../src/main/res/values-es-rES/strings.xml | 134 ++++++++++++------
fenix/app/src/main/res/values-oc/strings.xml | 3 +
11 files changed, 203 insertions(+), 65 deletions(-)
diff --git a/android-components/components/browser/menu/src/main/res/values-es-rES/strings.xml b/android-components/components/browser/menu/src/main/res/values-es-rES/strings.xml
index 06d3f3f85570..ee0e7a88adfc 100644
--- a/android-components/components/browser/menu/src/main/res/values-es-rES/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-es-rES/strings.xml
@@ -10,4 +10,6 @@
Administrador de complementosNavegar hacia arriba
+
+ Complementos, navega hacia arriba
diff --git a/android-components/components/browser/menu/src/main/res/values-is/strings.xml b/android-components/components/browser/menu/src/main/res/values-is/strings.xml
index 7eade3d9ab41..55f95706f127 100644
--- a/android-components/components/browser/menu/src/main/res/values-is/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-is/strings.xml
@@ -10,4 +10,6 @@
ViðbótastjóriFlakka upp
+
+ Viðbætur, fara upp
diff --git a/android-components/components/browser/menu/src/main/res/values-oc/strings.xml b/android-components/components/browser/menu/src/main/res/values-oc/strings.xml
index 07db23d5f203..245edcce1122 100644
--- a/android-components/components/browser/menu/src/main/res/values-oc/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-oc/strings.xml
@@ -10,4 +10,6 @@
Gestionari de moduls complementarisRemontar
+
+ Moduls complementaris, montar
diff --git a/android-components/components/feature/addons/src/main/res/values-br/strings.xml b/android-components/components/feature/addons/src/main/res/values-br/strings.xml
index 154d3f70d3d2..afd8b1f8a569 100644
--- a/android-components/components/feature/addons/src/main/res/values-br/strings.xml
+++ b/android-components/components/feature/addons/src/main/res/values-br/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. -->
Haeziñ ho roadennoù war %1$d a zomanioù all
+
+ %1$s, %2$d diwar %3$dHaeziñ ivinelloù ar merdeer
@@ -135,13 +137,15 @@
Nullañ
- Staliañ an askouezh
+ Staliañ an askouezh
+
+ Staliañ %1$sNullañBurutelladennoù: %1$s
- %1$.02f/5
+ %1$.02f/5Askouezhioù
@@ -236,10 +240,12 @@
Stad:Ouzhpennet eo bet %1$s da %2$s.
-
- Digeriñ anezhañ el lañser
+
+ Digeriñ anezhañ el lañser
- Mat eo, komprenet am eus
+ Mat eo, komprenet am eus
+
+ Mat eoGouzout hiroc’h
diff --git a/android-components/components/feature/addons/src/main/res/values-es-rES/strings.xml b/android-components/components/feature/addons/src/main/res/values-es-rES/strings.xml
index a6252ab57716..75611b757341 100644
--- a/android-components/components/feature/addons/src/main/res/values-es-rES/strings.xml
+++ b/android-components/components/feature/addons/src/main/res/values-es-rES/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$dAcceder a las pestañas del navegador
@@ -75,7 +77,7 @@
Autor
- Autores
+ AutoresÚltima actualización
@@ -135,13 +137,17 @@
Cancelar
- Instalar complemento
+ Instalar complemento
+
+ Instalar %1$sCancelarRevisiones: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Calificación: %1$.02f de 5Complementos
@@ -242,10 +248,14 @@
Estado:%1$s ha sido añadido a %2$s
-
- Ábrelo en el menú
+
+ Ábrelo en el menú
+
+ Accede a %1$s desde el menú %2$s.
+
+ Vale, entendido
- Vale, entendido
+ AceptarSaber más
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 965080b8f789..7fc046ada64a 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
@@ -98,6 +98,8 @@
Leyfa í huliðsvafriKeyra í huliðsvafri
+
+ Ekki leyfilegt í huliðsgluggumVirk
@@ -137,13 +139,17 @@
Hætta við
- Setja inn viðbót
+ Setja inn viðbót
+
+ Setja upp %1$sHætta viðUmsagnir: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Einkunn: %1$.02f af 5Viðbætur
@@ -244,10 +250,14 @@
Staða:%1$s hefur verið bætt við %2$s
-
- Opnaðu það í valmyndinni
+
+ Opnaðu það í valmyndinni
+
+ Finndu %1$s í %2$s valmyndinni.
+
+ Allt í lagi, ég skil
- Allt í lagi, ég skil
+ Í lagiFrekari upplýsingar
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 3efbf0284503..148f506c1131 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
@@ -98,6 +98,8 @@
Autorizar en navegacion privadaExecutar en navegacion privada
+
+ Non autorizat en fenèstras privadasActivat
@@ -137,13 +139,17 @@
Anullar
- Installar lo modul
+ Installar lo modul
+
+ Installar %1$sAnullarVejaires : %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Nòta : %1$.02f de 5Moduls complementaris
@@ -244,10 +250,14 @@
Estat :%1$s es estat ajustat a %2$s.
-
- Dorbissètz-lo del menú estant
+
+ Dorbissètz-lo del menú estant
+
+ Accedissètz a %1$s a partir del menú %2$s.
+
+ Òc, plan comprés
- Òc, plan comprés
+ D\'acòrdiNe saber mai
diff --git a/android-components/components/feature/media/src/main/res/values-es-rES/strings.xml b/android-components/components/feature/media/src/main/res/values-es-rES/strings.xml
index 844681158c04..71bef26954f1 100644
--- a/android-components/components/feature/media/src/main/res/values-es-rES/strings.xml
+++ b/android-components/components/feature/media/src/main/res/values-es-rES/strings.xml
@@ -1,5 +1,5 @@
-
+Multimedia
@@ -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 tu cámara. Toca para abrir la pestaña
+
- Recordatorio: %1$s todavía está usando tu micrófono y tu cámara. Toca para abrir la pestaña
+ Recordatorio: %1$s todavía está usando tu micrófono y tu cámara. Toca para abrir la pestaña.Reproducir
diff --git a/android-components/components/feature/prompts/src/main/res/values-es-rES/strings.xml b/android-components/components/feature/prompts/src/main/res/values-es-rES/strings.xml
index e849e61f528a..2457b86e360c 100644
--- a/android-components/components/feature/prompts/src/main/res/values-es-rES/strings.xml
+++ b/android-components/components/feature/prompts/src/main/res/values-es-rES/strings.xml
@@ -18,6 +18,8 @@
ContraseñaNo guardar
+
+ Ahora noNo guardar nunca
@@ -26,16 +28,26 @@
GuardarNo actualizar
+
+ Ahora noActualizarEl campo de contraseña no puede estar vacío
+ Introduce una contraseña
+
No se puede guardar el inicio de sesión
+
+ No se ha podido guardar la contraseña¿Guardar este inicio de sesión?
+
+ ¿Guardar contraseña?¿Actualizar este inicio de sesión?
+
+ ¿Actualizar contraseña?¿Añadir nombre de usuario a la contraseña guardada?
@@ -85,13 +97,22 @@
Establecer horaAdministrar inicios de sesión
+
+ Administrar contraseñasExpandir inicios de sesión sugeridos
+
+ Expandir las contraseñas guardadasContraer inicios de sesión sugeridos
+
+ Contraer las contraseñas guardadasInicios de sesión sugeridos
+
+ Contraseñas guardadas
+
Sugerir contraseña segura
@@ -111,12 +132,20 @@
Seleccionar tarjeta de crédito
+
+ Usar tarjeta guardadaExpandir la lista de tarjetas de crédito sugeridas
+
+ Expandir tarjetas guardadasContraer la lista de tarjetas de crédito sugeridas
+
+ Contraer tarjetas guardadasAdministrar 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. Tu código de seguridad no se guardará.
+
Seleccionar direcciónExpandir direcciones sugeridas
+
+ Expandir direcciones guardadasContraer direcciones sugeridas
+
+ Contraer direcciones guardadasAdministrar direcciones
diff --git a/fenix/app/src/main/res/values-es-rES/strings.xml b/fenix/app/src/main/res/values-es-rES/strings.xml
index 05599fb3992b..5f00a5e888b5 100644
--- a/fenix/app/src/main/res/values-es-rES/strings.xml
+++ b/fenix/app/src/main/res/values-es-rES/strings.xml
@@ -247,6 +247,7 @@
Personalizar la página de inicio
+
Pantalla de inicio
@@ -254,6 +255,9 @@
Eliminar historial de navegación
+
+ Traducir página
+
Idioma seleccionado
@@ -265,8 +269,6 @@
Escanear
-
- BuscadorAjustes del buscador
@@ -322,14 +324,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
@@ -448,21 +450,11 @@
Modo solo HTTPS
-
- Reducción de avisos de cookiesBloqueador de avisos de cookiesBloqueador de avisos de cookies en navegación privada
-
- Reducir los avisos de cookies
-
- Desactivado
-
- Activado
-
-
- %1$s intenta rechazar automáticamente las solicitudes de cookies en los avisos de cookies.
+
Desactivada para este sitio
@@ -480,35 +472,16 @@
Sitio actualmente no compatible
- ¿Activar la reducción de aviso de cookies para %1$s?
-
¿Activar el bloqueo de aviso de cookies para %1$s?
- ¿Desactivar la reducción de aviso de cookies para %1$s?
-
¿Desactivar el bloqueo de aviso de cookies para %1$s?%1$s no puede rechazar automáticamente los avisos de cookies en este sitio. Puede enviar una solicitud para admitir 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.Tras desactivarlo, %1$s borrará las cookies y recargará la página. Esto puede desconectarte del sitio o vaciar tu carrito de compra.
- %1$s intenta rechazar automáticamente las solicitudes de cookies en sitios compatibles.
-
Al activarlo %1$s intentará rechazar automáticamente los avisos de cookies en este sitio.
-
- ¿Permitir que %1$s rechace los avisos de cookies?
-
- %1$s puede rechazar automáticamente muchas solicitudes de cookies.
-
- Ahora no
-
- Verás menos solicitudes de cookies
-
-
- Permitir%1$s acaba de rechazar las cookies por ti
@@ -725,6 +698,8 @@
MarcadoresInicios de sesión
+
+ ContraseñasPestañas abiertas
@@ -751,6 +726,8 @@
Tarjetas de crédito
+
+ Métodos de pagoDirecciones
@@ -1306,8 +1283,6 @@
Descartar
- No se puede imprimir
-
No se puede imprimir esta páginaImprimir
@@ -1720,8 +1695,12 @@
Inicios de sesión y contraseñas
+
+ ContraseñasGuardar inicios de sesión y contraseñas
+
+ Guardar contraseñasPreguntar antes de guardar
@@ -1740,26 +1719,45 @@
Añadir cuenta
+
+ Añadir contraseña
+
Inicios de sesión sincronizados
+
+ Sincronizar contraseñasSincronizar inicios de sesión entre dispositivos
+
+ Sincronizar contraseñas entre dispositivosInicios de sesión guardados
+
+ Contraseñas guardadasLos inicios de sesión que guardes o sincronices con %s se mostrarán aquí.
+
+ Las contraseñas que guardes o sincronices con %s aparecerán aquí. Todas las contraseñas que guardes quedan cifradas.Saber más sobre Sync.
+
+ Descubre más sobre SyncExcepcionesLos inicios de sesión y contraseñas no guardados aparecerán aquí.
+
+ %s no guardará contraseñas para los sitios que se listen aquí.No se guardarán los inicios de sesión y contraseñas para estos sitios.
+
+ %s no guardará las contraseñas para estos sitios.Eliminar todas las excepcionesBuscar inicios de sesión
+
+ Buscar contraseñasSitio
@@ -1788,10 +1786,16 @@
Ocultar contraseñaDesbloquear para ver tus inicios de sesión guardados
+
+ Desbloquea para ver tus contraseñas guardadasAsegurar tus usuarios y contraseñas
+
+ Asegura tus contraseñas guardadasConfigura un patrón de bloqueo del dispositivo, un PIN o una contraseña para proteger el acceso a tus usuarios y contraseñas guardados si alguien más tiene tu dispositivo.
+
+ Establece un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus contraseñas guardadas y evitar que sean accedidas por otras personas en caso de que alguien más tenga tu dispositivo.Más tarde
@@ -1812,6 +1816,9 @@
Ordenar menú de inicio de sesión
+
+ Menú ordenar contraseñas
+
Autocompletado
@@ -1819,11 +1826,17 @@
DireccionesTarjetas de crédito
+
+ Métodos de pagoGuardar y autocompletar tarjetas
+
+ Guardar y completar métodos de pagoLos datos están cifrados
+
+ %s cifra todos los métodos de pago que guardesSincronizar tarjetas entre dispositivos
@@ -1831,17 +1844,26 @@
Añadir tarjeta de crédito
+
+ Añadir tarjetaAdministrar tarjetas guardadas
+
+ Administrar tarjetasAñadir direcciónAdministrar direccionesGuardar y autocompletar direcciones
+
+ Guardar y completar direccionesIncluir información como números, correos electrónicos y direcciones de envío
+
+ Incluye números de teléfono y direcciones de correo electrónico
+
Añadir tarjeta
@@ -1862,6 +1884,8 @@
Eliminar tarjeta¿Seguro que quieres eliminar esta tarjeta de crédito?
+
+ ¿Eliminar tarjeta?Eliminar
@@ -1877,14 +1901,22 @@
Por favor, escriba un número válido de tarjeta de crédito
+
+ Introduce un número de tarjeta válidoPor favor, rellena este campo
+
+ Añadir un nombreDesbloquear para ver tus tarjetas guardadasAsegurar tus tarjetas de crédito
+
+ Protege tus métodos de pago guardadosConfigura un patrón de bloqueo, PIN o contraseña para proteger el acceso a tus tarjetas guardadas si alguien más accede a tu dispositivo.
+
+ Establece un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus métodos de pago guardados y evitar que sean accedidos por otras personas en caso de que alguien más tenga tu dispositivo.Configurar ahora
@@ -1894,6 +1926,8 @@
Desbloquear para usar la información de la tarjeta de crédito almacenada
+
+ Desbloquea para utilizar métodos de pago guardadosAñadir dirección
@@ -1931,6 +1965,8 @@
¿Seguro que quieres eliminar esta dirección?
+
+ ¿Eliminar esta dirección?Eliminar
@@ -2030,26 +2066,44 @@
Editar¿Seguro que quieres eliminar este inicio de sesión?
+
+ ¿Estás seguro de que quieres eliminar esta contraseña?EliminarCancelarOpciones de inicio de sesión
+
+ Opciones de contraseñaEl 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.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.El campo de texto editable para la contraseña del inicio de sesión.
+
+ El campo de texto editable para la contraseña.Guardar cambios para el inicio de sesión.
+
+ Guardar cambios.Editar
+
+ Editar contraseñaAñadir nueva cuenta
+
+ Añadir contraseñaSe necesita contraseña
+
+ Introduce una contraseñaSe requiere nombre de usuario
@@ -2149,7 +2203,7 @@
Buscar con %s
-
+
Configura enlaces de sitios web, correos electrónicos y mensajes para que se abran automáticamente en Firefox.
@@ -2223,8 +2277,6 @@
puntos destacados provienen de reseñas de %s de los últimos 80 días que creemos que son fiables.]]>Saber más sobre %s.
-
- cómo %s de Mozilla determina la calidad de las reseñascómo determina %s la calidad de las reseñas
diff --git a/fenix/app/src/main/res/values-oc/strings.xml b/fenix/app/src/main/res/values-oc/strings.xml
index 25873903b86e..923a215e3e31 100644
--- a/fenix/app/src/main/res/values-oc/strings.xml
+++ b/fenix/app/src/main/res/values-oc/strings.xml
@@ -2210,6 +2210,9 @@ Exemple :\nhttps://suggestqueries.google.com/complete/search?client=firefox&
Recèrca %s
+
+ Cambiatz vòstre navegador per defaut
+
Causir de dobrir los sites web, los corrièls e messatges automaticament dins Firefox.
From 94f8a7e8cc5a18fc7a1c9d10e647fd15a79ac952 Mon Sep 17 00:00:00 2001
From: Pascal Chevrel
Date: Mon, 19 Feb 2024 09:46:11 +0100
Subject: [PATCH 240/586] Set version to 125.0a1
---
version.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/version.txt b/version.txt
index 4a191dc3641d..eae6fa023384 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-124.0a1
+125.0a1
From edbf5d968a225657ba4179bfbbe1434806415fc5 Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Mon, 19 Feb 2024 13:21:16 +0000
Subject: [PATCH 241/586] Update GeckoView (Nightly) to 125.0.20240219095613.
---
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 8408f36ce312..129f4c957b05 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.20240217214641"
+ const val version = "125.0.20240219095613"
/**
* GeckoView channel
From 7a03cd878b14d925d58a5e7ff8152b112f4c8f7e Mon Sep 17 00:00:00 2001
From: Ryan VanderMeulen
Date: Sun, 18 Feb 2024 15:52:33 -0500
Subject: [PATCH 242/586] Bug 1880759 - Update SnakeYAML to version 2.2
---
shared-settings.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/shared-settings.gradle b/shared-settings.gradle
index 133dae126585..268b208e375f 100644
--- a/shared-settings.gradle
+++ b/shared-settings.gradle
@@ -10,7 +10,7 @@ buildscript {
}
dependencies {
- classpath 'org.yaml:snakeyaml:2.0'
+ classpath 'org.yaml:snakeyaml:2.2'
}
}
From d69522f91e3f515cf00b294b758b2ad12c3f6ea4 Mon Sep 17 00:00:00 2001
From: James Hugman
Date: Mon, 29 Jan 2024 20:00:18 +0000
Subject: [PATCH 243/586] =?UTF-8?q?Bug=201880476=20=E2=80=94=C2=A0Remove?=
=?UTF-8?q?=20redundant=20nimbusFeature=20in=20NimbusMessagingStorage?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../service/nimbus/messaging/NimbusMessagingStorage.kt | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
index 0afc03d89426..b2d749197c19 100644
--- a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
+++ b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
@@ -49,7 +49,6 @@ class NimbusMessagingStorage(
@VisibleForTesting
val malFormedMap = mutableMapOf()
private val logger = Logger("MessagingStorage")
- private val nimbusFeature = messagingFeature
private val customAttributes: JSONObject
get() = attributeProvider?.getCustomAttributes(context) ?: JSONObject()
@@ -281,7 +280,7 @@ class NimbusMessagingStorage(
}
@VisibleForTesting
- internal fun getOnControlBehavior(): ControlMessageBehavior = nimbusFeature.value().onControl
+ internal fun getOnControlBehavior(): ControlMessageBehavior = messagingFeature.value().onControl
private suspend fun addMetadata(id: String): Message.Metadata {
return metadataStorage.addMetadata(
From 2e1baccf0234f95be7c258966d770c42bbcf8996 Mon Sep 17 00:00:00 2001
From: James Hugman
Date: Fri, 26 Jan 2024 16:59:04 +0000
Subject: [PATCH 244/586] =?UTF-8?q?Bug=201880476=20=E2=80=94=C2=A0Fixup=20?=
=?UTF-8?q?documentation=20to=20point=20to=20the=20correct=20class?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../service/nimbus/messaging/NimbusMessagingStorage.kt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
index b2d749197c19..c984f93e6dcb 100644
--- a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
+++ b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
@@ -17,8 +17,8 @@ import org.mozilla.experiments.nimbus.internal.NimbusException
import mozilla.components.service.nimbus.GleanMetrics.Messaging as GleanMessaging
/**
- * This ID must match the name given in the `nimbus.fml.yaml` file, which
- * itself generates the classname for [org.mozilla.fenix.nimbus.Messaging].
+ * This ID must match the name given in the `messaging.fml.yaml` file, which
+ * itself generates the classname for [mozilla.components.service.nimbus.messaging.FxNimbusMessaging].
*
* If that ever changes, it should also change here.
*
From 9d3a86f35417f3843d69c688cfedde8f63bcdced Mon Sep 17 00:00:00 2001
From: Ryan VanderMeulen
Date: Thu, 15 Feb 2024 10:34:10 -0500
Subject: [PATCH 245/586] Bug 1880516 - Update Kotlin Serialization to version
1.6.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 0e8be735cd80..06a36de2f71a 100644
--- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt
+++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt
@@ -16,7 +16,7 @@ class DependenciesPlugin : Plugin {
object Versions {
const val kotlin = "1.9.22"
const val coroutines = "1.7.3"
- const val serialization = "1.6.0"
+ const val serialization = "1.6.3"
const val python_envs_plugin = "0.0.31"
const val junit = "4.13.2"
From d4ce7a5b60d85be5cbdcc728dcb5fd299e4d3c09 Mon Sep 17 00:00:00 2001
From: Ryan VanderMeulen
Date: Thu, 15 Feb 2024 10:32:51 -0500
Subject: [PATCH 246/586] Bug 1880511 - Update Kotlin Coroutines to version
1.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 06a36de2f71a..782583eaea0a 100644
--- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt
+++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt
@@ -15,7 +15,7 @@ class DependenciesPlugin : Plugin {
// Synchronized version numbers for dependencies used by (some) modules
object Versions {
const val kotlin = "1.9.22"
- const val coroutines = "1.7.3"
+ const val coroutines = "1.8.0"
const val serialization = "1.6.3"
const val python_envs_plugin = "0.0.31"
From 5cf44597c61e6379b1cc50e53ce2e789465a554b Mon Sep 17 00:00:00 2001
From: github-actions
Date: Tue, 20 Feb 2024 00:03:19 +0000
Subject: [PATCH 247/586] Import translations from android-l10n
---
.../menu/src/main/res/values-cy/strings.xml | 2 +-
.../menu/src/main/res/values-es/strings.xml | 2 +
.../addons/src/main/res/values-cy/strings.xml | 4 +-
.../addons/src/main/res/values-el/strings.xml | 2 +
.../addons/src/main/res/values-es/strings.xml | 22 ++-
.../src/main/res/values-fy-rNL/strings.xml | 2 +
.../media/src/main/res/values-es/strings.xml | 11 +-
.../src/main/res/values-es/strings.xml | 36 +++++
.../src/main/res/values-es-rAR/strings.xml | 2 +-
fenix/app/src/main/res/values-es/strings.xml | 134 ++++++++++++------
.../src/main/res/values-sv-rSE/strings.xml | 2 +-
fenix/app/src/main/res/values-vi/strings.xml | 2 +-
12 files changed, 165 insertions(+), 56 deletions(-)
diff --git a/android-components/components/browser/menu/src/main/res/values-cy/strings.xml b/android-components/components/browser/menu/src/main/res/values-cy/strings.xml
index 496c299482af..7e8c13ab3172 100644
--- a/android-components/components/browser/menu/src/main/res/values-cy/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-cy/strings.xml
@@ -11,5 +11,5 @@
Llywio i fyny
- Ychwanegion, llywiwch i fyny
+ Ychwanegion, symud i fyny
diff --git a/android-components/components/browser/menu/src/main/res/values-es/strings.xml b/android-components/components/browser/menu/src/main/res/values-es/strings.xml
index 06d3f3f85570..ee0e7a88adfc 100644
--- a/android-components/components/browser/menu/src/main/res/values-es/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-es/strings.xml
@@ -10,4 +10,6 @@
Administrador de complementosNavegar hacia arriba
+
+ Complementos, navega hacia arriba
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 b420dd55493e..f039819ea7b5 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
@@ -99,7 +99,7 @@
Rhedeg yn y pori preifat
- Ni chaniateir mewn ffenestri preifat
+ Heb ei ganiatáu mewn ffenestri preifatGalluogwyd
@@ -253,7 +253,7 @@
Agorwch ef yn y ddewislen
- Mynediad %1$s o ddewislen %2$s.
+ Cael %1$s o ddewislen %2$s.Iawn, rwy’n deall
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 a5a1a4aeb18b..429e2cebdbe9 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
@@ -98,6 +98,8 @@
Να επιτρέπεται στην ιδιωτική περιήγησηΕκτέλεση στην ιδιωτική περιήγηση
+
+ Δεν επιτρέπεται στα ιδιωτικά παράθυραΕνεργά
diff --git a/android-components/components/feature/addons/src/main/res/values-es/strings.xml b/android-components/components/feature/addons/src/main/res/values-es/strings.xml
index a6252ab57716..75611b757341 100644
--- a/android-components/components/feature/addons/src/main/res/values-es/strings.xml
+++ b/android-components/components/feature/addons/src/main/res/values-es/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$dAcceder a las pestañas del navegador
@@ -75,7 +77,7 @@
Autor
- Autores
+ AutoresÚltima actualización
@@ -135,13 +137,17 @@
Cancelar
- Instalar complemento
+ Instalar complemento
+
+ Instalar %1$sCancelarRevisiones: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Calificación: %1$.02f de 5Complementos
@@ -242,10 +248,14 @@
Estado:%1$s ha sido añadido a %2$s
-
- Ábrelo en el menú
+
+ Ábrelo en el menú
+
+ Accede a %1$s desde el menú %2$s.
+
+ Vale, entendido
- Vale, entendido
+ AceptarSaber más
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 9bcdf8520974..63cc2ba4c0f9 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
@@ -98,6 +98,8 @@
Tastean yn priveenavigaasjeUtfiere yn priveenavigaasje
+
+ Net tastien yn priveefinstersYnskeakele
diff --git a/android-components/components/feature/media/src/main/res/values-es/strings.xml b/android-components/components/feature/media/src/main/res/values-es/strings.xml
index 844681158c04..71bef26954f1 100644
--- a/android-components/components/feature/media/src/main/res/values-es/strings.xml
+++ b/android-components/components/feature/media/src/main/res/values-es/strings.xml
@@ -1,5 +1,5 @@
-
+Multimedia
@@ -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 tu cámara. Toca para abrir la pestaña
+
- Recordatorio: %1$s todavía está usando tu micrófono y tu cámara. Toca para abrir la pestaña
+ Recordatorio: %1$s todavía está usando tu micrófono y tu cámara. Toca para abrir la pestaña.Reproducir
diff --git a/android-components/components/feature/prompts/src/main/res/values-es/strings.xml b/android-components/components/feature/prompts/src/main/res/values-es/strings.xml
index e849e61f528a..2457b86e360c 100644
--- a/android-components/components/feature/prompts/src/main/res/values-es/strings.xml
+++ b/android-components/components/feature/prompts/src/main/res/values-es/strings.xml
@@ -18,6 +18,8 @@
ContraseñaNo guardar
+
+ Ahora noNo guardar nunca
@@ -26,16 +28,26 @@
GuardarNo actualizar
+
+ Ahora noActualizarEl campo de contraseña no puede estar vacío
+ Introduce una contraseña
+
No se puede guardar el inicio de sesión
+
+ No se ha podido guardar la contraseña¿Guardar este inicio de sesión?
+
+ ¿Guardar contraseña?¿Actualizar este inicio de sesión?
+
+ ¿Actualizar contraseña?¿Añadir nombre de usuario a la contraseña guardada?
@@ -85,13 +97,22 @@
Establecer horaAdministrar inicios de sesión
+
+ Administrar contraseñasExpandir inicios de sesión sugeridos
+
+ Expandir las contraseñas guardadasContraer inicios de sesión sugeridos
+
+ Contraer las contraseñas guardadasInicios de sesión sugeridos
+
+ Contraseñas guardadas
+
Sugerir contraseña segura
@@ -111,12 +132,20 @@
Seleccionar tarjeta de crédito
+
+ Usar tarjeta guardadaExpandir la lista de tarjetas de crédito sugeridas
+
+ Expandir tarjetas guardadasContraer la lista de tarjetas de crédito sugeridas
+
+ Contraer tarjetas guardadasAdministrar 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. Tu código de seguridad no se guardará.
+
Seleccionar direcciónExpandir direcciones sugeridas
+
+ Expandir direcciones guardadasContraer direcciones sugeridas
+
+ Contraer direcciones guardadasAdministrar direcciones
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 36b024d21b91..68be82b68f4d 100644
--- a/fenix/app/src/main/res/values-es-rAR/strings.xml
+++ b/fenix/app/src/main/res/values-es-rAR/strings.xml
@@ -505,7 +505,7 @@
Sitio seguro no disponible
- Lo más probable es que el sitio web simplemente no sea compatible con HTTPs.
+ Lo más probable es que el sitio web simplemente no sea compatible con HTTPS.Sin embargo, también es posible que un atacante esté involucrado. Si continúa al sitio web, no debe ingresar ninguna información sensible. Si continúa, el modo solo HTTPS se desactivará temporalmente para el sitio.
diff --git a/fenix/app/src/main/res/values-es/strings.xml b/fenix/app/src/main/res/values-es/strings.xml
index 05599fb3992b..5f00a5e888b5 100644
--- a/fenix/app/src/main/res/values-es/strings.xml
+++ b/fenix/app/src/main/res/values-es/strings.xml
@@ -247,6 +247,7 @@
Personalizar la página de inicio
+
Pantalla de inicio
@@ -254,6 +255,9 @@
Eliminar historial de navegación
+
+ Traducir página
+
Idioma seleccionado
@@ -265,8 +269,6 @@
Escanear
-
- BuscadorAjustes del buscador
@@ -322,14 +324,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
@@ -448,21 +450,11 @@
Modo solo HTTPS
-
- Reducción de avisos de cookiesBloqueador de avisos de cookiesBloqueador de avisos de cookies en navegación privada
-
- Reducir los avisos de cookies
-
- Desactivado
-
- Activado
-
-
- %1$s intenta rechazar automáticamente las solicitudes de cookies en los avisos de cookies.
+
Desactivada para este sitio
@@ -480,35 +472,16 @@
Sitio actualmente no compatible
- ¿Activar la reducción de aviso de cookies para %1$s?
-
¿Activar el bloqueo de aviso de cookies para %1$s?
- ¿Desactivar la reducción de aviso de cookies para %1$s?
-
¿Desactivar el bloqueo de aviso de cookies para %1$s?%1$s no puede rechazar automáticamente los avisos de cookies en este sitio. Puede enviar una solicitud para admitir 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.Tras desactivarlo, %1$s borrará las cookies y recargará la página. Esto puede desconectarte del sitio o vaciar tu carrito de compra.
- %1$s intenta rechazar automáticamente las solicitudes de cookies en sitios compatibles.
-
Al activarlo %1$s intentará rechazar automáticamente los avisos de cookies en este sitio.
-
- ¿Permitir que %1$s rechace los avisos de cookies?
-
- %1$s puede rechazar automáticamente muchas solicitudes de cookies.
-
- Ahora no
-
- Verás menos solicitudes de cookies
-
-
- Permitir%1$s acaba de rechazar las cookies por ti
@@ -725,6 +698,8 @@
MarcadoresInicios de sesión
+
+ ContraseñasPestañas abiertas
@@ -751,6 +726,8 @@
Tarjetas de crédito
+
+ Métodos de pagoDirecciones
@@ -1306,8 +1283,6 @@
Descartar
- No se puede imprimir
-
No se puede imprimir esta páginaImprimir
@@ -1720,8 +1695,12 @@
Inicios de sesión y contraseñas
+
+ ContraseñasGuardar inicios de sesión y contraseñas
+
+ Guardar contraseñasPreguntar antes de guardar
@@ -1740,26 +1719,45 @@
Añadir cuenta
+
+ Añadir contraseña
+
Inicios de sesión sincronizados
+
+ Sincronizar contraseñasSincronizar inicios de sesión entre dispositivos
+
+ Sincronizar contraseñas entre dispositivosInicios de sesión guardados
+
+ Contraseñas guardadasLos inicios de sesión que guardes o sincronices con %s se mostrarán aquí.
+
+ Las contraseñas que guardes o sincronices con %s aparecerán aquí. Todas las contraseñas que guardes quedan cifradas.Saber más sobre Sync.
+
+ Descubre más sobre SyncExcepcionesLos inicios de sesión y contraseñas no guardados aparecerán aquí.
+
+ %s no guardará contraseñas para los sitios que se listen aquí.No se guardarán los inicios de sesión y contraseñas para estos sitios.
+
+ %s no guardará las contraseñas para estos sitios.Eliminar todas las excepcionesBuscar inicios de sesión
+
+ Buscar contraseñasSitio
@@ -1788,10 +1786,16 @@
Ocultar contraseñaDesbloquear para ver tus inicios de sesión guardados
+
+ Desbloquea para ver tus contraseñas guardadasAsegurar tus usuarios y contraseñas
+
+ Asegura tus contraseñas guardadasConfigura un patrón de bloqueo del dispositivo, un PIN o una contraseña para proteger el acceso a tus usuarios y contraseñas guardados si alguien más tiene tu dispositivo.
+
+ Establece un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus contraseñas guardadas y evitar que sean accedidas por otras personas en caso de que alguien más tenga tu dispositivo.Más tarde
@@ -1812,6 +1816,9 @@
Ordenar menú de inicio de sesión
+
+ Menú ordenar contraseñas
+
Autocompletado
@@ -1819,11 +1826,17 @@
DireccionesTarjetas de crédito
+
+ Métodos de pagoGuardar y autocompletar tarjetas
+
+ Guardar y completar métodos de pagoLos datos están cifrados
+
+ %s cifra todos los métodos de pago que guardesSincronizar tarjetas entre dispositivos
@@ -1831,17 +1844,26 @@
Añadir tarjeta de crédito
+
+ Añadir tarjetaAdministrar tarjetas guardadas
+
+ Administrar tarjetasAñadir direcciónAdministrar direccionesGuardar y autocompletar direcciones
+
+ Guardar y completar direccionesIncluir información como números, correos electrónicos y direcciones de envío
+
+ Incluye números de teléfono y direcciones de correo electrónico
+
Añadir tarjeta
@@ -1862,6 +1884,8 @@
Eliminar tarjeta¿Seguro que quieres eliminar esta tarjeta de crédito?
+
+ ¿Eliminar tarjeta?Eliminar
@@ -1877,14 +1901,22 @@
Por favor, escriba un número válido de tarjeta de crédito
+
+ Introduce un número de tarjeta válidoPor favor, rellena este campo
+
+ Añadir un nombreDesbloquear para ver tus tarjetas guardadasAsegurar tus tarjetas de crédito
+
+ Protege tus métodos de pago guardadosConfigura un patrón de bloqueo, PIN o contraseña para proteger el acceso a tus tarjetas guardadas si alguien más accede a tu dispositivo.
+
+ Establece un patrón de bloqueo de dispositivo, PIN o contraseña para proteger tus métodos de pago guardados y evitar que sean accedidos por otras personas en caso de que alguien más tenga tu dispositivo.Configurar ahora
@@ -1894,6 +1926,8 @@
Desbloquear para usar la información de la tarjeta de crédito almacenada
+
+ Desbloquea para utilizar métodos de pago guardadosAñadir dirección
@@ -1931,6 +1965,8 @@
¿Seguro que quieres eliminar esta dirección?
+
+ ¿Eliminar esta dirección?Eliminar
@@ -2030,26 +2066,44 @@
Editar¿Seguro que quieres eliminar este inicio de sesión?
+
+ ¿Estás seguro de que quieres eliminar esta contraseña?EliminarCancelarOpciones de inicio de sesión
+
+ Opciones de contraseñaEl 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.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.El campo de texto editable para la contraseña del inicio de sesión.
+
+ El campo de texto editable para la contraseña.Guardar cambios para el inicio de sesión.
+
+ Guardar cambios.Editar
+
+ Editar contraseñaAñadir nueva cuenta
+
+ Añadir contraseñaSe necesita contraseña
+
+ Introduce una contraseñaSe requiere nombre de usuario
@@ -2149,7 +2203,7 @@
Buscar con %s
-
+
Configura enlaces de sitios web, correos electrónicos y mensajes para que se abran automáticamente en Firefox.
@@ -2223,8 +2277,6 @@
puntos destacados provienen de reseñas de %s de los últimos 80 días que creemos que son fiables.]]>Saber más sobre %s.
-
- cómo %s de Mozilla determina la calidad de las reseñascómo determina %s la calidad de las reseñas
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 b4c270ba6e1c..f718c9bed43d 100644
--- a/fenix/app/src/main/res/values-sv-rSE/strings.xml
+++ b/fenix/app/src/main/res/values-sv-rSE/strings.xml
@@ -505,7 +505,7 @@
Säker webbplats är inte tillgänglig
- Troligtvis stöder webbplatsen helt enkelt inte HTTPs.
+ Troligtvis stöder webbplatsen helt enkelt inte HTTPS.Men det är också möjligt att en angripare är inblandad. Om du fortsätter till webbplatsen ska du inte ange någon känslig information. Om du fortsätter kommer endast HTTPS-läget att stängas av tillfälligt för webbplatsen.
diff --git a/fenix/app/src/main/res/values-vi/strings.xml b/fenix/app/src/main/res/values-vi/strings.xml
index 356737044dd8..1b7a232b0890 100644
--- a/fenix/app/src/main/res/values-vi/strings.xml
+++ b/fenix/app/src/main/res/values-vi/strings.xml
@@ -498,7 +498,7 @@
Trang web an toàn không khả dụng
- Rất có thể, trang web chỉ đơn giản là không hỗ trợ HTTPs.
+ Rất có thể, trang web chỉ đơn giản là không hỗ trợ HTTPS.Tuy nhiên, cũng có thể có kẻ tấn công tham gia. Nếu bạn tiếp tục vào trang web, bạn không nên nhập bất kỳ thông tin nhạy cảm nào. Nếu bạn tiếp tục, chế độ chỉ HTTPS sẽ tạm thời bị tắt cho trang web.
From b0e0b657b07a70426e42be39bc8063e4c1e16ed3 Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Tue, 20 Feb 2024 00:36:58 +0000
Subject: [PATCH 248/586] Update GeckoView (Nightly) to 125.0.20240219212225.
---
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 129f4c957b05..b102cdf5f129 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 = "125.0.20240219095613"
+ const val version = "125.0.20240219212225"
/**
* GeckoView channel
From e5a9344c59c7c9d6032a66e74479f1f1b4f8a537 Mon Sep 17 00:00:00 2001
From: Jonathan Almeida
Date: Mon, 19 Feb 2024 23:08:07 -0500
Subject: [PATCH 249/586] Bug 1875379 - Fix ambiguity in string description.
---
focus-android/app/src/main/res/values/strings.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/focus-android/app/src/main/res/values/strings.xml b/focus-android/app/src/main/res/values/strings.xml
index 20aa1234291f..cec6aa586aac 100644
--- a/focus-android/app/src/main/res/values/strings.xml
+++ b/focus-android/app/src/main/res/values/strings.xml
@@ -88,7 +88,7 @@
Erase browsing history?Tap or clear this notification to securely erase your browsing history.
-
Tap or swipe this notification to securely erase your browsing history.
From 99a72d7607302ced75dc36277fedc76283dcc231 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Fri, 16 Feb 2024 13:35:25 +0200
Subject: [PATCH 250/586] Bug 1880640 - Convert private variables to functions
so they don't get initialised
---
.../ui/robots/SettingsSubMenuAutofillRobot.kt | 316 +++++++++---------
1 file changed, 158 insertions(+), 158 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt
index 349451b69c60..6f7a581cd079 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt
@@ -36,7 +36,7 @@ import org.mozilla.fenix.helpers.click
class SettingsSubMenuAutofillRobot {
fun verifyAutofillToolbarTitle() {
- assertUIObjectExists(autofillToolbarTitle)
+ assertUIObjectExists(autofillToolbarTitle())
Log.i(TAG, "verifyAutofillToolbarTitle: Verified \"Autofill\" toolbar title exists")
}
fun verifyManageAddressesToolbarTitle() {
@@ -54,16 +54,16 @@ class SettingsSubMenuAutofillRobot {
fun verifyAddressAutofillSection(isAddressAutofillEnabled: Boolean, userHasSavedAddress: Boolean) {
assertUIObjectExists(
- autofillToolbarTitle,
- addressesSectionTitle,
- saveAndAutofillAddressesOption,
- saveAndAutofillAddressesSummary,
+ autofillToolbarTitle(),
+ addressesSectionTitle(),
+ saveAndAutofillAddressesOption(),
+ saveAndAutofillAddressesSummary(),
)
if (userHasSavedAddress) {
- assertUIObjectExists(manageAddressesButton)
+ assertUIObjectExists(manageAddressesButton())
} else {
- assertUIObjectExists(addAddressButton)
+ assertUIObjectExists(addAddressButton())
}
verifyAddressesAutofillToggle(isAddressAutofillEnabled)
@@ -71,18 +71,18 @@ class SettingsSubMenuAutofillRobot {
fun verifyCreditCardsAutofillSection(isAddressAutofillEnabled: Boolean, userHasSavedCreditCard: Boolean) {
assertUIObjectExists(
- autofillToolbarTitle,
- creditCardsSectionTitle,
- saveAndAutofillCreditCardsOption,
- saveAndAutofillCreditCardsSummary,
- syncCreditCardsAcrossDevicesButton,
+ autofillToolbarTitle(),
+ creditCardsSectionTitle(),
+ saveAndAutofillCreditCardsOption(),
+ saveAndAutofillCreditCardsSummary(),
+ syncCreditCardsAcrossDevicesButton(),
)
if (userHasSavedCreditCard) {
- assertUIObjectExists(manageSavedCreditCardsButton)
+ assertUIObjectExists(manageSavedCreditCardsButton())
} else {
- assertUIObjectExists(addCreditCardButton)
+ assertUIObjectExists(addCreditCardButton())
}
verifySaveAndAutofillCreditCardsToggle(isAddressAutofillEnabled)
@@ -90,9 +90,9 @@ class SettingsSubMenuAutofillRobot {
fun verifyManageAddressesSection(vararg savedAddressDetails: String) {
assertUIObjectExists(
- navigateBackButton,
- manageAddressesToolbarTitle,
- addAddressButton,
+ navigateBackButton(),
+ manageAddressesToolbarTitle(),
+ addAddressButton(),
)
for (savedAddressDetail in savedAddressDetails) {
assertUIObjectExists(itemContainingText(savedAddressDetail))
@@ -102,9 +102,9 @@ class SettingsSubMenuAutofillRobot {
fun verifySavedCreditCardsSection(creditCardLastDigits: String, creditCardExpiryDate: String) {
assertUIObjectExists(
- navigateBackButton,
- savedCreditCardsToolbarTitle,
- addCreditCardButton,
+ navigateBackButton(),
+ savedCreditCardsToolbarTitle(),
+ addCreditCardButton(),
itemContainingText(creditCardLastDigits),
itemContainingText(creditCardExpiryDate),
)
@@ -148,35 +148,35 @@ class SettingsSubMenuAutofillRobot {
fun verifyAddAddressView() {
assertUIObjectExists(
- addAddressToolbarTitle,
- navigateBackButton,
- toolbarCheckmarkButton,
- firstNameTextInput,
- middleNameTextInput,
+ addAddressToolbarTitle(),
+ navigateBackButton(),
+ toolbarCheckmarkButton(),
+ firstNameTextInput(),
+ middleNameTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_street_address))
Log.i(TAG, "verifyAddAddressView: Scrolled to \"Street Address\" text input")
assertUIObjectExists(
- lastNameTextInput,
- streetAddressTextInput,
+ lastNameTextInput(),
+ streetAddressTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_country))
Log.i(TAG, "verifyAddAddressView: Scrolled to \"Country or region\" dropdown")
assertUIObjectExists(
- cityTextInput,
- subRegionDropDown,
- zipCodeTextInput,
+ cityTextInput(),
+ subRegionDropDown(),
+ zipCodeTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_save_button))
Log.i(TAG, "verifyAddAddressView: Scrolled to \"Save\" button")
assertUIObjectExists(
- countryDropDown,
- phoneTextInput,
- emailTextInput,
+ countryDropDown(),
+ phoneTextInput(),
+ emailTextInput(),
)
assertUIObjectExists(
- saveButton,
- cancelButton,
+ saveButton(),
+ cancelButton(),
)
}
@@ -193,7 +193,7 @@ class SettingsSubMenuAutofillRobot {
}
fun verifyCountryOptions(vararg countries: String) {
- countryDropDown.click()
+ countryDropDown().click()
Log.i(TAG, "verifyCountryOptions: Clicked \"Country or region\" dropdown")
for (country in countries) {
assertUIObjectExists(itemContainingText(country))
@@ -201,7 +201,7 @@ class SettingsSubMenuAutofillRobot {
}
fun selectCountry(country: String) {
- countryDropDown.click()
+ countryDropDown().click()
Log.i(TAG, "selectCountry: Clicked \"Country or region\" dropdown")
countryOption(country).click()
Log.i(TAG, "selectCountry: Selected $country dropdown option")
@@ -209,50 +209,50 @@ class SettingsSubMenuAutofillRobot {
fun verifyEditAddressView() {
assertUIObjectExists(
- editAddressToolbarTitle,
- navigateBackButton,
- toolbarDeleteAddressButton,
- toolbarCheckmarkButton,
- firstNameTextInput,
- middleNameTextInput,
+ editAddressToolbarTitle(),
+ navigateBackButton(),
+ toolbarDeleteAddressButton(),
+ toolbarCheckmarkButton(),
+ firstNameTextInput(),
+ middleNameTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_street_address))
Log.i(TAG, "verifyEditAddressView: Scrolled to \"Street Address\" text input")
assertUIObjectExists(
- lastNameTextInput,
- streetAddressTextInput,
+ lastNameTextInput(),
+ streetAddressTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_country))
Log.i(TAG, "verifyEditAddressView: Scrolled to \"Country or region\" dropdown")
assertUIObjectExists(
- cityTextInput,
- subRegionDropDown,
- zipCodeTextInput,
+ cityTextInput(),
+ subRegionDropDown(),
+ zipCodeTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_save_button))
Log.i(TAG, "verifyEditAddressView: Scrolled to \"Save\" button")
assertUIObjectExists(
- countryDropDown,
- phoneTextInput,
- emailTextInput,
+ countryDropDown(),
+ phoneTextInput(),
+ emailTextInput(),
)
assertUIObjectExists(
- saveButton,
- cancelButton,
+ saveButton(),
+ cancelButton(),
)
- assertUIObjectExists(deleteAddressButton)
+ assertUIObjectExists(deleteAddressButton())
}
fun clickSaveAndAutofillAddressesOption() {
- saveAndAutofillAddressesOption.click()
+ saveAndAutofillAddressesOption().click()
Log.i(TAG, "clickSaveAndAutofillAddressesOption: Clicked \"Save and autofill addresses\" button")
}
fun clickAddAddressButton() {
- addAddressButton.click()
+ addAddressButton().click()
Log.i(TAG, "clickAddAddressButton: Clicked \"Add address\" button")
}
fun clickManageAddressesButton() {
- manageAddressesButton.click()
+ manageAddressesButton().click()
Log.i(TAG, "clickManageAddressesButton: Clicked \"Manage addresses\" button")
}
fun clickSavedAddress(firstName: String) {
@@ -261,17 +261,17 @@ class SettingsSubMenuAutofillRobot {
}
fun clickDeleteAddressButton() {
Log.i(TAG, "clickDeleteAddressButton: Looking for delete address toolbar button")
- toolbarDeleteAddressButton.waitForExists(waitingTime)
- toolbarDeleteAddressButton.click()
+ toolbarDeleteAddressButton().waitForExists(waitingTime)
+ toolbarDeleteAddressButton().click()
Log.i(TAG, "clickDeleteAddressButton: Clicked delete address toolbar button")
}
fun clickCancelDeleteAddressButton() {
- cancelDeleteAddressButton.click()
+ cancelDeleteAddressButton().click()
Log.i(TAG, "clickCancelDeleteAddressButton: Clicked \"CANCEL\" button from delete address dialog")
}
fun clickConfirmDeleteAddressButton() {
- confirmDeleteAddressButton.click()
+ confirmDeleteAddressButton().click()
Log.i(TAG, "clickConfirmDeleteAddressButton: Clicked \"DELETE\" button from delete address dialog")
}
@@ -292,7 +292,7 @@ class SettingsSubMenuAutofillRobot {
Log.i(TAG, "clickCountryOption: Clicked \"Country or region\" $country dropdown option")
}
fun verifyAddAddressButton() {
- assertUIObjectExists(addAddressButton)
+ assertUIObjectExists(addAddressButton())
Log.i(TAG, "verifyAddAddressButton: Verified \"Add address\" button exists")
}
@@ -321,58 +321,58 @@ class SettingsSubMenuAutofillRobot {
}
}
Log.i(TAG, "fillAndSaveAddress: Looking for \"First Name\" text input")
- firstNameTextInput.waitForExists(waitingTime)
+ firstNameTextInput().waitForExists(waitingTime)
mDevice.pressBack()
Log.i(TAG, "fillAndSaveAddress: Dismissed keyboard using device back button")
- firstNameTextInput.setText(firstName)
+ firstNameTextInput().setText(firstName)
Log.i(TAG, "fillAndSaveAddress: \"First Name\" set to $firstName")
- middleNameTextInput.setText(middleName)
+ middleNameTextInput().setText(middleName)
Log.i(TAG, "fillAndSaveAddress: \"Middle Name\" set to $middleName")
- lastNameTextInput.setText(lastName)
+ lastNameTextInput().setText(lastName)
Log.i(TAG, "fillAndSaveAddress: \"Last Name\" set to $lastName")
- streetAddressTextInput.setText(streetAddress)
+ streetAddressTextInput().setText(streetAddress)
Log.i(TAG, "fillAndSaveAddress: \"Street Address\" set to $streetAddress")
- cityTextInput.setText(city)
+ cityTextInput().setText(city)
Log.i(TAG, "fillAndSaveAddress: \"City\" set to $city")
- subRegionDropDown.click()
+ subRegionDropDown().click()
Log.i(TAG, "fillAndSaveAddress: Clicked \"State\" dropdown button")
clickSubRegionOption(state)
Log.i(TAG, "fillAndSaveAddress: Selected $state as \"State\"")
- zipCodeTextInput.setText(zipCode)
+ zipCodeTextInput().setText(zipCode)
Log.i(TAG, "fillAndSaveAddress: \"Zip\" set to $zipCode")
- countryDropDown.click()
+ countryDropDown().click()
Log.i(TAG, "fillAndSaveAddress: Clicked \"Country or region\" dropdown button")
clickCountryOption(country)
Log.i(TAG, "fillAndSaveAddress: Selected $country as \"Country or region\"")
scrollToElementByText(getStringResource(R.string.addresses_save_button))
Log.i(TAG, "fillAndSaveAddress: Scrolled to \"Save\" button")
- phoneTextInput.setText(phoneNumber)
+ phoneTextInput().setText(phoneNumber)
Log.i(TAG, "fillAndSaveAddress: \"Phone\" set to $phoneNumber")
- emailTextInput.setText(emailAddress)
+ emailTextInput().setText(emailAddress)
Log.i(TAG, "fillAndSaveAddress: \"Email\" set to $emailAddress")
- saveButton.click()
+ saveButton().click()
Log.i(TAG, "fillAndSaveAddress: Clicked \"Save\" button")
Log.i(TAG, "fillAndSaveAddress: Looking for \"Manage addressese\" button")
- manageAddressesButton.waitForExists(waitingTime)
+ manageAddressesButton().waitForExists(waitingTime)
}
- fun clickAddCreditCardButton() = addCreditCardButton.click()
- fun clickManageSavedCreditCardsButton() = manageSavedCreditCardsButton.click()
- fun clickSecuredCreditCardsLaterButton() = securedCreditCardsLaterButton.click()
- fun clickSavedCreditCard() = savedCreditCardNumber.clickAndWaitForNewWindow(waitingTime)
+ fun clickAddCreditCardButton() = addCreditCardButton().click()
+ fun clickManageSavedCreditCardsButton() = manageSavedCreditCardsButton().click()
+ fun clickSecuredCreditCardsLaterButton() = securedCreditCardsLaterButton().click()
+ fun clickSavedCreditCard() = savedCreditCardNumber().clickAndWaitForNewWindow(waitingTime)
fun clickDeleteCreditCardToolbarButton() {
- deleteCreditCardToolbarButton.waitForExists(waitingTime)
- deleteCreditCardToolbarButton.click()
+ deleteCreditCardToolbarButton().waitForExists(waitingTime)
+ deleteCreditCardToolbarButton().click()
}
fun clickDeleteCreditCardMenuButton() {
- deleteCreditCardMenuButton.waitForExists(waitingTime)
- deleteCreditCardMenuButton.click()
+ deleteCreditCardMenuButton().waitForExists(waitingTime)
+ deleteCreditCardMenuButton().click()
}
- fun clickSaveAndAutofillCreditCardsOption() = saveAndAutofillCreditCardsOption.click()
+ fun clickSaveAndAutofillCreditCardsOption() = saveAndAutofillCreditCardsOption().click()
- fun clickConfirmDeleteCreditCardButton() = confirmDeleteCreditCardButton.click()
+ fun clickConfirmDeleteCreditCardButton() = confirmDeleteCreditCardButton().click()
- fun clickCancelDeleteCreditCardButton() = cancelDeleteCreditCardButton.click()
+ fun clickCancelDeleteCreditCardButton() = cancelDeleteCreditCardButton().click()
fun clickExpiryMonthOption(expiryMonth: String) {
expiryMonthOption(expiryMonth).waitForExists(waitingTime)
@@ -384,34 +384,34 @@ class SettingsSubMenuAutofillRobot {
expiryYearOption(expiryYear).click()
}
- fun verifyAddCreditCardsButton() = assertUIObjectExists(addCreditCardButton)
+ fun verifyAddCreditCardsButton() = assertUIObjectExists(addCreditCardButton())
fun fillAndSaveCreditCard(cardNumber: String, cardName: String, expiryMonth: String, expiryYear: String) {
- creditCardNumberTextInput.waitForExists(waitingTime)
- creditCardNumberTextInput.setText(cardNumber)
- nameOnCreditCardTextInput.setText(cardName)
- expiryMonthDropDown.click()
+ creditCardNumberTextInput().waitForExists(waitingTime)
+ creditCardNumberTextInput().setText(cardNumber)
+ nameOnCreditCardTextInput().setText(cardName)
+ expiryMonthDropDown().click()
clickExpiryMonthOption(expiryMonth)
- expiryYearDropDown.click()
+ expiryYearDropDown().click()
clickExpiryYearOption(expiryYear)
- saveButton.click()
- manageSavedCreditCardsButton.waitForExists(waitingTime)
+ saveButton().click()
+ manageSavedCreditCardsButton().waitForExists(waitingTime)
}
fun clearCreditCardNumber() =
- creditCardNumberTextInput.also {
+ creditCardNumberTextInput().also {
it.waitForExists(waitingTime)
it.clearTextField()
}
fun clearNameOnCreditCard() =
- nameOnCreditCardTextInput.also {
+ nameOnCreditCardTextInput().also {
it.waitForExists(waitingTime)
it.clearTextField()
}
- fun clickSaveCreditCardToolbarButton() = saveCreditCardToolbarButton.click()
+ fun clickSaveCreditCardToolbarButton() = saveCreditCardToolbarButton().click()
fun verifyEditCreditCardView(
cardNumber: String,
@@ -420,19 +420,19 @@ class SettingsSubMenuAutofillRobot {
expiryYear: String,
) {
assertUIObjectExists(
- editCreditCardToolbarTitle,
- navigateBackButton,
- deleteCreditCardToolbarButton,
- saveCreditCardToolbarButton,
+ editCreditCardToolbarTitle(),
+ navigateBackButton(),
+ deleteCreditCardToolbarButton(),
+ saveCreditCardToolbarButton(),
)
- assertEquals(cardNumber, creditCardNumberTextInput.text)
- assertEquals(cardName, nameOnCreditCardTextInput.text)
+ assertEquals(cardNumber, creditCardNumberTextInput().text)
+ assertEquals(cardName, nameOnCreditCardTextInput().text)
// Can't get the text from the drop-down items, need to verify them individually
assertUIObjectExists(
- expiryYearDropDown,
- expiryMonthDropDown,
+ expiryYearDropDown(),
+ expiryMonthDropDown(),
)
assertUIObjectExists(
@@ -441,14 +441,14 @@ class SettingsSubMenuAutofillRobot {
)
assertUIObjectExists(
- saveButton,
- cancelButton,
+ saveButton(),
+ cancelButton(),
)
- assertUIObjectExists(deleteCreditCardMenuButton)
+ assertUIObjectExists(deleteCreditCardMenuButton())
}
- fun verifyEditCreditCardToolbarTitle() = assertUIObjectExists(editCreditCardToolbarTitle)
+ fun verifyEditCreditCardToolbarTitle() = assertUIObjectExists(editCreditCardToolbarTitle())
fun verifyCreditCardNumberErrorMessage() =
assertUIObjectExists(itemContainingText(getStringResource(R.string.credit_cards_number_validation_error_message)))
@@ -465,7 +465,7 @@ class SettingsSubMenuAutofillRobot {
}
fun goBackToAutofillSettings(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition {
- navigateBackButton.click()
+ navigateBackButton().click()
Log.i(TAG, "goBackToAutofillSettings: Clicked \"Navigate back\" toolbar button")
SettingsSubMenuAutofillRobot().interact()
@@ -473,7 +473,7 @@ class SettingsSubMenuAutofillRobot {
}
fun goBackToSavedCreditCards(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition {
- navigateBackButton.click()
+ navigateBackButton().click()
SettingsSubMenuAutofillRobot().interact()
return SettingsSubMenuAutofillRobot.Transition()
@@ -494,64 +494,64 @@ fun autofillScreen(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsS
return SettingsSubMenuAutofillRobot.Transition()
}
-private val autofillToolbarTitle = itemContainingText(getStringResource(R.string.preferences_autofill))
-private val addressesSectionTitle = itemContainingText(getStringResource(R.string.preferences_addresses))
-private val manageAddressesToolbarTitle =
+private fun autofillToolbarTitle() = itemContainingText(getStringResource(R.string.preferences_autofill))
+private fun addressesSectionTitle() = itemContainingText(getStringResource(R.string.preferences_addresses))
+private fun manageAddressesToolbarTitle() =
mDevice.findObject(
UiSelector()
.resourceId("$packageName:id/navigationToolbar")
.childSelector(UiSelector().text(getStringResource(R.string.addresses_manage_addresses))),
)
-private val saveAndAutofillAddressesOption = itemContainingText(getStringResource(R.string.preferences_addresses_save_and_autofill_addresses))
-private val saveAndAutofillAddressesSummary = itemContainingText(getStringResource(R.string.preferences_addresses_save_and_autofill_addresses_summary))
-private val addAddressButton = itemContainingText(getStringResource(R.string.preferences_addresses_add_address))
-private val manageAddressesButton =
+private fun saveAndAutofillAddressesOption() = itemContainingText(getStringResource(R.string.preferences_addresses_save_and_autofill_addresses))
+private fun saveAndAutofillAddressesSummary() = itemContainingText(getStringResource(R.string.preferences_addresses_save_and_autofill_addresses_summary))
+private fun addAddressButton() = itemContainingText(getStringResource(R.string.preferences_addresses_add_address))
+private fun manageAddressesButton() =
mDevice.findObject(
UiSelector()
.resourceId("android:id/title")
.text(getStringResource(R.string.preferences_addresses_manage_addresses)),
)
-private val addAddressToolbarTitle = itemContainingText(getStringResource(R.string.addresses_add_address))
-private val editAddressToolbarTitle = itemContainingText(getStringResource(R.string.addresses_edit_address))
-private val toolbarCheckmarkButton = itemWithResId("$packageName:id/save_address_button")
-private val navigateBackButton = itemWithDescription(getStringResource(R.string.action_bar_up_description))
-private val firstNameTextInput = itemWithResId("$packageName:id/first_name_input")
-private val middleNameTextInput = itemWithResId("$packageName:id/middle_name_input")
-private val lastNameTextInput = itemWithResId("$packageName:id/last_name_input")
-private val streetAddressTextInput = itemWithResId("$packageName:id/street_address_input")
-private val cityTextInput = itemWithResId("$packageName:id/city_input")
-private val subRegionDropDown = itemWithResId("$packageName:id/subregion_drop_down")
-private val zipCodeTextInput = itemWithResId("$packageName:id/zip_input")
-private val countryDropDown = itemWithResId("$packageName:id/country_drop_down")
-private val phoneTextInput = itemWithResId("$packageName:id/phone_input")
-private val emailTextInput = itemWithResId("$packageName:id/email_input")
-private val saveButton = itemWithResId("$packageName:id/save_button")
-private val cancelButton = itemWithResId("$packageName:id/cancel_button")
-private val deleteAddressButton = itemContainingText(getStringResource(R.string.addressess_delete_address_button))
-private val toolbarDeleteAddressButton = itemWithResId("$packageName:id/delete_address_button")
-private val cancelDeleteAddressButton = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog())
-private val confirmDeleteAddressButton = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog())
-
-private val creditCardsSectionTitle = itemContainingText(getStringResource(R.string.preferences_credit_cards))
-private val saveAndAutofillCreditCardsOption = itemContainingText(getStringResource(R.string.preferences_credit_cards_save_and_autofill_cards))
-private val saveAndAutofillCreditCardsSummary = itemContainingText(getStringResource(R.string.preferences_credit_cards_save_and_autofill_cards_summary))
-private val syncCreditCardsAcrossDevicesButton = itemContainingText(getStringResource(R.string.preferences_credit_cards_sync_cards_across_devices))
-private val addCreditCardButton = mDevice.findObject(UiSelector().textContains(getStringResource(R.string.preferences_credit_cards_add_credit_card)))
-private val savedCreditCardsToolbarTitle = itemContainingText(getStringResource(R.string.credit_cards_saved_cards))
-private val editCreditCardToolbarTitle = itemContainingText(getStringResource(R.string.credit_cards_edit_card))
-private val manageSavedCreditCardsButton = mDevice.findObject(UiSelector().textContains(getStringResource(R.string.preferences_credit_cards_manage_saved_cards)))
-private val creditCardNumberTextInput = mDevice.findObject(UiSelector().resourceId("$packageName:id/card_number_input"))
-private val nameOnCreditCardTextInput = mDevice.findObject(UiSelector().resourceId("$packageName:id/name_on_card_input"))
-private val expiryMonthDropDown = mDevice.findObject(UiSelector().resourceId("$packageName:id/expiry_month_drop_down"))
-private val expiryYearDropDown = mDevice.findObject(UiSelector().resourceId("$packageName:id/expiry_year_drop_down"))
-private val savedCreditCardNumber = mDevice.findObject(UiSelector().resourceId("$packageName:id/credit_card_logo"))
-private val deleteCreditCardToolbarButton = mDevice.findObject(UiSelector().resourceId("$packageName:id/delete_credit_card_button"))
-private val saveCreditCardToolbarButton = itemWithResId("$packageName:id/save_credit_card_button")
-private val deleteCreditCardMenuButton = itemContainingText(getStringResource(R.string.credit_cards_delete_card_button))
-private val confirmDeleteCreditCardButton = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog())
-private val cancelDeleteCreditCardButton = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog())
-private val securedCreditCardsLaterButton = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog())
+private fun addAddressToolbarTitle() = itemContainingText(getStringResource(R.string.addresses_add_address))
+private fun editAddressToolbarTitle() = itemContainingText(getStringResource(R.string.addresses_edit_address))
+private fun toolbarCheckmarkButton() = itemWithResId("$packageName:id/save_address_button")
+private fun navigateBackButton() = itemWithDescription(getStringResource(R.string.action_bar_up_description))
+private fun firstNameTextInput() = itemWithResId("$packageName:id/first_name_input")
+private fun middleNameTextInput() = itemWithResId("$packageName:id/middle_name_input")
+private fun lastNameTextInput() = itemWithResId("$packageName:id/last_name_input")
+private fun streetAddressTextInput() = itemWithResId("$packageName:id/street_address_input")
+private fun cityTextInput() = itemWithResId("$packageName:id/city_input")
+private fun subRegionDropDown() = itemWithResId("$packageName:id/subregion_drop_down")
+private fun zipCodeTextInput() = itemWithResId("$packageName:id/zip_input")
+private fun countryDropDown() = itemWithResId("$packageName:id/country_drop_down")
+private fun phoneTextInput() = itemWithResId("$packageName:id/phone_input")
+private fun emailTextInput() = itemWithResId("$packageName:id/email_input")
+private fun saveButton() = itemWithResId("$packageName:id/save_button")
+private fun cancelButton() = itemWithResId("$packageName:id/cancel_button")
+private fun deleteAddressButton() = itemContainingText(getStringResource(R.string.addressess_delete_address_button))
+private fun toolbarDeleteAddressButton() = itemWithResId("$packageName:id/delete_address_button")
+private fun cancelDeleteAddressButton() = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog())
+private fun confirmDeleteAddressButton() = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog())
+
+private fun creditCardsSectionTitle() = itemContainingText(getStringResource(R.string.preferences_credit_cards))
+private fun saveAndAutofillCreditCardsOption() = itemContainingText(getStringResource(R.string.preferences_credit_cards_save_and_autofill_cards))
+private fun saveAndAutofillCreditCardsSummary() = itemContainingText(getStringResource(R.string.preferences_credit_cards_save_and_autofill_cards_summary))
+private fun syncCreditCardsAcrossDevicesButton() = itemContainingText(getStringResource(R.string.preferences_credit_cards_sync_cards_across_devices))
+private fun addCreditCardButton() = mDevice.findObject(UiSelector().textContains(getStringResource(R.string.preferences_credit_cards_add_credit_card)))
+private fun savedCreditCardsToolbarTitle() = itemContainingText(getStringResource(R.string.credit_cards_saved_cards))
+private fun editCreditCardToolbarTitle() = itemContainingText(getStringResource(R.string.credit_cards_edit_card))
+private fun manageSavedCreditCardsButton() = mDevice.findObject(UiSelector().textContains(getStringResource(R.string.preferences_credit_cards_manage_saved_cards)))
+private fun creditCardNumberTextInput() = mDevice.findObject(UiSelector().resourceId("$packageName:id/card_number_input"))
+private fun nameOnCreditCardTextInput() = mDevice.findObject(UiSelector().resourceId("$packageName:id/name_on_card_input"))
+private fun expiryMonthDropDown() = mDevice.findObject(UiSelector().resourceId("$packageName:id/expiry_month_drop_down"))
+private fun expiryYearDropDown() = mDevice.findObject(UiSelector().resourceId("$packageName:id/expiry_year_drop_down"))
+private fun savedCreditCardNumber() = mDevice.findObject(UiSelector().resourceId("$packageName:id/credit_card_logo"))
+private fun deleteCreditCardToolbarButton() = mDevice.findObject(UiSelector().resourceId("$packageName:id/delete_credit_card_button"))
+private fun saveCreditCardToolbarButton() = itemWithResId("$packageName:id/save_credit_card_button")
+private fun deleteCreditCardMenuButton() = itemContainingText(getStringResource(R.string.credit_cards_delete_card_button))
+private fun confirmDeleteCreditCardButton() = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog())
+private fun cancelDeleteCreditCardButton() = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog())
+private fun securedCreditCardsLaterButton() = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog())
private fun savedAddress(firstName: String) = mDevice.findObject(UiSelector().textContains(firstName))
private fun subRegionOption(subRegion: String) = mDevice.findObject(UiSelector().textContains(subRegion))
From 34f121ed5bf2ac5e006e0f11d9655b0c0f3b1cc4 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Fri, 16 Feb 2024 14:27:29 +0200
Subject: [PATCH 251/586] Bug 1880640 - Add pairs of logs to
SettingsSubMenuAutofillRobot
---
.../ui/robots/SettingsSubMenuAutofillRobot.kt | 222 +++++++++++++-----
1 file changed, 163 insertions(+), 59 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt
index 6f7a581cd079..c9af2fdc6dff 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt
@@ -37,10 +37,9 @@ class SettingsSubMenuAutofillRobot {
fun verifyAutofillToolbarTitle() {
assertUIObjectExists(autofillToolbarTitle())
- Log.i(TAG, "verifyAutofillToolbarTitle: Verified \"Autofill\" toolbar title exists")
}
fun verifyManageAddressesToolbarTitle() {
- Log.i(TAG, "verifyManageAddressesToolbarTitle: Trying to verify the \"Manage addresses\" toolbar title is displayed")
+ Log.i(TAG, "verifyManageAddressesToolbarTitle: Trying to verify that the \"Manage addresses\" toolbar title is displayed")
onView(
allOf(
withId(R.id.navigationToolbar),
@@ -49,7 +48,7 @@ class SettingsSubMenuAutofillRobot {
),
),
).check(matches(isDisplayed()))
- Log.i(TAG, "verifyManageAddressesToolbarTitle: Verified the \"Manage addresses\" toolbar title is displayed")
+ Log.i(TAG, "verifyManageAddressesToolbarTitle: Verified that the \"Manage addresses\" toolbar title is displayed")
}
fun verifyAddressAutofillSection(isAddressAutofillEnabled: Boolean, userHasSavedAddress: Boolean) {
@@ -96,7 +95,6 @@ class SettingsSubMenuAutofillRobot {
)
for (savedAddressDetail in savedAddressDetails) {
assertUIObjectExists(itemContainingText(savedAddressDetail))
- Log.i(TAG, "verifyManageAddressesSection: Verified saved address detail: $savedAddressDetail exists")
}
}
@@ -111,6 +109,7 @@ class SettingsSubMenuAutofillRobot {
}
fun verifyAddressesAutofillToggle(enabled: Boolean) {
+ Log.i(TAG, "verifyAddressesAutofillToggle: Trying to verify that the \"Save and autofill addresses\" toggle is checked: $enabled")
onView(withText(R.string.preferences_addresses_save_and_autofill_addresses))
.check(
matches(
@@ -126,10 +125,11 @@ class SettingsSubMenuAutofillRobot {
),
),
)
- Log.i(TAG, "verifyAddressesAutofillToggle: Verified if address autofill toggle is enabled: $enabled")
+ Log.i(TAG, "verifyAddressesAutofillToggle: Verified that the \"Save and autofill addresses\" toggle is checked: $enabled")
}
- fun verifySaveAndAutofillCreditCardsToggle(enabled: Boolean) =
+ fun verifySaveAndAutofillCreditCardsToggle(enabled: Boolean) {
+ Log.i(TAG, "verifySaveAndAutofillCreditCardsToggle: Trying to verify that the \"Save and autofill cards\" toggle is checked: $enabled")
onView(withText(R.string.preferences_credit_cards_save_and_autofill_cards))
.check(
matches(
@@ -145,6 +145,8 @@ class SettingsSubMenuAutofillRobot {
),
),
)
+ Log.i(TAG, "verifySaveAndAutofillCreditCardsToggle: Verified that the \"Save and autofill cards\" toggle is checked: $enabled")
+ }
fun verifyAddAddressView() {
assertUIObjectExists(
@@ -155,20 +157,17 @@ class SettingsSubMenuAutofillRobot {
middleNameTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_street_address))
- Log.i(TAG, "verifyAddAddressView: Scrolled to \"Street Address\" text input")
assertUIObjectExists(
lastNameTextInput(),
streetAddressTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_country))
- Log.i(TAG, "verifyAddAddressView: Scrolled to \"Country or region\" dropdown")
assertUIObjectExists(
cityTextInput(),
subRegionDropDown(),
zipCodeTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_save_button))
- Log.i(TAG, "verifyAddAddressView: Scrolled to \"Save\" button")
assertUIObjectExists(
countryDropDown(),
phoneTextInput(),
@@ -182,9 +181,9 @@ class SettingsSubMenuAutofillRobot {
fun verifyCountryOption(country: String) {
scrollToElementByText(getStringResource(R.string.addresses_country))
- Log.i(TAG, "verifyCountryOption: Scrolled to \"Country or region\" dropdown")
+ Log.i(TAG, "verifyCountryOption: Trying to click device back button")
mDevice.pressBack()
- Log.i(TAG, "fillAndSaveAddress: Dismissed \"Country or region\" dropdown using device back button")
+ Log.i(TAG, "verifyCountryOption: Clicked device back button")
assertUIObjectExists(itemContainingText(country))
}
@@ -193,16 +192,19 @@ class SettingsSubMenuAutofillRobot {
}
fun verifyCountryOptions(vararg countries: String) {
+ Log.i(TAG, "verifyCountryOptions: Trying to click the \"Country or region\" dropdown")
countryDropDown().click()
- Log.i(TAG, "verifyCountryOptions: Clicked \"Country or region\" dropdown")
+ Log.i(TAG, "verifyCountryOptions: Clicked the \"Country or region\" dropdown")
for (country in countries) {
assertUIObjectExists(itemContainingText(country))
}
}
fun selectCountry(country: String) {
+ Log.i(TAG, "selectCountry: Trying to click the \"Country or region\" dropdown")
countryDropDown().click()
- Log.i(TAG, "selectCountry: Clicked \"Country or region\" dropdown")
+ Log.i(TAG, "selectCountry: Clicked the \"Country or region\" dropdown")
+ Log.i(TAG, "selectCountry: Trying to select $country dropdown option")
countryOption(country).click()
Log.i(TAG, "selectCountry: Selected $country dropdown option")
}
@@ -217,20 +219,17 @@ class SettingsSubMenuAutofillRobot {
middleNameTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_street_address))
- Log.i(TAG, "verifyEditAddressView: Scrolled to \"Street Address\" text input")
assertUIObjectExists(
lastNameTextInput(),
streetAddressTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_country))
- Log.i(TAG, "verifyEditAddressView: Scrolled to \"Country or region\" dropdown")
assertUIObjectExists(
cityTextInput(),
subRegionDropDown(),
zipCodeTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_save_button))
- Log.i(TAG, "verifyEditAddressView: Scrolled to \"Save\" button")
assertUIObjectExists(
countryDropDown(),
phoneTextInput(),
@@ -244,57 +243,65 @@ class SettingsSubMenuAutofillRobot {
}
fun clickSaveAndAutofillAddressesOption() {
+ Log.i(TAG, "clickSaveAndAutofillAddressesOption: Trying to click the \"Save and autofill addresses\" button")
saveAndAutofillAddressesOption().click()
- Log.i(TAG, "clickSaveAndAutofillAddressesOption: Clicked \"Save and autofill addresses\" button")
+ Log.i(TAG, "clickSaveAndAutofillAddressesOption: Clicked the \"Save and autofill addresses\" button")
}
fun clickAddAddressButton() {
+ Log.i(TAG, "clickAddAddressButton: Trying to click the \"Add address\" button")
addAddressButton().click()
- Log.i(TAG, "clickAddAddressButton: Clicked \"Add address\" button")
+ Log.i(TAG, "clickAddAddressButton: Clicked the \"Add address\" button")
}
fun clickManageAddressesButton() {
+ Log.i(TAG, "clickManageAddressesButton: Trying to click the \"Manage addresses\" button")
manageAddressesButton().click()
- Log.i(TAG, "clickManageAddressesButton: Clicked \"Manage addresses\" button")
+ Log.i(TAG, "clickManageAddressesButton: Clicked the \"Manage addresses\" button")
}
fun clickSavedAddress(firstName: String) {
+ Log.i(TAG, "clickSavedAddress: Trying to click the $firstName saved address and and wait for $waitingTime ms for a new window")
savedAddress(firstName).clickAndWaitForNewWindow(waitingTime)
- Log.i(TAG, "clickSavedAddress: Clicked $firstName saved address and waiting for a new window for $waitingTime")
+ Log.i(TAG, "clickSavedAddress: Clicked the $firstName saved address and and waited for $waitingTime ms for a new window")
}
fun clickDeleteAddressButton() {
- Log.i(TAG, "clickDeleteAddressButton: Looking for delete address toolbar button")
+ Log.i(TAG, "clickDeleteAddressButton: Waiting for $waitingTime ms for the delete address toolbar button to exist")
toolbarDeleteAddressButton().waitForExists(waitingTime)
+ Log.i(TAG, "clickDeleteAddressButton: Waited for $waitingTime ms for the delete address toolbar button to exist")
+ Log.i(TAG, "clickDeleteAddressButton: Trying to click the delete address toolbar button")
toolbarDeleteAddressButton().click()
- Log.i(TAG, "clickDeleteAddressButton: Clicked delete address toolbar button")
+ Log.i(TAG, "clickDeleteAddressButton: Clicked the delete address toolbar button")
}
fun clickCancelDeleteAddressButton() {
+ Log.i(TAG, "clickCancelDeleteAddressButton: Trying to click the \"CANCEL\" button from the delete address dialog")
cancelDeleteAddressButton().click()
- Log.i(TAG, "clickCancelDeleteAddressButton: Clicked \"CANCEL\" button from delete address dialog")
+ Log.i(TAG, "clickCancelDeleteAddressButton: Clicked the \"CANCEL\" button from the delete address dialog")
}
fun clickConfirmDeleteAddressButton() {
+ Log.i(TAG, "clickConfirmDeleteAddressButton: Trying to click the \"DELETE\" button from the delete address dialog")
confirmDeleteAddressButton().click()
- Log.i(TAG, "clickConfirmDeleteAddressButton: Clicked \"DELETE\" button from delete address dialog")
+ Log.i(TAG, "clickConfirmDeleteAddressButton: Clicked \"DELETE\" button from the delete address dialog")
}
fun clickSubRegionOption(subRegion: String) {
scrollToElementByText(subRegion)
- Log.i(TAG, "clickSubRegionOption: Scrolled to \"State\" drop down")
subRegionOption(subRegion).also {
- Log.i(TAG, "clickSubRegionOption: Looking for \"State\" $subRegion dropdown option")
+ Log.i(TAG, "clickSubRegionOption: Waiting for $waitingTime ms for the \"State\" $subRegion dropdown option to exist")
it.waitForExists(waitingTime)
+ Log.i(TAG, "clickSubRegionOption: Waited for $waitingTime ms for the \"State\" $subRegion dropdown option to exist")
+ Log.i(TAG, "clickSubRegionOption: Trying to click the \"State\" $subRegion dropdown option")
it.click()
- Log.i(TAG, "clickSubRegionOption: Clicked \"State\" $subRegion dropdown option")
+ Log.i(TAG, "clickSubRegionOption: Clicked the \"State\" $subRegion dropdown option")
}
}
fun clickCountryOption(country: String) {
- Log.i(TAG, "clickCountryOption: Looking for \"Country or region\" $country dropdown option")
+ Log.i(TAG, "clickCountryOption: Waiting for $waitingTime ms for the \"Country or region\" $country dropdown option to exist")
countryOption(country).waitForExists(waitingTime)
+ Log.i(TAG, "clickCountryOption: Waited for $waitingTime ms for the \"Country or region\" $country dropdown option to exist")
+ Log.i(TAG, "clickCountryOption: Trying to click \"Country or region\" $country dropdown option")
countryOption(country).click()
Log.i(TAG, "clickCountryOption: Clicked \"Country or region\" $country dropdown option")
}
- fun verifyAddAddressButton() {
- assertUIObjectExists(addAddressButton())
- Log.i(TAG, "verifyAddAddressButton: Verified \"Add address\" button exists")
- }
+ fun verifyAddAddressButton() = assertUIObjectExists(addAddressButton())
fun fillAndSaveAddress(
navigateToAutofillSettings: Boolean,
@@ -320,98 +327,186 @@ class SettingsSubMenuAutofillRobot {
clickAddAddressButton()
}
}
- Log.i(TAG, "fillAndSaveAddress: Looking for \"First Name\" text input")
+ Log.i(TAG, "fillAndSaveAddress: Waiting for $waitingTime ms for \"First Name\" text field to exist")
firstNameTextInput().waitForExists(waitingTime)
+ Log.i(TAG, "fillAndSaveAddress: Waited for $waitingTime ms for \"First Name\" text field to exist")
+ Log.i(TAG, "fillAndSaveAddress: Trying to click device back button to dismiss keyboard using device back button")
mDevice.pressBack()
- Log.i(TAG, "fillAndSaveAddress: Dismissed keyboard using device back button")
+ Log.i(TAG, "fillAndSaveAddress: Clicked device back button to dismiss keyboard using device back button")
+ Log.i(TAG, "fillAndSaveAddress: Trying to set \"First Name\" to $firstName")
firstNameTextInput().setText(firstName)
- Log.i(TAG, "fillAndSaveAddress: \"First Name\" set to $firstName")
+ Log.i(TAG, "fillAndSaveAddress: \"First Name\" was set to $firstName")
+ Log.i(TAG, "fillAndSaveAddress: Trying to set \"Middle Name\" to $middleName")
middleNameTextInput().setText(middleName)
- Log.i(TAG, "fillAndSaveAddress: \"Middle Name\" set to $middleName")
+ Log.i(TAG, "fillAndSaveAddress: \"Middle Name\" was set to $middleName")
+ Log.i(TAG, "fillAndSaveAddress: Trying to set \"Last Name\" to $lastName")
lastNameTextInput().setText(lastName)
- Log.i(TAG, "fillAndSaveAddress: \"Last Name\" set to $lastName")
+ Log.i(TAG, "fillAndSaveAddress: \"Last Name\" was set to $lastName")
+ Log.i(TAG, "fillAndSaveAddress: Trying to set \"Street Address\" to $streetAddress")
streetAddressTextInput().setText(streetAddress)
- Log.i(TAG, "fillAndSaveAddress: \"Street Address\" set to $streetAddress")
+ Log.i(TAG, "fillAndSaveAddress: \"Street Address\" was set to $streetAddress")
+ Log.i(TAG, "fillAndSaveAddress: Trying to set \"City\" to $city")
cityTextInput().setText(city)
- Log.i(TAG, "fillAndSaveAddress: \"City\" set to $city")
+ Log.i(TAG, "fillAndSaveAddress: \"City\" was set to $city")
+ Log.i(TAG, "fillAndSaveAddress: Trying to click \"State\" dropdown button")
subRegionDropDown().click()
Log.i(TAG, "fillAndSaveAddress: Clicked \"State\" dropdown button")
+ Log.i(TAG, "fillAndSaveAddress: Trying to click the $state dropdown option")
clickSubRegionOption(state)
- Log.i(TAG, "fillAndSaveAddress: Selected $state as \"State\"")
+ Log.i(TAG, "fillAndSaveAddress: Clicked $state dropdown option")
+ Log.i(TAG, "fillAndSaveAddress: Trying to set \"Zip\" to $zipCode")
zipCodeTextInput().setText(zipCode)
- Log.i(TAG, "fillAndSaveAddress: \"Zip\" set to $zipCode")
+ Log.i(TAG, "fillAndSaveAddress: \"Zip\" was set to $zipCode")
+ Log.i(TAG, "fillAndSaveAddress: Trying to click \"Country or region\" dropdown button")
countryDropDown().click()
Log.i(TAG, "fillAndSaveAddress: Clicked \"Country or region\" dropdown button")
+ Log.i(TAG, "fillAndSaveAddress: Trying to click $country dropdown option")
clickCountryOption(country)
- Log.i(TAG, "fillAndSaveAddress: Selected $country as \"Country or region\"")
+ Log.i(TAG, "fillAndSaveAddress: Clicked $country dropdown option")
scrollToElementByText(getStringResource(R.string.addresses_save_button))
- Log.i(TAG, "fillAndSaveAddress: Scrolled to \"Save\" button")
+ Log.i(TAG, "fillAndSaveAddress: Trying to set \"Phone\" to $phoneNumber")
phoneTextInput().setText(phoneNumber)
- Log.i(TAG, "fillAndSaveAddress: \"Phone\" set to $phoneNumber")
+ Log.i(TAG, "fillAndSaveAddress: \"Phone\" was set to $phoneNumber")
+ Log.i(TAG, "fillAndSaveAddress: Trying to set \"Email\" to $emailAddress")
emailTextInput().setText(emailAddress)
- Log.i(TAG, "fillAndSaveAddress: \"Email\" set to $emailAddress")
+ Log.i(TAG, "fillAndSaveAddress: \"Email\" was set to $emailAddress")
+ Log.i(TAG, "fillAndSaveAddress: Trying to click the \"Save\" button")
saveButton().click()
- Log.i(TAG, "fillAndSaveAddress: Clicked \"Save\" button")
- Log.i(TAG, "fillAndSaveAddress: Looking for \"Manage addressese\" button")
+ Log.i(TAG, "fillAndSaveAddress: Clicked the \"Save\" button")
+ Log.i(TAG, "fillAndSaveAddress: Waiting for $waitingTime ms for for \"Manage addresses\" button to exist")
manageAddressesButton().waitForExists(waitingTime)
+ Log.i(TAG, "fillAndSaveAddress: Waited for $waitingTime ms for for \"Manage addresses\" button to exist")
}
- fun clickAddCreditCardButton() = addCreditCardButton().click()
- fun clickManageSavedCreditCardsButton() = manageSavedCreditCardsButton().click()
- fun clickSecuredCreditCardsLaterButton() = securedCreditCardsLaterButton().click()
- fun clickSavedCreditCard() = savedCreditCardNumber().clickAndWaitForNewWindow(waitingTime)
+ fun clickAddCreditCardButton() {
+ Log.i(TAG, "clickAddCreditCardButton: Trying to click the \"Add credit card\" button")
+ addCreditCardButton().click()
+ Log.i(TAG, "clickAddCreditCardButton: Clicked the \"Add credit card\" button")
+ }
+ fun clickManageSavedCreditCardsButton() {
+ Log.i(TAG, "clickManageSavedCreditCardsButton: Trying to click the \"Manage saved cards\" button")
+ manageSavedCreditCardsButton().click()
+ Log.i(TAG, "clickManageSavedCreditCardsButton: Clicked the \"Manage saved cards\" button")
+ }
+ fun clickSecuredCreditCardsLaterButton() {
+ Log.i(TAG, "clickSecuredCreditCardsLaterButton: Trying to click the \"Later\" button")
+ securedCreditCardsLaterButton().click()
+ Log.i(TAG, "clickSecuredCreditCardsLaterButton: Clicked the \"Later\" button")
+ }
+ fun clickSavedCreditCard() {
+ Log.i(TAG, "clickSavedCreditCard: Trying to click the saved credit card and and wait for $waitingTime ms for a new window")
+ savedCreditCardNumber().clickAndWaitForNewWindow(waitingTime)
+ Log.i(TAG, "clickSavedCreditCard: Clicked the saved credit card and and waited for $waitingTime ms for a new window")
+ }
fun clickDeleteCreditCardToolbarButton() {
+ Log.i(TAG, "clickDeleteCreditCardToolbarButton: Waiting for $waitingTime ms for the delete credit card toolbar button to exist")
deleteCreditCardToolbarButton().waitForExists(waitingTime)
+ Log.i(TAG, "clickDeleteCreditCardToolbarButton: Waited for $waitingTime ms for the delete credit card toolbar button to exist")
+ Log.i(TAG, "clickDeleteCreditCardToolbarButton: Trying to click the delete credit card toolbar button")
deleteCreditCardToolbarButton().click()
+ Log.i(TAG, "clickDeleteCreditCardToolbarButton: Clicked the delete credit card toolbar button")
}
fun clickDeleteCreditCardMenuButton() {
+ Log.i(TAG, "clickDeleteCreditCardMenuButton: Waiting for $waitingTime ms for the delete credit card menu button to exist")
deleteCreditCardMenuButton().waitForExists(waitingTime)
+ Log.i(TAG, "clickDeleteCreditCardMenuButton: Waited for $waitingTime ms for the delete credit card menu button to exist")
+ Log.i(TAG, "clickDeleteCreditCardMenuButton: Trying to click the delete credit card menu button")
deleteCreditCardMenuButton().click()
+ Log.i(TAG, "clickDeleteCreditCardMenuButton: Clicked the delete credit card menu button")
+ }
+ fun clickSaveAndAutofillCreditCardsOption() {
+ Log.i(TAG, "clickSaveAndAutofillCreditCardsOption: Trying to click the \"Save and autofill cards\" option")
+ saveAndAutofillCreditCardsOption().click()
+ Log.i(TAG, "clickSaveAndAutofillCreditCardsOption: Clicked the \"Save and autofill cards\" option")
}
- fun clickSaveAndAutofillCreditCardsOption() = saveAndAutofillCreditCardsOption().click()
- fun clickConfirmDeleteCreditCardButton() = confirmDeleteCreditCardButton().click()
+ fun clickConfirmDeleteCreditCardButton() {
+ Log.i(TAG, "clickConfirmDeleteCreditCardButton: Trying to click the \"Delete\" credit card dialog button")
+ confirmDeleteCreditCardButton().click()
+ Log.i(TAG, "clickConfirmDeleteCreditCardButton: Clicked the \"Delete\" credit card dialog button")
+ }
- fun clickCancelDeleteCreditCardButton() = cancelDeleteCreditCardButton().click()
+ fun clickCancelDeleteCreditCardButton() {
+ Log.i(TAG, "clickCancelDeleteCreditCardButton: Trying to click the \"Cancel\" credit card dialog button")
+ cancelDeleteCreditCardButton().click()
+ Log.i(TAG, "clickCancelDeleteCreditCardButton: Clicked the \"Cancel\" credit card dialog button")
+ }
fun clickExpiryMonthOption(expiryMonth: String) {
+ Log.i(TAG, "clickExpiryMonthOption: Waiting for $waitingTime ms for the $expiryMonth expiry month option to exist")
expiryMonthOption(expiryMonth).waitForExists(waitingTime)
+ Log.i(TAG, "clickExpiryMonthOption: Waited for $waitingTime ms for the $expiryMonth expiry month option to exist")
+ Log.i(TAG, "clickExpiryMonthOption: Trying to click $expiryMonth expiry month option")
expiryMonthOption(expiryMonth).click()
+ Log.i(TAG, "clickExpiryMonthOption: Clicked $expiryMonth expiry month option")
}
fun clickExpiryYearOption(expiryYear: String) {
+ Log.i(TAG, "clickExpiryYearOption: Waiting for $waitingTime ms for the $expiryYear expiry year option to exist")
expiryYearOption(expiryYear).waitForExists(waitingTime)
+ Log.i(TAG, "clickExpiryYearOption: Waited for $waitingTime ms for the $expiryYear expiry year option to exist")
+ Log.i(TAG, "clickExpiryYearOption: Trying to click $expiryYear expiry year option")
expiryYearOption(expiryYear).click()
+ Log.i(TAG, "clickExpiryYearOption: Clicked $expiryYear expiry year option")
}
fun verifyAddCreditCardsButton() = assertUIObjectExists(addCreditCardButton())
fun fillAndSaveCreditCard(cardNumber: String, cardName: String, expiryMonth: String, expiryYear: String) {
+ Log.i(TAG, "fillAndSaveCreditCard: Waiting for $waitingTime ms for the credit card number text field to exist")
creditCardNumberTextInput().waitForExists(waitingTime)
+ Log.i(TAG, "fillAndSaveCreditCard: Waited for $waitingTime ms for the credit card number text field to exist")
+ Log.i(TAG, "fillAndSaveCreditCard: Trying to set the credit card number to: $cardNumber")
creditCardNumberTextInput().setText(cardNumber)
+ Log.i(TAG, "fillAndSaveCreditCard: The credit card number was set to: $cardNumber")
+ Log.i(TAG, "fillAndSaveCreditCard: Trying to set the name on card to: $cardName")
nameOnCreditCardTextInput().setText(cardName)
+ Log.i(TAG, "fillAndSaveCreditCard: The credit card name was set to: $cardName")
+ Log.i(TAG, "fillAndSaveCreditCard: Trying to click the expiry month dropdown")
expiryMonthDropDown().click()
+ Log.i(TAG, "fillAndSaveCreditCard: Clicked the expiry month dropdown")
+ Log.i(TAG, "fillAndSaveCreditCard: Trying to click $expiryMonth expiry month option")
clickExpiryMonthOption(expiryMonth)
+ Log.i(TAG, "fillAndSaveCreditCard: Clicked $expiryMonth expiry month option")
+ Log.i(TAG, "fillAndSaveCreditCard: Trying to click the expiry year dropdown")
expiryYearDropDown().click()
+ Log.i(TAG, "fillAndSaveCreditCard: Clicked the expiry year dropdown")
+ Log.i(TAG, "fillAndSaveCreditCard: Trying to click $expiryYear expiry year option")
clickExpiryYearOption(expiryYear)
-
+ Log.i(TAG, "fillAndSaveCreditCard: Clicked $expiryYear expiry year option")
+ Log.i(TAG, "fillAndSaveCreditCard: Trying to click the \"Save\" button")
saveButton().click()
+ Log.i(TAG, "fillAndSaveCreditCard: Clicked the \"Save\" button")
+ Log.i(TAG, "fillAndSaveCreditCard: Waiting for $waitingTime ms for the \"Manage saved cards\" button to exist")
manageSavedCreditCardsButton().waitForExists(waitingTime)
+ Log.i(TAG, "fillAndSaveCreditCard: Waited for $waitingTime ms for the \"Manage saved cards\" button to exist")
}
fun clearCreditCardNumber() =
creditCardNumberTextInput().also {
+ Log.i(TAG, "clearCreditCardNumber: Waiting for $waitingTime ms for the credit card number text field to exist")
it.waitForExists(waitingTime)
+ Log.i(TAG, "clearCreditCardNumber: Waited for $waitingTime ms for the credit card number text field to exist")
+ Log.i(TAG, "clearCreditCardNumber: Trying to clear the credit card number text field")
it.clearTextField()
+ Log.i(TAG, "clearCreditCardNumber: Cleared the credit card number text field")
}
fun clearNameOnCreditCard() =
nameOnCreditCardTextInput().also {
+ Log.i(TAG, "clearNameOnCreditCard: Waiting for $waitingTime ms for name on card text field to exist")
it.waitForExists(waitingTime)
+ Log.i(TAG, "clearNameOnCreditCard: Waited for $waitingTime ms for name on card text field to exist")
+ Log.i(TAG, "clearNameOnCreditCard: Trying to clear the name on card text field")
it.clearTextField()
+ Log.i(TAG, "clearNameOnCreditCard: Cleared the name on card text field")
}
- fun clickSaveCreditCardToolbarButton() = saveCreditCardToolbarButton().click()
+ fun clickSaveCreditCardToolbarButton() {
+ Log.i(TAG, "clickSaveCreditCardToolbarButton: Trying to click the save credit card toolbar button")
+ saveCreditCardToolbarButton().click()
+ Log.i(TAG, "clickSaveCreditCardToolbarButton: Clicked the save credit card toolbar button")
+ }
fun verifyEditCreditCardView(
cardNumber: String,
@@ -425,9 +520,12 @@ class SettingsSubMenuAutofillRobot {
deleteCreditCardToolbarButton(),
saveCreditCardToolbarButton(),
)
-
+ Log.i(TAG, "verifyEditCreditCardView: Trying to verify that the card number text field is set to: $cardNumber")
assertEquals(cardNumber, creditCardNumberTextInput().text)
+ Log.i(TAG, "verifyEditCreditCardView: Verified that the card number text field was set to: $cardNumber")
+ Log.i(TAG, "verifyEditCreditCardView: Trying to verify that the card name text field is set to: $cardName")
assertEquals(cardName, nameOnCreditCardTextInput().text)
+ Log.i(TAG, "verifyEditCreditCardView: Verified that the card card name text field was set to: $cardName")
// Can't get the text from the drop-down items, need to verify them individually
assertUIObjectExists(
@@ -458,30 +556,36 @@ class SettingsSubMenuAutofillRobot {
class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
+ Log.i(TAG, "goBack: Trying to click the device back button")
mDevice.pressBack()
+ Log.i(TAG, "goBack: Clicked the device back button")
SettingsRobot().interact()
return SettingsRobot.Transition()
}
fun goBackToAutofillSettings(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition {
+ Log.i(TAG, "goBackToAutofillSettings: Trying to click the navigate up toolbar button")
navigateBackButton().click()
- Log.i(TAG, "goBackToAutofillSettings: Clicked \"Navigate back\" toolbar button")
+ Log.i(TAG, "goBackToAutofillSettings: Clicked the navigate up toolbar button")
SettingsSubMenuAutofillRobot().interact()
return SettingsSubMenuAutofillRobot.Transition()
}
fun goBackToSavedCreditCards(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition {
+ Log.i(TAG, "goBackToSavedCreditCards: Trying to click the navigate up toolbar button")
navigateBackButton().click()
+ Log.i(TAG, "goBackToSavedCreditCards: Clicked the navigate up toolbar button")
SettingsSubMenuAutofillRobot().interact()
return SettingsSubMenuAutofillRobot.Transition()
}
fun goBackToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
+ Log.i(TAG, "goBackToBrowser: Trying to click the device back button")
mDevice.pressBack()
- Log.i(TAG, "goBackToBrowser: Go back to browser view using device back button")
+ Log.i(TAG, "goBackToBrowser: Clicked the device back button")
BrowserRobot().interact()
return BrowserRobot.Transition()
From 4859b063800bc3679bccc3caef187027328ad5ae Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Mon, 19 Feb 2024 11:17:15 +0200
Subject: [PATCH 252/586] Bug 1880808 - Convert private variables to functions
so they don't get initialised
---
.../mozilla/fenix/ui/robots/SearchRobot.kt | 42 +++++++++----------
1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt
index c28cc8fc1467..0cf474f7024c 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt
@@ -67,14 +67,14 @@ class SearchRobot {
)
fun verifyScanButtonVisibility(visible: Boolean = true) =
- assertUIObjectExists(scanButton, exists = visible)
+ assertUIObjectExists(scanButton(), exists = visible)
fun verifyVoiceSearchButtonVisibility(enabled: Boolean) =
- assertUIObjectExists(voiceSearchButton, exists = enabled)
+ assertUIObjectExists(voiceSearchButton(), exists = enabled)
// Device or AVD requires a Google Services Android OS installation
fun startVoiceSearch() {
- voiceSearchButton.click()
+ voiceSearchButton().click()
grantSystemPermission()
if (isPackageInstalled(Constants.PackageName.GOOGLE_QUICK_SEARCH)) {
@@ -170,11 +170,11 @@ class SearchRobot {
).click()
}
- fun verifySearchSelectorButton() = assertUIObjectExists(searchSelectorButton)
+ fun verifySearchSelectorButton() = assertUIObjectExists(searchSelectorButton())
fun clickSearchSelectorButton() {
- searchSelectorButton.waitForExists(waitingTime)
- searchSelectorButton.click()
+ searchSelectorButton().waitForExists(waitingTime)
+ searchSelectorButton().click()
}
fun verifySearchEngineIcon(name: String) = assertUIObjectExists(itemWithDescription(name))
@@ -188,33 +188,33 @@ class SearchRobot {
searchEngineName.forEach {
if (shouldExist) {
assertUIObjectExists(
- searchShortcutList.getChild(UiSelector().text(it)),
+ searchShortcutList().getChild(UiSelector().text(it)),
)
} else {
- assertUIObjectIsGone(searchShortcutList.getChild(UiSelector().text(it)))
+ assertUIObjectIsGone(searchShortcutList().getChild(UiSelector().text(it)))
}
}
}
// New unified search UI search selector.
fun selectTemporarySearchMethod(searchEngineName: String) {
- searchShortcutList.getChild(UiSelector().text(searchEngineName)).click()
+ searchShortcutList().getChild(UiSelector().text(searchEngineName)).click()
}
fun clickScanButton() =
- scanButton.also {
+ scanButton().also {
it.waitForExists(waitingTime)
it.click()
}
fun clickDismissPermissionRequiredDialog() {
- dismissPermissionButton.waitForExists(waitingTime)
- dismissPermissionButton.click()
+ dismissPermissionButton().waitForExists(waitingTime)
+ dismissPermissionButton().click()
}
fun clickGoToPermissionsSettings() {
- goToPermissionsSettingsButton.waitForExists(waitingTime)
- goToPermissionsSettingsButton.click()
+ goToPermissionsSettingsButton().waitForExists(waitingTime)
+ goToPermissionsSettingsButton().click()
}
fun verifyScannerOpen() {
@@ -346,7 +346,7 @@ class SearchRobot {
}
fun clickSearchEngineSettings(interact: SettingsSubMenuSearchRobot.() -> Unit): SettingsSubMenuSearchRobot.Transition {
- searchShortcutList.getChild(UiSelector().text("Search settings")).click()
+ searchShortcutList().getChild(UiSelector().text("Search settings")).click()
SettingsSubMenuSearchRobot().interact()
return SettingsSubMenuSearchRobot.Transition()
@@ -372,22 +372,22 @@ fun searchScreen(interact: SearchRobot.() -> Unit): SearchRobot.Transition {
private fun browserToolbarEditView() =
mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_edit_url_view"))
-private val dismissPermissionButton =
+private fun dismissPermissionButton() =
mDevice.findObject(UiSelector().text("DISMISS"))
-private val goToPermissionsSettingsButton =
+private fun goToPermissionsSettingsButton() =
mDevice.findObject(UiSelector().text("GO TO SETTINGS"))
-private val scanButton = itemWithDescription("Scan")
+private fun scanButton() = itemWithDescription("Scan")
private fun clearButton() =
mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_clear_view"))
private fun searchWrapper() = mDevice.findObject(UiSelector().resourceId("$packageName:id/search_wrapper"))
-private val searchSelectorButton = itemWithResId("$packageName:id/search_selector")
+private fun searchSelectorButton() = itemWithResId("$packageName:id/search_selector")
-private val searchShortcutList =
+private fun searchShortcutList() =
mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_menu_recyclerView"))
-private val voiceSearchButton = mDevice.findObject(UiSelector().description("Voice search"))
+private fun voiceSearchButton() = mDevice.findObject(UiSelector().description("Voice search"))
From 2df6aa7397ce8974398423d8838418eb20eff9ad Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Mon, 19 Feb 2024 12:30:40 +0200
Subject: [PATCH 253/586] Bug 1880808 - Add logs to SearchRobot
---
.../mozilla/fenix/ui/robots/SearchRobot.kt | 148 ++++++++++++++----
1 file changed, 121 insertions(+), 27 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt
index 0cf474f7024c..04f0c420dddb 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt
@@ -18,7 +18,6 @@ import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performScrollToNode
import androidx.test.espresso.Espresso.onView
-import androidx.test.espresso.action.ViewActions.closeSoftKeyboard
import androidx.test.espresso.assertion.PositionAssertions
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents
@@ -34,10 +33,11 @@ import org.junit.Assert.assertTrue
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.AppAndSystemHelper.grantSystemPermission
import org.mozilla.fenix.helpers.AppAndSystemHelper.isPackageInstalled
-import org.mozilla.fenix.helpers.Constants
import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION
+import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_QUICK_SEARCH
import org.mozilla.fenix.helpers.Constants.RETRY_COUNT
import org.mozilla.fenix.helpers.Constants.SPEECH_RECOGNITION
+import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextContains
import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextEquals
@@ -74,11 +74,16 @@ class SearchRobot {
// Device or AVD requires a Google Services Android OS installation
fun startVoiceSearch() {
+ Log.i(TAG, "startVoiceSearch: Trying to click the voice search button button")
voiceSearchButton().click()
+ Log.i(TAG, "startVoiceSearch: Clicked the voice search button button")
grantSystemPermission()
- if (isPackageInstalled(Constants.PackageName.GOOGLE_QUICK_SEARCH)) {
+ if (isPackageInstalled(GOOGLE_QUICK_SEARCH)) {
+ Log.i(TAG, "startVoiceSearch: $GOOGLE_QUICK_SEARCH is installed")
+ Log.i(TAG, "startVoiceSearch: Trying to verify the intent to: $GOOGLE_QUICK_SEARCH")
Intents.intended(IntentMatchers.hasAction(SPEECH_RECOGNITION))
+ Log.i(TAG, "startVoiceSearch: Verified the intent to: $GOOGLE_QUICK_SEARCH")
}
}
@@ -91,15 +96,20 @@ class SearchRobot {
) {
rule.waitForIdle()
for (i in 1..RETRY_COUNT) {
+ Log.i(TAG, "verifySearchEngineSuggestionResults: Started try #$i")
try {
for (searchSuggestion in searchSuggestions) {
mDevice.waitForObjects(mDevice.findObject(UiSelector().textContains(searchSuggestion)))
- rule.onNodeWithTag("mozac.awesomebar.suggestions")
- .performScrollToNode(hasText(searchSuggestion))
- .assertExists()
+ Log.i(TAG, "verifySearchEngineSuggestionResults: Trying to perform scroll action to $searchSuggestion search suggestion")
+ rule.onNodeWithTag("mozac.awesomebar.suggestions").performScrollToNode(hasText(searchSuggestion))
+ Log.i(TAG, "verifySearchEngineSuggestionResults: Performed scroll action to $searchSuggestion search suggestion")
+ Log.i(TAG, "verifySearchEngineSuggestionResults: Trying to verify that $searchSuggestion search suggestion exists")
+ rule.onNodeWithTag("mozac.awesomebar.suggestions").assertExists()
+ Log.i(TAG, "verifySearchEngineSuggestionResults: Verified that $searchSuggestion search suggestion exists")
}
break
} catch (e: AssertionError) {
+ Log.i(TAG, "verifySearchEngineSuggestionResults: AssertionError caught, executing fallback methods")
if (i == RETRY_COUNT) {
throw e
} else {
@@ -117,29 +127,41 @@ class SearchRobot {
}
fun verifySuggestionsAreNotDisplayed(rule: ComposeTestRule, vararg searchSuggestions: String) {
+ Log.i(TAG, "verifySuggestionsAreNotDisplayed: Waiting for compose test rule to be idle")
rule.waitForIdle()
+ Log.i(TAG, "verifySuggestionsAreNotDisplayed: Waited for compose test rule to be idle")
for (searchSuggestion in searchSuggestions) {
+ Log.i(TAG, "verifySuggestionsAreNotDisplayed: Trying to verify that there are no $searchSuggestion related search suggestions")
rule.onAllNodesWithTag("mozac.awesomebar.suggestions")
.assertAny(
hasText(searchSuggestion)
.not(),
)
+ Log.i(TAG, "verifySuggestionsAreNotDisplayed: Verified that there are no $searchSuggestion related search suggestions")
}
}
@OptIn(ExperimentalTestApi::class)
fun verifySearchSuggestionsCount(rule: ComposeTestRule, numberOfSuggestions: Int, searchTerm: String) {
for (i in 1..RETRY_COUNT) {
+ Log.i(TAG, "verifySearchSuggestionsCount: Started try #$i")
try {
+ Log.i(TAG, "verifySearchSuggestionsCount: Compose test rule is waiting for $waitingTime ms until the note count equals to: $numberOfSuggestions")
rule.waitUntilNodeCount(hasTestTag("mozac.awesomebar.suggestion"), numberOfSuggestions, waitingTime)
+ Log.i(TAG, "verifySearchSuggestionsCount: Compose test rule waited for $waitingTime ms until the note count equals to: $numberOfSuggestions")
+ Log.i(TAG, "verifySearchSuggestionsCount: Trying to verify that the count of the search suggestions equals: $numberOfSuggestions")
rule.onAllNodesWithTag("mozac.awesomebar.suggestion").assertCountEquals(numberOfSuggestions)
+ Log.i(TAG, "verifySearchSuggestionsCount: Verified that the count of the search suggestions equals: $numberOfSuggestions")
break
} catch (e: ComposeTimeoutException) {
+ Log.i(TAG, "verifySearchSuggestionsCount: ComposeTimeoutException caught, executing fallback methods")
if (i == RETRY_COUNT) {
throw e
} else {
+ Log.i(TAG, "verifySearchSuggestionsCount: Trying to click device back button")
mDevice.pressBack()
+ Log.i(TAG, "verifySearchSuggestionsCount: Clicked device back button")
homeScreen {
}.openSearch {
typeSearch(searchTerm)
@@ -159,28 +181,38 @@ class SearchRobot {
)
fun denySuggestionsInPrivateMode() {
+ Log.i(TAG, "denySuggestionsInPrivateMode: Trying to click the \"Don’t allow\" button")
mDevice.findObject(
UiSelector().text(getStringResource(R.string.search_suggestions_onboarding_do_not_allow_button)),
).click()
+ Log.i(TAG, "denySuggestionsInPrivateMode: Clicked the \"Don’t allow\" button")
}
fun allowSuggestionsInPrivateMode() {
+ Log.i(TAG, "allowSuggestionsInPrivateMode: Trying to click the \"Allow\" button")
mDevice.findObject(
UiSelector().text(getStringResource(R.string.search_suggestions_onboarding_allow_button)),
).click()
+ Log.i(TAG, "allowSuggestionsInPrivateMode: Clicked the \"Allow\" button")
}
fun verifySearchSelectorButton() = assertUIObjectExists(searchSelectorButton())
fun clickSearchSelectorButton() {
+ Log.i(TAG, "clickSearchSelectorButton: Waiting for $waitingTime ms for search selector button to exist")
searchSelectorButton().waitForExists(waitingTime)
+ Log.i(TAG, "clickSearchSelectorButton: Waited for $waitingTime ms for 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")
}
fun verifySearchEngineIcon(name: String) = assertUIObjectExists(itemWithDescription(name))
fun verifySearchBarPlaceholder(text: String) {
+ Log.i(TAG, "verifySearchBarPlaceholder: Waiting for $waitingTime ms for the edit mode toolbar to exist")
browserToolbarEditView().waitForExists(waitingTime)
+ Log.i(TAG, "verifySearchBarPlaceholder: Waited for $waitingTime ms for the edit mode toolbar to exist")
assertItemTextEquals(browserToolbarEditView(), expectedText = text)
}
@@ -198,95 +230,128 @@ class SearchRobot {
// New unified search UI search selector.
fun selectTemporarySearchMethod(searchEngineName: String) {
+ Log.i(TAG, "selectTemporarySearchMethod: Trying to click the $searchEngineName search shortcut")
searchShortcutList().getChild(UiSelector().text(searchEngineName)).click()
+ Log.i(TAG, "selectTemporarySearchMethod: Clicked the $searchEngineName search shortcut")
}
fun clickScanButton() =
scanButton().also {
+ Log.i(TAG, "clickScanButton: Waiting for $waitingTime ms for the scan button to exist")
it.waitForExists(waitingTime)
+ Log.i(TAG, "clickScanButton: Waited for $waitingTime ms for the scan button to exist")
+ Log.i(TAG, "clickScanButton: Trying to click the scan button")
it.click()
+ Log.i(TAG, "clickScanButton: Clicked the scan button")
}
fun clickDismissPermissionRequiredDialog() {
+ Log.i(TAG, "clickDismissPermissionRequiredDialog: Waiting for $waitingTime ms for the \"Dismiss\" permission button to exist")
dismissPermissionButton().waitForExists(waitingTime)
+ Log.i(TAG, "clickDismissPermissionRequiredDialog: Waited for $waitingTime ms for the \"Dismiss\" permission button to exist")
+ Log.i(TAG, "clickDismissPermissionRequiredDialog: Trying to click the \"Dismiss\" permission button")
dismissPermissionButton().click()
+ Log.i(TAG, "clickDismissPermissionRequiredDialog: Clicked the \"Dismiss\" permission button")
}
fun clickGoToPermissionsSettings() {
+ Log.i(TAG, "clickGoToPermissionsSettings: Waiting for $waitingTime ms for the \"Go To Settings\" permission button to exist")
goToPermissionsSettingsButton().waitForExists(waitingTime)
+ Log.i(TAG, "clickGoToPermissionsSettings: Waited for $waitingTime ms for the \"Go To Settings\" permission button to exist")
+ Log.i(TAG, "clickGoToPermissionsSettings: Trying to click the \"Go To Settings\" permission button")
goToPermissionsSettingsButton().click()
+ Log.i(TAG, "clickGoToPermissionsSettings: Clicked the \"Go To Settings\" permission button")
}
fun verifyScannerOpen() {
+ Log.i(TAG, "verifyScannerOpen: Trying to verify that the device camera is opened or that the camera app error message exist")
assertTrue(
+ "$TAG: Neither the device camera was opened nor the camera app error message was displayed",
mDevice.findObject(UiSelector().resourceId("$packageName:id/view_finder"))
.waitForExists(waitingTime) ||
// In case there is no camera available, an error will be shown.
mDevice.findObject(UiSelector().resourceId("$packageName:id/camera_error"))
.exists(),
)
+ Log.i(TAG, "verifyScannerOpen: Verified that the device camera is opened or that the camera app error message exist")
}
fun typeSearch(searchTerm: String) {
- mDevice.findObject(
- UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_edit_url_view"),
- ).waitForExists(waitingTime)
-
+ Log.i(TAG, "typeSearch: Waiting for $waitingTime ms for the edit mode toolbar to exist")
+ browserToolbarEditView().waitForExists(waitingTime)
+ Log.i(TAG, "typeSearch: Waited for $waitingTime ms for the edit mode toolbar to exist")
+ Log.i(TAG, "typeSearch: Trying to set the edit mode toolbar text to $searchTerm")
browserToolbarEditView().setText(searchTerm)
-
+ Log.i(TAG, "typeSearch: Edit mode toolbar text was set to $searchTerm")
+ Log.i(TAG, "typeSearch: Waiting for device to be idle")
mDevice.waitForIdle()
+ Log.i(TAG, "typeSearch: Waited for device to be idle")
}
fun clickClearButton() {
+ Log.i(TAG, "clickClearButton: Trying to click the clear button")
clearButton().click()
+ Log.i(TAG, "clickClearButton: Clicked the clear button")
}
fun tapOutsideToDismissSearchBar() {
+ Log.i(TAG, "tapOutsideToDismissSearchBar: Trying to click the search wrapper")
itemWithResId("$packageName:id/search_wrapper").click()
- itemWithResId("$packageName:id/mozac_browser_toolbar_edit_url_view")
- .waitUntilGone(waitingTime)
+ Log.i(TAG, "tapOutsideToDismissSearchBar: Clicked the search wrapper")
+ Log.i(TAG, "tapOutsideToDismissSearchBar: Waiting for $waitingTime ms for the edit mode toolbar to be gone")
+ browserToolbarEditView().waitUntilGone(waitingTime)
+ Log.i(TAG, "tapOutsideToDismissSearchBar: Waited for $waitingTime ms for the edit mode toolbar to be gone")
}
fun longClickToolbar() {
+ Log.i(TAG, "longClickToolbar: Waiting for $waitingTime ms for $packageName window to be updated")
mDevice.waitForWindowUpdate(packageName, waitingTime)
+ Log.i(TAG, "longClickToolbar: Waited for $waitingTime ms for $packageName window to be updated")
+ Log.i(TAG, "longClickToolbar: Waiting for $waitingTime ms for the awesome bar to exist")
mDevice.findObject(UiSelector().resourceId("$packageName:id/awesomeBar"))
.waitForExists(waitingTime)
+ Log.i(TAG, "longClickToolbar: Waited for $waitingTime ms for the awesome bar to exist")
+ Log.i(TAG, "longClickToolbar: Waiting for $waitingTime ms for the toolbar to exist")
mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar"))
.waitForExists(waitingTime)
- val toolbar = mDevice.findObject(By.res("$packageName:id/toolbar"))
- toolbar.click(LONG_CLICK_DURATION)
+ Log.i(TAG, "longClickToolbar: Waited for $waitingTime ms for the toolbar to exist")
+ Log.i(TAG, "longClickToolbar: Trying to perform long click on the toolbar")
+ mDevice.findObject(By.res("$packageName:id/toolbar")).click(LONG_CLICK_DURATION)
+ Log.i(TAG, "longClickToolbar: Performed long click on the toolbar")
}
fun clickPasteText() {
+ Log.i(TAG, "clickPasteText: Waiting for $waitingTime ms for the \"Paste\" option to exist")
mDevice.findObject(UiSelector().textContains("Paste")).waitForExists(waitingTime)
- val pasteText = mDevice.findObject(By.textContains("Paste"))
- pasteText.click()
- }
-
- fun expandSearchSuggestionsList() {
- onView(allOf(withId(R.id.search_wrapper))).perform(
- closeSoftKeyboard(),
- )
- browserToolbarEditView().swipeUp(2)
+ Log.i(TAG, "clickPasteText: Waited for $waitingTime ms for the \"Paste\" option to exist")
+ Log.i(TAG, "clickPasteText: Trying to click the \"Paste\" button")
+ mDevice.findObject(By.textContains("Paste")).click()
+ Log.i(TAG, "clickPasteText: Clicked the \"Paste\" button")
}
fun verifyTranslatedFocusedNavigationToolbar(toolbarHintString: String) =
assertItemTextContains(browserToolbarEditView(), itemText = toolbarHintString)
fun verifyTypedToolbarText(expectedText: String) {
+ Log.i(TAG, "verifyTypedToolbarText: Waiting for $waitingTime ms for the toolbar to exist")
mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar"))
.waitForExists(waitingTime)
- mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_url_view"))
- .waitForExists(waitingTime)
+ Log.i(TAG, "verifyTypedToolbarText: Waited for $waitingTime ms for the toolbar to exist")
+ Log.i(TAG, "verifyTypedToolbarText: Waiting for $waitingTime ms for the edit mode toolbar to exist")
+ browserToolbarEditView().waitForExists(waitingTime)
+ Log.i(TAG, "verifyTypedToolbarText: Waited for $waitingTime ms for the edit mode toolbar to exist")
+ Log.i(TAG, "verifyTypedToolbarText: Trying to verify that $expectedText is visible in the toolbar")
onView(
allOf(
withText(expectedText),
withId(R.id.mozac_browser_toolbar_edit_url_view),
),
).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
+ Log.i(TAG, "verifyTypedToolbarText: Verified that $expectedText is visible in the toolbar")
}
fun verifySearchBarPosition(bottomPosition: Boolean) {
+ Log.i(TAG, "verifySearchBarPosition: Trying to verify that the search bar is set to bottom: $bottomPosition")
onView(withId(R.id.toolbar))
.check(
if (bottomPosition) {
@@ -295,13 +360,17 @@ class SearchRobot {
PositionAssertions.isCompletelyAbove(withId(R.id.keyboard_divider))
},
)
+ Log.i(TAG, "verifySearchBarPosition: Verified that the search bar is set to bottom: $bottomPosition")
}
fun deleteSearchKeywordCharacters(numberOfDeletionSteps: Int) {
for (i in 1..numberOfDeletionSteps) {
+ Log.i(TAG, "deleteSearchKeywordCharacters: Trying to click keyboard delete button $i times")
mDevice.pressDelete()
- Log.i(Constants.TAG, "deleteSearchKeywordCharacters: Pressed keyboard delete button $i times")
+ Log.i(TAG, "deleteSearchKeywordCharacters: Clicked keyboard delete button $i times")
+ Log.i(TAG, "deleteSearchKeywordCharacters: Waiting for $waitingTimeShort ms for $appName window to be updated")
mDevice.waitForWindowUpdate(appName, waitingTimeShort)
+ Log.i(TAG, "deleteSearchKeywordCharacters: Waited for $waitingTimeShort ms for $appName window to be updated")
}
}
@@ -310,11 +379,18 @@ class SearchRobot {
fun dismissSearchBar(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
try {
+ Log.i(TAG, "dismissSearchBar: Waiting for $waitingTime ms for the search wrapper to exist")
searchWrapper().waitForExists(waitingTime)
+ Log.i(TAG, "dismissSearchBar: Waited for $waitingTime ms for the search wrapper to exist")
+ Log.i(TAG, "dismissSearchBar: Trying to click device back button")
mDevice.pressBack()
+ Log.i(TAG, "dismissSearchBar: Clicked device back button")
assertUIObjectIsGone(searchWrapper())
} catch (e: AssertionError) {
+ Log.i(TAG, "dismissSearchBar: AssertionError caught, executing fallback methods")
+ Log.i(TAG, "dismissSearchBar: Trying to click device back button")
mDevice.pressBack()
+ Log.i(TAG, "dismissSearchBar: Clicked device back button")
assertUIObjectIsGone(searchWrapper())
}
@@ -323,9 +399,15 @@ class SearchRobot {
}
fun openBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
+ Log.i(TAG, "openBrowser: Waiting for device to be idle")
mDevice.waitForIdle()
+ Log.i(TAG, "openBrowser: Waited for device to be idle")
+ Log.i(TAG, "openBrowser: Trying to set the edit mode toolbar text to: mozilla")
browserToolbarEditView().setText("mozilla\n")
+ Log.i(TAG, "openBrowser: Edit mode toolbar text was set to: mozilla")
+ Log.i(TAG, "openBrowser: Trying to click device enter button")
mDevice.pressEnter()
+ Log.i(TAG, "openBrowser: Clicked device enter button")
BrowserRobot().interact()
return BrowserRobot.Transition()
@@ -333,9 +415,15 @@ class SearchRobot {
fun submitQuery(query: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
sessionLoadedIdlingResource = SessionLoadedIdlingResource()
+ Log.i(TAG, "submitQuery: Waiting for $waitingTime ms for the search wrapper to exist")
searchWrapper().waitForExists(waitingTime)
+ Log.i(TAG, "submitQuery: Waited for $waitingTime ms for the search wrapper to exist")
+ Log.i(TAG, "submitQuery: Trying to set the edit mode toolbar text to: $query")
browserToolbarEditView().setText(query)
+ Log.i(TAG, "submitQuery: Edit mode toolbar text was set to: $query")
+ Log.i(TAG, "submitQuery: Trying to click device enter button")
mDevice.pressEnter()
+ Log.i(TAG, "submitQuery: Clicked device enter button")
runWithIdleRes(sessionLoadedIdlingResource) {
assertUIObjectExists(itemWithResId("$packageName:id/browserLayout"))
@@ -346,7 +434,9 @@ class SearchRobot {
}
fun clickSearchEngineSettings(interact: SettingsSubMenuSearchRobot.() -> Unit): SettingsSubMenuSearchRobot.Transition {
+ Log.i(TAG, "clickSearchEngineSettings: Trying to click the \"Search settings\" button")
searchShortcutList().getChild(UiSelector().text("Search settings")).click()
+ Log.i(TAG, "clickSearchEngineSettings: Clicked the \"Search settings\" button")
SettingsSubMenuSearchRobot().interact()
return SettingsSubMenuSearchRobot.Transition()
@@ -354,8 +444,12 @@ class SearchRobot {
fun clickSearchSuggestion(searchSuggestion: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
mDevice.findObject(UiSelector().textContains(searchSuggestion)).also {
+ Log.i(TAG, "clickSearchSuggestion: Waiting for $waitingTime ms for search suggestion: $searchSuggestion to exist")
it.waitForExists(waitingTime)
+ Log.i(TAG, "clickSearchSuggestion: Waited for $waitingTime ms for search suggestion: $searchSuggestion to exist")
+ Log.i(TAG, "clickSearchSuggestion: Trying to click search suggestion: $searchSuggestion and wait for $waitingTimeShort ms for a new window")
it.clickAndWaitForNewWindow(waitingTimeShort)
+ Log.i(TAG, "clickSearchSuggestion: Clicked search suggestion: $searchSuggestion and waited for $waitingTimeShort ms for a new window")
}
BrowserRobot().interact()
From 26a838911c3b5653aa79dd9a4efd978cad5c59f3 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Mon, 19 Feb 2024 13:13:26 +0200
Subject: [PATCH 254/586] Bug 1880812 - Convert private variables to functions
so they don't get initialised
---
.../fenix/ui/robots/SettingsSubMenuCustomizeRobot.kt | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuCustomizeRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuCustomizeRobot.kt
index 20d455d19766..d8be72bed145 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuCustomizeRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuCustomizeRobot.kt
@@ -46,12 +46,12 @@ class SettingsSubMenuCustomizeRobot {
.check(matches(hasSibling(allOf(withId(R.id.radio_button), isChecked()))))
}
- fun clickSwipeToolbarToSwitchTabToggle() = swipeToolbarToggle.click()
+ fun clickSwipeToolbarToSwitchTabToggle() = swipeToolbarToggle().click()
- fun clickPullToRefreshToggle() = pullToRefreshToggle.click()
+ fun clickPullToRefreshToggle() = pullToRefreshToggle().click()
fun verifySwipeToolbarGesturePrefState(isEnabled: Boolean) {
- swipeToolbarToggle
+ swipeToolbarToggle()
.check(
matches(
hasCousin(
@@ -69,7 +69,7 @@ class SettingsSubMenuCustomizeRobot {
}
fun verifyPullToRefreshGesturePrefState(isEnabled: Boolean) {
- pullToRefreshToggle
+ pullToRefreshToggle()
.check(
matches(
hasCousin(
@@ -120,10 +120,10 @@ private fun deviceModeToggle(): ViewInteraction {
return onView(withText(followDeviceThemeText))
}
-private val swipeToolbarToggle =
+private fun swipeToolbarToggle() =
onView(withText(getStringResource(R.string.preference_gestures_swipe_toolbar_switch_tabs)))
-private val pullToRefreshToggle =
+private fun pullToRefreshToggle() =
onView(withText(getStringResource(R.string.preference_gestures_website_pull_to_refresh)))
private fun goBackButton() =
From 4b0fe5b5bdf2421a3545f9626d4ab75467395708 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Mon, 19 Feb 2024 13:28:57 +0200
Subject: [PATCH 255/586] Bug 1880812 - Add logs to
SettingsSubMenuCustomizeRobot
---
.../robots/SettingsSubMenuCustomizeRobot.kt | 76 ++++++++++++++-----
1 file changed, 58 insertions(+), 18 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuCustomizeRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuCustomizeRobot.kt
index d8be72bed145..e9ffe4992342 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuCustomizeRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuCustomizeRobot.kt
@@ -7,9 +7,10 @@
package org.mozilla.fenix.ui.robots
import android.os.Build
+import android.util.Log
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.ViewInteraction
-import androidx.test.espresso.action.ViewActions
+import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.hasSibling
@@ -21,6 +22,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.Matchers.endsWith
import org.mozilla.fenix.R
+import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.TestHelper.hasCousin
import org.mozilla.fenix.helpers.TestHelper.mDevice
@@ -31,26 +33,66 @@ import org.mozilla.fenix.helpers.click
*/
class SettingsSubMenuCustomizeRobot {
- fun verifyThemes() = assertThemes()
+ fun verifyThemes() {
+ Log.i(TAG, "verifyThemes: Trying to verify that the \"Light\" mode option is visible")
+ lightModeToggle()
+ .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
+ Log.i(TAG, "verifyThemes: Verified that the \"Light\" mode option is visible")
+ Log.i(TAG, "verifyThemes: Trying to verify that the \"Dark\" mode option is visible")
+ darkModeToggle()
+ .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
+ Log.i(TAG, "verifyThemes: Verified that the \"Dark\" mode option is visible")
+ Log.i(TAG, "verifyThemes: Trying to verify that the \"Follow device theme\" option is visible")
+ deviceModeToggle()
+ .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
+ Log.i(TAG, "verifyThemes: Verified that the \"Follow device theme\" option is visible")
+ }
- fun selectDarkMode() = darkModeToggle().click()
+ fun selectDarkMode() {
+ Log.i(TAG, "selectDarkMode: Trying to click the \"Dark\" mode option")
+ darkModeToggle().click()
+ Log.i(TAG, "selectDarkMode: Clicked the \"Dark\" mode option")
+ }
- fun selectLightMode() = lightModeToggle().click()
+ fun selectLightMode() {
+ Log.i(TAG, "selectLightMode: Trying to click the \"Light\" mode option")
+ lightModeToggle().click()
+ Log.i(TAG, "selectLightMode: Clicked the \"Light\" mode option")
+ }
- fun clickTopToolbarToggle() = topToolbarToggle().click()
+ fun clickTopToolbarToggle() {
+ Log.i(TAG, "clickTopToolbarToggle: Trying to click the \"Top\" toolbar option")
+ topToolbarToggle().click()
+ Log.i(TAG, "clickTopToolbarToggle: Clicked the \"Top\" toolbar option")
+ }
- fun clickBottomToolbarToggle() = bottomToolbarToggle().click()
+ fun clickBottomToolbarToggle() {
+ Log.i(TAG, "clickBottomToolbarToggle: Trying to click the \"Bottom\" toolbar option")
+ bottomToolbarToggle().click()
+ Log.i(TAG, "clickBottomToolbarToggle: Clicked the \"Bottom\" toolbar option")
+ }
fun verifyToolbarPositionPreference(selectedPosition: String) {
+ Log.i(TAG, "verifyToolbarPositionPreference: Trying to verify that the $selectedPosition toolbar option is checked")
onView(withText(selectedPosition))
.check(matches(hasSibling(allOf(withId(R.id.radio_button), isChecked()))))
+ Log.i(TAG, "verifyToolbarPositionPreference: Verified that the $selectedPosition toolbar option is checked")
}
- fun clickSwipeToolbarToSwitchTabToggle() = swipeToolbarToggle().click()
+ fun clickSwipeToolbarToSwitchTabToggle() {
+ Log.i(TAG, "clickSwipeToolbarToSwitchTabToggle: Trying to click the \"Swipe toolbar sideways to switch tabs\" toggle")
+ swipeToolbarToggle().click()
+ Log.i(TAG, "clickSwipeToolbarToSwitchTabToggle: Clicked the \"Swipe toolbar sideways to switch tabs\" toggle")
+ }
- fun clickPullToRefreshToggle() = pullToRefreshToggle().click()
+ fun clickPullToRefreshToggle() {
+ Log.i(TAG, "clickPullToRefreshToggle: Trying to click the \"Pull to refresh\" toggle")
+ pullToRefreshToggle().click()
+ Log.i(TAG, "clickPullToRefreshToggle: Clicked the \"Pull to refresh\" toggle")
+ }
fun verifySwipeToolbarGesturePrefState(isEnabled: Boolean) {
+ Log.i(TAG, "verifySwipeToolbarGesturePrefState: Trying to verify that the \"Swipe toolbar sideways to switch tabs\" toggle is checked: $isEnabled")
swipeToolbarToggle()
.check(
matches(
@@ -66,9 +108,11 @@ class SettingsSubMenuCustomizeRobot {
),
),
)
+ Log.i(TAG, "verifySwipeToolbarGesturePrefState: Verified that the \"Swipe toolbar sideways to switch tabs\" toggle is checked: $isEnabled")
}
fun verifyPullToRefreshGesturePrefState(isEnabled: Boolean) {
+ Log.i(TAG, "verifyPullToRefreshGesturePrefState: Trying to verify that the \"Pull to refresh\" toggle is checked: $isEnabled")
pullToRefreshToggle()
.check(
matches(
@@ -84,12 +128,17 @@ class SettingsSubMenuCustomizeRobot {
),
),
)
+ Log.i(TAG, "verifyPullToRefreshGesturePrefState: Verified that the \"Pull to refresh\" toggle is checked: $isEnabled")
}
class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
+ Log.i(TAG, "goBack: Waiting for device to be idle")
mDevice.waitForIdle()
- goBackButton().perform(ViewActions.click())
+ Log.i(TAG, "goBack: Waited for device to be idle")
+ Log.i(TAG, "goBack: Trying to click the navigate up toolbar button")
+ goBackButton().perform(click())
+ Log.i(TAG, "goBack: Clicked the navigate up toolbar button")
SettingsRobot().interact()
return SettingsRobot.Transition()
@@ -97,15 +146,6 @@ class SettingsSubMenuCustomizeRobot {
}
}
-private fun assertThemes() {
- lightModeToggle()
- .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
- darkModeToggle()
- .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
- deviceModeToggle()
- .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
-}
-
private fun darkModeToggle() = onView(withText("Dark"))
private fun lightModeToggle() = onView(withText("Light"))
From 840668dd7c1767f7efca013fac7c4a7f1aa794bd Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Mon, 19 Feb 2024 14:42:24 +0200
Subject: [PATCH 256/586] Bug 1880821 - Add test logs to
SettingsSubMenuDataCollectionRobot
---
.../SettingsSubMenuDataCollectionRobot.kt | 63 +++++++++++++++----
1 file changed, 50 insertions(+), 13 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDataCollectionRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDataCollectionRobot.kt
index 062d3a05cf35..10a375746454 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDataCollectionRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDataCollectionRobot.kt
@@ -4,6 +4,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
@@ -17,6 +18,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.endsWith
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
@@ -54,7 +56,8 @@ class SettingsSubMenuDataCollectionRobot {
)
}
- fun verifyUsageAndTechnicalDataToggle(enabled: Boolean) =
+ fun verifyUsageAndTechnicalDataToggle(enabled: Boolean) {
+ Log.i(TAG, "verifyUsageAndTechnicalDataToggle: Trying to verify that the \"Usage and technical data\" toggle is checked: $enabled")
onView(withText(R.string.preference_usage_data))
.check(
matches(
@@ -70,8 +73,11 @@ class SettingsSubMenuDataCollectionRobot {
),
),
)
+ Log.i(TAG, "verifyUsageAndTechnicalDataToggle: Verified that the \"Usage and technical data\" toggle is checked: $enabled")
+ }
- fun verifyMarketingDataToggle(enabled: Boolean) =
+ fun verifyMarketingDataToggle(enabled: Boolean) {
+ Log.i(TAG, "verifyMarketingDataToggle: Trying to verify that the \"Marketing data\" toggle is checked: $enabled")
onView(withText(R.string.preferences_marketing_data))
.check(
matches(
@@ -87,8 +93,11 @@ class SettingsSubMenuDataCollectionRobot {
),
),
)
+ Log.i(TAG, "verifyMarketingDataToggle: Verified that the \"Marketing data\" toggle is checked: $enabled")
+ }
- fun verifyStudiesToggle(enabled: Boolean) =
+ fun verifyStudiesToggle(enabled: Boolean) {
+ Log.i(TAG, "verifyStudiesToggle: Trying to verify that the \"Studies\" toggle is checked: $enabled")
onView(withId(R.id.studies_switch))
.check(
matches(
@@ -99,35 +108,63 @@ class SettingsSubMenuDataCollectionRobot {
},
),
)
+ Log.i(TAG, "verifyStudiesToggle: Verified that the \"Studies\" toggle is checked: $enabled")
+ }
- fun clickUsageAndTechnicalDataToggle() =
+ fun clickUsageAndTechnicalDataToggle() {
+ Log.i(TAG, "clickUsageAndTechnicalDataToggle: Trying to click the \"Usage and technical data\" toggle")
itemContainingText(getStringResource(R.string.preference_usage_data)).click()
+ Log.i(TAG, "clickUsageAndTechnicalDataToggle: Clicked the \"Usage and technical data\" toggle")
+ }
- fun clickMarketingDataToggle() =
+ fun clickMarketingDataToggle() {
+ Log.i(TAG, "clickUsageAndTechnicalDataToggle: Trying to click the \"Marketing data\" toggle")
itemContainingText(getStringResource(R.string.preferences_marketing_data)).click()
+ Log.i(TAG, "clickUsageAndTechnicalDataToggle: Clicked the \"Marketing data\" toggle")
+ }
- fun clickStudiesOption() =
+ fun clickStudiesOption() {
+ Log.i(TAG, "clickStudiesOption: Trying to click the \"Studies\" option")
itemContainingText(getStringResource(R.string.preference_experiments_2)).click()
+ Log.i(TAG, "clickStudiesOption: Clicked the \"Studies\" option")
+ }
- fun clickStudiesToggle() =
+ fun clickStudiesToggle() {
+ Log.i(TAG, "clickStudiesToggle: Trying to click the \"Studies\" toggle")
itemWithResId("$packageName:id/studies_switch").click()
+ Log.i(TAG, "clickStudiesToggle: Clicked the \"Studies\" toggle")
+ }
fun verifyStudiesDialog() {
assertUIObjectExists(
itemWithResId("$packageName:id/alertTitle"),
itemContainingText(getStringResource(R.string.studies_restart_app)),
)
- studiesDialogOkButton.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
- studiesDialogCancelButton.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
+ Log.i(TAG, "verifyStudiesDialog: Trying to verify that the \"Studies\" dialog \"Ok\" button is visible")
+ studiesDialogOkButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
+ Log.i(TAG, "verifyStudiesDialog: Verified that the \"Studies\" dialog \"Ok\" button is visible")
+ Log.i(TAG, "verifyStudiesDialog: Trying to verify that the \"Studies\" dialog \"Cancel\" button is visible")
+ studiesDialogCancelButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
+ Log.i(TAG, "verifyStudiesDialog: Verified that the \"Studies\" dialog \"Cancel\" button is visible")
}
- fun clickStudiesDialogCancelButton() = studiesDialogCancelButton.click()
+ fun clickStudiesDialogCancelButton() {
+ Log.i(TAG, "clickStudiesDialogCancelButton: Trying to click the \"Studies\" dialog \"Cancel\" button")
+ studiesDialogCancelButton().click()
+ Log.i(TAG, "clickStudiesDialogCancelButton: Clicked the \"Studies\" dialog \"Cancel\" button")
+ }
- fun clickStudiesDialogOkButton() = studiesDialogOkButton.click()
+ fun clickStudiesDialogOkButton() {
+ Log.i(TAG, "clickStudiesDialogOkButton: Trying to click the \"Studies\" dialog \"Ok\" button")
+ studiesDialogOkButton().click()
+ Log.i(TAG, "clickStudiesDialogOkButton: Clicked the \"Studies\" dialog \"Ok\" button")
+ }
class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
+ Log.i(TAG, "goBack: Trying to click the navigate up toolbar button")
goBackButton().click()
+ Log.i(TAG, "goBack: Clicked the navigate up toolbar button")
SettingsRobot().interact()
return SettingsRobot.Transition()
@@ -136,5 +173,5 @@ class SettingsSubMenuDataCollectionRobot {
}
private fun goBackButton() = itemWithDescription("Navigate up")
-private val studiesDialogOkButton = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog())
-private val studiesDialogCancelButton = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog())
+private fun studiesDialogOkButton() = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog())
+private fun studiesDialogCancelButton() = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog())
From 9d8158c4feb6b8148b6dea70a62b84d56c338a40 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Mon, 19 Feb 2024 15:01:07 +0200
Subject: [PATCH 257/586] Bug 1880827 - Convert private variables to functions
so they don't get initialised
---
...ngsSubMenuDeleteBrowsingDataOnQuitRobot.kt | 31 ++++++++++---------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataOnQuitRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataOnQuitRobot.kt
index a818ef487f0c..1f7a8feb4c37 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataOnQuitRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataOnQuitRobot.kt
@@ -28,7 +28,7 @@ import org.mozilla.fenix.helpers.isChecked
*/
class SettingsSubMenuDeleteBrowsingDataOnQuitRobot {
- fun verifyNavigationToolBarHeader() =
+ fun verifyNavigationToolBarHeader() {
onView(
allOf(
withId(R.id.navigationToolbar),
@@ -36,9 +36,10 @@ class SettingsSubMenuDeleteBrowsingDataOnQuitRobot {
),
)
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ }
fun verifyDeleteBrowsingOnQuitEnabled(enabled: Boolean) =
- deleteBrowsingOnQuitButton.assertIsChecked(enabled)
+ deleteBrowsingOnQuitButton().assertIsChecked(enabled)
fun verifyDeleteBrowsingOnQuitButtonSummary() =
onView(
@@ -48,25 +49,25 @@ class SettingsSubMenuDeleteBrowsingDataOnQuitRobot {
fun clickDeleteBrowsingOnQuitButtonSwitch() = onView(withResourceName("switch_widget")).click()
fun verifyAllTheCheckBoxesText() {
- openTabsCheckbox
+ openTabsCheckbox()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
- browsingHistoryCheckbox
+ browsingHistoryCheckbox()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
- cookiesAndSiteDataCheckbox
+ cookiesAndSiteDataCheckbox()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
onView(withText(R.string.preferences_delete_browsing_data_cookies_subtitle))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
- cachedFilesCheckbox
+ cachedFilesCheckbox()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
onView(withText(R.string.preferences_delete_browsing_data_cached_files_subtitle))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
- sitePermissionsCheckbox
+ sitePermissionsCheckbox()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
@@ -91,7 +92,7 @@ class SettingsSubMenuDeleteBrowsingDataOnQuitRobot {
class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
- goBackButton.click()
+ goBackButton().click()
SettingsRobot().interact()
return SettingsRobot.Transition()
@@ -99,21 +100,21 @@ class SettingsSubMenuDeleteBrowsingDataOnQuitRobot {
}
}
-private val goBackButton = onView(withContentDescription("Navigate up"))
+private fun goBackButton() = onView(withContentDescription("Navigate up"))
-private val deleteBrowsingOnQuitButton =
+private fun deleteBrowsingOnQuitButton() =
onView(withClassName(containsString("android.widget.Switch")))
-private val openTabsCheckbox =
+private fun openTabsCheckbox() =
onView(withText(R.string.preferences_delete_browsing_data_tabs_title_2))
-private val browsingHistoryCheckbox =
+private fun browsingHistoryCheckbox() =
onView(withText(R.string.preferences_delete_browsing_data_browsing_history_title))
-private val cookiesAndSiteDataCheckbox = onView(withText(R.string.preferences_delete_browsing_data_cookies_and_site_data))
+private fun cookiesAndSiteDataCheckbox() = onView(withText(R.string.preferences_delete_browsing_data_cookies_and_site_data))
-private val cachedFilesCheckbox =
+private fun cachedFilesCheckbox() =
onView(withText(R.string.preferences_delete_browsing_data_cached_files))
-private val sitePermissionsCheckbox =
+private fun sitePermissionsCheckbox() =
onView(withText(R.string.preferences_delete_browsing_data_site_permissions))
From 9fdb6f4930578134b83c1fd16b317545d29ff046 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Mon, 19 Feb 2024 15:18:24 +0200
Subject: [PATCH 258/586] Bug 1880827 - Add test logs to
SettingsSubMenuDeleteBrowsingDataOnQuitRobot
---
...ngsSubMenuDeleteBrowsingDataOnQuitRobot.kt | 44 +++++++++++++++----
1 file changed, 35 insertions(+), 9 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataOnQuitRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataOnQuitRobot.kt
index 1f7a8feb4c37..af8c306925bd 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataOnQuitRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataOnQuitRobot.kt
@@ -4,6 +4,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.ViewMatchers.Visibility
@@ -18,6 +19,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.containsString
import org.mozilla.fenix.R
+import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.assertIsChecked
import org.mozilla.fenix.helpers.atPosition
import org.mozilla.fenix.helpers.click
@@ -29,6 +31,7 @@ import org.mozilla.fenix.helpers.isChecked
class SettingsSubMenuDeleteBrowsingDataOnQuitRobot {
fun verifyNavigationToolBarHeader() {
+ Log.i(TAG, "verifyNavigationToolBarHeader: Trying to verify that the \"Delete browsing data on quit\" toolbar title is visible")
onView(
allOf(
withId(R.id.navigationToolbar),
@@ -36,43 +39,63 @@ class SettingsSubMenuDeleteBrowsingDataOnQuitRobot {
),
)
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ Log.i(TAG, "verifyNavigationToolBarHeader: Verified that the \"Delete browsing data on quit\" toolbar title is visible")
}
- fun verifyDeleteBrowsingOnQuitEnabled(enabled: Boolean) =
+ fun verifyDeleteBrowsingOnQuitEnabled(enabled: Boolean) {
+ Log.i(TAG, "verifyDeleteBrowsingOnQuitEnabled: Trying to verify that the \"Delete browsing data on quit\" toggle is checked: $enabled")
deleteBrowsingOnQuitButton().assertIsChecked(enabled)
+ Log.i(TAG, "verifyDeleteBrowsingOnQuitEnabled: Verified that the \"Delete browsing data on quit\" toggle is checked: $enabled")
+ }
- fun verifyDeleteBrowsingOnQuitButtonSummary() =
+ fun verifyDeleteBrowsingOnQuitButtonSummary() {
+ Log.i(TAG, "verifyDeleteBrowsingOnQuitButtonSummary: Trying to verify that the \"Delete browsing data on quit\" option summary is visible")
onView(
withText(R.string.preference_summary_delete_browsing_data_on_quit_2),
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ Log.i(TAG, "verifyDeleteBrowsingOnQuitButtonSummary: Verified that the \"Delete browsing data on quit\" option summary is visible")
+ }
- fun clickDeleteBrowsingOnQuitButtonSwitch() = onView(withResourceName("switch_widget")).click()
+ fun clickDeleteBrowsingOnQuitButtonSwitch() {
+ Log.i(TAG, "clickDeleteBrowsingOnQuitButtonSwitch: Trying to click the \"Delete browsing data on quit\" toggle")
+ onView(withResourceName("switch_widget")).click()
+ Log.i(TAG, "clickDeleteBrowsingOnQuitButtonSwitch: Clicked the \"Delete browsing data on quit\" toggle")
+ }
fun verifyAllTheCheckBoxesText() {
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Trying to verify that the \"Open tabs\" option is visible")
openTabsCheckbox()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Verified that the \"Open tabs\" option is visible")
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Trying to verify that the \"Browsing history\" option is visible")
browsingHistoryCheckbox()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Verified that the \"Browsing history\" option is visible")
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Trying to verify that the \"Cookies and site data\" option is visible")
cookiesAndSiteDataCheckbox()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Verified that the \"Cookies and site data\" option is visible")
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Trying to verify that the \"Cookies and site data\" option summary is visible")
onView(withText(R.string.preferences_delete_browsing_data_cookies_subtitle))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Verified that the \"Cookies and site data\" option summary is visible")
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Trying to verify that the \"Cached images and files\" option is visible")
cachedFilesCheckbox()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Verified that the \"Cached images and files\" option is visible")
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Trying to verify that the \"Cached images and files\" option summary is visible")
onView(withText(R.string.preferences_delete_browsing_data_cached_files_subtitle))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Verified that the \"Cached images and files\" option summary is visible")
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Trying to verify that the \"Site permissions\" option is visible")
sitePermissionsCheckbox()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ Log.i(TAG, "verifyAllTheCheckBoxesText: Verified that the \"Site permissions\" option is visible")
}
fun verifyAllTheCheckBoxesChecked(checked: Boolean) {
for (index in 2..7) {
+ Log.i(TAG, "verifyAllTheCheckBoxesChecked: Trying to verify that the the check box at position ${index - 1} is checked: $checked")
onView(withId(R.id.recycler_view))
.check(
matches(
@@ -87,12 +110,15 @@ class SettingsSubMenuDeleteBrowsingDataOnQuitRobot {
),
),
)
+ Log.i(TAG, "verifyAllTheCheckBoxesChecked: Verified that the the check box at position ${index - 1} is checked: $checked")
}
}
class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
+ Log.i(TAG, "goBack: Trying to click navigate up toolbar button")
goBackButton().click()
+ Log.i(TAG, "goBack: Clicked navigate up toolbar button")
SettingsRobot().interact()
return SettingsRobot.Transition()
From ff739ce4fc53612df850f938ac688fb3ffb186db Mon Sep 17 00:00:00 2001
From: Titouan Thibaud
Date: Tue, 20 Feb 2024 11:16:41 +0100
Subject: [PATCH 259/586] Bug 1880999 - Start the Nightly 125 development cycle
---
docs/changelog.md | 10 ++++++++--
fenix/app/src/main/res/values/strings.xml | 6 ------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/docs/changelog.md b/docs/changelog.md
index c3de6235c869..56cd323fcfcf 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -4,12 +4,18 @@ title: Changelog
permalink: /changelog/
---
-# 124.0 (In Development)
-* [Commits](https://github.com/mozilla-mobile/firefox-android/compare/releases_v123..main)
+# 125.0 (In Development)
+* [Commits](https://github.com/mozilla-mobile/firefox-android/compare/releases_v124..main)
* [Dependencies](https://github.com/mozilla-mobile/firefox-android/blob/main/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt)
* [Gecko](https://github.com/mozilla-mobile/firefox-android/blob/main/android-components/plugins/dependencies/src/main/java/Gecko.kt)
* [Configuration](https://github.com/mozilla-mobile/firefox-android/blob/main/android-components/.config.yml)
+# 124.0
+* [Commits](https://github.com/mozilla-mobile/firefox-android/compare/releases_v123..releases_v124)
+* [Dependencies](https://github.com/mozilla-mobile/firefox-android/blob/releases_v124/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt)
+* [Gecko](https://github.com/mozilla-mobile/firefox-android/blob/releases_v124/android-components/plugins/dependencies/src/main/java/Gecko.kt)
+* [Configuration](https://github.com/mozilla-mobile/firefox-android/blob/releases_v124/android-components/.config.yml)
+
* **feature-prompts**:
* 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
diff --git a/fenix/app/src/main/res/values/strings.xml b/fenix/app/src/main/res/values/strings.xml
index 486a5a0caf8d..c1a749708963 100644
--- a/fenix/app/src/main/res/values/strings.xml
+++ b/fenix/app/src/main/res/values/strings.xml
@@ -2141,8 +2141,6 @@
Adjusted rating
- Unreliable reviews removed
-
Based on reliable reviewsHighlights from recent reviews
@@ -2198,10 +2196,6 @@
If you see this product is back in stock, report it and we’ll work on checking the reviews.Report product is in stock
-
- Checking review quality
-
- Checking review qualityChecking review quality (%s)
From 0d8d7a02efbba2d9bc08b973cd7a14e8f58ca531 Mon Sep 17 00:00:00 2001
From: James Hugman
Date: Mon, 29 Jan 2024 15:05:17 +0000
Subject: [PATCH 260/586] =?UTF-8?q?Bug=201880476=20=E2=80=94=20Remove=20re?=
=?UTF-8?q?dundant=20caching=20and=20destroy=20jexl=20helper=20after=20use?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../messaging/NimbusMessagingStorage.kt | 74 +++++++++++--------
.../messaging/NimbusMessagingStorageTest.kt | 14 ++--
.../fenix/onboarding/OnboardingFragment.kt | 19 +++--
3 files changed, 61 insertions(+), 46 deletions(-)
diff --git a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
index c984f93e6dcb..be91cb73c41f 100644
--- a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
+++ b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
@@ -52,8 +52,15 @@ class NimbusMessagingStorage(
private val customAttributes: JSONObject
get() = attributeProvider?.getCustomAttributes(context) ?: JSONObject()
- val helper: NimbusMessagingHelperInterface
- get() = gleanPlumb.createMessageHelper(customAttributes)
+ /**
+ * Returns a Nimbus message helper, for evaluating JEXL.
+ *
+ * The JEXL context is time-sensitive, so this should be created new for each set of evaluations.
+ *
+ * Since it has a native peer, it should be [destroy]ed after finishing the set of evaluations.
+ */
+ fun createMessagingHelper(): NimbusMessagingHelperInterface =
+ gleanPlumb.createMessageHelper(customAttributes)
/**
* Returns the [Message] for the given [key] or returns null if none found.
@@ -113,13 +120,14 @@ class NimbusMessagingStorage(
* Returns the next higher priority message which all their triggers are true.
*/
fun getNextMessage(surface: MessageSurfaceId, availableMessages: List): Message? =
- getNextMessage(
- surface,
- availableMessages,
- setOf(),
- helper,
- mutableMapOf(),
- )
+ createMessagingHelper().use {
+ getNextMessage(
+ surface,
+ availableMessages,
+ setOf(),
+ it,
+ )
+ }
@Suppress("ReturnCount")
private fun getNextMessage(
@@ -127,12 +135,11 @@ class NimbusMessagingStorage(
availableMessages: List,
excluded: Set,
helper: NimbusMessagingHelperInterface,
- jexlCache: MutableMap,
): Message? {
val message = availableMessages
.filter { surface == it.surface }
.filter { !excluded.contains(it.id) }
- .firstOrNull { isMessageEligible(it, helper, jexlCache) } ?: return null
+ .firstOrNull { isMessageEligible(it, helper) } ?: return null
val slug = message.data.experiment
if (slug != null) {
@@ -167,7 +174,6 @@ class NimbusMessagingStorage(
availableMessages,
excluded + message.id,
helper,
- jexlCache,
)
ControlMessageBehavior.SHOW_NONE -> null
@@ -189,12 +195,12 @@ class NimbusMessagingStorage(
* The fully resolved (with all substitutions) action is returned as the second value
* of the [Pair].
*/
- fun generateUuidAndFormatAction(action: String): Pair {
- val helper = gleanPlumb.createMessageHelper(customAttributes)
- val uuid = helper.getUuid(action)
-
- return Pair(uuid, helper.stringFormat(action, uuid))
- }
+ fun generateUuidAndFormatAction(action: String): Pair =
+ createMessagingHelper().use { helper ->
+ val uuid = helper.getUuid(action)
+ val url = helper.stringFormat(action, uuid)
+ Pair(uuid, url)
+ }
/**
* Updated the provided [metadata] in the storage.
@@ -259,23 +265,19 @@ class NimbusMessagingStorage(
fun isMessageEligible(
message: Message,
helper: NimbusMessagingHelperInterface,
- jexlCache: MutableMap = mutableMapOf(),
): Boolean {
return message.triggers.all { condition ->
- jexlCache[condition]
- ?: try {
- if (malFormedMap.containsKey(condition)) {
- return false
- }
- helper.evalJexl(condition).also { result ->
- jexlCache[condition] = result
- }
- } catch (e: NimbusException.EvaluationException) {
- reportMalformedMessage(message.id)
- malFormedMap[condition] = message.id
- logger.info("Unable to evaluate $condition")
- false
+ try {
+ if (malFormedMap.containsKey(condition)) {
+ return false
}
+ helper.evalJexl(condition)
+ } catch (e: NimbusException.EvaluationException) {
+ reportMalformedMessage(message.id)
+ malFormedMap[condition] = message.id
+ logger.info("Unable to evaluate $condition")
+ false
+ }
}
}
@@ -290,3 +292,11 @@ class NimbusMessagingStorage(
)
}
}
+
+/**
+ * A helper method to safely destroy the message helper after use.
+ */
+fun NimbusMessagingHelperInterface.use(block: (NimbusMessagingHelperInterface) -> R) =
+ block(this).also {
+ this.destroy()
+ }
diff --git a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt
index 7b325c16b599..5e9ef8294f96 100644
--- a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt
+++ b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt
@@ -83,6 +83,8 @@ class NimbusMessagingStorageTest {
gleanPlumb,
messagingFeature,
)
+
+ `when`(gleanPlumb.createMessageHelper(any())).thenReturn(mock())
}
@After
@@ -489,7 +491,7 @@ class NimbusMessagingStorageTest {
Message.Metadata("same-id"),
)
- doReturn(false).`when`(spiedStorage).isMessageEligible(any(), any(), any())
+ doReturn(false).`when`(spiedStorage).isMessageEligible(any(), any())
val result = spiedStorage.getNextMessage(HOMESCREEN, listOf(message))
@@ -508,7 +510,7 @@ class NimbusMessagingStorageTest {
Message.Metadata("same-id"),
)
- doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any(), any())
+ doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any())
val result = spiedStorage.getNextMessage(HOMESCREEN, listOf(message))
@@ -530,7 +532,7 @@ class NimbusMessagingStorageTest {
Message.Metadata("same-id"),
)
- doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any(), any())
+ doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any())
val result = spiedStorage.getNextMessage(HOMESCREEN, listOf(message))
@@ -565,7 +567,7 @@ class NimbusMessagingStorageTest {
Message.Metadata("same-id"),
)
- doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any(), any())
+ doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any())
val result = spiedStorage.getNextMessage(
HOMESCREEN,
@@ -603,7 +605,7 @@ class NimbusMessagingStorageTest {
Message.Metadata("same-id"),
)
- doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any(), any())
+ doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any())
val result = spiedStorage.getNextMessage(
HOMESCREEN,
@@ -652,7 +654,7 @@ class NimbusMessagingStorageTest {
Message.Metadata("same-id"),
)
- doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any(), any())
+ doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any())
var result = spiedStorage.getNextMessage(
HOMESCREEN,
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
index d46adfac3133..d216668cabf5 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
@@ -23,6 +23,7 @@ import androidx.fragment.app.Fragment
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.navigation.fragment.findNavController
import mozilla.components.service.nimbus.evalJexlSafe
+import mozilla.components.service.nimbus.messaging.use
import mozilla.components.support.base.ext.areNotificationsEnabledSafe
import mozilla.components.support.utils.BrowsersCache
import org.mozilla.fenix.R
@@ -228,7 +229,7 @@ class OnboardingFragment : Fragment() {
showAddWidgetPage: Boolean,
): List {
val jexlConditions = FxNimbus.features.junoOnboarding.value().conditions
- val jexlHelper = requireContext().components.analytics.messagingStorage.helper
+ val jexlHelper = requireContext().components.analytics.messagingStorage.createMessagingHelper()
val privacyCaption = Caption(
text = getString(R.string.juno_onboarding_privacy_notice_text),
@@ -249,12 +250,14 @@ class OnboardingFragment : Fragment() {
},
),
)
- return FxNimbus.features.junoOnboarding.value().cards.values.toPageUiData(
- privacyCaption,
- showDefaultBrowserPage,
- showNotificationPage,
- showAddWidgetPage,
- jexlConditions,
- ) { condition -> jexlHelper.evalJexlSafe(condition) }
+ return jexlHelper.use {
+ FxNimbus.features.junoOnboarding.value().cards.values.toPageUiData(
+ privacyCaption,
+ showDefaultBrowserPage,
+ showNotificationPage,
+ showAddWidgetPage,
+ jexlConditions,
+ ) { condition -> jexlHelper.evalJexlSafe(condition) }
+ }
}
}
From 0f396cc2e70198f54e4e53f681caae943ac5f83d Mon Sep 17 00:00:00 2001
From: t-p-white
Date: Mon, 19 Feb 2024 13:49:55 +0000
Subject: [PATCH 261/586] Bug 1880829 - Restrict suggest to show a single open
tab suggestion for identical tabs
---
.../provider/SessionSuggestionProvider.kt | 6 ++--
.../provider/SessionSuggestionProviderTest.kt | 30 +++++++++++++++++++
2 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/android-components/components/feature/awesomebar/src/main/java/mozilla/components/feature/awesomebar/provider/SessionSuggestionProvider.kt b/android-components/components/feature/awesomebar/src/main/java/mozilla/components/feature/awesomebar/provider/SessionSuggestionProvider.kt
index 8051b04551e3..d94e94153ee6 100644
--- a/android-components/components/feature/awesomebar/src/main/java/mozilla/components/feature/awesomebar/provider/SessionSuggestionProvider.kt
+++ b/android-components/components/feature/awesomebar/src/main/java/mozilla/components/feature/awesomebar/provider/SessionSuggestionProvider.kt
@@ -50,15 +50,15 @@ class SessionSuggestionProvider(
}
val state = store.state
- val tabs = state.tabs
+ val distinctTabs = state.tabs.distinctBy { it.content.url }
val suggestions = mutableListOf()
- val iconRequests: List?> = tabs.map {
+ val iconRequests: List?> = distinctTabs.map {
icons?.loadIcon(IconRequest(url = it.content.url, waitOnNetworkLoad = false))
}
val searchWords = searchText.split(" ")
- tabs.zip(iconRequests) { result, icon ->
+ distinctTabs.zip(iconRequests) { result, icon ->
if (
resultsUriFilter?.invoke(result.content.url.toUri()) != false &&
searchWords.all { result.contains(it) } &&
diff --git a/android-components/components/feature/awesomebar/src/test/java/mozilla/components/feature/awesomebar/provider/SessionSuggestionProviderTest.kt b/android-components/components/feature/awesomebar/src/test/java/mozilla/components/feature/awesomebar/provider/SessionSuggestionProviderTest.kt
index 028e4f33b16e..f412dc74a212 100644
--- a/android-components/components/feature/awesomebar/src/test/java/mozilla/components/feature/awesomebar/provider/SessionSuggestionProviderTest.kt
+++ b/android-components/components/feature/awesomebar/src/test/java/mozilla/components/feature/awesomebar/provider/SessionSuggestionProviderTest.kt
@@ -416,4 +416,34 @@ class SessionSuggestionProviderTest {
assertTrue(suggestions.map { it.title }.contains("http://www.mobile.mozilla.org"))
assertTrue(suggestions.map { it.title }.contains("https://www.mozilla.org/vpn"))
}
+
+ @Test
+ fun `GIVEN multiple tabs have the same url WHEN user inputs the same url THEN provider returns a single suggestion for the matching input`() = runTest {
+ val store = BrowserStore()
+
+ val url = "https://www.mozilla.org"
+ val tab1 = createTab(url)
+ val tab2 = createTab(url)
+ val tab3 = createTab(url)
+
+ val resources: Resources = mock()
+ `when`(resources.getString(anyInt())).thenReturn("Switch to tab")
+
+ val provider = SessionSuggestionProvider(resources, store, mock())
+
+ run {
+ val suggestions = provider.onInputChanged("Mozilla")
+ assertTrue(suggestions.isEmpty())
+ }
+
+ store.dispatch(TabListAction.AddTabAction(tab1)).join()
+ store.dispatch(TabListAction.AddTabAction(tab2)).join()
+ store.dispatch(TabListAction.AddTabAction(tab3)).join()
+
+ run {
+ val suggestions = provider.onInputChanged("Mozilla")
+ assertEquals(1, suggestions.size)
+ assertEquals(tab1.id, suggestions[0].id)
+ }
+ }
}
From 4e75e6e7142029e857f764674116af2fb98e8d4d Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Tue, 20 Feb 2024 13:33:42 +0000
Subject: [PATCH 262/586] Update GeckoView (Nightly) to 125.0.20240220094730.
---
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 b102cdf5f129..e2cdf07fb843 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 = "125.0.20240219212225"
+ const val version = "125.0.20240220094730"
/**
* GeckoView channel
From e0985856142010995a36bfd621cf3e760bfc47a2 Mon Sep 17 00:00:00 2001
From: ohall-m
Date: Thu, 15 Feb 2024 10:50:02 -0500
Subject: [PATCH 263/586] Bug 1876803 - Translation Download Size Action
This patch adds a flow for determining the download size that would
occur for a given translation. Expected use case is for low-data modes.
* New `FetchTranslationDownloadSizeAction`
* New `SetTranslationDownloadSizeAction`
* New `CouldNotDetermineDownloadSizeError`
* New `TranslationDownloadSize` object and `translationDownloadSize` on the
session `TranslationsState`
---
.../browser/state/action/BrowserAction.kt | 28 ++++++++
.../middleware/TranslationsMiddleware.kt | 68 ++++++++++++++++++
.../state/reducer/TranslationsStateReducer.kt | 16 +++++
.../browser/state/state/TranslationsState.kt | 5 ++
.../state/action/TranslationsActionTest.kt | 55 ++++++++++++++
.../middleware/TranslationsMiddlewareTest.kt | 71 +++++++++++++++++++
.../translate/TranslationDownloadSize.kt | 27 +++++++
.../engine/translate/TranslationError.kt | 13 ++++
8 files changed, 283 insertions(+)
create mode 100644 android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationDownloadSize.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 2594fb6840d6..e2861b0c3e0d 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
@@ -45,6 +45,8 @@ import mozilla.components.concept.engine.mediasession.MediaSession
import mozilla.components.concept.engine.permission.PermissionRequest
import mozilla.components.concept.engine.prompt.PromptRequest
import mozilla.components.concept.engine.search.SearchRequest
+import mozilla.components.concept.engine.translate.Language
+import mozilla.components.concept.engine.translate.TranslationDownloadSize
import mozilla.components.concept.engine.translate.TranslationEngineState
import mozilla.components.concept.engine.translate.TranslationError
import mozilla.components.concept.engine.translate.TranslationOperation
@@ -912,6 +914,32 @@ sealed class TranslationsAction : BrowserAction() {
override val tabId: String,
) : TranslationsAction(), ActionWithTab
+ /**
+ * Fetch the translation download size for the given [tabId]. Will use the specified
+ * [fromLanguage] and [toLanguage] to query the download size.
+ *
+ * @property tabId The ID of the tab the [EngineSession] should set the state on.
+ * @property fromLanguage The from [Language] in the translation pair.
+ * @property toLanguage The to [Language] in the translation pair.
+ */
+ data class FetchTranslationDownloadSizeAction(
+ override val tabId: String,
+ val fromLanguage: Language,
+ val toLanguage: Language,
+ ) : TranslationsAction(), ActionWithTab
+
+ /**
+ * Set the [TranslationDownloadSize] for the given [tabId].
+ *
+ * @property tabId The ID of the tab the [EngineSession] should set the state on.
+ * @property translationSize The [TranslationDownloadSize] that contains a to/from translations
+ * pair and a download size.
+ */
+ data class SetTranslationDownloadSizeAction(
+ override val tabId: String,
+ val translationSize: TranslationDownloadSize,
+ ) : TranslationsAction(), ActionWithTab
+
/**
* Indicates the given [tabId] was successful in translating or restoring the page
* or acquiring a necessary resource.
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 f3e95c065f55..ca33b091f5f9 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,9 +11,12 @@ import mozilla.components.browser.state.action.InitAction
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.SessionState
import mozilla.components.concept.engine.Engine
import mozilla.components.concept.engine.EngineSession
+import mozilla.components.concept.engine.translate.Language
import mozilla.components.concept.engine.translate.LanguageSetting
+import mozilla.components.concept.engine.translate.TranslationDownloadSize
import mozilla.components.concept.engine.translate.TranslationError
import mozilla.components.concept.engine.translate.TranslationOperation
import mozilla.components.concept.engine.translate.TranslationPageSettingOperation
@@ -34,6 +37,7 @@ class TranslationsMiddleware(
) : Middleware {
private val logger = Logger("TranslationsMiddleware")
+ @Suppress("LongMethod")
override fun invoke(
context: MiddlewareContext,
next: (BrowserAction) -> Unit,
@@ -68,6 +72,18 @@ class TranslationsMiddleware(
-> Unit
}
}
+
+ is TranslationsAction.FetchTranslationDownloadSizeAction -> {
+ scope.launch {
+ requestTranslationSize(
+ context = context,
+ tabId = action.tabId,
+ fromLanguage = action.fromLanguage,
+ toLanguage = action.toLanguage,
+ )
+ }
+ }
+
is TranslationsAction.RemoveNeverTranslateSiteAction -> {
scope.launch {
removeNeverTranslateSite(context, action.tabId, action.origin)
@@ -365,6 +381,58 @@ class TranslationsMiddleware(
}
}
+ /**
+ * Retrieves the download size and dispatches the result to the
+ * [SessionState.translationsState] on the [BrowserStore]
+ * via [TranslationsAction.SetTranslationDownloadSizeAction].
+ *
+ * @param context Context to use to dispatch to the store.
+ * @param tabId Tab ID associated with the request.
+ * @param fromLanguage The from language to request the translation download size for.
+ * @param toLanguage The to language to request the translation download size for.
+ */
+ private fun requestTranslationSize(
+ context: MiddlewareContext,
+ tabId: String,
+ fromLanguage: Language,
+ toLanguage: Language,
+ ) {
+ engine.getTranslationsPairDownloadSize(
+ fromLanguage = fromLanguage.code,
+ toLanguage = toLanguage.code,
+
+ onSuccess = { size ->
+ context.store.dispatch(
+ TranslationsAction.SetTranslationDownloadSizeAction(
+ tabId = tabId,
+ translationSize = TranslationDownloadSize(
+ fromLanguage = fromLanguage,
+ toLanguage = toLanguage,
+ size = size,
+ error = null,
+ ),
+ ),
+ )
+ logger.info("Success requesting download size.")
+ },
+
+ onError = { error ->
+ context.store.dispatch(
+ TranslationsAction.SetTranslationDownloadSizeAction(
+ tabId = tabId,
+ translationSize = TranslationDownloadSize(
+ fromLanguage = fromLanguage,
+ toLanguage = toLanguage,
+ size = null,
+ error = TranslationError.CouldNotDetermineDownloadSizeError(null),
+ ),
+ ),
+ )
+ logger.error("Error requesting download size: ", error)
+ },
+ )
+ }
+
/**
* Updates the always offer popup setting with the [Engine].
*
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 107af97ec90e..8008b2af80be 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
@@ -295,6 +295,22 @@ internal object TranslationsStateReducer {
),
)
}
+
+ is TranslationsAction.FetchTranslationDownloadSizeAction -> {
+ state.copyWithTranslationsState(action.tabId) {
+ it.copy(
+ translationDownloadSize = null,
+ )
+ }
+ }
+
+ is TranslationsAction.SetTranslationDownloadSizeAction -> {
+ state.copyWithTranslationsState(action.tabId) {
+ it.copy(
+ translationDownloadSize = action.translationSize,
+ )
+ }
+ }
}
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 3bc7b288da0a..fd83eba06f5d 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
@@ -4,6 +4,7 @@
package mozilla.components.browser.state.state
+import mozilla.components.concept.engine.translate.TranslationDownloadSize
import mozilla.components.concept.engine.translate.TranslationEngineState
import mozilla.components.concept.engine.translate.TranslationError
import mozilla.components.concept.engine.translate.TranslationPageSettings
@@ -19,6 +20,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 translationDownloadSize The download size for the given to/from translation pair. The
+ * translation engine requires the pair's ML models to be present on the device to complete a
+ * translation.
* @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.
@@ -33,6 +37,7 @@ data class TranslationsState(
val isTranslated: Boolean = false,
val isTranslateProcessing: Boolean = false,
val isRestoreProcessing: Boolean = false,
+ val translationDownloadSize: TranslationDownloadSize? = null,
val supportedLanguages: TranslationSupport? = null,
val pageSettings: TranslationPageSettings? = null,
val neverTranslateSites: List? = 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 f770ca80b665..06e4fdf15431 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
@@ -11,6 +11,7 @@ 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.TranslationDownloadSize
import mozilla.components.concept.engine.translate.TranslationEngineState
import mozilla.components.concept.engine.translate.TranslationError
import mozilla.components.concept.engine.translate.TranslationOperation
@@ -349,6 +350,60 @@ class TranslationsActionTest {
assertEquals(pageSettings, tabState().translationsState.pageSettings)
}
+ @Test
+ fun `WHEN a SetTranslationDownloadSize is dispatched THEN set translationSize is set`() {
+ // Initial
+ assertNull(tabState().translationsState.translationDownloadSize)
+
+ // Action started
+ val translationSize = TranslationDownloadSize(
+ fromLanguage = Language("en", "English"),
+ toLanguage = Language("fr", "French"),
+ size = 10000L,
+ error = null,
+ )
+ store.dispatch(
+ TranslationsAction.SetTranslationDownloadSizeAction(
+ tabId = tab.id,
+ translationSize = translationSize,
+ ),
+ ).joinBlocking()
+
+ // Action success
+ assertEquals(translationSize, tabState().translationsState.translationDownloadSize)
+ }
+
+ @Test
+ fun `WHEN a FetchTranslationDownloadSize is dispatched THEN translationSize is cleared`() {
+ // Initial setting size for a more robust test
+ val translationSize = TranslationDownloadSize(
+ fromLanguage = Language("en", "English"),
+ toLanguage = Language("fr", "French"),
+ size = 10000L,
+ error = null,
+ )
+ store.dispatch(
+ TranslationsAction.SetTranslationDownloadSizeAction(
+ tabId = tab.id,
+ translationSize = translationSize,
+ ),
+ ).joinBlocking()
+
+ assertEquals(translationSize, tabState().translationsState.translationDownloadSize)
+
+ // Action started
+ store.dispatch(
+ TranslationsAction.FetchTranslationDownloadSizeAction(
+ tabId = tab.id,
+ fromLanguage = Language("en", "English"),
+ toLanguage = Language("fr", "French"),
+ ),
+ ).joinBlocking()
+
+ // Action success
+ assertNull(tabState().translationsState.translationDownloadSize)
+ }
+
@Test
fun `WHEN a OperationRequestedAction is dispatched for FETCH_PAGE_SETTINGS THEN clear pageSettings`() {
// Setting first to have a more robust 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 0c970f8dddd0..48fe1ca37589 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
@@ -19,6 +19,7 @@ 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.TranslationDownloadSize
import mozilla.components.concept.engine.translate.TranslationEngineState
import mozilla.components.concept.engine.translate.TranslationError
import mozilla.components.concept.engine.translate.TranslationOperation
@@ -386,6 +387,76 @@ class TranslationsMiddlewareTest {
waitForIdle()
}
+ @Test
+ fun `WHEN FetchTranslationDownloadSize is requested AND succeeds THEN SetTranslationDownloadSize is dispatched`() = runTest {
+ val translationSize = TranslationDownloadSize(
+ fromLanguage = Language("en", "English"),
+ toLanguage = Language("fr", "French"),
+ size = 10000L,
+ error = null,
+ )
+
+ val action =
+ TranslationsAction.FetchTranslationDownloadSizeAction(
+ tabId = tab.id,
+ fromLanguage = translationSize.fromLanguage,
+ toLanguage = translationSize.toLanguage,
+ )
+ translationsMiddleware.invoke(context = context, next = {}, action = action)
+
+ val sizeCaptor = argumentCaptor<((Long) -> Unit)>()
+ verify(engine).getTranslationsPairDownloadSize(
+ fromLanguage = any(),
+ toLanguage = any(),
+ onSuccess = sizeCaptor.capture(),
+ onError = any(),
+ )
+ sizeCaptor.value.invoke(translationSize.size!!)
+
+ verify(context.store).dispatch(
+ TranslationsAction.SetTranslationDownloadSizeAction(
+ tabId = tab.id,
+ translationSize = translationSize,
+ ),
+ )
+
+ waitForIdle()
+ }
+
+ @Test
+ fun `WHEN FetchTranslationDownloadSize is requested AND fails THEN SetTranslationDownloadSize is dispatched`() = runTest {
+ val action =
+ TranslationsAction.FetchTranslationDownloadSizeAction(
+ tabId = tab.id,
+ fromLanguage = Language("en", "English"),
+ toLanguage = Language("fr", "French"),
+ )
+ translationsMiddleware.invoke(context = context, next = {}, action = action)
+
+ val errorCaptor = argumentCaptor<((Throwable) -> Unit)>()
+ verify(engine).getTranslationsPairDownloadSize(
+ fromLanguage = any(),
+ toLanguage = any(),
+ onSuccess = any(),
+ onError = errorCaptor.capture(),
+ )
+ errorCaptor.value.invoke(TranslationError.CouldNotDetermineDownloadSizeError(cause = null))
+
+ verify(context.store).dispatch(
+ TranslationsAction.SetTranslationDownloadSizeAction(
+ tabId = tab.id,
+ translationSize = TranslationDownloadSize(
+ fromLanguage = Language("en", "English"),
+ toLanguage = Language("fr", "French"),
+ size = null,
+ error = any(),
+ ),
+ ),
+ )
+
+ waitForIdle()
+ }
+
@Test
fun `WHEN RemoveNeverTranslateSiteAction is dispatched AND removing is unsuccessful THEN FETCH_NEVER_TRANSLATE_SITES is dispatched`() = runTest {
val errorCallback = argumentCaptor<((Throwable) -> Unit)>()
diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationDownloadSize.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationDownloadSize.kt
new file mode 100644
index 000000000000..37782dfde40c
--- /dev/null
+++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationDownloadSize.kt
@@ -0,0 +1,27 @@
+/* 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
+
+/**
+ * A data class to contain information related to the download size required for a given
+ * translation to/from pair.
+ *
+ * For the translations engine to complete a translation on a specified to/from pair,
+ * first, the necessary ML models must be downloaded to the device.
+ * This class represents the download state of the ML models necessary to translate the
+ * given to/from pair.
+ *
+ * @property fromLanguage The [Language] to translate from on a given translation.
+ * @property toLanguage The [Language] to translate to on a given translation.
+ * @property size The size of the download to perform the translation in bytes. Null means the value has
+ * yet to be received or an error occurred. Zero means no download required or else a model does not exist.
+ * @property error The [TranslationError] reported if an error occurred while fetching the size.
+ */
+data class TranslationDownloadSize(
+ val fromLanguage: Language,
+ val toLanguage: Language,
+ val size: Long? = null,
+ val error: TranslationError? = null,
+)
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 a12017fa2aca..0a7581088639 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,19 @@ sealed class TranslationError(
class CouldNotRestoreError(override val cause: Throwable?) :
TranslationError(errorName = "could-not-restore", displayError = false, cause = cause)
+ /**
+ * Could not determine the translation download size between a given "to" and "from" language
+ * translation pair.
+ *
+ * @param cause The original [Throwable] before it was converted into this error state.
+ */
+ class CouldNotDetermineDownloadSizeError(override val cause: Throwable?) :
+ TranslationError(
+ errorName = "could-not-determine-translation-download-size",
+ displayError = false,
+ cause = cause,
+ )
+
/**
* Could not load language options error.
*
From 2d668b05a6610b893008e3a9c7faa6966beda6d8 Mon Sep 17 00:00:00 2001
From: Jackie Johnson <107960801+jjSDET@users.noreply.github.com>
Date: Mon, 19 Feb 2024 17:25:50 -0600
Subject: [PATCH 264/586] Bug 1880912 - Remove TestRail Script and Dependencies
from ui-test-apk TC Task
---
taskcluster/ci/ui-test-apk/kind.yml | 108 ----------------------------
1 file changed, 108 deletions(-)
diff --git a/taskcluster/ci/ui-test-apk/kind.yml b/taskcluster/ci/ui-test-apk/kind.yml
index c0da544b0c02..f841eb7ae233 100644
--- a/taskcluster/ci/ui-test-apk/kind.yml
+++ b/taskcluster/ci/ui-test-apk/kind.yml
@@ -170,72 +170,18 @@ tasks:
key: firebaseToken
path: .firebase_token.json
json: true
- - name: project/mobile/ci/testrail
- key: testrailCredentials
- path: .testrail_credentials.json
- json: true
pre-commands:
- ["cd", "focus-android"]
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- [wget, {artifact-reference: ''}, '-O', android-test.apk]
- ['automation/taskcluster/androidTest/ui-test.sh', 'arm-beta-tests', 'app.apk', 'android-test.apk', '1']
- - [python3, automation/taskcluster/androidTest/testrail.py]
treeherder:
platform: 'focus-ui-test/opt'
symbol: focus-beta(ui-test-arm-beta)
worker:
env:
GOOGLE_PROJECT: 'moz-focus-android'
- PRODUCT_TYPE: Focus
- RELEASE_TYPE: Beta
- routes:
- - notify.slack-channel.G016BC5FUHJ.on-completed
- scopes:
- - queue:route:notify.slack-channel.G016BC5FUHJ.on-completed
- - notify:slack-channel:G016BC5FUHJ
- extra:
- notify:
- # slackText: 'https://firefox-ci-tc.services.mozilla.com/tasks/${status.taskId} | ${task.metadata.name} | ${task.metadata.source}'
- slackBlocks: |
- [
- {
- "type": "header",
- "text": {
- "type": "plain_text",
- "text": "firefox-android :tada: Testrail Release Milestone Creation :tada:\n "
- }
- },
- {
- "type": "divider"
- },
- {
- "type": "section",
- "text": {
- "type": "mrkdwn",
- "text": "*Testrail Release Milestone*: :clown_face:"
- }
- },
- {
- "type": "section",
- "text": {
- "type": "mrkdwn",
- "text": "*Testrail Release Milestone* has been created"
- }
- },
- {
- "type": "divider"
- },
- {
- "type": "context",
- "elements": [
- {
- "type": "mrkdwn",
- "text": ":testops-notify: created by "
- }
- ]
- }
- ]
fenix-arm-debug:
attributes:
shipping-product: fenix
@@ -307,72 +253,18 @@ tasks:
key: firebaseToken
path: .firebase_token.json
json: true
- - name: project/mobile/ci/testrail
- key: testrailCredentials
- path: .testrail_credentials.json
- json: true
pre-commands:
- ["cd", "fenix"]
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- [wget, {artifact-reference: ''}, '-O', android-test.apk]
- [automation/taskcluster/androidTest/ui-test.sh, arm-beta-tests, app.apk, android-test.apk, '2']
- - [python3, automation/taskcluster/androidTest/testrail.py]
treeherder:
platform: 'fenix-ui-test/opt'
symbol: fenix-beta(ui-test-arm-beta)
worker:
env:
GOOGLE_PROJECT: moz-fenix
- PRODUCT_TYPE: Firefox
- RELEASE_TYPE: Beta
- routes:
- - notify.slack-channel.G016BC5FUHJ.on-completed
- scopes:
- - queue:route:notify.slack-channel.G016BC5FUHJ.on-completed
- - notify:slack-channel:G016BC5FUHJ
- extra:
- notify:
- # slackText: 'https://firefox-ci-tc.services.mozilla.com/tasks/${status.taskId} | ${task.metadata.name} | ${task.metadata.source}'
- slackBlocks: |
- [
- {
- "type": "header",
- "text": {
- "type": "plain_text",
- "text": "firefox-android :tada: Testrail Release Milestone Creation :tada:\n "
- }
- },
- {
- "type": "divider"
- },
- {
- "type": "section",
- "text": {
- "type": "mrkdwn",
- "text": "*Testrail Release Milestone*: :clown_face:"
- }
- },
- {
- "type": "section",
- "text": {
- "type": "mrkdwn",
- "text": "*Testrail Release Milestone* has been created"
- }
- },
- {
- "type": "divider"
- },
- {
- "type": "context",
- "elements": [
- {
- "type": "mrkdwn",
- "text": ":testops-notify: created by "
- }
- ]
- }
- ]
fenix-arm-nightly:
attributes:
build-type: fenix-nightly-firebase
From 324cb904e70ac64190092ec8f3d3a0a96ad201d5 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Tue, 20 Feb 2024 12:12:15 +0200
Subject: [PATCH 265/586] Bug 1881010 - Remove redundant assertion functions
from SettingsSubMenuDeleteBrowsingDataRobot
---
.../SettingsSubMenuDeleteBrowsingDataRobot.kt | 95 ++++++++-----------
1 file changed, 40 insertions(+), 55 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataRobot.kt
index 21978b4a390c..6cc3380f5ffa 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataRobot.kt
@@ -29,15 +29,22 @@ import org.mozilla.fenix.helpers.click
*/
class SettingsSubMenuDeleteBrowsingDataRobot {
- fun verifyAllCheckBoxesAreChecked() = assertAllCheckBoxesAreChecked()
- fun verifyOpenTabsCheckBox(status: Boolean) = assertOpenTabsCheckBox(status)
- fun verifyBrowsingHistoryDetails(status: Boolean) = assertBrowsingHistoryCheckBox(status)
- fun verifyCookiesCheckBox(status: Boolean) = assertCookiesCheckBox(status)
- fun verifyCachedFilesCheckBox(status: Boolean) = assertCachedFilesCheckBox(status)
- fun verifySitePermissionsCheckBox(status: Boolean) = assertSitePermissionsCheckBox(status)
- fun verifyDownloadsCheckBox(status: Boolean) = assertDownloadsCheckBox(status)
- fun verifyOpenTabsDetails(tabNumber: String) = assertOpenTabsDescription(tabNumber)
- fun verifyBrowsingHistoryDetails(addresses: String) = assertBrowsingHistoryDescription(addresses)
+ fun verifyAllCheckBoxesAreChecked() {
+ openTabsCheckBox().assertIsChecked(true)
+ browsingHistoryCheckBox().assertIsChecked(true)
+ cookiesAndSiteDataCheckBox().assertIsChecked(true)
+ cachedFilesCheckBox().assertIsChecked(true)
+ sitePermissionsCheckBox().assertIsChecked(true)
+ downloadsCheckBox().assertIsChecked(true)
+ }
+ fun verifyOpenTabsCheckBox(status: Boolean) = openTabsCheckBox().assertIsChecked(status)
+ fun verifyBrowsingHistoryDetails(status: Boolean) = browsingHistoryCheckBox().assertIsChecked(status)
+ fun verifyCookiesCheckBox(status: Boolean) = cookiesAndSiteDataCheckBox().assertIsChecked(status)
+ fun verifyCachedFilesCheckBox(status: Boolean) = cachedFilesCheckBox().assertIsChecked(status)
+ fun verifySitePermissionsCheckBox(status: Boolean) = sitePermissionsCheckBox().assertIsChecked(status)
+ fun verifyDownloadsCheckBox(status: Boolean) = downloadsCheckBox().assertIsChecked(status)
+ fun verifyOpenTabsDetails(tabNumber: String) = openTabsDescription(tabNumber).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ fun verifyBrowsingHistoryDetails(addresses: String) = assertUIObjectExists(browsingHistoryDescription(addresses))
fun verifyDeleteBrowsingDataDialog() {
dialogMessage().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
@@ -56,78 +63,78 @@ class SettingsSubMenuDeleteBrowsingDataRobot {
fun selectOnlyOpenTabsCheckBox() {
clickBrowsingHistoryCheckBox()
- assertBrowsingHistoryCheckBox(false)
+ browsingHistoryCheckBox().assertIsChecked(false)
clickCookiesCheckBox()
- assertCookiesCheckBox(false)
+ cookiesAndSiteDataCheckBox().assertIsChecked(false)
clickCachedFilesCheckBox()
- assertCachedFilesCheckBox(false)
+ cachedFilesCheckBox().assertIsChecked(false)
clickSitePermissionsCheckBox()
- assertSitePermissionsCheckBox(false)
+ sitePermissionsCheckBox().assertIsChecked(false)
clickDownloadsCheckBox()
- assertDownloadsCheckBox(false)
+ downloadsCheckBox().assertIsChecked(false)
- assertOpenTabsCheckBox(true)
+ openTabsCheckBox().assertIsChecked(true)
}
fun selectOnlyBrowsingHistoryCheckBox() {
clickOpenTabsCheckBox()
- assertOpenTabsCheckBox(false)
+ openTabsCheckBox().assertIsChecked(false)
clickCookiesCheckBox()
- assertCookiesCheckBox(false)
+ cookiesAndSiteDataCheckBox().assertIsChecked(false)
clickCachedFilesCheckBox()
- assertCachedFilesCheckBox(false)
+ cachedFilesCheckBox().assertIsChecked(false)
clickSitePermissionsCheckBox()
- assertSitePermissionsCheckBox(false)
+ sitePermissionsCheckBox().assertIsChecked(false)
clickDownloadsCheckBox()
- assertDownloadsCheckBox(false)
+ downloadsCheckBox().assertIsChecked(false)
- assertBrowsingHistoryCheckBox(true)
+ browsingHistoryCheckBox().assertIsChecked(true)
}
fun selectOnlyCookiesCheckBox() {
clickOpenTabsCheckBox()
- assertOpenTabsCheckBox(false)
+ openTabsCheckBox().assertIsChecked(false)
- assertCookiesCheckBox(true)
+ cookiesAndSiteDataCheckBox().assertIsChecked(true)
clickCachedFilesCheckBox()
- assertCachedFilesCheckBox(false)
+ cachedFilesCheckBox().assertIsChecked(false)
clickSitePermissionsCheckBox()
- assertSitePermissionsCheckBox(false)
+ sitePermissionsCheckBox().assertIsChecked(false)
clickDownloadsCheckBox()
- assertDownloadsCheckBox(false)
+ downloadsCheckBox().assertIsChecked(false)
clickBrowsingHistoryCheckBox()
- assertBrowsingHistoryCheckBox(false)
+ browsingHistoryCheckBox().assertIsChecked(false)
}
fun selectOnlyCachedFilesCheckBox() {
clickOpenTabsCheckBox()
- assertOpenTabsCheckBox(false)
+ openTabsCheckBox().assertIsChecked(false)
clickBrowsingHistoryCheckBox()
- assertBrowsingHistoryCheckBox(false)
+ browsingHistoryCheckBox().assertIsChecked(false)
clickCookiesCheckBox()
- assertCookiesCheckBox(false)
+ cookiesAndSiteDataCheckBox().assertIsChecked(false)
- assertCachedFilesCheckBox(true)
+ cachedFilesCheckBox().assertIsChecked(true)
clickSitePermissionsCheckBox()
- assertSitePermissionsCheckBox(false)
+ sitePermissionsCheckBox().assertIsChecked(false)
clickDownloadsCheckBox()
- assertDownloadsCheckBox(false)
+ downloadsCheckBox().assertIsChecked(false)
}
fun confirmDeletionAndAssertSnackbar() {
@@ -179,32 +186,10 @@ private fun dialogMessage() =
onView(withText("$appName will delete the selected browsing data."))
.inRoot(isDialog())
-private fun assertAllCheckBoxesAreChecked() {
- openTabsCheckBox().assertIsChecked(true)
- browsingHistoryCheckBox().assertIsChecked(true)
- cookiesAndSiteDataCheckBox().assertIsChecked(true)
- cachedFilesCheckBox().assertIsChecked(true)
- sitePermissionsCheckBox().assertIsChecked(true)
- downloadsCheckBox().assertIsChecked(true)
-}
-
-private fun assertOpenTabsDescription(tabNumber: String) =
- openTabsDescription(tabNumber).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
-private fun assertBrowsingHistoryDescription(addresses: String) =
- assertUIObjectExists(browsingHistoryDescription(addresses))
-
private fun assertDeleteBrowsingDataSnackbar() = assertUIObjectIsGone(itemWithText("Browsing data deleted"))
-
private fun clickOpenTabsCheckBox() = openTabsCheckBox().click()
-private fun assertOpenTabsCheckBox(status: Boolean) = openTabsCheckBox().assertIsChecked(status)
private fun clickBrowsingHistoryCheckBox() = browsingHistoryCheckBox().click()
-private fun assertBrowsingHistoryCheckBox(status: Boolean) = browsingHistoryCheckBox().assertIsChecked(status)
private fun clickCookiesCheckBox() = cookiesAndSiteDataCheckBox().click()
-private fun assertCookiesCheckBox(status: Boolean) = cookiesAndSiteDataCheckBox().assertIsChecked(status)
private fun clickCachedFilesCheckBox() = cachedFilesCheckBox().click()
-private fun assertCachedFilesCheckBox(status: Boolean) = cachedFilesCheckBox().assertIsChecked(status)
private fun clickSitePermissionsCheckBox() = sitePermissionsCheckBox().click()
-private fun assertSitePermissionsCheckBox(status: Boolean) = sitePermissionsCheckBox().assertIsChecked(status)
private fun clickDownloadsCheckBox() = downloadsCheckBox().click()
-private fun assertDownloadsCheckBox(status: Boolean) = downloadsCheckBox().assertIsChecked(status)
From f33bb09ab654b7d8e1d62bc85045321cfc021be6 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Tue, 20 Feb 2024 12:12:35 +0200
Subject: [PATCH 266/586] Bug 1881010 - Add logs to
SettingsSubMenuDeleteBrowsingDataRobot
---
.../SettingsSubMenuDeleteBrowsingDataRobot.kt | 165 ++++++++++++++++--
1 file changed, 147 insertions(+), 18 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataRobot.kt
index 6cc3380f5ffa..44e935660076 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataRobot.kt
@@ -4,6 +4,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.isDialog
@@ -16,6 +17,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.uiautomator.UiSelector
import org.hamcrest.CoreMatchers.allOf
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.assertUIObjectIsGone
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
@@ -30,26 +32,72 @@ import org.mozilla.fenix.helpers.click
class SettingsSubMenuDeleteBrowsingDataRobot {
fun verifyAllCheckBoxesAreChecked() {
+ Log.i(TAG, "verifyAllCheckBoxesAreChecked: Trying to verify that the \"Open tabs\" check box is checked")
openTabsCheckBox().assertIsChecked(true)
+ Log.i(TAG, "verifyAllCheckBoxesAreChecked: Verified that the \"Open tabs\" check box is checked")
+ Log.i(TAG, "verifyAllCheckBoxesAreChecked: Trying to verify that the \"Browsing history\" check box is checked")
browsingHistoryCheckBox().assertIsChecked(true)
+ Log.i(TAG, "verifyAllCheckBoxesAreChecked: Verified that the \"Browsing history\" check box is checked")
+ Log.i(TAG, "verifyAllCheckBoxesAreChecked: Trying to verify that the \"Cookies and site data\" check box is checked")
cookiesAndSiteDataCheckBox().assertIsChecked(true)
+ Log.i(TAG, "verifyAllCheckBoxesAreChecked: Verified that the \"Cookies and site data\" check box is checked")
+ Log.i(TAG, "verifyAllCheckBoxesAreChecked: Trying to verify that the \"Cached images and files\" check box is checked")
cachedFilesCheckBox().assertIsChecked(true)
+ Log.i(TAG, "verifyAllCheckBoxesAreChecked: Verified that the \"Cached images and files\" check box is checked")
+ Log.i(TAG, "verifyAllCheckBoxesAreChecked: Trying to verify that the \"Site permissions\" check box is checked")
sitePermissionsCheckBox().assertIsChecked(true)
+ Log.i(TAG, "verifyAllCheckBoxesAreChecked: Verified that the \"Site permissions\" check box is checked")
+ Log.i(TAG, "verifyAllCheckBoxesAreChecked: Trying to verify that the \"Downloads\" check box is checked")
downloadsCheckBox().assertIsChecked(true)
+ Log.i(TAG, "verifyAllCheckBoxesAreChecked: Verified that the \"Downloads\" check box is checked")
+ }
+ fun verifyOpenTabsCheckBox(status: Boolean) {
+ Log.i(TAG, "verifyOpenTabsCheckBox: Trying to verify that the \"Open tabs\" check box is checked: $status")
+ openTabsCheckBox().assertIsChecked(status)
+ Log.i(TAG, "verifyOpenTabsCheckBox: Verified that the \"Open tabs\" check box is checked: $status")
+ }
+ fun verifyBrowsingHistoryDetails(status: Boolean) {
+ Log.i(TAG, "verifyBrowsingHistoryDetails: Trying to verify that the \"Browsing history\" check box is checked: $status")
+ browsingHistoryCheckBox().assertIsChecked(status)
+ Log.i(TAG, "verifyBrowsingHistoryDetails: Verified that the \"Browsing history\" check box is checked: $status")
+ }
+ fun verifyCookiesCheckBox(status: Boolean) {
+ Log.i(TAG, "verifyCookiesCheckBox: Trying to verify that the \"Cookies and site data\" check box is checked: $status")
+ cookiesAndSiteDataCheckBox().assertIsChecked(status)
+ Log.i(TAG, "verifyCookiesCheckBox: Verified that the \"Cookies and site data\" check box is checked: $status")
+ }
+ fun verifyCachedFilesCheckBox(status: Boolean) {
+ Log.i(TAG, "verifyCachedFilesCheckBox: Trying to verify that the \"Cached images and files\" check box is checked: $status")
+ cachedFilesCheckBox().assertIsChecked(status)
+ Log.i(TAG, "verifyCachedFilesCheckBox: Verified that the \"Cached images and files\" check box is checked: $status")
+ }
+ fun verifySitePermissionsCheckBox(status: Boolean) {
+ Log.i(TAG, "verifySitePermissionsCheckBox: Trying to verify that the \"Site permissions\" check box is checked: $status")
+ sitePermissionsCheckBox().assertIsChecked(status)
+ Log.i(TAG, "verifySitePermissionsCheckBox: Verified that the \"Site permissions\" check box is checked: $status")
+ }
+ fun verifyDownloadsCheckBox(status: Boolean) {
+ Log.i(TAG, "verifyDownloadsCheckBox: Trying to verify that the \"Downloads\" check box is checked: $status")
+ downloadsCheckBox().assertIsChecked(status)
+ Log.i(TAG, "verifyDownloadsCheckBox: Verified that the \"Downloads\" check box is checked: $status")
+ }
+ fun verifyOpenTabsDetails(tabNumber: String) {
+ Log.i(TAG, "verifyOpenTabsDetails: Trying to verify that the \"Open tabs\" option summary containing $tabNumber open tabs is visible")
+ openTabsDescription(tabNumber).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ Log.i(TAG, "verifyOpenTabsDetails: Verified that the \"Open tabs\" option summary containing $tabNumber open tabs is visible")
}
- fun verifyOpenTabsCheckBox(status: Boolean) = openTabsCheckBox().assertIsChecked(status)
- fun verifyBrowsingHistoryDetails(status: Boolean) = browsingHistoryCheckBox().assertIsChecked(status)
- fun verifyCookiesCheckBox(status: Boolean) = cookiesAndSiteDataCheckBox().assertIsChecked(status)
- fun verifyCachedFilesCheckBox(status: Boolean) = cachedFilesCheckBox().assertIsChecked(status)
- fun verifySitePermissionsCheckBox(status: Boolean) = sitePermissionsCheckBox().assertIsChecked(status)
- fun verifyDownloadsCheckBox(status: Boolean) = downloadsCheckBox().assertIsChecked(status)
- fun verifyOpenTabsDetails(tabNumber: String) = openTabsDescription(tabNumber).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
fun verifyBrowsingHistoryDetails(addresses: String) = assertUIObjectExists(browsingHistoryDescription(addresses))
fun verifyDeleteBrowsingDataDialog() {
+ Log.i(TAG, "verifyDeleteBrowsingDataDialog: Trying to verify that the delete browsing data dialog message is visible")
dialogMessage().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ Log.i(TAG, "verifyDeleteBrowsingDataDialog: Verified that the delete browsing data dialog message is visible")
+ Log.i(TAG, "verifyDeleteBrowsingDataDialog: Trying to verify that the delete browsing data dialog \"Cancel\" button is visible")
dialogCancelButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ Log.i(TAG, "verifyDeleteBrowsingDataDialog: Verified that the delete browsing data dialog \"Cancel\" button is visible")
+ Log.i(TAG, "verifyDeleteBrowsingDataDialog: Trying to verify that the delete browsing data dialog \"Delete\" button is visible")
dialogDeleteButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ Log.i(TAG, "verifyDeleteBrowsingDataDialog: Verified that the delete browsing data dialog \"Delete\" button is visible")
}
fun switchOpenTabsCheckBox() = clickOpenTabsCheckBox()
@@ -58,93 +106,150 @@ class SettingsSubMenuDeleteBrowsingDataRobot {
fun switchCachedFilesCheckBox() = clickCachedFilesCheckBox()
fun switchSitePermissionsCheckBox() = clickSitePermissionsCheckBox()
fun switchDownloadsCheckBox() = clickDownloadsCheckBox()
- fun clickDeleteBrowsingDataButton() = deleteBrowsingDataButton().click()
- fun clickDialogCancelButton() = dialogCancelButton().click()
+ fun clickDeleteBrowsingDataButton() {
+ Log.i(TAG, "clickDeleteBrowsingDataButton: Trying to click the \"Delete browsing data\" button")
+ deleteBrowsingDataButton().click()
+ Log.i(TAG, "clickDeleteBrowsingDataButton: Clicked the \"Delete browsing data\" button")
+ }
+ fun clickDialogCancelButton() {
+ Log.i(TAG, "clickDialogCancelButton: Trying to click the delete browsing data dialog \"Cancel\" button")
+ dialogCancelButton().click()
+ Log.i(TAG, "clickDialogCancelButton: Clicked the delete browsing data dialog \"Cancel\" button")
+ }
fun selectOnlyOpenTabsCheckBox() {
clickBrowsingHistoryCheckBox()
+ Log.i(TAG, "selectOnlyOpenTabsCheckBox: Trying to verify that the \"Browsing history\" check box is not checked")
browsingHistoryCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyOpenTabsCheckBox: Verified that the \"Browsing history\" check box is not checked")
clickCookiesCheckBox()
+ Log.i(TAG, "selectOnlyOpenTabsCheckBox: Trying to verify that the \"Cookies and site data\" check box is not checked")
cookiesAndSiteDataCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyOpenTabsCheckBox: Verified that the \"Cookies and site data\" check box is not checked")
clickCachedFilesCheckBox()
+ Log.i(TAG, "selectOnlyOpenTabsCheckBox: Trying to verify that the \"Cached images and files\" check box is not checked")
cachedFilesCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyOpenTabsCheckBox: Verified that the \"Cached images and files\" check box is not checked")
clickSitePermissionsCheckBox()
+ Log.i(TAG, "selectOnlyOpenTabsCheckBox: Trying to verify that the \"Site permissions\" check box is not checked")
sitePermissionsCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyOpenTabsCheckBox: Verified that the \"Site permissions\" check box is not checked")
clickDownloadsCheckBox()
+ Log.i(TAG, "selectOnlyOpenTabsCheckBox: Trying to verify that the \"Downloads\" check box is not checked")
downloadsCheckBox().assertIsChecked(false)
-
+ Log.i(TAG, "selectOnlyOpenTabsCheckBox: Verified that the \"Downloads\" check box is not checked")
+ Log.i(TAG, "selectOnlyOpenTabsCheckBox: Trying to verify that the \"Open tabs\" check box is checked")
openTabsCheckBox().assertIsChecked(true)
+ Log.i(TAG, "selectOnlyOpenTabsCheckBox: Trying to verify that the \"Open tabs\" check box is checked")
}
fun selectOnlyBrowsingHistoryCheckBox() {
clickOpenTabsCheckBox()
+ Log.i(TAG, "selectOnlyBrowsingHistoryCheckBox: Trying to verify that the \"Open tabs\" check box is not checked")
openTabsCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyBrowsingHistoryCheckBox: Verified that the \"Open tabs\" check box is not checked")
clickCookiesCheckBox()
+ Log.i(TAG, "selectOnlyBrowsingHistoryCheckBox: Trying to verify that the \"Cookies and site data\" check box is not checked")
cookiesAndSiteDataCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyBrowsingHistoryCheckBox: Verified that the \"Cookies and site data\" check box is not checked")
clickCachedFilesCheckBox()
+ Log.i(TAG, "selectOnlyBrowsingHistoryCheckBox: Trying to verify that the \"Cached images and files\" check box is not checked")
cachedFilesCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyBrowsingHistoryCheckBox: Verified that the \"Cached images and files\" check box is not checked")
clickSitePermissionsCheckBox()
+ Log.i(TAG, "selectOnlyBrowsingHistoryCheckBox: Trying to verify that the \"Site permissions\" check box is not checked")
sitePermissionsCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyBrowsingHistoryCheckBox: Verified that the \"Site permissions\" check box is not checked")
clickDownloadsCheckBox()
+ Log.i(TAG, "selectOnlyBrowsingHistoryCheckBox: Trying to verify that the \"Downloads\" check box is not checked")
downloadsCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyBrowsingHistoryCheckBox: Verified that the \"Downloads\" check box is not checked")
+ Log.i(TAG, "selectOnlyBrowsingHistoryCheckBox: Trying to verify that the \"Browsing history\" check box is checked")
browsingHistoryCheckBox().assertIsChecked(true)
+ Log.i(TAG, "selectOnlyBrowsingHistoryCheckBox: Verified that the \"Browsing history\" check box is checked")
}
fun selectOnlyCookiesCheckBox() {
clickOpenTabsCheckBox()
+ Log.i(TAG, "selectOnlyCookiesCheckBox: Trying to verify that the \"Open tabs\" check box is not checked")
openTabsCheckBox().assertIsChecked(false)
-
+ Log.i(TAG, "selectOnlyCookiesCheckBox: Verified that the \"Open tabs\" check box is not checked")
+ Log.i(TAG, "selectOnlyCookiesCheckBox: Trying to verify that the \"Cookies and site data\" check box is checked")
cookiesAndSiteDataCheckBox().assertIsChecked(true)
+ Log.i(TAG, "selectOnlyCookiesCheckBox: Verified that the \"Cookies and site data\" check box is checked")
clickCachedFilesCheckBox()
+ Log.i(TAG, "selectOnlyCookiesCheckBox: Trying to verify that the \"Cached images and files\" check box is not checked")
cachedFilesCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyCookiesCheckBox: Verified that the \"Cached images and files\" check box is not checked")
clickSitePermissionsCheckBox()
+ Log.i(TAG, "selectOnlyCookiesCheckBox: Trying to verify that the \"Site permissions\" check box is not checked")
sitePermissionsCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyCookiesCheckBox: Verified that the \"Site permissions\" check box is not checked")
clickDownloadsCheckBox()
+ Log.i(TAG, "selectOnlyCookiesCheckBox: Trying to verify that the \"Downloads\" check box is not checked")
downloadsCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyCookiesCheckBox: Verified that the \"Downloads\" check box is not checked")
clickBrowsingHistoryCheckBox()
+ Log.i(TAG, "selectOnlyCookiesCheckBox: Trying to verify that the \"Browsing history\" check box is not checked")
browsingHistoryCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyCookiesCheckBox: Verified that the \"Browsing history\" check box is not checked")
}
fun selectOnlyCachedFilesCheckBox() {
clickOpenTabsCheckBox()
+ Log.i(TAG, "selectOnlyCachedFilesCheckBox: Trying to verify that the \"Open tabs\" check box is not checked")
openTabsCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyCachedFilesCheckBox: Verified that the \"Open tabs\" check box is not checked")
clickBrowsingHistoryCheckBox()
+ Log.i(TAG, "selectOnlyCachedFilesCheckBox: Trying to verify that the \"Browsing history\" check box is not checked")
browsingHistoryCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyCachedFilesCheckBox: Verified that the \"Browsing history\" check box is not checked")
clickCookiesCheckBox()
+ Log.i(TAG, "selectOnlyCachedFilesCheckBox: Trying to verify that the \"Cookies and site data\" check box is not checked")
cookiesAndSiteDataCheckBox().assertIsChecked(false)
-
+ Log.i(TAG, "selectOnlyCachedFilesCheckBox: Verified that the \"Cookies and site data\" check box is not checked")
+ Log.i(TAG, "selectOnlyCachedFilesCheckBox: Trying to verify that the \"Cached images and files\" check box is checked")
cachedFilesCheckBox().assertIsChecked(true)
+ Log.i(TAG, "selectOnlyCachedFilesCheckBox: Verified that the \"Cached images and files\" check box is checked")
clickSitePermissionsCheckBox()
+ Log.i(TAG, "selectOnlyCachedFilesCheckBox: Trying to verify that the \"Site permissions\" check box is not checked")
sitePermissionsCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyCachedFilesCheckBox: Verified that the \"Site permissions\" check box is not checked")
clickDownloadsCheckBox()
+ Log.i(TAG, "selectOnlyCachedFilesCheckBox: Trying to verify that the \"Downloads\" check box is not checked")
downloadsCheckBox().assertIsChecked(false)
+ Log.i(TAG, "selectOnlyCachedFilesCheckBox: Verified that the \"Downloads\" check box is not checked")
}
fun confirmDeletionAndAssertSnackbar() {
+ Log.i(TAG, "confirmDeletionAndAssertSnackbar: Trying to click the delete browsing data dialog \"Delete\" button")
dialogDeleteButton().click()
+ Log.i(TAG, "confirmDeletionAndAssertSnackbar: Clicked the delete browsing data dialog \"Delete\" button")
assertDeleteBrowsingDataSnackbar()
}
class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
+ Log.i(TAG, "goBack: Trying to click navigate up toolbar button")
goBackButton().click()
+ Log.i(TAG, "goBack: Clicked the navigate up toolbar button")
SettingsRobot().interact()
return SettingsRobot.Transition()
@@ -187,9 +292,33 @@ private fun dialogMessage() =
.inRoot(isDialog())
private fun assertDeleteBrowsingDataSnackbar() = assertUIObjectIsGone(itemWithText("Browsing data deleted"))
-private fun clickOpenTabsCheckBox() = openTabsCheckBox().click()
-private fun clickBrowsingHistoryCheckBox() = browsingHistoryCheckBox().click()
-private fun clickCookiesCheckBox() = cookiesAndSiteDataCheckBox().click()
-private fun clickCachedFilesCheckBox() = cachedFilesCheckBox().click()
-private fun clickSitePermissionsCheckBox() = sitePermissionsCheckBox().click()
-private fun clickDownloadsCheckBox() = downloadsCheckBox().click()
+private fun clickOpenTabsCheckBox() {
+ Log.i(TAG, "clickOpenTabsCheckBox: Trying to click the \"Open tabs\" check box")
+ openTabsCheckBox().click()
+ Log.i(TAG, "clickOpenTabsCheckBox: Clicked the \"Open tabs\" check box")
+}
+private fun clickBrowsingHistoryCheckBox() {
+ Log.i(TAG, "clickBrowsingHistoryCheckBox: Trying to click the \"Browsing history\" check box")
+ browsingHistoryCheckBox().click()
+ Log.i(TAG, "clickBrowsingHistoryCheckBox: Clicked the \"Browsing history\" check box")
+}
+private fun clickCookiesCheckBox() {
+ Log.i(TAG, "clickCookiesCheckBox: Trying to click the \"Cookies and site data\" check box")
+ cookiesAndSiteDataCheckBox().click()
+ Log.i(TAG, "clickCookiesCheckBox: Clicked the \"Cookies and site data\" check box")
+}
+private fun clickCachedFilesCheckBox() {
+ Log.i(TAG, "clickCachedFilesCheckBox: Trying to click the \"Cached images and files\" check box")
+ cachedFilesCheckBox().click()
+ Log.i(TAG, "clickCachedFilesCheckBox: Clicked the \"Cached images and files\" check box")
+}
+private fun clickSitePermissionsCheckBox() {
+ Log.i(TAG, "clickSitePermissionsCheckBox: Trying to click the \"Site permissions\" check box")
+ sitePermissionsCheckBox().click()
+ Log.i(TAG, "clickSitePermissionsCheckBox: Clicked the \"Site permissions\" check box")
+}
+private fun clickDownloadsCheckBox() {
+ Log.i(TAG, "clickDownloadsCheckBox: Trying to click the \"Downloads\" check box")
+ downloadsCheckBox().click()
+ Log.i(TAG, "clickDownloadsCheckBox: Clicked the \"Downloads\" check box")
+}
From 72721160b19378827d11cb375ef7bef44c205b84 Mon Sep 17 00:00:00 2001
From: iorgamgabriel
Date: Mon, 22 Jan 2024 17:13:54 +0200
Subject: [PATCH 267/586] Bug 1856979 - Translations UI Post-Translate Popup
---
.../mozilla/fenix/browser/BrowserFragment.kt | 23 +
.../translations/TranslationsBottomSheet.kt | 31 +-
.../translations/TranslationsDialogBinding.kt | 142 +++++
.../TranslationsDialogBottomSheet.kt | 552 ++++++++++++------
.../TranslationsDialogFragment.kt | 192 +++---
.../TranslationsDialogMiddleware.kt | 62 ++
.../translations/TranslationsDialogStore.kt | 285 +++++++++
fenix/app/src/main/res/values/strings.xml | 8 +
.../TranslationsDialogBindingTest.kt | 308 ++++++++++
.../TranslationsDialogMiddlewareTest.kt | 101 ++++
.../TranslationsDialogReducerTest.kt | 229 ++++++++
11 files changed, 1663 insertions(+), 270 deletions(-)
create mode 100644 fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt
create mode 100644 fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogMiddleware.kt
create mode 100644 fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogStore.kt
create mode 100644 fenix/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogBindingTest.kt
create mode 100644 fenix/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogMiddlewareTest.kt
create mode 100644 fenix/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogReducerTest.kt
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
index 5248f0773840..0d37c0847bde 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
@@ -11,6 +11,7 @@ import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
+import androidx.fragment.app.setFragmentResultListener
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
@@ -52,6 +53,8 @@ import org.mozilla.fenix.shopping.DefaultShoppingExperienceFeature
import org.mozilla.fenix.shopping.ReviewQualityCheckFeature
import org.mozilla.fenix.shortcut.PwaOnboardingObserver
import org.mozilla.fenix.theme.ThemeManager
+import org.mozilla.fenix.translations.TranslationsDialogFragment.Companion.SESSION_ID
+import org.mozilla.fenix.translations.TranslationsDialogFragment.Companion.TRANSLATION_IN_PROGRESS
/**
* Fragment used for browsing the web within the main app.
@@ -211,6 +214,26 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
owner = viewLifecycleOwner,
view = binding.root,
)
+
+ setTranslationFragmentResultListener()
+ }
+
+ private fun setTranslationFragmentResultListener() {
+ setFragmentResultListener(
+ TRANSLATION_IN_PROGRESS,
+ ) { _, result ->
+ result.getString(SESSION_ID)?.let {
+ if (it == getCurrentTab()?.id) {
+ FenixSnackbar.make(
+ view = binding.dynamicSnackbarContainer,
+ duration = Snackbar.LENGTH_LONG,
+ isDisplayedWithBrowserToolbar = true,
+ )
+ .setText(requireContext().getString(R.string.translation_in_progress_snackbar))
+ .show()
+ }
+ }
+ }
}
private fun initTranslationsAction(context: Context) {
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsBottomSheet.kt b/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsBottomSheet.kt
index efab01c24200..98c341ac3b9c 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsBottomSheet.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsBottomSheet.kt
@@ -27,7 +27,6 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import mozilla.components.concept.engine.translate.Language
-import mozilla.components.concept.engine.translate.TranslationError
import org.mozilla.fenix.theme.FirefoxTheme
private const val BOTTOM_SHEET_HANDLE_WIDTH_PERCENT = 0.1f
@@ -127,37 +126,29 @@ internal fun TranslationsOptionsAnimation(
}
}
-@Composable
@Suppress("LongParameterList")
+@Composable
internal fun TranslationsDialog(
+ translationsDialogState: TranslationsDialogState,
learnMoreUrl: String,
- showFirstTimeTranslation: Boolean,
- translateFromLanguages: List?,
- translateToLanguages: List?,
- initialFrom: Language? = null,
- initialTo: Language? = null,
- translationError: TranslationError? = null,
+ showFirstTime: Boolean = false,
onSettingClicked: () -> Unit,
onLearnMoreClicked: () -> Unit,
- onTranslateButtonClick: () -> Unit,
- onNotNowButtonClick: () -> Unit,
+ onPositiveButtonClicked: () -> Unit,
+ onNegativeButtonClicked: () -> Unit,
onFromSelected: (Language) -> Unit,
onToSelected: (Language) -> Unit,
) {
TranslationsDialogBottomSheet(
+ translationsDialogState = translationsDialogState,
learnMoreUrl = learnMoreUrl,
- showFirstTimeTranslation = showFirstTimeTranslation,
- translationError = translationError,
- translateFromLanguages = translateFromLanguages,
- translateToLanguages = translateToLanguages,
- initialFrom = initialFrom,
- initialTo = initialTo,
+ showFirstTimeFlow = showFirstTime,
onSettingClicked = onSettingClicked,
onLearnMoreClicked = onLearnMoreClicked,
- onTranslateButtonClicked = onTranslateButtonClick,
- onNotNowButtonClicked = onNotNowButtonClick,
- onFromSelected = onFromSelected,
- onToSelected = onToSelected,
+ onPositiveButtonClicked = onPositiveButtonClicked,
+ onNegativeButtonClicked = onNegativeButtonClicked,
+ onFromDropdownSelected = onFromSelected,
+ onToDropdownSelected = onToSelected,
)
}
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt b/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt
new file mode 100644
index 000000000000..3d1e8381973c
--- /dev/null
+++ b/fenix/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt
@@ -0,0 +1,142 @@
+/* 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.translations
+
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChangedBy
+import kotlinx.coroutines.flow.mapNotNull
+import mozilla.components.browser.state.selector.findTab
+import mozilla.components.browser.state.state.BrowserState
+import mozilla.components.browser.state.store.BrowserStore
+import mozilla.components.concept.engine.translate.initialFromLanguage
+import mozilla.components.concept.engine.translate.initialToLanguage
+import mozilla.components.lib.state.helpers.AbstractBinding
+
+/**
+ * Helper for observing Translation state from [BrowserStore].
+ */
+class TranslationsDialogBinding(
+ browserStore: BrowserStore,
+ private val translationsDialogStore: TranslationsDialogStore,
+ private val sessionId: String,
+ private val getTranslatedPageTitle: (localizedFrom: String?, localizedTo: String?) -> String,
+) : AbstractBinding(browserStore) {
+
+ override suspend fun onState(flow: Flow) {
+ flow.mapNotNull { state -> state.findTab(sessionId) }
+ .distinctUntilChangedBy {
+ it.translationsState
+ }
+ .collect { sessionState ->
+ val translationsState = sessionState.translationsState
+
+ val fromSelected =
+ translationsState.translationEngineState?.initialFromLanguage(
+ translationsState.supportedLanguages?.fromLanguages,
+ )
+
+ fromSelected?.let {
+ translationsDialogStore.dispatch(
+ TranslationsDialogAction.UpdateFromSelectedLanguage(
+ fromSelected,
+ ),
+ )
+ }
+
+ val toSelected =
+ translationsState.translationEngineState?.initialToLanguage(
+ translationsState.supportedLanguages?.toLanguages,
+ )
+ toSelected?.let {
+ translationsDialogStore.dispatch(
+ TranslationsDialogAction.UpdateToSelectedLanguage(
+ toSelected,
+ ),
+ )
+ }
+
+ if (
+ toSelected != null && fromSelected != null &&
+ translationsDialogStore.state.translatedPageTitle == null
+ ) {
+ translationsDialogStore.dispatch(
+ TranslationsDialogAction.UpdateTranslatedPageTitle(
+ getTranslatedPageTitle(
+ fromSelected.localizedDisplayName,
+ toSelected.localizedDisplayName,
+ ),
+ ),
+ )
+ }
+
+ val translateFromLanguages = translationsState.supportedLanguages?.fromLanguages
+ translateFromLanguages?.let {
+ translationsDialogStore.dispatch(
+ TranslationsDialogAction.UpdateTranslateFromLanguages(
+ translateFromLanguages,
+ ),
+ )
+ }
+
+ val translateToLanguages = translationsState.supportedLanguages?.toLanguages
+ translateToLanguages?.let {
+ translationsDialogStore.dispatch(
+ TranslationsDialogAction.UpdateTranslateToLanguages(
+ translateToLanguages,
+ ),
+ )
+ }
+
+ if (translationsState.isTranslateProcessing) {
+ updateStoreIfIsTranslateProcessing()
+ }
+
+ if (translationsState.isTranslated && !translationsState.isTranslateProcessing) {
+ updateStoreIfTranslated()
+ }
+
+ if (translationsState.translationError != null) {
+ translationsDialogStore.dispatch(
+ TranslationsDialogAction.UpdateTranslationError(translationsState.translationError),
+ )
+ }
+ }
+ }
+
+ private fun updateStoreIfIsTranslateProcessing() {
+ translationsDialogStore.dispatch(
+ TranslationsDialogAction.UpdateTranslationInProgress(
+ true,
+ ),
+ )
+ translationsDialogStore.dispatch(
+ TranslationsDialogAction.DismissDialog(
+ dismissDialogState = DismissDialogState.WaitingToBeDismissed,
+ ),
+ )
+ }
+
+ private fun updateStoreIfTranslated() {
+ translationsDialogStore.dispatch(
+ TranslationsDialogAction.UpdateTranslationInProgress(
+ false,
+ ),
+ )
+
+ translationsDialogStore.dispatch(
+ TranslationsDialogAction.UpdateTranslated(
+ true,
+ ),
+ )
+
+ if (translationsDialogStore.state.dismissDialogState == DismissDialogState.WaitingToBeDismissed) {
+ translationsDialogStore.dispatch(
+ TranslationsDialogAction.DismissDialog(
+ dismissDialogState = DismissDialogState.Dismiss,
+ ),
+ )
+ }
+ }
+}
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 18b1f11cf184..13aa8a7333b1 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
@@ -67,45 +67,29 @@ private val ICON_SIZE = 24.dp
/**
* Firefox Translations bottom sheet dialog.
*
+ * @param translationsDialogState The current state of the Translations bottom sheet dialog.
* @param learnMoreUrl The learn more link for translations website.
- * @param showFirstTimeTranslation Whether translations first flow should be shown.
- * @param translateFromLanguages Translation menu items to be shown in the translate from dropdown.
- * @param translateToLanguages Translation menu items are to be shown in the translate to dropdown.
- * @param initialFrom The initial selection for the translate from dropdown.
- * @param initialTo The initial selection for the translate to dropdown.
- * @param translationError The type of translation errors that can occur.
+ * @param showFirstTimeFlow Whether translations first flow should be shown.
* @param onSettingClicked Invoked when the user clicks on the settings button.
* @param onLearnMoreClicked Invoked when the user clicks on the "Learn More" button.
- * @param onTranslateButtonClicked Invoked when the user clicks on the "Translate" button.
- * @param onNotNowButtonClicked Invoked when the user clicks on the "Not Now" button.
- * @param onFromSelected Invoked when the user selects an item on the from dropdown.
- * @param onToSelected Invoked when the user selects an item on the to dropdown.
+ * @param onPositiveButtonClicked Invoked when the user clicks on the positive button.
+ * @param onNegativeButtonClicked Invoked when the user clicks on the negative button.
+ * @param onFromDropdownSelected Invoked when the user selects an item on the from dropdown.
+ * @param onToDropdownSelected Invoked when the user selects an item on the to dropdown.
*/
-@Composable
@Suppress("LongParameterList")
+@Composable
fun TranslationsDialogBottomSheet(
+ translationsDialogState: TranslationsDialogState,
learnMoreUrl: String,
- showFirstTimeTranslation: Boolean,
- translateFromLanguages: List?,
- translateToLanguages: List?,
- initialFrom: Language? = null,
- initialTo: Language? = null,
- translationError: TranslationError? = null,
+ showFirstTimeFlow: Boolean = false,
onSettingClicked: () -> Unit,
onLearnMoreClicked: () -> Unit,
- onTranslateButtonClicked: () -> Unit,
- onNotNowButtonClicked: () -> Unit,
- onFromSelected: (Language) -> Unit,
- onToSelected: (Language) -> Unit,
+ onPositiveButtonClicked: () -> Unit,
+ onNegativeButtonClicked: () -> Unit,
+ onFromDropdownSelected: (Language) -> Unit,
+ onToDropdownSelected: (Language) -> Unit,
) {
- var orientation by remember { mutableIntStateOf(Configuration.ORIENTATION_PORTRAIT) }
-
- val configuration = LocalConfiguration.current
-
- LaunchedEffect(configuration) {
- snapshotFlow { configuration.orientation }.collect { orientation = it }
- }
-
Column(
modifier = Modifier.padding(16.dp),
) {
@@ -116,142 +100,347 @@ fun TranslationsDialogBottomSheet(
)
TranslationsDialogHeader(
- showFirstTimeTranslation = showFirstTimeTranslation,
+ title = if (
+ translationsDialogState.isTranslated && translationsDialogState.translatedPageTitle != null
+ ) {
+ translationsDialogState.translatedPageTitle
+ } else {
+ getTranslationsDialogTitle(
+ showFirstTime = showFirstTimeFlow,
+ )
+ },
onSettingClicked = onSettingClicked,
)
Spacer(modifier = Modifier.height(8.dp))
- if (showFirstTimeTranslation) {
+ if (showFirstTimeFlow) {
TranslationsDialogInfoMessage(
learnMoreUrl = learnMoreUrl,
onLearnMoreClicked = onLearnMoreClicked,
)
}
- translationError?.let {
- TranslationErrorWarning(translationError)
- }
+ DialogContentBaseOnTranslationState(
+ translationsDialogState = translationsDialogState,
+ learnMoreUrl = learnMoreUrl,
+ onLearnMoreClicked = onLearnMoreClicked,
+ onPositiveButtonClicked = onPositiveButtonClicked,
+ onNegativeButtonClicked = onNegativeButtonClicked,
+ onFromDropdownSelected = onFromDropdownSelected,
+ onToDropdownSelected = onToDropdownSelected,
+ )
+ }
+}
+/**
+ * Dialog content will adapt based on the [TranslationsDialogState].
+ *
+ * @param translationsDialogState The current state of the Translations bottom sheet dialog.
+ * @param learnMoreUrl The learn more link for translations website.
+ * @param onLearnMoreClicked Invoked when the user clicks on the learn more button.
+ * @param onPositiveButtonClicked Invoked when the user clicks on the positive button.
+ * @param onNegativeButtonClicked Invoked when the user clicks on the negative button.
+ * @param onFromDropdownSelected Invoked when the user selects an item on the from dropdown.
+ * @param onToDropdownSelected Invoked when the user selects an item on the to dropdown.
+ */
+@Composable
+private fun DialogContentBaseOnTranslationState(
+ translationsDialogState: TranslationsDialogState,
+ learnMoreUrl: String,
+ onLearnMoreClicked: () -> Unit,
+ onPositiveButtonClicked: () -> Unit,
+ onNegativeButtonClicked: () -> Unit,
+ onFromDropdownSelected: (Language) -> Unit,
+ onToDropdownSelected: (Language) -> Unit,
+) {
+ if (translationsDialogState.error != null) {
+ DialogContentAnErrorOccurred(
+ error = translationsDialogState.error,
+ learnMoreUrl = learnMoreUrl,
+ onLearnMoreClicked = onLearnMoreClicked,
+ fromLanguages = translationsDialogState.fromLanguages,
+ toLanguages = translationsDialogState.toLanguages,
+ initialFrom = translationsDialogState.initialFrom,
+ initialTo = translationsDialogState.initialTo,
+ onFromDropdownSelected = onFromDropdownSelected,
+ onToDropdownSelected = onToDropdownSelected,
+ onPositiveButtonClicked = onPositiveButtonClicked,
+ onNegativeButtonClicked = onNegativeButtonClicked,
+ )
+ } else if (translationsDialogState.isTranslated) {
+ DialogContentTranslated(
+ translateToLanguages = translationsDialogState.toLanguages,
+ onFromDropdownSelected = onFromDropdownSelected,
+ onToDropdownSelected = onToDropdownSelected,
+ onPositiveButtonClicked = onPositiveButtonClicked,
+ onNegativeButtonClicked = onNegativeButtonClicked,
+ positiveButtonType = translationsDialogState.positiveButtonType,
+ initialTo = translationsDialogState.initialTo,
+ )
+ } else {
Spacer(modifier = Modifier.height(14.dp))
- if (translationError !is TranslationError.CouldNotLoadLanguagesError &&
- translateFromLanguages != null && translateToLanguages != null
- ) {
- when (orientation) {
- Configuration.ORIENTATION_LANDSCAPE -> {
- TranslationsDialogContentInLandscapeMode(
- translateFromLanguages = translateFromLanguages,
- translateToLanguages = translateToLanguages,
- initialFrom = initialFrom,
- initialTo = initialTo,
- onFromSelected = onFromSelected,
- onToSelected = onToSelected,
- )
- }
-
- else -> {
- TranslationsDialogContentInPortraitMode(
- translateFromLanguages = translateFromLanguages,
- translateToLanguages = translateToLanguages,
- initialFrom = initialFrom,
- initialTo = initialTo,
- onFromSelected = onFromSelected,
- onToSelected = onToSelected,
- )
- }
- }
+ TranslationsDialogContent(
+ translateFromLanguages = translationsDialogState.fromLanguages,
+ translateToLanguages = translationsDialogState.toLanguages,
+ initialFrom = translationsDialogState.initialFrom,
+ initialTo = translationsDialogState.initialTo,
+ onFromDropdownSelected = onFromDropdownSelected,
+ onToDropdownSelected = onToDropdownSelected,
+ )
- Spacer(modifier = Modifier.height(16.dp))
- }
+ Spacer(modifier = Modifier.height(16.dp))
TranslationsDialogActionButtons(
- translationError = translationError,
- onTranslateButtonClicked = onTranslateButtonClicked,
- onNotNowButtonClicked = onNotNowButtonClicked,
+ positiveButtonText = stringResource(id = R.string.translations_bottom_sheet_positive_button),
+ negativeButtonText = stringResource(id = R.string.translations_bottom_sheet_negative_button),
+ positiveButtonType = translationsDialogState.positiveButtonType,
+ onNegativeButtonClicked = onNegativeButtonClicked,
+ onPositiveButtonClicked = onPositiveButtonClicked,
)
}
}
+/**
+ * Dialog content if the web page was translated.
+ *
+ * @param translateToLanguages Translation menu items to be shown in the translate to dropdown.
+ * @param onFromDropdownSelected Invoked when the user selects an item on the from dropdown.
+ * @param onToDropdownSelected Invoked when the user selects an item on the to dropdown.
+ * @param onPositiveButtonClicked Invoked when the user clicks on the positive button.
+ * @param onNegativeButtonClicked Invoked when the user clicks on the negative button.
+ * @param positiveButtonType Can be enabled,disabled or in progress. If it is null, the button will be disabled.
+ * @param initialTo Initial "to" language, based on the translation state and page state.
+ */
@Composable
-private fun TranslationsDialogContentInPortraitMode(
- translateFromLanguages: List,
- translateToLanguages: List,
- initialFrom: Language? = null,
+private fun DialogContentTranslated(
+ translateToLanguages: List?,
+ onFromDropdownSelected: (Language) -> Unit,
+ onToDropdownSelected: (Language) -> Unit,
+ onPositiveButtonClicked: () -> Unit,
+ onNegativeButtonClicked: () -> Unit,
+ positiveButtonType: PositiveButtonType? = null,
initialTo: Language? = null,
- onFromSelected: (Language) -> Unit,
- onToSelected: (Language) -> Unit,
+) {
+ Spacer(modifier = Modifier.height(14.dp))
+
+ TranslationsDialogContent(
+ translateToLanguages = translateToLanguages,
+ initialTo = initialTo,
+ onFromDropdownSelected = onFromDropdownSelected,
+ onToDropdownSelected = onToDropdownSelected,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ TranslationsDialogActionButtons(
+ positiveButtonText = stringResource(id = R.string.translations_bottom_sheet_positive_button),
+ negativeButtonText = stringResource(id = R.string.translations_bottom_sheet_negative_button_restore),
+ positiveButtonType = positiveButtonType,
+ onPositiveButtonClicked = onPositiveButtonClicked,
+ onNegativeButtonClicked = onNegativeButtonClicked,
+ )
+}
+/**
+ * Dialog content if an [TranslationError] appears during the translation process.
+ *
+ * @param error An error that can occur during the translation process.
+ * @param learnMoreUrl The learn more link for translations website.
+ * @param onLearnMoreClicked Invoked when the user clicks on the learn more button.
+ * @param fromLanguages Translation menu items to be shown in the translate from dropdown.
+ * @param toLanguages Translation menu items to be shown in the translate to dropdown.
+ * @param initialFrom Initial "from" language, based on the translation state and page state.
+ * @param initialTo Initial "to" language, based on the translation state and page state.
+ * @param onFromDropdownSelected Invoked when the user selects an item on the from dropdown.
+ * @param onToDropdownSelected Invoked when the user selects an item on the to dropdown.
+ * @param onPositiveButtonClicked Invoked when the user clicks on the positive button.
+ * @param onNegativeButtonClicked Invoked when the user clicks on the negative button.
+ */
+@Suppress("LongParameterList")
+@Composable
+private fun DialogContentAnErrorOccurred(
+ error: TranslationError,
+ learnMoreUrl: String,
+ onLearnMoreClicked: () -> Unit,
+ fromLanguages: List?,
+ toLanguages: List?,
+ initialFrom: Language? = null,
+ initialTo: Language? = null,
+ onFromDropdownSelected: (Language) -> Unit,
+ onToDropdownSelected: (Language) -> Unit,
+ onPositiveButtonClicked: () -> Unit,
+ onNegativeButtonClicked: () -> Unit,
) {
- Column {
- TranslationsDropdown(
- header = stringResource(id = R.string.translations_bottom_sheet_translate_from),
- modifier = Modifier.fillMaxWidth(),
- translateLanguages = translateFromLanguages,
- initiallySelected = initialFrom,
- onLanguageSelection = onFromSelected,
- )
+ TranslationErrorWarning(
+ error,
+ learnMoreUrl = learnMoreUrl,
+ onLearnMoreClicked = onLearnMoreClicked,
+ )
- Spacer(modifier = Modifier.height(16.dp))
+ Spacer(modifier = Modifier.height(14.dp))
- TranslationsDropdown(
- header = stringResource(id = R.string.translations_bottom_sheet_translate_to),
- modifier = Modifier.fillMaxWidth(),
- translateLanguages = translateToLanguages,
- initiallySelected = initialTo,
- onLanguageSelection = onToSelected,
+ if (error !is TranslationError.CouldNotLoadLanguagesError) {
+ TranslationsDialogContent(
+ translateFromLanguages = fromLanguages,
+ translateToLanguages = toLanguages,
+ initialFrom = initialFrom,
+ initialTo = initialTo,
+ onFromDropdownSelected = onFromDropdownSelected,
+ onToDropdownSelected = onToDropdownSelected,
)
}
+
+ val negativeButtonTitle = if (error is TranslationError.LanguageNotSupportedError) {
+ stringResource(id = R.string.translations_bottom_sheet_negative_button_error)
+ } else {
+ stringResource(id = R.string.translations_bottom_sheet_negative_button)
+ }
+
+ val positiveButtonTitle = if (error is TranslationError.CouldNotLoadLanguagesError) {
+ stringResource(id = R.string.translations_bottom_sheet_positive_button_error)
+ } else {
+ stringResource(id = R.string.translations_bottom_sheet_positive_button)
+ }
+
+ val positiveButtonType = if (error is TranslationError.LanguageNotSupportedError) {
+ PositiveButtonType.Disabled
+ } else {
+ PositiveButtonType.Enabled
+ }
+
+ TranslationsDialogActionButtons(
+ positiveButtonText = positiveButtonTitle,
+ negativeButtonText = negativeButtonTitle,
+ positiveButtonType = positiveButtonType,
+ onNegativeButtonClicked = onNegativeButtonClicked,
+ onPositiveButtonClicked = onPositiveButtonClicked,
+ )
}
@Composable
-private fun TranslationsDialogContentInLandscapeMode(
- translateFromLanguages: List,
- translateToLanguages: List,
+private fun TranslationsDialogContent(
+ translateFromLanguages: List? = null,
+ translateToLanguages: List? = null,
+ initialFrom: Language? = null,
+ initialTo: Language? = null,
+ onFromDropdownSelected: (Language) -> Unit,
+ onToDropdownSelected: (Language) -> Unit,
+) {
+ var orientation by remember { mutableIntStateOf(Configuration.ORIENTATION_PORTRAIT) }
+
+ val configuration = LocalConfiguration.current
+
+ LaunchedEffect(configuration) {
+ snapshotFlow { configuration.orientation }.collect { orientation = it }
+ }
+ when (orientation) {
+ Configuration.ORIENTATION_LANDSCAPE -> {
+ TranslationsDialogContentInLandscapeMode(
+ translateFromLanguages = translateFromLanguages,
+ translateToLanguages = translateToLanguages,
+ initialFrom = initialFrom,
+ initialTo = initialTo,
+ onFromDropdownSelected = onFromDropdownSelected,
+ onToDropdownSelected = onToDropdownSelected,
+ )
+ }
+
+ else -> {
+ TranslationsDialogContentInPortraitMode(
+ translateFromLanguages = translateFromLanguages,
+ translateToLanguages = translateToLanguages,
+ initialFrom = initialFrom,
+ initialTo = initialTo,
+ onFromDropdownSelected = onFromDropdownSelected,
+ onToDropdownSelected = onToDropdownSelected,
+ )
+ }
+ }
+
+ Spacer(modifier = Modifier.height(16.dp))
+}
+
+@Composable
+private fun TranslationsDialogContentInPortraitMode(
+ translateFromLanguages: List? = null,
+ translateToLanguages: List? = null,
initialFrom: Language? = null,
initialTo: Language? = null,
- onFromSelected: (Language) -> Unit,
- onToSelected: (Language) -> Unit,
+ onFromDropdownSelected: (Language) -> Unit,
+ onToDropdownSelected: (Language) -> Unit,
) {
Column {
- Row {
+ translateFromLanguages?.let {
TranslationsDropdown(
header = stringResource(id = R.string.translations_bottom_sheet_translate_from),
- modifier = Modifier.weight(1f),
- isInLandscapeMode = true,
+ modifier = Modifier.fillMaxWidth(),
+ isInLandscapeMode = false,
translateLanguages = translateFromLanguages,
initiallySelected = initialFrom,
- onLanguageSelection = onFromSelected,
+ onLanguageSelection = onFromDropdownSelected,
)
- Spacer(modifier = Modifier.width(16.dp))
+ Spacer(modifier = Modifier.height(16.dp))
+ }
+ translateToLanguages?.let {
TranslationsDropdown(
header = stringResource(id = R.string.translations_bottom_sheet_translate_to),
- modifier = Modifier.weight(1f),
- isInLandscapeMode = true,
- translateLanguages = translateToLanguages,
+ modifier = Modifier.fillMaxWidth(),
+ isInLandscapeMode = false,
+ translateLanguages = it,
initiallySelected = initialTo,
- onLanguageSelection = onToSelected,
+ onLanguageSelection = onToDropdownSelected,
)
}
}
}
@Composable
-private fun TranslationsDialogHeader(
- showFirstTimeTranslation: Boolean,
- onSettingClicked: () -> Unit,
+private fun TranslationsDialogContentInLandscapeMode(
+ translateFromLanguages: List? = null,
+ translateToLanguages: List? = null,
+ initialFrom: Language? = null,
+ initialTo: Language? = null,
+ onFromDropdownSelected: (Language) -> Unit,
+ onToDropdownSelected: (Language) -> Unit,
) {
- val title: String = if (showFirstTimeTranslation) {
- stringResource(
- id = R.string.translations_bottom_sheet_title_first_time,
- stringResource(id = R.string.firefox),
- )
- } else {
- stringResource(id = R.string.translations_bottom_sheet_title)
+ Column {
+ Row {
+ translateFromLanguages?.let {
+ TranslationsDropdown(
+ header = stringResource(id = R.string.translations_bottom_sheet_translate_from),
+ modifier = Modifier.weight(1f),
+ isInLandscapeMode = true,
+ translateLanguages = translateFromLanguages,
+ initiallySelected = initialFrom,
+ onLanguageSelection = onFromDropdownSelected,
+ )
+
+ Spacer(modifier = Modifier.width(16.dp))
+ }
+
+ translateToLanguages?.let {
+ TranslationsDropdown(
+ header = stringResource(id = R.string.translations_bottom_sheet_translate_to),
+ modifier = Modifier.weight(1f),
+ isInLandscapeMode = true,
+ translateLanguages = it,
+ initiallySelected = initialTo,
+ onLanguageSelection = onToDropdownSelected,
+ )
+ }
+ }
}
+}
+@Composable
+private fun TranslationsDialogHeader(
+ title: String,
+ onSettingClicked: () -> Unit,
+) {
Row(
verticalAlignment = Alignment.CenterVertically,
) {
@@ -280,7 +469,11 @@ private fun TranslationsDialogHeader(
}
@Composable
-private fun TranslationErrorWarning(translationError: TranslationError) {
+private fun TranslationErrorWarning(
+ translationError: TranslationError,
+ learnMoreUrl: String,
+ onLearnMoreClicked: () -> Unit,
+) {
val modifier = Modifier
.padding(top = 8.dp)
.fillMaxWidth()
@@ -303,6 +496,9 @@ private fun TranslationErrorWarning(translationError: TranslationError) {
}
is TranslationError.LanguageNotSupportedError -> {
+ val learnMoreText =
+ stringResource(id = R.string.translation_error_language_not_supported_learn_more)
+
ReviewQualityCheckInfoCard(
title = stringResource(
id = R.string.translation_error_language_not_supported_warning_text,
@@ -313,9 +509,9 @@ private fun TranslationErrorWarning(translationError: TranslationError) {
footer = stringResource(
id = R.string.translation_error_language_not_supported_learn_more,
) to LinkTextState(
- text = stringResource(id = R.string.translation_error_language_not_supported_learn_more),
- url = "https://www.mozilla.org",
- onClick = {},
+ text = learnMoreText,
+ url = learnMoreUrl,
+ onClick = { onLearnMoreClicked() },
),
)
}
@@ -353,22 +549,13 @@ private fun TranslationsDialogInfoMessage(
}
}
-/**
- * Creates a dropdown with language selection to use to select languages for translation.
- *
- * @param header The title of the dropdown.
- * @param translateLanguages The language choices the dropdown should provide.
- * @param modifier Any modifiers for the component.
- * @param isInLandscapeMode If the item should layout for landscape mode.
- * @param initiallySelected The language initially selected, if null will show "Choose a language".
- * @param onLanguageSelection Callback for the selected language.
- */
+@Suppress("LongMethod")
@Composable
private fun TranslationsDropdown(
header: String,
translateLanguages: List,
modifier: Modifier = Modifier,
- isInLandscapeMode: Boolean = false,
+ isInLandscapeMode: Boolean,
initiallySelected: Language? = null,
onLanguageSelection: (Language) -> Unit,
) {
@@ -396,7 +583,8 @@ private fun TranslationsDropdown(
Spacer(modifier = Modifier.height(4.dp))
- var initialValue = stringResource(R.string.translations_bottom_sheet_default_dropdown_selection)
+ var initialValue =
+ stringResource(R.string.translations_bottom_sheet_default_dropdown_selection)
initiallySelected?.localizedDisplayName?.let {
initialValue = it
}
@@ -423,19 +611,21 @@ private fun TranslationsDropdown(
onDismissRequest = {
expanded = false
},
-
menuItems = getContextMenuItems(
translateLanguages = translateLanguages,
- onClickItem = onLanguageSelection,
+ selectedLanguage = initiallySelected,
+ onClickItem = {
+ onLanguageSelection(it)
+ },
),
-
modifier = Modifier
.onGloballyPositioned { coordinates ->
contextMenuWidthDp = with(density) {
coordinates.size.width.toDp()
}
}
- .requiredSizeIn(maxHeight = 200.dp),
+ .requiredSizeIn(maxHeight = 200.dp)
+ .padding(horizontal = if (initiallySelected == null) 36.dp else 4.dp),
offset = if (isInLandscapeMode) {
DpOffset(
-contextMenuWidthDp + ICON_SIZE,
@@ -455,8 +645,21 @@ private fun TranslationsDropdown(
}
}
+@Composable
+private fun getTranslationsDialogTitle(
+ showFirstTime: Boolean = false,
+) = if (showFirstTime) {
+ stringResource(
+ id = R.string.translations_bottom_sheet_title_first_time,
+ stringResource(id = R.string.firefox),
+ )
+} else {
+ stringResource(id = R.string.translations_bottom_sheet_title)
+}
+
private fun getContextMenuItems(
translateLanguages: List,
+ selectedLanguage: Language? = null,
onClickItem: (Language) -> Unit,
): List
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 f2f95d1471e2..13a5eab58365 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
@@ -98,6 +98,8 @@
Allow in private browsingRun in private browsing
+
+ Not allowed in private windowsEnabled
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 ed6fc14cb9d9..055d1ca868f9 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
@@ -98,6 +98,8 @@
Дозволити у приватному переглядіЗапуск у приватному перегляді
+
+ Не дозволено в приватних вікнахУвімкнено
@@ -137,13 +139,17 @@
Скасувати
- Встановити додаток
+ Встановити додаток
+
+ Встановити %1$sСкасуватиВідгуків: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Оцінка: %1$.02f з 5Додатки
@@ -244,10 +250,14 @@
Стан:%1$s додано до %2$s
-
- Відкрити в меню
+
+ Відкрити в меню
+
+ Отримайте доступ до %1$s з меню %2$s.
+
+ Гаразд, зрозуміло
- Гаразд, зрозуміло
+ OKДокладніше
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 31dfb31b8d99..7f37c4523f06 100644
--- a/fenix/app/src/main/res/values-en-rGB/strings.xml
+++ b/fenix/app/src/main/res/values-en-rGB/strings.xml
@@ -496,7 +496,7 @@
Secure site not available
- Most likely, the web site simply does not support HTTPs.
+ Most likely, the web site simply does not support HTTPS.However, it’s also possible that an attacker is involved. If you continue to the web site, you should not enter any sensitive info. If you continue, HTTPS-Only mode will be turned off temporarily for the site.
diff --git a/focus-android/app/src/main/res/values-tr/strings.xml b/focus-android/app/src/main/res/values-tr/strings.xml
index c54778b905ff..78018a53a54d 100644
--- a/focus-android/app/src/main/res/values-tr/strings.xml
+++ b/focus-android/app/src/main/res/values-tr/strings.xml
@@ -331,7 +331,7 @@
JavaScript’i engelle
- Sayfaları daha hızlı yüklenebilir ama sorun da çıkarabilirler
+ Sayfalar daha hızlı yüklenebilir ama sorun da çıkarabilirler
- buraya bakabilirsiniz.]]>
+ buraya bakabilirsiniz.]]>
- Arama önerileri alabilmeniz için %1$s’un adres çubuğuna yazdığınız şeyleri seçtiğiniz arama motoruna göndermesi gerekir.
+ Arama önerileri alabilmeniz için %1$s’un adres çubuğuna yazdığınız şeyleri seçtiğiniz arama motoruna göndermesi gerekir.Hayır
From 1a4beb9342df3375bf7212f04f8d650313802e08 Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Wed, 21 Feb 2024 01:28:58 +0000
Subject: [PATCH 278/586] Update GeckoView (Nightly) to 125.0.20240220212334.
---
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 e2cdf07fb843..4ce686789659 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 = "125.0.20240220094730"
+ const val version = "125.0.20240220212334"
/**
* GeckoView channel
From d24034b03db1f535d7a65873b0945838014029fa Mon Sep 17 00:00:00 2001
From: t-p-white
Date: Tue, 20 Feb 2024 11:06:51 +0000
Subject: [PATCH 279/586] Bug 1881009 - Added experimental onboarding strings
for Nimbus
---
fenix/app/src/main/res/values/strings.xml | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/fenix/app/src/main/res/values/strings.xml b/fenix/app/src/main/res/values/strings.xml
index 8f14076d63c9..85c99f579dd0 100644
--- a/fenix/app/src/main/res/values/strings.xml
+++ b/fenix/app/src/main/res/values/strings.xml
@@ -314,12 +314,18 @@
Firefox privacy notice
-
+
+ Learn more in our privacy noticeWe love keeping you safe
+
+ Find out why millions love FirefoxOur non-profit backed browser helps stop companies from secretly following you around the web.
+ More than 100 million people protect their privacy by choosing a browser that’s backed by a nonprofit.
+
Our non-profit backed browser helps stop companies from secretly following you around the web.\n\nLearn more in our privacy notice.
From 4d5b630da25f14bcba8e930f379d98b5925d5ec8 Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Wed, 21 Feb 2024 05:21:38 +0000
Subject: [PATCH 280/586] Update A-S to 125.20240221050347.
---
.../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 0048a6223ee9..cac2ce191806 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 = "125.20240216050339"
+val VERSION = "125.20240221050347"
val CHANNEL = ApplicationServicesChannel.NIGHTLY
object ApplicationServicesConfig {
From f98e606dca8d4d27f174a237fb329dead7d70959 Mon Sep 17 00:00:00 2001
From: DreVla
Date: Thu, 15 Feb 2024 15:43:29 +0200
Subject: [PATCH 281/586] Bug 1879507 - Show Default prompt when
default-browser card disabled
As part of the Set as default optimization experiment, treatment
branch A will show the "Set as Default" System prompt when the
onboarding started, without showing the default-browser card.
This will be controlled from the experimenter and will require
disabling the default-browser card.
If the user already set Firefox as default browser, this prompt
will not be shown.
---
.../fenix/onboarding/OnboardingFragment.kt | 27 +++++++++++++------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
index d216668cabf5..af4693681b9f 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
@@ -52,7 +52,7 @@ class OnboardingFragment : Fragment() {
private val pagesToDisplay by lazy {
pagesToDisplay(
- shouldShowDefaultBrowserCard(requireContext()),
+ isNotDefaultBrowser(requireContext()),
canShowNotificationPage(requireContext()),
canShowAddWidgetCard(),
)
@@ -63,6 +63,7 @@ class OnboardingFragment : Fragment() {
@SuppressLint("SourceLockedOrientationActivity")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ val context = requireContext()
if (pagesToDisplay.isEmpty()) {
/* do not continue if there's no onboarding pages to display */
onFinish(null)
@@ -72,8 +73,14 @@ class OnboardingFragment : Fragment() {
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
val filter = IntentFilter(WidgetPinnedReceiver.ACTION)
- LocalBroadcastManager.getInstance(requireContext())
+ LocalBroadcastManager.getInstance(context)
.registerReceiver(pinAppWidgetReceiver, filter)
+
+ if (isNotDefaultBrowser(context) &&
+ pagesToDisplay.none { it.type == OnboardingPageUiData.Type.DEFAULT_BROWSER }
+ ) {
+ promptToSetAsDefaultBrowser()
+ }
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@@ -109,11 +116,7 @@ class OnboardingFragment : Fragment() {
OnboardingScreen(
pagesToDisplay = pagesToDisplay,
onMakeFirefoxDefaultClick = {
- activity?.openSetDefaultBrowserOption(useCustomTab = true)
- telemetryRecorder.onSetToDefaultClick(
- sequenceId = pagesToDisplay.telemetrySequenceId(),
- sequencePosition = pagesToDisplay.sequencePosition(OnboardingPageUiData.Type.DEFAULT_BROWSER),
- )
+ promptToSetAsDefaultBrowser()
},
onSkipDefaultClick = {
telemetryRecorder.onSkipSetToDefaultClick(
@@ -212,7 +215,7 @@ class OnboardingFragment : Fragment() {
)
}
- private fun shouldShowDefaultBrowserCard(context: Context) =
+ private fun isNotDefaultBrowser(context: Context) =
!BrowsersCache.all(context.applicationContext).isDefaultBrowser
private fun canShowNotificationPage(context: Context) =
@@ -260,4 +263,12 @@ class OnboardingFragment : Fragment() {
) { condition -> jexlHelper.evalJexlSafe(condition) }
}
}
+
+ private fun promptToSetAsDefaultBrowser() {
+ activity?.openSetDefaultBrowserOption(useCustomTab = true)
+ telemetryRecorder.onSetToDefaultClick(
+ sequenceId = pagesToDisplay.telemetrySequenceId(),
+ sequencePosition = pagesToDisplay.sequencePosition(OnboardingPageUiData.Type.DEFAULT_BROWSER),
+ )
+ }
}
From dabd35c801ec924887098c692d429bfa6b46000c Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Tue, 20 Feb 2024 15:42:39 +0200
Subject: [PATCH 282/586] Bug 1881228 - Remove redundant assertion functions
from SettingsSubMenuHomepageRobot
---
.../ui/robots/SettingsSubMenuHomepageRobot.kt | 493 +++++++++---------
1 file changed, 245 insertions(+), 248 deletions(-)
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 6585616f2282..b04ca8a30a89 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
@@ -43,24 +43,218 @@ class SettingsSubMenuHomepageRobot {
pocketSwitchEnabled: Boolean = true,
sponsoredStoriesCheckBox: Boolean = true,
) {
- assertShortcutsButton()
- assertShortcutsSwitchState(shortcutsSwitchEnabled)
- assertSponsoredShortcutsButton()
- assertSponsoredShortcutsCheckBox(sponsoredShortcutsCheckBox)
- assertJumpBackInButton()
- assertJumpBackInSwitchState(jumpBackInSwitchEnabled)
- assertRecentBookmarksButton()
- assertRecentBookmarksSwitchState(recentBookmarksSwitchEnabled)
- assertRecentlyVisitedButton()
- assertRecentlyVisitedSwitchState(recentlyVisitedSwitchEnabled)
- assertPocketButton()
- assertPocketSwitchState(pocketSwitchEnabled)
- assertSponsoredStoriesButton()
- assertSponsoredStoriesCheckBox(sponsoredStoriesCheckBox)
- assertOpeningScreenHeading()
- assertHomepageButton()
- assertLastTabButton()
- assertHomepageAfterFourHoursButton()
+ shortcutsButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+
+ if (shortcutsSwitchEnabled) {
+ shortcutsButton()
+ .check(
+ matches(
+ TestHelper.hasCousin(
+ Matchers.allOf(
+ withClassName(Matchers.endsWith("Switch")),
+ isChecked(),
+ ),
+ ),
+ ),
+ )
+ } else {
+ shortcutsButton()
+ .check(
+ matches(
+ TestHelper.hasCousin(
+ Matchers.allOf(
+ withClassName(Matchers.endsWith("Switch")),
+ isNotChecked(),
+ ),
+ ),
+ ),
+ )
+ }
+
+ sponsoredShortcutsButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+
+ if (sponsoredShortcutsCheckBox) {
+ sponsoredShortcutsButton()
+ .check(
+ matches(
+ hasSibling(
+ ViewMatchers.withChild(
+ allOf(
+ withClassName(CoreMatchers.endsWith("CheckBox")),
+ isChecked(),
+ ),
+ ),
+ ),
+ ),
+ )
+ } else {
+ sponsoredShortcutsButton()
+ .check(
+ matches(
+ hasSibling(
+ ViewMatchers.withChild(
+ allOf(
+ withClassName(CoreMatchers.endsWith("CheckBox")),
+ isNotChecked(),
+ ),
+ ),
+ ),
+ ),
+ )
+ }
+
+ jumpBackInButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+
+ if (jumpBackInSwitchEnabled) {
+ jumpBackInButton()
+ .check(
+ matches(
+ TestHelper.hasCousin(
+ Matchers.allOf(
+ withClassName(Matchers.endsWith("Switch")),
+ isChecked(),
+ ),
+ ),
+ ),
+ )
+ } else {
+ jumpBackInButton()
+ .check(
+ matches(
+ TestHelper.hasCousin(
+ Matchers.allOf(
+ withClassName(Matchers.endsWith("Switch")),
+ isNotChecked(),
+ ),
+ ),
+ ),
+ )
+ }
+
+ recentBookmarksButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+
+ if (recentBookmarksSwitchEnabled) {
+ recentBookmarksButton()
+ .check(
+ matches(
+ TestHelper.hasCousin(
+ Matchers.allOf(
+ withClassName(Matchers.endsWith("Switch")),
+ isChecked(),
+ ),
+ ),
+ ),
+ )
+ } else {
+ recentBookmarksButton()
+ .check(
+ matches(
+ TestHelper.hasCousin(
+ Matchers.allOf(
+ withClassName(Matchers.endsWith("Switch")),
+ isNotChecked(),
+ ),
+ ),
+ ),
+ )
+ }
+
+ recentlyVisitedButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+
+ if (recentlyVisitedSwitchEnabled) {
+ recentlyVisitedButton()
+ .check(
+ matches(
+ TestHelper.hasCousin(
+ Matchers.allOf(
+ withClassName(Matchers.endsWith("Switch")),
+ isChecked(),
+ ),
+ ),
+ ),
+ )
+ } else {
+ recentlyVisitedButton()
+ .check(
+ matches(
+ TestHelper.hasCousin(
+ Matchers.allOf(
+ withClassName(Matchers.endsWith("Switch")),
+ isNotChecked(),
+ ),
+ ),
+ ),
+ )
+ }
+
+ pocketButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+
+ if (pocketSwitchEnabled) {
+ pocketButton()
+ .check(
+ matches(
+ TestHelper.hasCousin(
+ Matchers.allOf(
+ withClassName(Matchers.endsWith("Switch")),
+ isChecked(),
+ ),
+ ),
+ ),
+ )
+ } else {
+ pocketButton()
+ .check(
+ matches(
+ TestHelper.hasCousin(
+ Matchers.allOf(
+ withClassName(Matchers.endsWith("Switch")),
+ isNotChecked(),
+ ),
+ ),
+ ),
+ )
+ }
+
+ sponsoredStoriesButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+
+ if (sponsoredStoriesCheckBox) {
+ sponsoredStoriesButton()
+ .check(
+ matches(
+ hasSibling(
+ ViewMatchers.withChild(
+ allOf(
+ withClassName(CoreMatchers.endsWith("CheckBox")),
+ isChecked(),
+ ),
+ ),
+ ),
+ ),
+ )
+ } else {
+ sponsoredStoriesButton()
+ .check(
+ matches(
+ hasSibling(
+ ViewMatchers.withChild(
+ allOf(
+ withClassName(CoreMatchers.endsWith("CheckBox")),
+ isNotChecked(),
+ ),
+ ),
+ ),
+ ),
+ )
+ }
+
+ openingScreenHeading().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+
+ homepageButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+
+ lastTabButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+
+ homepageAfterFourHoursButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+
Log.i(Constants.TAG, "verifyHomePageView: Verified the home page elements")
}
@@ -94,12 +288,42 @@ class SettingsSubMenuHomepageRobot {
}
}
- fun openWallpapersMenu() = wallpapersMenuButton.click()
+ fun openWallpapersMenu() = wallpapersMenuButton().click()
fun selectWallpaper(wallpaperName: String) =
mDevice.findObject(UiSelector().description(wallpaperName)).click()
- fun verifySponsoredShortcutsCheckBox(checked: Boolean) = assertSponsoredShortcutsCheckBox(checked)
+ fun verifySponsoredShortcutsCheckBox(checked: Boolean) {
+ if (checked) {
+ sponsoredShortcutsButton()
+ .check(
+ matches(
+ hasSibling(
+ ViewMatchers.withChild(
+ allOf(
+ withClassName(CoreMatchers.endsWith("CheckBox")),
+ isChecked(),
+ ),
+ ),
+ ),
+ ),
+ )
+ } else {
+ sponsoredShortcutsButton()
+ .check(
+ matches(
+ hasSibling(
+ ViewMatchers.withChild(
+ allOf(
+ withClassName(CoreMatchers.endsWith("CheckBox")),
+ isNotChecked(),
+ ),
+ ),
+ ),
+ ),
+ )
+ }
+ }
class Transition {
@@ -180,231 +404,4 @@ private fun homepageAfterFourHoursButton() =
private fun goBackButton() = onView(allOf(withContentDescription(R.string.action_bar_up_description)))
-private fun assertShortcutsButton() =
- shortcutsButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-private fun assertSponsoredShortcutsButton() =
- sponsoredShortcutsButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-private fun assertJumpBackInButton() =
- jumpBackInButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-private fun assertRecentBookmarksButton() =
- recentBookmarksButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-private fun assertRecentlyVisitedButton() =
- recentlyVisitedButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-private fun assertPocketButton() =
- pocketButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-private fun assertSponsoredStoriesButton() =
- sponsoredStoriesButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-private fun assertOpeningScreenHeading() =
- openingScreenHeading().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-private fun assertHomepageButton() =
- homepageButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-private fun assertLastTabButton() =
- lastTabButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-private fun assertHomepageAfterFourHoursButton() =
- homepageAfterFourHoursButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
-fun assertShortcutsSwitchState(enabled: Boolean) {
- if (enabled) {
- shortcutsButton()
- .check(
- matches(
- TestHelper.hasCousin(
- Matchers.allOf(
- withClassName(Matchers.endsWith("Switch")),
- isChecked(),
- ),
- ),
- ),
- )
- } else {
- shortcutsButton()
- .check(
- matches(
- TestHelper.hasCousin(
- Matchers.allOf(
- withClassName(Matchers.endsWith("Switch")),
- isNotChecked(),
- ),
- ),
- ),
- )
- }
-}
-
-fun assertSponsoredShortcutsCheckBox(checked: Boolean) {
- if (checked) {
- sponsoredShortcutsButton()
- .check(
- matches(
- hasSibling(
- ViewMatchers.withChild(
- allOf(
- withClassName(CoreMatchers.endsWith("CheckBox")),
- isChecked(),
- ),
- ),
- ),
- ),
- )
- } else {
- sponsoredShortcutsButton()
- .check(
- matches(
- hasSibling(
- ViewMatchers.withChild(
- allOf(
- withClassName(CoreMatchers.endsWith("CheckBox")),
- isNotChecked(),
- ),
- ),
- ),
- ),
- )
- }
-}
-
-fun assertJumpBackInSwitchState(enabled: Boolean) {
- if (enabled) {
- jumpBackInButton()
- .check(
- matches(
- TestHelper.hasCousin(
- Matchers.allOf(
- withClassName(Matchers.endsWith("Switch")),
- isChecked(),
- ),
- ),
- ),
- )
- } else {
- jumpBackInButton()
- .check(
- matches(
- TestHelper.hasCousin(
- Matchers.allOf(
- withClassName(Matchers.endsWith("Switch")),
- isNotChecked(),
- ),
- ),
- ),
- )
- }
-}
-
-fun assertRecentBookmarksSwitchState(enabled: Boolean) {
- if (enabled) {
- recentBookmarksButton()
- .check(
- matches(
- TestHelper.hasCousin(
- Matchers.allOf(
- withClassName(Matchers.endsWith("Switch")),
- isChecked(),
- ),
- ),
- ),
- )
- } else {
- recentBookmarksButton()
- .check(
- matches(
- TestHelper.hasCousin(
- Matchers.allOf(
- withClassName(Matchers.endsWith("Switch")),
- isNotChecked(),
- ),
- ),
- ),
- )
- }
-}
-
-fun assertRecentlyVisitedSwitchState(enabled: Boolean) {
- if (enabled) {
- recentlyVisitedButton()
- .check(
- matches(
- TestHelper.hasCousin(
- Matchers.allOf(
- withClassName(Matchers.endsWith("Switch")),
- isChecked(),
- ),
- ),
- ),
- )
- } else {
- recentlyVisitedButton()
- .check(
- matches(
- TestHelper.hasCousin(
- Matchers.allOf(
- withClassName(Matchers.endsWith("Switch")),
- isNotChecked(),
- ),
- ),
- ),
- )
- }
-}
-
-fun assertPocketSwitchState(enabled: Boolean) {
- if (enabled) {
- pocketButton()
- .check(
- matches(
- TestHelper.hasCousin(
- Matchers.allOf(
- withClassName(Matchers.endsWith("Switch")),
- isChecked(),
- ),
- ),
- ),
- )
- } else {
- pocketButton()
- .check(
- matches(
- TestHelper.hasCousin(
- Matchers.allOf(
- withClassName(Matchers.endsWith("Switch")),
- isNotChecked(),
- ),
- ),
- ),
- )
- }
-}
-
-fun assertSponsoredStoriesCheckBox(checked: Boolean) {
- if (checked) {
- sponsoredStoriesButton()
- .check(
- matches(
- hasSibling(
- ViewMatchers.withChild(
- allOf(
- withClassName(CoreMatchers.endsWith("CheckBox")),
- isChecked(),
- ),
- ),
- ),
- ),
- )
- } else {
- sponsoredStoriesButton()
- .check(
- matches(
- hasSibling(
- ViewMatchers.withChild(
- allOf(
- withClassName(CoreMatchers.endsWith("CheckBox")),
- isNotChecked(),
- ),
- ),
- ),
- ),
- )
- }
-}
-
-private val wallpapersMenuButton = onView(withText("Wallpapers"))
+private fun wallpapersMenuButton() = onView(withText("Wallpapers"))
From 18cd542854890f7f1731d1e231b99b38d51df5a7 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Tue, 20 Feb 2024 16:21:41 +0200
Subject: [PATCH 283/586] Bug 1881228 - Add logs to
SettingsSubMenuHomepageRobot
---
.../ui/robots/SettingsSubMenuHomepageRobot.kt | 148 ++++++++++++++----
1 file changed, 115 insertions(+), 33 deletions(-)
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 b04ca8a30a89..9d1c919a3778 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
@@ -22,7 +22,7 @@ import org.hamcrest.CoreMatchers
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.Constants.TAG
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
import org.mozilla.fenix.helpers.TestHelper
import org.mozilla.fenix.helpers.TestHelper.mDevice
@@ -43,9 +43,11 @@ class SettingsSubMenuHomepageRobot {
pocketSwitchEnabled: Boolean = true,
sponsoredStoriesCheckBox: Boolean = true,
) {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Shortcuts\" option is visible")
shortcutsButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Shortcuts\" option is visible")
if (shortcutsSwitchEnabled) {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Shortcuts\" toggle is checked")
shortcutsButton()
.check(
matches(
@@ -57,7 +59,9 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Shortcuts\" toggle is checked")
} else {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Shortcuts\" toggle is not checked")
shortcutsButton()
.check(
matches(
@@ -69,11 +73,13 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Shortcuts\" toggle is not checked")
}
-
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Sponsored shortcuts\" option is visible")
sponsoredShortcutsButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Sponsored shortcuts\" option is visible")
if (sponsoredShortcutsCheckBox) {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Sponsored shortcuts\" check box is checked")
sponsoredShortcutsButton()
.check(
matches(
@@ -87,7 +93,9 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Sponsored shortcuts\" check box is checked")
} else {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Sponsored shortcuts\" check box is not checked")
sponsoredShortcutsButton()
.check(
matches(
@@ -101,11 +109,13 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Sponsored shortcuts\" check box is not checked")
}
-
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Jump back in\" option is visible")
jumpBackInButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Jump back in\" option is visible")
if (jumpBackInSwitchEnabled) {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Jump back in\" toggle is checked")
jumpBackInButton()
.check(
matches(
@@ -117,7 +127,9 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Jump back in\" toggle is checked")
} else {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Jump back in\" toggle is not checked")
jumpBackInButton()
.check(
matches(
@@ -129,11 +141,13 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Jump back in\" toggle is not checked")
}
-
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Recent bookmarks\" option is visible")
recentBookmarksButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Recent bookmarks\" option is visible")
if (recentBookmarksSwitchEnabled) {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Recent bookmarks\" toggle is checked")
recentBookmarksButton()
.check(
matches(
@@ -145,7 +159,9 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Recent bookmarks\" toggle is checked")
} else {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Recent bookmarks\" toggle is not checked")
recentBookmarksButton()
.check(
matches(
@@ -157,11 +173,13 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Recent bookmarks\" toggle is not checked")
}
-
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Recently visited\" option is visible")
recentlyVisitedButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Recently visited\" option is visible")
if (recentlyVisitedSwitchEnabled) {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Recently visited\" toggle is checked")
recentlyVisitedButton()
.check(
matches(
@@ -173,7 +191,9 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Recently visited\" toggle is checked")
} else {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Recently visited\" toggle is not checked")
recentlyVisitedButton()
.check(
matches(
@@ -185,11 +205,13 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Recently visited\" toggle is not checked")
}
-
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Thought-provoking stories\" option is visible")
pocketButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Thought-provoking stories\" option is visible")
if (pocketSwitchEnabled) {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Thought-provoking stories\" toggle is checked")
pocketButton()
.check(
matches(
@@ -201,7 +223,9 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Thought-provoking stories\" toggle is checked")
} else {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Thought-provoking stories\" toggle is not checked")
pocketButton()
.check(
matches(
@@ -213,11 +237,13 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Thought-provoking stories\" toggle is not checked")
}
-
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Sponsored stories\" option is visible")
sponsoredStoriesButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Sponsored stories\" option is visible")
if (sponsoredStoriesCheckBox) {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Sponsored stories\" check box is checked")
sponsoredStoriesButton()
.check(
matches(
@@ -231,7 +257,9 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Sponsored stories\" check box is checked")
} else {
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Sponsored stories\" check box is not checked")
sponsoredStoriesButton()
.check(
matches(
@@ -245,56 +273,100 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Sponsored stories\" check box is not checked")
}
-
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Opening screen\" heading is visible")
openingScreenHeading().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Opening screen\" heading is visible")
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Homepage\" option is visible")
homepageButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Homepage\" option is visible")
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Last tab\" option is visible")
lastTabButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Last tab\" option is visible")
+ Log.i(TAG, "verifyHomePageView: Trying to verify that the \"Homepage after four hours of inactivity\" option is visible")
homepageAfterFourHoursButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-
- Log.i(Constants.TAG, "verifyHomePageView: Verified the home page elements")
+ Log.i(TAG, "verifyHomePageView: Verified that the \"Homepage after four hours of inactivity\" option is visible")
}
- fun verifySelectedOpeningScreenOption(openingScreenOption: String) =
+ fun verifySelectedOpeningScreenOption(openingScreenOption: String) {
+ Log.i(TAG, "verifySelectedOpeningScreenOption: Trying to verify that the \"Opening screen\" option $openingScreenOption is checked")
onView(
allOf(
withId(R.id.radio_button),
hasSibling(withText(openingScreenOption)),
),
).check(matches(isChecked(true)))
+ Log.i(TAG, "verifySelectedOpeningScreenOption: Verified that the \"Opening screen\" option $openingScreenOption is checked")
+ }
- fun clickShortcutsButton() = shortcutsButton().click()
+ fun clickShortcutsButton() {
+ Log.i(TAG, "clickShortcutsButton: Trying to click the \"Shortcuts\" option")
+ shortcutsButton().click()
+ Log.i(TAG, "clickShortcutsButton: Clicked the \"Shortcuts\" option")
+ }
- fun clickSponsoredShortcuts() = sponsoredShortcutsButton().click()
+ fun clickSponsoredShortcuts() {
+ Log.i(TAG, "clickSponsoredShortcuts: Trying to click the \"Sponsored shortcuts\" option")
+ sponsoredShortcutsButton().click()
+ Log.i(TAG, "clickSponsoredShortcuts: Clicked the \"Sponsored shortcuts\" option")
+ }
- fun clickJumpBackInButton() = jumpBackInButton().click()
+ fun clickJumpBackInButton() {
+ Log.i(TAG, "clickJumpBackInButton: Trying to click the \"Jump back in\" option")
+ jumpBackInButton().click()
+ Log.i(TAG, "clickJumpBackInButton: Clicked the \"Jump back in\" option")
+ }
- fun clickRecentlyVisited() = recentlyVisitedButton().click()
+ fun clickRecentlyVisited() {
+ Log.i(TAG, "clickRecentlyVisited: Trying to click the \"Recently visited\" option")
+ recentlyVisitedButton().click()
+ Log.i(TAG, "clickRecentlyVisited: Clicked the \"Recently visited\" option")
+ }
- fun clickRecentBookmarksButton() = recentBookmarksButton().click()
+ fun clickRecentBookmarksButton() {
+ Log.i(TAG, "clickRecentBookmarksButton: Trying to click the \"Recent bookmarks\" option")
+ recentBookmarksButton().click()
+ Log.i(TAG, "clickRecentBookmarksButton: Clicked the \"Recent bookmarks\" option")
+ }
- fun clickRecentSearchesButton() = recentlyVisitedButton().click()
+ fun clickRecentSearchesButton() {
+ Log.i(TAG, "clickRecentSearchesButton: Trying to click the \"Recently visited\" option")
+ recentlyVisitedButton().click()
+ Log.i(TAG, "clickRecentSearchesButton: Clicked the \"Recently visited\" option")
+ }
- fun clickPocketButton() = pocketButton().click()
+ fun clickPocketButton() {
+ Log.i(TAG, "clickPocketButton: Trying to click the \"Thought-provoking stories\" option")
+ pocketButton().click()
+ Log.i(TAG, "clickPocketButton: Clicked the \"Thought-provoking stories\" option")
+ }
fun clickOpeningScreenOption(openingScreenOption: String) {
+ Log.i(TAG, "clickOpeningScreenOption: Trying to click \"Opening screen\" option: $openingScreenOption")
when (openingScreenOption) {
"Homepage" -> homepageButton().click()
"Last tab" -> lastTabButton().click()
"Homepage after four hours of inactivity" -> homepageAfterFourHoursButton().click()
}
+ Log.i(TAG, "clickOpeningScreenOption: Clicked \"Opening screen\" option: $openingScreenOption")
}
- fun openWallpapersMenu() = wallpapersMenuButton().click()
+ fun openWallpapersMenu() {
+ Log.i(TAG, "openWallpapersMenu: Trying to click the \"Wallpapers\" option")
+ wallpapersMenuButton().click()
+ Log.i(TAG, "openWallpapersMenu: Clicked the \"Wallpapers\" option")
+ }
- fun selectWallpaper(wallpaperName: String) =
+ fun selectWallpaper(wallpaperName: String) {
+ Log.i(TAG, "selectWallpaper: Trying to click wallpaper: $wallpaperName")
mDevice.findObject(UiSelector().description(wallpaperName)).click()
+ Log.i(TAG, "selectWallpaper: Clicked wallpaper: $wallpaperName")
+ }
fun verifySponsoredShortcutsCheckBox(checked: Boolean) {
if (checked) {
+ Log.i(TAG, "verifySponsoredShortcutsCheckBox: Trying to verify that the \"Sponsored shortcuts\" check box is checked")
sponsoredShortcutsButton()
.check(
matches(
@@ -308,7 +380,9 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifySponsoredShortcutsCheckBox: Verified that the \"Sponsored shortcuts\" check box is checked")
} else {
+ Log.i(TAG, "verifySponsoredShortcutsCheckBox: Trying to verify that the \"Sponsored shortcuts\" check box is not checked")
sponsoredShortcutsButton()
.check(
matches(
@@ -322,29 +396,37 @@ class SettingsSubMenuHomepageRobot {
),
),
)
+ Log.i(TAG, "verifySponsoredShortcutsCheckBox: Verified that the \"Sponsored shortcuts\" check box is not checked")
}
}
class Transition {
fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
+ Log.i(TAG, "goBackToHomeScreen: Trying to click the navigate up toolbar button")
goBackButton().click()
+ Log.i(TAG, "goBackToHomeScreen: Clicked the navigate up toolbar button")
HomeScreenRobot().interact()
return HomeScreenRobot.Transition()
}
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
+ Log.i(TAG, "goBack: Trying to click the navigate up toolbar button")
goBackButton().click()
+ Log.i(TAG, "goBack: Clicked the navigate up toolbar button")
SettingsRobot().interact()
return SettingsRobot.Transition()
}
fun clickSnackBarViewButton(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
- val snackBarButton = mDevice.findObject(UiSelector().text("VIEW"))
- snackBarButton.waitForExists(waitingTimeShort)
- snackBarButton.click()
+ Log.i(TAG, "clickSnackBarViewButton: Waiting for $waitingTimeShort ms for \"VIEW\" snackbar button to exist")
+ mDevice.findObject(UiSelector().text("VIEW")).waitForExists(waitingTimeShort)
+ Log.i(TAG, "clickSnackBarViewButton: Waited for $waitingTimeShort ms for \"VIEW\" snackbar button to exist")
+ Log.i(TAG, "clickSnackBarViewButton: Trying to click the \"VIEW\" snackbar button")
+ mDevice.findObject(UiSelector().text("VIEW")).click()
+ Log.i(TAG, "clickSnackBarViewButton: Clicked the \"VIEW\" snackbar button")
HomeScreenRobot().interact()
return HomeScreenRobot.Transition()
From 13ee04ea67fc6ec730b926b1f24b8b77918a73d1 Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Wed, 21 Feb 2024 13:21:20 +0000
Subject: [PATCH 284/586] Update GeckoView (Nightly) to 125.0.20240221090755.
---
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 4ce686789659..ff2e42f96b19 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 = "125.0.20240220212334"
+ const val version = "125.0.20240221090755"
/**
* GeckoView channel
From 766654abb03872a0ea7f2c93b7b58bf3f20f5423 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Wed, 21 Feb 2024 15:48:26 +0200
Subject: [PATCH 285/586] Bug 1881250 - Convert private variables to functions
so they don't get initialised
---
.../ui/robots/SettingsSubMenuLanguageRobot.kt | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLanguageRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLanguageRobot.kt
index f1feb3bd1b0f..83c92e503d29 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLanguageRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLanguageRobot.kt
@@ -21,8 +21,8 @@ import org.mozilla.fenix.helpers.click
class SettingsSubMenuLanguageRobot {
fun selectLanguage(language: String) {
- languagesList.waitForExists(waitingTime)
- languagesList
+ languagesList().waitForExists(waitingTime)
+ languagesList()
.getChildByText(UiSelector().text(language), language)
.click()
}
@@ -35,9 +35,9 @@ class SettingsSubMenuLanguageRobot {
fun verifyLanguageHeaderIsTranslated(translation: String) = assertUIObjectExists(itemWithText(translation))
fun verifySelectedLanguage(language: String) {
- languagesList.waitForExists(waitingTime)
+ languagesList().waitForExists(waitingTime)
assertUIObjectExists(
- languagesList
+ languagesList()
.getChildByText(UiSelector().text(language), language, true)
.getFromParent(UiSelector().resourceId("$packageName:id/locale_selected_icon")),
)
@@ -48,8 +48,8 @@ class SettingsSubMenuLanguageRobot {
}
fun typeInSearchBar(text: String) {
- searchBar.waitForExists(waitingTime)
- searchBar.text = text
+ searchBar().waitForExists(waitingTime)
+ searchBar().text = text
}
fun verifySearchResultsContains(languageName: String) =
@@ -59,7 +59,7 @@ class SettingsSubMenuLanguageRobot {
onView(withId(R.id.search_close_btn)).click()
}
- fun verifyLanguageListIsDisplayed() = assertUIObjectExists(languagesList)
+ fun verifyLanguageListIsDisplayed() = assertUIObjectExists(languagesList())
class Transition {
@@ -76,7 +76,7 @@ class SettingsSubMenuLanguageRobot {
private fun goBackButton() =
onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up")))
-private val languagesList =
+private fun languagesList() =
UiScrollable(
UiSelector()
.resourceId("$packageName:id/locale_list")
@@ -85,5 +85,5 @@ private val languagesList =
private fun language(name: String) = mDevice.findObject(UiSelector().text(name))
-private val searchBar =
+private fun searchBar() =
mDevice.findObject(UiSelector().resourceId("$packageName:id/search_src_text"))
From a4889b3e133c5fce3d1e431aca954e45dcf5be5a Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Wed, 21 Feb 2024 16:08:17 +0200
Subject: [PATCH 286/586] Bug 1881250 - Add logs to
SettingsSubMenuLanguageRobot
---
.../ui/robots/SettingsSubMenuLanguageRobot.kt | 24 +++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLanguageRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLanguageRobot.kt
index 83c92e503d29..7bca7bb375ea 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLanguageRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLanguageRobot.kt
@@ -4,6 +4,7 @@
package org.mozilla.fenix.ui.robots
+import android.util.Log
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.matcher.ViewMatchers
@@ -12,6 +13,7 @@ import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector
import org.hamcrest.CoreMatchers
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.itemWithText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
@@ -21,21 +23,31 @@ import org.mozilla.fenix.helpers.click
class SettingsSubMenuLanguageRobot {
fun selectLanguage(language: String) {
+ Log.i(TAG, "selectLanguage: Waiting for $waitingTime ms for language list to exist")
languagesList().waitForExists(waitingTime)
+ Log.i(TAG, "selectLanguage: Waited for $waitingTime ms for language list to exist")
+ Log.i(TAG, "selectLanguage: Trying to click language: $language")
languagesList()
.getChildByText(UiSelector().text(language), language)
.click()
+ Log.i(TAG, "selectLanguage: Clicked language: $language")
}
fun selectLanguageSearchResult(languageName: String) {
+ Log.i(TAG, "selectLanguageSearchResult: Waiting for $waitingTime ms for language list to exist")
language(languageName).waitForExists(waitingTime)
+ Log.i(TAG, "selectLanguageSearchResult: Waited for $waitingTime ms for language list to exist")
+ Log.i(TAG, "selectLanguageSearchResult: Trying to click language: $languageName")
language(languageName).click()
+ Log.i(TAG, "selectLanguageSearchResult: Clicked language: $languageName")
}
fun verifyLanguageHeaderIsTranslated(translation: String) = assertUIObjectExists(itemWithText(translation))
fun verifySelectedLanguage(language: String) {
+ Log.i(TAG, "verifySelectedLanguage: Waiting for $waitingTime ms for language list to exist")
languagesList().waitForExists(waitingTime)
+ Log.i(TAG, "verifySelectedLanguage: Waited for $waitingTime ms for language list to exist")
assertUIObjectExists(
languagesList()
.getChildByText(UiSelector().text(language), language, true)
@@ -44,19 +56,27 @@ class SettingsSubMenuLanguageRobot {
}
fun openSearchBar() {
+ Log.i(TAG, "openSearchBar: Trying to click the search bar")
onView(withId(R.id.search)).click()
+ Log.i(TAG, "openSearchBar: Clicked the search bar")
}
fun typeInSearchBar(text: String) {
+ Log.i(TAG, "typeInSearchBar: Waiting for $waitingTime ms for search bar to exist")
searchBar().waitForExists(waitingTime)
+ Log.i(TAG, "typeInSearchBar: Waited for $waitingTime ms for search bar to exist")
+ Log.i(TAG, "typeInSearchBar: Trying to set search bar text to: $text")
searchBar().text = text
+ Log.i(TAG, "typeInSearchBar: Search bar text was set to: $text")
}
fun verifySearchResultsContains(languageName: String) =
assertUIObjectExists(language(languageName))
fun clearSearchBar() {
+ Log.i(TAG, "clearSearchBar: Trying to click the clear search bar button")
onView(withId(R.id.search_close_btn)).click()
+ Log.i(TAG, "clearSearchBar: Clicked the clear search bar button")
}
fun verifyLanguageListIsDisplayed() = assertUIObjectExists(languagesList())
@@ -64,8 +84,12 @@ class SettingsSubMenuLanguageRobot {
class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
+ Log.i(TAG, "goBack: Waiting for device to be idle")
mDevice.waitForIdle()
+ Log.i(TAG, "goBack: Waited for device to be idle")
+ Log.i(TAG, "goBack: Trying to click the navigate up button")
goBackButton().perform(ViewActions.click())
+ Log.i(TAG, "goBack: Clicked the navigate up button")
SettingsRobot().interact()
return SettingsRobot.Transition()
From 1cd9d3afb8423a04fc6a04abb57c7fc765c264a6 Mon Sep 17 00:00:00 2001
From: James Hugman
Date: Thu, 1 Feb 2024 14:03:09 +0000
Subject: [PATCH 287/586] =?UTF-8?q?Bug=201880476=20=E2=80=94=C2=A0NimbusMe?=
=?UTF-8?q?ssaging:=20Move=20filtering=20to=20getNextMessage?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../messaging/NimbusMessagingStorage.kt | 45 ++++++++++++++-----
.../messaging/NimbusMessagingStorageTest.kt | 40 ++++++++++-------
2 files changed, 59 insertions(+), 26 deletions(-)
diff --git a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
index cb8016efff2e..ff463104c9c8 100644
--- a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
+++ b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
@@ -111,8 +111,19 @@ class NimbusMessagingStorage(
}
/**
- * Returns a list of currently available messages descending sorted by their priority.
- * This list of messages will not include any expired, pressed or dismissed messages.
+ * Returns a list of currently available messages descending sorted by their [StyleData.priority].
+ *
+ * "Currently available" means all messages contained in the Nimbus SDK, validated and denormalized.
+ *
+ * The messages have the JEXL triggers and actions that came from the Nimbus SDK, but these themselves
+ * are not validated at this time.
+ *
+ * The messages also have state attached, which manage how many times the messages has been shown,
+ * and if the user has interacted with it or not.
+ *
+ * The list of messages may also contain control messages which should not be shown to the user.
+ *
+ * All additional filtering of these messages will happen in [getNextMessage].
*/
suspend fun getMessages(): List {
val featureValue = messagingFeature.value()
@@ -120,20 +131,34 @@ class NimbusMessagingStorage(
return nimbusMessages.keys
.mapNotNull { key ->
createMessage(featureValue, key)
- }.filter {
- !it.isExpired &&
- !it.metadata.dismissed &&
- !it.metadata.pressed
}.sortedByDescending {
it.style.priority
}
}
/**
- * Returns the next higher priority message which all their triggers are true.
+ * Returns the next message for this surface.
+ *
+ * Message selection takes into account,
+ * - the message's surface,
+ * - how many times the message has been displayed already
+ * - whether or not the user has interacted with the message already.
+ * - the message eligibility, via JEXL triggers.
+ *
+ * If more than one message for this surface is eligible to be shown, then the
+ * first one to be encountered in [messages] list is returned.
*/
- fun getNextMessage(surface: MessageSurfaceId, availableMessages: List): Message? =
- createMessagingHelper().use {
+ fun getNextMessage(surface: MessageSurfaceId, messages: List): Message? {
+ val availableMessages = messages
+ .filter {
+ it.surface == surface
+ }
+ .filter {
+ !it.isExpired &&
+ !it.metadata.dismissed &&
+ !it.metadata.pressed
+ }
+ return createMessagingHelper().use {
getNextMessage(
surface,
availableMessages,
@@ -141,6 +166,7 @@ class NimbusMessagingStorage(
it,
)
}
+ }
@Suppress("ReturnCount")
private fun getNextMessage(
@@ -150,7 +176,6 @@ class NimbusMessagingStorage(
helper: NimbusMessagingHelperInterface,
): Message? {
val message = availableMessages
- .filter { surface == it.surface }
.filter { !excluded.contains(it.id) }
.firstOrNull { isMessageEligible(it, helper) } ?: return null
diff --git a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt
index b298af5d05d8..c59736f8f048 100644
--- a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt
+++ b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt
@@ -55,6 +55,8 @@ class NimbusMessagingStorageTest {
}
private lateinit var featuresInterface: FeaturesInterface
+ private val displayOnceStyle = StyleData(maxDisplayCount = 1)
+
@get:Rule
val coroutinesTestRule = MainCoroutineRule()
@@ -84,7 +86,9 @@ class NimbusMessagingStorageTest {
messagingFeature,
)
- `when`(nimbus.createMessageHelper(any())).thenReturn(mock())
+ val helper: NimbusMessagingHelperInterface = mock()
+ `when`(helper.evalJexl(any())).thenReturn(true)
+ `when`(nimbus.createMessageHelper(any())).thenReturn(helper)
}
@After
@@ -175,8 +179,10 @@ class NimbusMessagingStorageTest {
val results = storage.getMessages()
- assertEquals(1, results.size)
- assertEquals("normal-message", results[0].id)
+ assertEquals(2, results.size)
+
+ val message = storage.getNextMessage(HOMESCREEN, results)!!
+ assertEquals("normal-message", message.id)
}
@Test
@@ -210,9 +216,10 @@ class NimbusMessagingStorageTest {
)
val results = storage.getMessages()
+ assertEquals(2, results.size)
- assertEquals(1, results.size)
- assertEquals("normal-message", results[0].id)
+ val message = storage.getNextMessage(HOMESCREEN, results)!!
+ assertEquals("normal-message", message.id)
}
@Test
@@ -258,9 +265,10 @@ class NimbusMessagingStorageTest {
)
val results = storage.getMessages()
+ assertEquals(3, results.size)
- assertEquals(1, results.size)
- assertEquals("normal-message", results[0].id)
+ val message = storage.getNextMessage(HOMESCREEN, results)!!
+ assertEquals("normal-message", message.id)
}
@Test
@@ -489,7 +497,7 @@ class NimbusMessagingStorageTest {
"same-id",
createMessageData(surface = HOMESCREEN),
action = "action",
- mock(),
+ style = displayOnceStyle,
listOf("trigger"),
Message.Metadata("same-id"),
)
@@ -511,7 +519,7 @@ class NimbusMessagingStorageTest {
"same-id",
messageData,
action = "action",
- mock(),
+ style = displayOnceStyle,
listOf("trigger"),
Message.Metadata("same-id"),
)
@@ -537,7 +545,7 @@ class NimbusMessagingStorageTest {
"id",
messageData,
action = "action",
- mock(),
+ style = displayOnceStyle,
listOf("trigger"),
Message.Metadata("same-id"),
)
@@ -546,7 +554,7 @@ class NimbusMessagingStorageTest {
"control-id",
controlMessageData,
action = "action",
- mock(),
+ style = displayOnceStyle,
listOf("trigger"),
Message.Metadata("same-id"),
)
@@ -575,7 +583,7 @@ class NimbusMessagingStorageTest {
"id",
messageData,
action = "action",
- mock(),
+ style = displayOnceStyle,
listOf("trigger"),
Message.Metadata("same-id"),
)
@@ -584,7 +592,7 @@ class NimbusMessagingStorageTest {
"control-id",
controlMessageData,
action = "action",
- mock(),
+ style = displayOnceStyle,
listOf("trigger"),
Message.Metadata("same-id"),
)
@@ -615,7 +623,7 @@ class NimbusMessagingStorageTest {
"id",
messageData,
action = "action",
- mock(),
+ style = displayOnceStyle,
listOf("trigger"),
Message.Metadata("same-id"),
)
@@ -624,7 +632,7 @@ class NimbusMessagingStorageTest {
"incorrect-id",
incorrectMessageData,
action = "action",
- mock(),
+ style = displayOnceStyle,
listOf("trigger"),
Message.Metadata("same-id"),
)
@@ -633,7 +641,7 @@ class NimbusMessagingStorageTest {
"control-id",
controlMessageData,
action = "action",
- mock(),
+ style = displayOnceStyle,
listOf("trigger"),
Message.Metadata("same-id"),
)
From d882c0ba03f35eee0aeefe372dba9e07dacfc7fa Mon Sep 17 00:00:00 2001
From: James Hugman
Date: Mon, 29 Jan 2024 13:03:54 +0000
Subject: [PATCH 288/586] =?UTF-8?q?Bug=201880476=20=E2=80=94=20Move=20nimb?=
=?UTF-8?q?us=20from=20components.analytics=20to=20components.nimbus?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../mozilla/fenix/helpers/Experimentation.kt | 5 +-
.../fenix/ui/NimbusMessagingMessageTest.kt | 9 +-
.../fenix/ui/NimbusMessagingTriggerTest.kt | 2 +-
.../org/mozilla/fenix/FenixApplication.kt | 4 +-
.../java/org/mozilla/fenix/HomeActivity.kt | 6 +-
.../org/mozilla/fenix/components/Analytics.kt | 20 -----
.../fenix/components/BackgroundServices.kt | 2 +-
.../mozilla/fenix/components/Components.kt | 3 +-
.../fenix/components/NimbusComponents.kt | 88 +++++++++++++++++++
.../org/mozilla/fenix/home/HomeFragment.kt | 2 +-
.../messaging/MessageNotificationWorker.kt | 6 +-
.../fenix/nimbus/NimbusBranchesFragment.kt | 4 +-
.../fenix/nimbus/NimbusExperimentsFragment.kt | 2 +-
.../fenix/onboarding/OnboardingFragment.kt | 2 +-
.../fenix/settings/DataChoicesFragment.kt | 2 +-
.../fenix/settings/studies/StudiesFragment.kt | 2 +-
.../components/BackgroundServicesTest.kt | 5 +-
17 files changed, 114 insertions(+), 50 deletions(-)
create mode 100644 fenix/app/src/main/java/org/mozilla/fenix/components/NimbusComponents.kt
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/Experimentation.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/Experimentation.kt
index 34f4d15e6487..4c320a8687d0 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/Experimentation.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/Experimentation.kt
@@ -9,11 +9,8 @@ import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.TestHelper.appContext
object Experimentation {
- val experiments =
- appContext.components.analytics.experiments
-
fun withHelper(block: NimbusMessagingHelperInterface.() -> Unit) {
- val helper = experiments.createMessageHelper()
+ val helper = appContext.components.nimbus.createJexlHelper()
block(helper)
}
}
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt
index 87b1079574fa..c353b668f47a 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt
@@ -20,7 +20,6 @@ import org.junit.Test
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.TestHelper
-import org.mozilla.fenix.messaging.CustomAttributeProvider
/**
* This test is to test the integrity of messages hardcoded in the FML.
@@ -35,7 +34,7 @@ class NimbusMessagingMessageTest {
private lateinit var context: Context
private val storage
- get() = context.components.analytics.messagingStorage
+ get() = context.components.nimbus.messagingStorage
@get:Rule
val activityTestRule =
@@ -73,10 +72,7 @@ class NimbusMessagingMessageTest {
*/
@Test
fun testAllMessageTriggers() = runTest {
- val nimbus = context.components.analytics.experiments
- val helper = nimbus.createMessageHelper(
- CustomAttributeProvider.getCustomAttributes(context),
- )
+ val helper = context.components.nimbus.createJexlHelper()
val messages = storage.getMessages()
messages.forEach { message ->
storage.isMessageEligible(message, helper)
@@ -84,6 +80,7 @@ class NimbusMessagingMessageTest {
fail("${message.id} has a problem with its JEXL trigger: ${storage.malFormedMap.keys}")
}
}
+ helper.destroy()
}
private fun checkIsLocalized(string: String) {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingTriggerTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingTriggerTest.kt
index 6ba04c9e8810..e061d6845f64 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingTriggerTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingTriggerTest.kt
@@ -38,7 +38,7 @@ class NimbusMessagingTriggerTest {
@Before
fun setUp() {
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- nimbus = TestHelper.appContext.components.analytics.experiments
+ nimbus = TestHelper.appContext.components.nimbus.sdk
feature = FxNimbusMessaging.features.messaging.value()
}
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 6dfd7a06951f..f87e5a0f9db7 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
@@ -433,7 +433,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
fun queueNimbusFetchInForeground() {
queue.runIfReadyOrQueue {
GlobalScope.launch(Dispatchers.IO) {
- components.analytics.experiments.maybeFetchExperiments(
+ components.nimbus.sdk.maybeFetchExperiments(
context = this@FenixApplication,
)
}
@@ -502,7 +502,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
beginSetupMegazord()
// This lazily constructs the Nimbus object…
- val nimbus = components.analytics.experiments
+ val nimbus = components.nimbus.sdk
// … which we then can populate the feature configuration.
FxNimbus.initialize { nimbus }
}
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 c649a8dd0ded..1bc06595f218 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
@@ -225,7 +225,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
val startTimeProfiler = components.core.engine.profiler?.getProfilerTime()
// Setup nimbus-cli tooling. This is a NOOP when launching normally.
- components.analytics.experiments.initializeTooling(applicationContext, intent)
+ components.nimbus.sdk.initializeTooling(applicationContext, intent)
components.strictMode.attachListenerToDisablePenaltyDeath(supportFragmentManager)
MarkersFragmentLifecycleCallbacks.register(supportFragmentManager, components.core.engine)
@@ -354,7 +354,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
?.also {
Events.appOpened.record(Events.AppOpenedExtra(it))
// This will record an event in Nimbus' internal event store. Used for behavioral targeting
- components.analytics.experiments.recordEvent("app_opened")
+ components.nimbus.events.recordEvent("app_opened")
if (safeIntent.action.equals(ACTION_OPEN_PRIVATE_TAB) && it == APP_ICON) {
AppIcon.newPrivateTabTapped.record(NoExtras())
@@ -1221,7 +1221,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
}
private suspend fun showFullscreenMessageIfNeeded(context: Context) {
- val messagingStorage = context.components.analytics.messagingStorage
+ val messagingStorage = context.components.nimbus.messagingStorage
val messages = messagingStorage.getMessages()
val nextMessage =
messagingStorage.getNextMessage(FenixMessageSurfaceId.SURVEY, messages)
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/Analytics.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/Analytics.kt
index b68ea5e1457b..0208c135b5fa 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/components/Analytics.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/components/Analytics.kt
@@ -14,10 +14,6 @@ import mozilla.components.lib.crash.sentry.SentryService
import mozilla.components.lib.crash.service.CrashReporterService
import mozilla.components.lib.crash.service.GleanCrashReporterService
import mozilla.components.lib.crash.service.MozillaSocorroService
-import mozilla.components.service.nimbus.NimbusApi
-import mozilla.components.service.nimbus.messaging.FxNimbusMessaging
-import mozilla.components.service.nimbus.messaging.NimbusMessagingStorage
-import mozilla.components.service.nimbus.messaging.OnDiskMessageMetadataStorage
import mozilla.components.support.ktx.android.content.isMainProcess
import mozilla.components.support.utils.BrowsersCache
import mozilla.components.support.utils.RunWhenReadyQueue
@@ -33,10 +29,8 @@ import org.mozilla.fenix.components.metrics.InstallReferrerMetricsService
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.components.metrics.MetricsStorage
import org.mozilla.fenix.crashes.CrashFactCollector
-import org.mozilla.fenix.experiments.createNimbus
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
-import org.mozilla.fenix.messaging.CustomAttributeProvider
import org.mozilla.fenix.perf.lazyMonitored
import org.mozilla.geckoview.BuildConfig.MOZ_APP_BUILDID
import org.mozilla.geckoview.BuildConfig.MOZ_APP_VENDOR
@@ -159,20 +153,6 @@ class Analytics(
context.settings(),
)
}
-
- val experiments: NimbusApi by lazyMonitored {
- createNimbus(context, BuildConfig.NIMBUS_ENDPOINT)
- }
-
- val messagingStorage by lazyMonitored {
- NimbusMessagingStorage(
- context = context,
- metadataStorage = OnDiskMessageMetadataStorage(context),
- nimbus = experiments,
- messagingFeature = FxNimbusMessaging.features.messaging,
- attributeProvider = CustomAttributeProvider,
- )
- }
}
private fun isSentryEnabled() = !BuildConfig.SENTRY_TOKEN.isNullOrEmpty()
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt
index 250a380ca4e3..9b6f4bfbd55d 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/components/BackgroundServices.kt
@@ -230,7 +230,7 @@ internal class TelemetryAccountObserver(
// User signed-in into an existing FxA account.
AuthType.Signin -> {
SyncAuth.signIn.record(NoExtras())
- context.components.analytics.experiments.recordEvent("sync_auth.sign_in")
+ context.components.nimbus.events.recordEvent("sync_auth.sign_in")
}
// User created a new FxA account.
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 6a4ea2328c2e..fd74fcb37827 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
@@ -170,6 +170,7 @@ class Components(private val context: Context) {
}
val analytics by lazyMonitored { Analytics(context, performance.visualCompletenessQueue.queue) }
+ val nimbus by lazyMonitored { NimbusComponents(context) }
val publicSuffixList by lazyMonitored { PublicSuffixList(context) }
val clipboardHandler by lazyMonitored { ClipboardHandler(context) }
val performance by lazyMonitored { PerformanceComponent() }
@@ -231,7 +232,7 @@ class Components(private val context: Context) {
context.pocketStoriesSelectedCategoriesDataStore,
),
MessagingMiddleware(
- messagingStorage = analytics.messagingStorage,
+ messagingStorage = nimbus.messagingStorage,
),
MetricsMiddleware(metrics = analytics.metrics),
),
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/NimbusComponents.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/NimbusComponents.kt
new file mode 100644
index 000000000000..a83b3ef5948f
--- /dev/null
+++ b/fenix/app/src/main/java/org/mozilla/fenix/components/NimbusComponents.kt
@@ -0,0 +1,88 @@
+/* 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.components
+
+import android.content.Context
+import mozilla.components.service.nimbus.NimbusApi
+import mozilla.components.service.nimbus.messaging.FxNimbusMessaging
+import mozilla.components.service.nimbus.messaging.NimbusMessagingStorage
+import mozilla.components.service.nimbus.messaging.OnDiskMessageMetadataStorage
+import org.mozilla.experiments.nimbus.NimbusEventStore
+import org.mozilla.experiments.nimbus.NimbusMessagingHelperInterface
+import org.mozilla.fenix.BuildConfig
+import org.mozilla.fenix.experiments.createNimbus
+import org.mozilla.fenix.messaging.CustomAttributeProvider
+import org.mozilla.fenix.perf.lazyMonitored
+
+/**
+ * Component group for access to Nimbus and other Nimbus services.
+ */
+class NimbusComponents(private val context: Context) {
+
+ /**
+ * The main entry point for the Nimbus SDK. Note that almost all access to feature configuration
+ * should be mediated through a FML generated class, e.g. [FxNimbus].
+ */
+ val sdk: NimbusApi by lazyMonitored {
+ createNimbus(context, BuildConfig.NIMBUS_ENDPOINT)
+ }
+
+ /**
+ * Convenience method for getting the event store from the SDK.
+ *
+ * Before EXP-4354, this is the main write API for recording events to drive
+ * messaging, experiments and onboarding.
+ *
+ * Following EXP-4354, clients will not need to write these events
+ * themselves.
+ *
+ * Read access to the event store should be done through
+ * the JEXL helper available from [createJexlHelper].
+ */
+ val events: NimbusEventStore by lazyMonitored {
+ sdk.events
+ }
+
+ /**
+ * Create a new JEXL evaluator suitable for use by any feature.
+ *
+ * JEXL evaluator context is provided by the app and changes over time.
+ *
+ * For this reason, an evaluator should be not be stored or cached.
+ *
+ * Since it has a native peer, to avoid leaking memory, the helper's [destroy] method
+ * should be called after finishing the set of evaluations.
+ *
+ * This can be done automatically using the interface's `use` method, e.g.
+ *
+ * ```
+ * val isEligible = nimbus.createJexlHelper().use { helper ->
+ * expressions.all { exp -> helper.evalJexl(exp) }
+ * }
+ * ```
+ *
+ * The helper has access to all context needed to drive decisions
+ * about messaging, onboarding and experimentation.
+ *
+ * It also has a built-in cache.
+ */
+ fun createJexlHelper(): NimbusMessagingHelperInterface =
+ messagingStorage.createMessagingHelper()
+
+ /**
+ * Low level access to the messaging component.
+ *
+ * The app should access this through a [mozilla.components.service.nimbus.messaging.NimbusMessagingController].
+ */
+ val messagingStorage by lazyMonitored {
+ NimbusMessagingStorage(
+ context = context,
+ metadataStorage = OnDiskMessageMetadataStorage(context),
+ nimbus = sdk,
+ messagingFeature = FxNimbusMessaging.features.messaging,
+ attributeProvider = CustomAttributeProvider,
+ )
+ }
+}
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 588737e35a1b..24fb5ec9ff0d 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
@@ -360,7 +360,7 @@ class HomeFragment : Fragment() {
engine = components.core.engine,
messageController = DefaultMessageController(
appStore = components.appStore,
- messagingController = FenixNimbusMessagingController(components.analytics.messagingStorage),
+ messagingController = FenixNimbusMessagingController(components.nimbus.messagingStorage),
homeActivity = activity,
),
store = store,
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/messaging/MessageNotificationWorker.kt b/fenix/app/src/main/java/org/mozilla/fenix/messaging/MessageNotificationWorker.kt
index 6a8bd3ba7fc7..f75b4ef28113 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/messaging/MessageNotificationWorker.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/messaging/MessageNotificationWorker.kt
@@ -45,7 +45,7 @@ class MessageNotificationWorker(
override suspend fun doWork(): Result {
val context = applicationContext
- val messagingStorage = context.components.analytics.messagingStorage
+ val messagingStorage = context.components.nimbus.messagingStorage
val messages = messagingStorage.getMessages()
val nextMessage =
messagingStorage.getNextMessage(FenixMessageSurfaceId.NOTIFICATION, messages)
@@ -178,7 +178,7 @@ class NotificationDismissedService : LifecycleService() {
if (intent != null) {
val nimbusMessagingController =
- FenixNimbusMessagingController(applicationContext.components.analytics.messagingStorage)
+ FenixNimbusMessagingController(applicationContext.components.nimbus.messagingStorage)
lifecycleScope.launch {
// Get the relevant message.
@@ -209,7 +209,7 @@ class NotificationClickedReceiverActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
val nimbusMessagingController =
- FenixNimbusMessagingController(components.analytics.messagingStorage)
+ FenixNimbusMessagingController(components.nimbus.messagingStorage)
lifecycleScope.launch {
// Get the relevant message.
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/nimbus/NimbusBranchesFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/nimbus/NimbusBranchesFragment.kt
index 9b0854cd5d1e..f2ec4422777b 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/nimbus/NimbusBranchesFragment.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/nimbus/NimbusBranchesFragment.kt
@@ -51,7 +51,7 @@ class NimbusBranchesFragment : Fragment() {
context = requireContext(),
navController = findNavController(),
nimbusBranchesStore = nimbusBranchesStore,
- experiments = requireContext().components.analytics.experiments,
+ experiments = requireContext().components.nimbus.sdk,
experimentId = args.experimentId,
)
@@ -77,7 +77,7 @@ class NimbusBranchesFragment : Fragment() {
private fun loadExperimentBranches() {
lifecycleScope.launch(Dispatchers.IO) {
try {
- val experiments = requireContext().components.analytics.experiments
+ val experiments = requireContext().components.nimbus.sdk
val branches = experiments.getExperimentBranches(args.experimentId) ?: emptyList()
val selectedBranch = experiments.getExperimentBranch(args.experimentId) ?: ""
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/nimbus/NimbusExperimentsFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/nimbus/NimbusExperimentsFragment.kt
index 37f50d6ede5d..3cfe906d7c98 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/nimbus/NimbusExperimentsFragment.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/nimbus/NimbusExperimentsFragment.kt
@@ -35,7 +35,7 @@ class NimbusExperimentsFragment : Fragment() {
setContent {
FirefoxTheme {
val experiments =
- requireContext().components.analytics.experiments.getAvailableExperiments()
+ requireContext().components.nimbus.sdk.getAvailableExperiments()
NimbusExperiments(
experiments = experiments,
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
index af4693681b9f..97d87682e5d1 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
@@ -232,7 +232,7 @@ class OnboardingFragment : Fragment() {
showAddWidgetPage: Boolean,
): List {
val jexlConditions = FxNimbus.features.junoOnboarding.value().conditions
- val jexlHelper = requireContext().components.analytics.messagingStorage.createMessagingHelper()
+ val jexlHelper = requireContext().components.nimbus.createJexlHelper()
val privacyCaption = Caption(
text = getString(R.string.juno_onboarding_privacy_notice_text),
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/settings/DataChoicesFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/settings/DataChoicesFragment.kt
index e029e2ebf805..f64fecc63a85 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/settings/DataChoicesFragment.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/settings/DataChoicesFragment.kt
@@ -37,7 +37,7 @@ class DataChoicesFragment : PreferenceFragmentCompat() {
// Reset experiment identifiers on both opt-in and opt-out; it's likely
// that in future we will need to pass in the new telemetry client_id
// to this method when the user opts back in.
- context.components.analytics.experiments.resetTelemetryIdentifiers()
+ context.components.nimbus.sdk.resetTelemetryIdentifiers()
} else if (key == getPreferenceKey(R.string.pref_key_marketing_telemetry)) {
if (context.settings().isMarketingTelemetryEnabled) {
context.components.analytics.metrics.start(MetricServiceType.Marketing)
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/settings/studies/StudiesFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/settings/studies/StudiesFragment.kt
index 87d9c6e1bd3d..f2ecc0ea6c44 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/settings/studies/StudiesFragment.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/settings/studies/StudiesFragment.kt
@@ -30,7 +30,7 @@ class StudiesFragment : Fragment() {
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
- val experiments = requireComponents.analytics.experiments
+ val experiments = requireComponents.nimbus.sdk
_binding = SettingsStudiesBinding.inflate(inflater, container, false)
val interactor = DefaultStudiesInteractor((activity as HomeActivity), experiments)
StudiesView(
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/components/BackgroundServicesTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/components/BackgroundServicesTest.kt
index 5cf747049343..3723d4977249 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/components/BackgroundServicesTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/components/BackgroundServicesTest.kt
@@ -56,8 +56,9 @@ class BackgroundServicesTest {
val mockComponents: Components = mockk()
every { mockComponents.settings } returns settings
- every { mockComponents.analytics } returns mockk {
- every { experiments } returns nimbus
+ every { mockComponents.nimbus } returns mockk {
+ every { sdk } returns nimbus
+ every { events } returns nimbus
}
every { context.components } returns mockComponents
every { nimbus.recordEvent(any()) } returns Unit
From 8712fee885d37171b09fdf351d712934ab838cfd Mon Sep 17 00:00:00 2001
From: github-actions
Date: Thu, 22 Feb 2024 00:03:29 +0000
Subject: [PATCH 289/586] Import translations from android-l10n
---
.../menu/src/main/res/values-ia/strings.xml | 2 ++
.../addons/src/main/res/values-br/strings.xml | 2 ++
.../addons/src/main/res/values-ia/strings.xml | 4 ++++
.../prompts/src/main/res/values-uk/strings.xml | 2 +-
fenix/app/src/main/res/values-br/strings.xml | 4 +++-
fenix/app/src/main/res/values-nb-rNO/strings.xml | 2 +-
fenix/app/src/main/res/values-uk/strings.xml | 14 +++++++-------
.../app/src/main/res/values-lo/strings.xml | 8 +++-----
.../app/src/main/res/values-tr/strings.xml | 15 +++++++++++----
9 files changed, 34 insertions(+), 19 deletions(-)
diff --git a/android-components/components/browser/menu/src/main/res/values-ia/strings.xml b/android-components/components/browser/menu/src/main/res/values-ia/strings.xml
index c2721f89b2f3..b0a97cce88b3 100644
--- a/android-components/components/browser/menu/src/main/res/values-ia/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-ia/strings.xml
@@ -10,4 +10,6 @@
Gestor de additivosNavigar
+
+ Additivos, navigar retro
diff --git a/android-components/components/feature/addons/src/main/res/values-br/strings.xml b/android-components/components/feature/addons/src/main/res/values-br/strings.xml
index afd8b1f8a569..d5976b5bfb14 100644
--- a/android-components/components/feature/addons/src/main/res/values-br/strings.xml
+++ b/android-components/components/feature/addons/src/main/res/values-br/strings.xml
@@ -98,6 +98,8 @@
Aotren er Merdeiñ PrevezLañsañ er Merdeiñ Prevez
+
+ N’eo ket aotreet er prenestroù prevezGweredekaet
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 25558ed54892..bd82ac4649de 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
@@ -148,6 +148,8 @@
Recensiones: %1$s%1$.02f/5
+
+ Qualification: %1$.02f de 5Additivos
@@ -250,6 +252,8 @@
%1$s ha essite addite a %2$s.Aperi lo in le menu
+
+ Accede a %1$s ex menu de %2$s.OK, io lo comprende
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 4edeea324b7d..53c48170b53b 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
@@ -1,7 +1,7 @@
- Гаразд
+ OKСкасувати
diff --git a/fenix/app/src/main/res/values-br/strings.xml b/fenix/app/src/main/res/values-br/strings.xml
index f9fc661f16f4..59e397fc152b 100644
--- a/fenix/app/src/main/res/values-br/strings.xml
+++ b/fenix/app/src/main/res/values-br/strings.xml
@@ -2055,7 +2055,7 @@
Klask %s
-
+
Digeriñ liammoù al lec’hiennoù, posteloù ha kemennadennoù e Firefox en un doare emgefreek.
@@ -2249,6 +2249,8 @@
O treiñ
+
+ Dibab ur yezhUr gudenn zo bet gant an droidigezh. Klaskit en-dro.
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 86347ea1afd6..aef3dd0fc897 100644
--- a/fenix/app/src/main/res/values-nb-rNO/strings.xml
+++ b/fenix/app/src/main/res/values-nb-rNO/strings.xml
@@ -721,7 +721,7 @@
Betalingskort
- Betalingsmetoder
+ BetalingsmåterAdresser
diff --git a/fenix/app/src/main/res/values-uk/strings.xml b/fenix/app/src/main/res/values-uk/strings.xml
index b9f1506f0a69..8ce5dea5f0f9 100644
--- a/fenix/app/src/main/res/values-uk/strings.xml
+++ b/fenix/app/src/main/res/values-uk/strings.xml
@@ -603,7 +603,7 @@
Власна збірка додатків
- Гаразд
+ OKСкасувати
@@ -926,7 +926,7 @@
Програма припинить застосовувати зміни
- Гаразд
+ OKСкасувати
@@ -1135,13 +1135,13 @@
Очистити дозволи
- Гаразд
+ OKСкасуватиОчистити дозвіл
- Гаразд
+ OKСкасувати
@@ -1249,7 +1249,7 @@
Переглянути
- Гаразд
+ OKСкасувати
@@ -1385,7 +1385,7 @@
Вебадреса недійсна.
- Гаразд
+ OKВи дійсно хочете видалити %1$s?
@@ -2140,7 +2140,7 @@
Назва ярлика
- Гаразд
+ OKСкасувати
diff --git a/focus-android/app/src/main/res/values-lo/strings.xml b/focus-android/app/src/main/res/values-lo/strings.xml
index ba5e0445880c..f0e52c6c4ec7 100644
--- a/focus-android/app/src/main/res/values-lo/strings.xml
+++ b/focus-android/app/src/main/res/values-lo/strings.xml
@@ -53,7 +53,6 @@
ລຶບອອກຈາກທາງລັດ
- ສິ່ງໃຫມ່ໆການຕັ້ງຄ່າກ່ຽວກັບວິທີໃຊ້
@@ -84,10 +83,9 @@
sharing an URL. -->
ແບ່ງປັນຜ່ານທາງ
-
+ ລຶບປະຫວັດການທ່ອງເວັບ
+ ແຕະ ຫຼື ລຶບການແຈ້ງເຕືອນນີ້ເພື່ອລຶບປະຫວັດການທ່ອງເວັບຂອງທ່ານຢ່າງປອດໄພ.
+
ລຶບປະຫວັດການທ່ອງເວັບ
diff --git a/focus-android/app/src/main/res/values-tr/strings.xml b/focus-android/app/src/main/res/values-tr/strings.xml
index 78018a53a54d..fcf1369d7f30 100644
--- a/focus-android/app/src/main/res/values-tr/strings.xml
+++ b/focus-android/app/src/main/res/values-tr/strings.xml
@@ -894,7 +894,8 @@
- Düzgün görünmeyen bir site mi var?\n İzlenme Koruması’nı kapatmayı deneyin
+ Düzgün görünmeyen bir site mi var?\n
+ İzlenme Koruması’nı kapatmayı deneyin
@@ -903,15 +904,21 @@
- Her bağlantıyı %1$s ile açabilirsiniz\n %1$s’u varsayılan tarayıcınız yapın
+ Her bağlantıyı %1$s ile açabilirsiniz\n
+ %1$s’u varsayılan tarayıcınız yapın
+
- En çok kullandığınız sitelerin adreslerini otomatik tamamlayabilirsiniz\n Adres çubuğundaki herhangi bir adrese basılı tutun
+ En çok kullandığınız sitelerin adreslerini otomatik tamamlayabilirsiniz\n
+ Adres çubuğundaki herhangi bir adrese basılı tutun
+
- Bağlantıları yeni sekmede açabilirsiniz\n Bir sayfadaki herhangi bir bağlantıya uzun basın
+ Bağlantıları yeni sekmede açabilirsiniz\n
+ Bir sayfadaki herhangi bir bağlantıya uzun basın
+ Başlangıç ekranında ipuçlarını kapat
From 670e03089c43c8e45f35913c653273fa4909fa2a Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Thu, 22 Feb 2024 01:24:36 +0000
Subject: [PATCH 290/586] Update GeckoView (Nightly) to 125.0.20240221213323.
---
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 ff2e42f96b19..baa2bc44ae25 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 = "125.0.20240221090755"
+ const val version = "125.0.20240221213323"
/**
* GeckoView channel
From 25aefa27a1a5bfb7d51054fd588aec2f791c9ebd Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 22 Feb 2024 02:36:09 +0000
Subject: [PATCH 291/586] Bump cryptography
Bumps [cryptography](https://github.com/pyca/cryptography) from 42.0.2 to 42.0.4.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/42.0.2...42.0.4)
---
updated-dependencies:
- dependency-name: cryptography
dependency-type: indirect
...
Signed-off-by: dependabot[bot]
---
.../fenix/syncintegration/Pipfile.lock | 66 +++++++++----------
1 file changed, 33 insertions(+), 33 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 1f781e87a430..5f780ffb4bcb 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
@@ -196,42 +196,42 @@
},
"cryptography": {
"hashes": [
- "sha256:087887e55e0b9c8724cf05361357875adb5c20dec27e5816b653492980d20380",
- "sha256:09a77e5b2e8ca732a19a90c5bca2d124621a1edb5438c5daa2d2738bfeb02589",
- "sha256:130c0f77022b2b9c99d8cebcdd834d81705f61c68e91ddd614ce74c657f8b3ea",
- "sha256:141e2aa5ba100d3788c0ad7919b288f89d1fe015878b9659b307c9ef867d3a65",
- "sha256:28cb2c41f131a5758d6ba6a0504150d644054fd9f3203a1e8e8d7ac3aea7f73a",
- "sha256:2f9f14185962e6a04ab32d1abe34eae8a9001569ee4edb64d2304bf0d65c53f3",
- "sha256:320948ab49883557a256eab46149df79435a22d2fefd6a66fe6946f1b9d9d008",
- "sha256:36d4b7c4be6411f58f60d9ce555a73df8406d484ba12a63549c88bd64f7967f1",
- "sha256:3b15c678f27d66d247132cbf13df2f75255627bcc9b6a570f7d2fd08e8c081d2",
- "sha256:3dbd37e14ce795b4af61b89b037d4bc157f2cb23e676fa16932185a04dfbf635",
- "sha256:4383b47f45b14459cab66048d384614019965ba6c1a1a141f11b5a551cace1b2",
- "sha256:44c95c0e96b3cb628e8452ec060413a49002a247b2b9938989e23a2c8291fc90",
- "sha256:4b063d3413f853e056161eb0c7724822a9740ad3caa24b8424d776cebf98e7ee",
- "sha256:52ed9ebf8ac602385126c9a2fe951db36f2cb0c2538d22971487f89d0de4065a",
- "sha256:55d1580e2d7e17f45d19d3b12098e352f3a37fe86d380bf45846ef257054b242",
- "sha256:5ef9bc3d046ce83c4bbf4c25e1e0547b9c441c01d30922d812e887dc5f125c12",
- "sha256:5fa82a26f92871eca593b53359c12ad7949772462f887c35edaf36f87953c0e2",
- "sha256:61321672b3ac7aade25c40449ccedbc6db72c7f5f0fdf34def5e2f8b51ca530d",
- "sha256:701171f825dcab90969596ce2af253143b93b08f1a716d4b2a9d2db5084ef7be",
- "sha256:841ec8af7a8491ac76ec5a9522226e287187a3107e12b7d686ad354bb78facee",
- "sha256:8a06641fb07d4e8f6c7dda4fc3f8871d327803ab6542e33831c7ccfdcb4d0ad6",
- "sha256:8e88bb9eafbf6a4014d55fb222e7360eef53e613215085e65a13290577394529",
- "sha256:a00aee5d1b6c20620161984f8ab2ab69134466c51f58c052c11b076715e72929",
- "sha256:a047682d324ba56e61b7ea7c7299d51e61fd3bca7dad2ccc39b72bd0118d60a1",
- "sha256:a7ef8dd0bf2e1d0a27042b231a3baac6883cdd5557036f5e8df7139255feaac6",
- "sha256:ad28cff53f60d99a928dfcf1e861e0b2ceb2bc1f08a074fdd601b314e1cc9e0a",
- "sha256:b9097a208875fc7bbeb1286d0125d90bdfed961f61f214d3f5be62cd4ed8a446",
- "sha256:b97fe7d7991c25e6a31e5d5e795986b18fbbb3107b873d5f3ae6dc9a103278e9",
- "sha256:e0ec52ba3c7f1b7d813cd52649a5b3ef1fc0d433219dc8c93827c57eab6cf888",
- "sha256:ea2c3ffb662fec8bbbfce5602e2c159ff097a4631d96235fcf0fb00e59e3ece4",
- "sha256:fa3dec4ba8fb6e662770b74f62f1a0c7d4e37e25b58b2bf2c1be4c95372b4a33",
- "sha256:fbeb725c9dc799a574518109336acccaf1303c30d45c075c665c0793c2f79a7f"
+ "sha256:01911714117642a3f1792c7f376db572aadadbafcd8d75bb527166009c9f1d1b",
+ "sha256:0e89f7b84f421c56e7ff69f11c441ebda73b8a8e6488d322ef71746224c20fce",
+ "sha256:12d341bd42cdb7d4937b0cabbdf2a94f949413ac4504904d0cdbdce4a22cbf88",
+ "sha256:15a1fb843c48b4a604663fa30af60818cd28f895572386e5f9b8a665874c26e7",
+ "sha256:1cdcdbd117681c88d717437ada72bdd5be9de117f96e3f4d50dab3f59fd9ab20",
+ "sha256:1df6fcbf60560d2113b5ed90f072dc0b108d64750d4cbd46a21ec882c7aefce9",
+ "sha256:3c6048f217533d89f2f8f4f0fe3044bf0b2090453b7b73d0b77db47b80af8dff",
+ "sha256:3e970a2119507d0b104f0a8e281521ad28fc26f2820687b3436b8c9a5fcf20d1",
+ "sha256:44a64043f743485925d3bcac548d05df0f9bb445c5fcca6681889c7c3ab12764",
+ "sha256:4e36685cb634af55e0677d435d425043967ac2f3790ec652b2b88ad03b85c27b",
+ "sha256:5f8907fcf57392cd917892ae83708761c6ff3c37a8e835d7246ff0ad251d9298",
+ "sha256:69b22ab6506a3fe483d67d1ed878e1602bdd5912a134e6202c1ec672233241c1",
+ "sha256:6bfadd884e7280df24d26f2186e4e07556a05d37393b0f220a840b083dc6a824",
+ "sha256:6d0fbe73728c44ca3a241eff9aefe6496ab2656d6e7a4ea2459865f2e8613257",
+ "sha256:6ffb03d419edcab93b4b19c22ee80c007fb2d708429cecebf1dd3258956a563a",
+ "sha256:810bcf151caefc03e51a3d61e53335cd5c7316c0a105cc695f0959f2c638b129",
+ "sha256:831a4b37accef30cccd34fcb916a5d7b5be3cbbe27268a02832c3e450aea39cb",
+ "sha256:887623fe0d70f48ab3f5e4dbf234986b1329a64c066d719432d0698522749929",
+ "sha256:a0298bdc6e98ca21382afe914c642620370ce0470a01e1bef6dd9b5354c36854",
+ "sha256:a1327f280c824ff7885bdeef8578f74690e9079267c1c8bd7dc5cc5aa065ae52",
+ "sha256:c1f25b252d2c87088abc8bbc4f1ecbf7c919e05508a7e8628e6875c40bc70923",
+ "sha256:c3a5cbc620e1e17009f30dd34cb0d85c987afd21c41a74352d1719be33380885",
+ "sha256:ce8613beaffc7c14f091497346ef117c1798c202b01153a8cc7b8e2ebaaf41c0",
+ "sha256:d2a27aca5597c8a71abbe10209184e1a8e91c1fd470b5070a2ea60cafec35bcd",
+ "sha256:dad9c385ba8ee025bb0d856714f71d7840020fe176ae0229de618f14dae7a6e2",
+ "sha256:db4b65b02f59035037fde0998974d84244a64c3265bdef32a827ab9b63d61b18",
+ "sha256:e09469a2cec88fb7b078e16d4adec594414397e8879a4341c6ace96013463d5b",
+ "sha256:e53dc41cda40b248ebc40b83b31516487f7db95ab8ceac1f042626bc43a2f992",
+ "sha256:f1e85a178384bf19e36779d91ff35c7617c885da487d689b05c1366f9933ad74",
+ "sha256:f47be41843200f7faec0683ad751e5ef11b9a56a220d57f300376cd8aba81660",
+ "sha256:fb0cef872d8193e487fc6bdb08559c3aa41b659a7d9be48b2e10747f47863925",
+ "sha256:ffc73996c4fca3d2b6c1c8c12bfd3ad00def8621da24f547626bf06441400449"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
- "version": "==42.0.2"
+ "version": "==42.0.4"
},
"distro": {
"hashes": [
From 54276741b314b92f2b0590b93debccdb4b7c0355 Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Thu, 22 Feb 2024 05:21:40 +0000
Subject: [PATCH 292/586] Update A-S to 125.20240222050253.
---
.../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 cac2ce191806..83235e1feff6 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 = "125.20240221050347"
+val VERSION = "125.20240222050253"
val CHANNEL = ApplicationServicesChannel.NIGHTLY
object ApplicationServicesConfig {
From 77812384a1536fd1a69a881846c4b48dd12250f1 Mon Sep 17 00:00:00 2001
From: mcarare <48995920+mcarare@users.noreply.github.com>
Date: Tue, 20 Feb 2024 13:37:36 +0200
Subject: [PATCH 293/586] Bug 1880077 - Switch to using Compose BOM instead of
individual versioning
---
.../components/browser/state/build.gradle | 1 +
.../compose/awesomebar/build.gradle | 1 +
.../components/compose/cfr/build.gradle | 1 +
.../components/feature/autofill/build.gradle | 1 +
.../components/lib/state/build.gradle | 2 ++
.../components/support/images/build.gradle | 1 +
.../components/ui/colors/build.gradle | 1 +
.../components/ui/tabcounter/build.gradle | 1 +
.../components/ui/widgets/build.gradle | 1 +
.../src/main/java/DependenciesPlugin.kt | 26 ++++++++++---------
.../samples/browser/build.gradle | 1 +
.../samples/compose-browser/build.gradle | 1 +
fenix/app/build.gradle | 3 +++
focus-android/app/build.gradle | 3 +++
14 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/android-components/components/browser/state/build.gradle b/android-components/components/browser/state/build.gradle
index e3068f24afbd..1cee9a2eb18b 100644
--- a/android-components/components/browser/state/build.gradle
+++ b/android-components/components/browser/state/build.gradle
@@ -50,6 +50,7 @@ tasks.withType(KotlinCompile).configureEach {
dependencies {
api project(':lib-state')
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
implementation project(':concept-awesomebar')
implementation project(':concept-engine')
implementation project(':concept-storage')
diff --git a/android-components/components/compose/awesomebar/build.gradle b/android-components/components/compose/awesomebar/build.gradle
index 15cea512a51e..65691db0e530 100644
--- a/android-components/components/compose/awesomebar/build.gradle
+++ b/android-components/components/compose/awesomebar/build.gradle
@@ -39,6 +39,7 @@ tasks.withType(KotlinCompile).configureEach {
}
dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
implementation project(":concept-awesomebar")
implementation project(":browser-state")
implementation project(":support-base")
diff --git a/android-components/components/compose/cfr/build.gradle b/android-components/components/compose/cfr/build.gradle
index 3f20c9378d72..84e722924e8c 100644
--- a/android-components/components/compose/cfr/build.gradle
+++ b/android-components/components/compose/cfr/build.gradle
@@ -36,6 +36,7 @@ android {
}
dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
implementation project(':support-ktx')
implementation project(':ui-icons')
diff --git a/android-components/components/feature/autofill/build.gradle b/android-components/components/feature/autofill/build.gradle
index 36b31f253911..033eebdfe102 100644
--- a/android-components/components/feature/autofill/build.gradle
+++ b/android-components/components/feature/autofill/build.gradle
@@ -24,6 +24,7 @@ android {
}
dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
implementation project(':concept-fetch')
implementation project(':concept-storage')
implementation project(':lib-publicsuffixlist')
diff --git a/android-components/components/lib/state/build.gradle b/android-components/components/lib/state/build.gradle
index 3ae039f266bd..4424fce46590 100644
--- a/android-components/components/lib/state/build.gradle
+++ b/android-components/components/lib/state/build.gradle
@@ -41,6 +41,7 @@ tasks.withType(KotlinCompile).configureEach {
}
dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
implementation ComponentsDependencies.kotlin_coroutines
implementation ComponentsDependencies.androidx_fragment
implementation ComponentsDependencies.androidx_compose_ui
@@ -49,6 +50,7 @@ dependencies {
implementation project(':support-base')
implementation project(':support-ktx')
+ testImplementation platform(ComponentsDependencies.androidx_compose_bom)
testImplementation project(':support-test')
testImplementation ComponentsDependencies.androidx_test_core
diff --git a/android-components/components/support/images/build.gradle b/android-components/components/support/images/build.gradle
index 12af60c5351a..4ae828bb8aec 100644
--- a/android-components/components/support/images/build.gradle
+++ b/android-components/components/support/images/build.gradle
@@ -44,6 +44,7 @@ android {
}
dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
implementation project(':concept-fetch')
implementation project(':support-base')
diff --git a/android-components/components/ui/colors/build.gradle b/android-components/components/ui/colors/build.gradle
index d733c2227fcd..865b113e50cf 100644
--- a/android-components/components/ui/colors/build.gradle
+++ b/android-components/components/ui/colors/build.gradle
@@ -31,6 +31,7 @@ android {
}
dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
implementation ComponentsDependencies.androidx_compose_ui
}
diff --git a/android-components/components/ui/tabcounter/build.gradle b/android-components/components/ui/tabcounter/build.gradle
index 37cef3b26da7..04e3ccc2e166 100644
--- a/android-components/components/ui/tabcounter/build.gradle
+++ b/android-components/components/ui/tabcounter/build.gradle
@@ -28,6 +28,7 @@ android {
}
dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
implementation project(':support-ktx')
implementation project(':support-utils')
diff --git a/android-components/components/ui/widgets/build.gradle b/android-components/components/ui/widgets/build.gradle
index bc0d98e0e975..d320df9a262b 100644
--- a/android-components/components/ui/widgets/build.gradle
+++ b/android-components/components/ui/widgets/build.gradle
@@ -25,6 +25,7 @@ android {
}
dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
implementation project(':concept-base')
implementation project(':concept-engine')
implementation project(':ui-colors')
diff --git a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt
index 782583eaea0a..b5e9ec8d3761 100644
--- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt
+++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt
@@ -52,7 +52,6 @@ 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.9"
object AndroidX {
@@ -63,7 +62,7 @@ object Versions {
const val browser = "1.7.0"
const val biometric = "1.1.0"
const val cardview = "1.0.0"
- const val compose = compose_version
+ const val compose_bom = "2023.10.01"
const val constraintlayout = "2.1.4"
const val coordinatorlayout = "1.2.0"
const val core = "1.12.0"
@@ -119,16 +118,19 @@ object ComponentsDependencies {
const val androidx_biometric = "androidx.biometric:biometric:${Versions.AndroidX.biometric}"
const val androidx_browser = "androidx.browser:browser:${Versions.AndroidX.browser}"
const val androidx_cardview = "androidx.cardview:cardview:${Versions.AndroidX.cardview}"
- const val androidx_compose_animation = "androidx.compose.animation:animation:${Versions.AndroidX.compose}"
- const val androidx_compose_ui = "androidx.compose.ui:ui:${Versions.AndroidX.compose}"
- const val androidx_compose_ui_graphics = "androidx.compose.ui:ui-graphics:${Versions.AndroidX.compose}"
- const val androidx_compose_ui_test = "androidx.compose.ui:ui-test-junit4:${Versions.AndroidX.compose}"
- const val androidx_compose_ui_test_manifest = "androidx.compose.ui:ui-test-manifest:${Versions.AndroidX.compose}"
- const val androidx_compose_ui_tooling = "androidx.compose.ui:ui-tooling:${Versions.AndroidX.compose}"
- const val androidx_compose_ui_tooling_preview = "androidx.compose.ui:ui-tooling-preview:${Versions.AndroidX.compose}"
- 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_compose_bom = "androidx.compose:compose-bom:${Versions.AndroidX.compose_bom}"
+ const val androidx_compose_animation = "androidx.compose.animation:animation"
+ const val androidx_compose_ui = "androidx.compose.ui:ui"
+ const val androidx_compose_ui_graphics = "androidx.compose.ui:ui-graphics"
+ const val androidx_compose_ui_test = "androidx.compose.ui:ui-test-junit4"
+ const val androidx_compose_ui_test_manifest = "androidx.compose.ui:ui-test-manifest"
+ const val androidx_compose_ui_tooling = "androidx.compose.ui:ui-tooling"
+ const val androidx_compose_ui_tooling_preview = "androidx.compose.ui:ui-tooling-preview"
+ const val androidx_compose_foundation = "androidx.compose.foundation:foundation"
+ const val androidx_compose_material = "androidx.compose.material:material"
+ const val androidx_compose_runtime_livedata = "androidx.compose.runtime:runtime-livedata"
+
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}"
diff --git a/android-components/samples/browser/build.gradle b/android-components/samples/browser/build.gradle
index c5b3e3a75873..c4f63cc42068 100644
--- a/android-components/samples/browser/build.gradle
+++ b/android-components/samples/browser/build.gradle
@@ -68,6 +68,7 @@ tasks.register("updateTestExtensionVersion", Copy) { task ->
}
dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
implementation project(':concept-awesomebar')
implementation project(':concept-fetch')
implementation project(':concept-engine')
diff --git a/android-components/samples/compose-browser/build.gradle b/android-components/samples/compose-browser/build.gradle
index 74d7e416ce42..1dd2422ec23f 100644
--- a/android-components/samples/compose-browser/build.gradle
+++ b/android-components/samples/compose-browser/build.gradle
@@ -47,6 +47,7 @@ tasks.register("updateTestExtensionVersion", Copy) { task ->
}
dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
implementation project(':concept-engine')
implementation project(':concept-awesomebar')
implementation project(':concept-tabstray')
diff --git a/fenix/app/build.gradle b/fenix/app/build.gradle
index 4a689a89a7ab..44a84cfffce6 100644
--- a/fenix/app/build.gradle
+++ b/fenix/app/build.gradle
@@ -523,6 +523,9 @@ tasks.withType(KotlinCompile).configureEach {
}
dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
+ androidTestImplementation platform(ComponentsDependencies.androidx_compose_bom)
+
implementation project(':browser-engine-gecko')
implementation ComponentsDependencies.kotlin_coroutines
diff --git a/focus-android/app/build.gradle b/focus-android/app/build.gradle
index 271dc34f757e..5c6909f12b55 100644
--- a/focus-android/app/build.gradle
+++ b/focus-android/app/build.gradle
@@ -210,6 +210,9 @@ nimbus {
}
dependencies {
+ implementation platform(ComponentsDependencies.androidx_compose_bom)
+ androidTestImplementation platform(ComponentsDependencies.androidx_compose_bom)
+
implementation ComponentsDependencies.androidx_appcompat
implementation ComponentsDependencies.androidx_browser
implementation ComponentsDependencies.androidx_cardview
From 69f279cbdd4832fe4b55c9871206ab44030fae3a Mon Sep 17 00:00:00 2001
From: t-p-white
Date: Tue, 20 Feb 2024 12:09:26 +0000
Subject: [PATCH 294/586] Bug 1881016 - Added experimental onboarding strings
for Nimbus
---
fenix/app/src/main/res/values/strings.xml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fenix/app/src/main/res/values/strings.xml b/fenix/app/src/main/res/values/strings.xml
index 85c99f579dd0..194a28d3c989 100644
--- a/fenix/app/src/main/res/values/strings.xml
+++ b/fenix/app/src/main/res/values/strings.xml
@@ -321,11 +321,15 @@
Find out why millions love Firefox
+
+ Safe browsing with more choicesOur non-profit backed browser helps stop companies from secretly following you around the web.More than 100 million people protect their privacy by choosing a browser that’s backed by a nonprofit.
+ Known trackers? Blocked automatically. Extensions? Try all 700. PDFs? Our built-in reader makes them easy to manage.
+
Our non-profit backed browser helps stop companies from secretly following you around the web.\n\nLearn more in our privacy notice.
From 87a95eb5a0651c051d5fad4848bf2793ded9a605 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Wed, 21 Feb 2024 14:06:42 +0200
Subject: [PATCH 295/586] Bug 1881238 - Convert private variables to functions
so they don't get initialised
---
.../SettingsSubMenuHttpsOnlyModeRobot.kt | 34 +++++++++----------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHttpsOnlyModeRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHttpsOnlyModeRobot.kt
index 189482655417..f13acc5e51cc 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHttpsOnlyModeRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHttpsOnlyModeRobot.kt
@@ -39,7 +39,7 @@ class SettingsSubMenuHttpsOnlyModeRobot {
}
fun verifyHttpsOnlyModeIsEnabled(shouldBeEnabled: Boolean) {
- httpsModeOnlySwitch.check(
+ httpsModeOnlySwitch().check(
matches(
if (shouldBeEnabled) {
isChecked(true)
@@ -50,36 +50,36 @@ class SettingsSubMenuHttpsOnlyModeRobot {
)
}
- fun clickHttpsOnlyModeSwitch() = httpsModeOnlySwitch.click()
+ fun clickHttpsOnlyModeSwitch() = httpsModeOnlySwitch().click()
fun verifyHttpsOnlyModeOptionsEnabled(shouldBeEnabled: Boolean) {
- allTabsOption.assertIsEnabled(shouldBeEnabled)
- onlyPrivateTabsOption.assertIsEnabled(shouldBeEnabled)
+ allTabsOption().assertIsEnabled(shouldBeEnabled)
+ onlyPrivateTabsOption().assertIsEnabled(shouldBeEnabled)
}
fun verifyHttpsOnlyOptionSelected(allTabsOptionSelected: Boolean, privateTabsOptionSelected: Boolean) {
if (allTabsOptionSelected) {
- allTabsOption.assertIsChecked(true)
- onlyPrivateTabsOption.assertIsChecked(false)
+ allTabsOption().assertIsChecked(true)
+ onlyPrivateTabsOption().assertIsChecked(false)
} else if (privateTabsOptionSelected) {
- allTabsOption.assertIsChecked(false)
- onlyPrivateTabsOption.assertIsChecked(true)
+ allTabsOption().assertIsChecked(false)
+ onlyPrivateTabsOption().assertIsChecked(true)
}
}
fun selectHttpsOnlyModeOption(allTabsOptionSelected: Boolean, privateTabsOptionSelected: Boolean) {
if (allTabsOptionSelected) {
- allTabsOption.click()
- allTabsOption.assertIsChecked(true)
+ allTabsOption().click()
+ allTabsOption().assertIsChecked(true)
} else if (privateTabsOptionSelected) {
- onlyPrivateTabsOption.click()
- onlyPrivateTabsOption.assertIsChecked(true)
+ onlyPrivateTabsOption().click()
+ onlyPrivateTabsOption().assertIsChecked(true)
}
}
class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
- goBackButton.perform(click())
+ goBackButton().perform(click())
SettingsRobot().interact()
return SettingsRobot.Transition()
@@ -87,9 +87,9 @@ class SettingsSubMenuHttpsOnlyModeRobot {
}
}
-private val httpsModeOnlySwitch = onView(withId(R.id.https_only_switch))
+private fun httpsModeOnlySwitch() = onView(withId(R.id.https_only_switch))
-private val allTabsOption =
+private fun allTabsOption() =
onView(
allOf(
withId(R.id.https_only_all_tabs),
@@ -97,7 +97,7 @@ private val allTabsOption =
),
)
-private val onlyPrivateTabsOption =
+private fun onlyPrivateTabsOption() =
onView(
allOf(
withId(R.id.https_only_private_tabs),
@@ -105,4 +105,4 @@ private val onlyPrivateTabsOption =
),
)
-private val goBackButton = onView(withContentDescription("Navigate up"))
+private fun goBackButton() = onView(withContentDescription("Navigate up"))
From 0cd12a9e720e6a7a707e95824b825236f788f787 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Wed, 21 Feb 2024 14:26:14 +0200
Subject: [PATCH 296/586] Bug 1881238 - Add logs to
SettingsSubMenuHttpsOnlyModeRobot
---
.../SettingsSubMenuHttpsOnlyModeRobot.kt | 42 +++++++++++++++++--
1 file changed, 39 insertions(+), 3 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHttpsOnlyModeRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHttpsOnlyModeRobot.kt
index f13acc5e51cc..d4a0c5c6427c 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHttpsOnlyModeRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHttpsOnlyModeRobot.kt
@@ -4,8 +4,8 @@
package org.mozilla.fenix.ui.robots
+import android.util.Log
import androidx.test.espresso.Espresso.onView
-import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.hasSibling
@@ -15,6 +15,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import org.hamcrest.CoreMatchers.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.assertIsChecked
import org.mozilla.fenix.helpers.assertIsEnabled
@@ -23,22 +24,30 @@ import org.mozilla.fenix.helpers.isChecked
class SettingsSubMenuHttpsOnlyModeRobot {
- fun verifyHttpsOnlyModeMenuHeader(): ViewInteraction =
+ fun verifyHttpsOnlyModeMenuHeader() {
+ Log.i(TAG, "verifyHttpsOnlyModeMenuHeader: Trying to verify that the \"HTTPS-Only Mode\" toolbar items are visible")
onView(
allOf(
withText(getStringResource(R.string.preferences_https_only_title)),
hasSibling(withContentDescription("Navigate up")),
),
).check(matches(isDisplayed()))
+ Log.i(TAG, "verifyHttpsOnlyModeMenuHeader: Verified that the \"HTTPS-Only Mode\" toolbar items are visible")
+ }
fun verifyHttpsOnlyModeSummary() {
+ Log.i(TAG, "verifyHttpsOnlyModeSummary: Trying to verify that the \"HTTPS-Only Mode\" title is visible")
onView(withId(R.id.https_only_title))
.check(matches(withText("HTTPS-Only Mode")))
+ Log.i(TAG, "verifyHttpsOnlyModeSummary: Verified that the \"HTTPS-Only Mode\" title is visible")
+ Log.i(TAG, "verifyHttpsOnlyModeSummary: Trying to verify that the \"HTTPS-Only Mode\" summary is visible")
onView(withId(R.id.https_only_summary))
.check(matches(withText("Automatically attempts to connect to sites using HTTPS encryption protocol for increased security. Learn more")))
+ Log.i(TAG, "verifyHttpsOnlyModeSummary: Verified that the \"HTTPS-Only Mode\" summary is visible")
}
fun verifyHttpsOnlyModeIsEnabled(shouldBeEnabled: Boolean) {
+ Log.i(TAG, "verifyHttpsOnlyModeIsEnabled: Trying to verify that the \"HTTPS-Only Mode\" toggle is checked: $shouldBeEnabled")
httpsModeOnlySwitch().check(
matches(
if (shouldBeEnabled) {
@@ -48,38 +57,65 @@ class SettingsSubMenuHttpsOnlyModeRobot {
},
),
)
+ Log.i(TAG, "verifyHttpsOnlyModeIsEnabled: Verified that the \"HTTPS-Only Mode\" toggle is checked: $shouldBeEnabled")
}
- fun clickHttpsOnlyModeSwitch() = httpsModeOnlySwitch().click()
+ fun clickHttpsOnlyModeSwitch() {
+ Log.i(TAG, "clickHttpsOnlyModeSwitch: Trying to click the \"HTTPS-Only Mode\" toggle")
+ httpsModeOnlySwitch().click()
+ Log.i(TAG, "clickHttpsOnlyModeSwitch: Clicked the \"HTTPS-Only Mode\" toggle")
+ }
fun verifyHttpsOnlyModeOptionsEnabled(shouldBeEnabled: Boolean) {
+ Log.i(TAG, "verifyHttpsOnlyModeOptionsEnabled: Trying to verify that the \"Enable in all tabs\" option is enabled: $shouldBeEnabled")
allTabsOption().assertIsEnabled(shouldBeEnabled)
+ Log.i(TAG, "verifyHttpsOnlyModeOptionsEnabled: Verified that the \"Enable in all tabs\" option is enabled: $shouldBeEnabled")
+ Log.i(TAG, "verifyHttpsOnlyModeOptionsEnabled: Trying to verify that the \"Enable only in private tabs\" option is enabled: $shouldBeEnabled")
onlyPrivateTabsOption().assertIsEnabled(shouldBeEnabled)
+ Log.i(TAG, "verifyHttpsOnlyModeOptionsEnabled: Verified that the \"Enable only in private tabs\" option is enabled: $shouldBeEnabled")
}
fun verifyHttpsOnlyOptionSelected(allTabsOptionSelected: Boolean, privateTabsOptionSelected: Boolean) {
if (allTabsOptionSelected) {
+ Log.i(TAG, "verifyHttpsOnlyOptionSelected: Trying to verify that the \"Enable in all tabs\" option is checked: $allTabsOptionSelected")
allTabsOption().assertIsChecked(true)
+ Log.i(TAG, "verifyHttpsOnlyOptionSelected: Verified that the \"Enable in all tabs\" option is checked: $allTabsOptionSelected")
+ Log.i(TAG, "verifyHttpsOnlyOptionSelected: Trying to verify that the \"Enable only in private tabs\" option is checked: $privateTabsOptionSelected")
onlyPrivateTabsOption().assertIsChecked(false)
+ Log.i(TAG, "verifyHttpsOnlyOptionSelected: Verified that the \"Enable only in private tabs\" option is checked: $privateTabsOptionSelected")
} else if (privateTabsOptionSelected) {
+ Log.i(TAG, "verifyHttpsOnlyOptionSelected: Trying to verify that the \"Enable in all tabs\" option is checked: $allTabsOptionSelected")
allTabsOption().assertIsChecked(false)
+ Log.i(TAG, "verifyHttpsOnlyOptionSelected: Verified that the \"Enable in all tabs\" option is checked: $allTabsOptionSelected")
+ Log.i(TAG, "verifyHttpsOnlyOptionSelected: Trying to verify that the \"Enable only in private tabs\" option is checked: $privateTabsOptionSelected")
onlyPrivateTabsOption().assertIsChecked(true)
+ Log.i(TAG, "verifyHttpsOnlyOptionSelected: Verified that the \"Enable only in private tabs\" option is checked: $privateTabsOptionSelected")
}
}
fun selectHttpsOnlyModeOption(allTabsOptionSelected: Boolean, privateTabsOptionSelected: Boolean) {
if (allTabsOptionSelected) {
+ Log.i(TAG, "selectHttpsOnlyModeOption: Trying to click the \"Enable in all tabs\" option")
allTabsOption().click()
+ Log.i(TAG, "selectHttpsOnlyModeOption: Clicked the \"Enable in all tabs\" option")
+ Log.i(TAG, "selectHttpsOnlyModeOption: Trying to verify that the \"Enable in all tabs\" option is checked: $allTabsOptionSelected")
allTabsOption().assertIsChecked(true)
+ Log.i(TAG, "selectHttpsOnlyModeOption: Verified that the \"Enable in all tabs\" option is checked: $allTabsOptionSelected")
} else if (privateTabsOptionSelected) {
+ Log.i(TAG, "selectHttpsOnlyModeOption: Trying to click the \"Enable only in private tabs\" option")
onlyPrivateTabsOption().click()
+ Log.i(TAG, "selectHttpsOnlyModeOption: Clicked the \"Enable only in private tabs\" option")
+ Log.i(TAG, "selectHttpsOnlyModeOption: Trying to verify that the \"Enable only in private tabs\" option is checked: $privateTabsOptionSelected")
onlyPrivateTabsOption().assertIsChecked(true)
+ Log.i(TAG, "selectHttpsOnlyModeOption: Verified that the \"Enable only in private tabs\" option is checked: $privateTabsOptionSelected")
}
}
class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
+ Log.i(TAG, "goBack: Trying to click the navigate up toolbar button")
goBackButton().perform(click())
+ Log.i(TAG, "goBack: Clicked the navigate up toolbar button")
SettingsRobot().interact()
return SettingsRobot.Transition()
From 8e4344e80381a53c3c240567d6a8189394638191 Mon Sep 17 00:00:00 2001
From: Arturo Mejia
Date: Wed, 21 Feb 2024 15:29:12 -0500
Subject: [PATCH 297/586] Bug 1877881 - Prevent crash when downloadStatus is
not present.
---
.../downloads/manager/FetchDownloadManager.kt | 4 +--
.../manager/FetchDownloadManagerTest.kt | 25 +++++++++++++++++++
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/manager/FetchDownloadManager.kt b/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/manager/FetchDownloadManager.kt
index 2207bcc75b3d..dc8266c0030b 100644
--- a/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/manager/FetchDownloadManager.kt
+++ b/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/manager/FetchDownloadManager.kt
@@ -128,9 +128,9 @@ class FetchDownloadManager(
val downloadID = intent.getStringExtra(EXTRA_DOWNLOAD_ID) ?: ""
val download = store.state.downloads[downloadID]
val downloadStatus = intent.getSerializableExtraCompat(EXTRA_DOWNLOAD_STATUS, Status::class.java)
- as Status
+ as Status?
- if (download != null) {
+ if (download != null && downloadStatus != null) {
onDownloadStopped(download, downloadID, downloadStatus)
}
}
diff --git a/android-components/components/feature/downloads/src/test/java/mozilla/components/feature/downloads/manager/FetchDownloadManagerTest.kt b/android-components/components/feature/downloads/src/test/java/mozilla/components/feature/downloads/manager/FetchDownloadManagerTest.kt
index d79a12c1ed31..e72061db9817 100644
--- a/android-components/components/feature/downloads/src/test/java/mozilla/components/feature/downloads/manager/FetchDownloadManagerTest.kt
+++ b/android-components/components/feature/downloads/src/test/java/mozilla/components/feature/downloads/manager/FetchDownloadManagerTest.kt
@@ -27,6 +27,7 @@ import mozilla.components.support.test.mock
import mozilla.components.support.test.robolectric.grantPermission
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
@@ -94,6 +95,30 @@ class FetchDownloadManagerTest {
assertTrue(downloadStopped)
}
+ @Test
+ fun `sending an ACTION_DOWNLOAD_COMPLETE intent without an EXTRA_DOWNLOAD_STATUS should not crash`() {
+ var downloadStopped = false
+
+ downloadManager.onDownloadStopped = { _, _, _ -> downloadStopped = true }
+
+ grantPermissions()
+
+ assertTrue(store.state.downloads.isEmpty())
+ val id = downloadManager.download(download)!!
+ store.waitUntilIdle()
+ assertEquals(download, store.state.downloads[download.id])
+
+ // Excluding the EXTRA_DOWNLOAD_STATUS
+ val intent = Intent(ACTION_DOWNLOAD_COMPLETE)
+ intent.putExtra(EXTRA_DOWNLOAD_ID, id)
+
+ testContext.sendBroadcast(intent)
+
+ shadowOf(getMainLooper()).idle()
+
+ assertFalse(downloadStopped)
+ }
+
@Test
fun `calling tryAgain starts the download again`() {
val context = spy(testContext)
From b7c01cff1d9911e99bf16a0bffd842e2ade16623 Mon Sep 17 00:00:00 2001
From: James Hugman
Date: Mon, 29 Jan 2024 17:00:24 +0000
Subject: [PATCH 298/586] =?UTF-8?q?Bug=201880476=20=E2=80=94=20Messaging:?=
=?UTF-8?q?=20promote=20NimbusMessagingController=20to=20components.nimbus?=
=?UTF-8?q?.messaging?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../messaging/NimbusMessagingController.kt | 33 ++++++---
.../NimbusMessagingControllerInterface.kt | 73 +++++++++++++++++++
.../NimbusMessagingControllerTest.kt | 8 +-
.../fenix/ui/NimbusMessagingMessageTest.kt | 22 +-----
.../java/org/mozilla/fenix/HomeActivity.kt | 21 +-----
.../mozilla/fenix/components/Components.kt | 2 +-
.../fenix/components/NimbusComponents.kt | 15 +++-
.../org/mozilla/fenix/home/HomeFragment.kt | 3 +-
.../messaging/DefaultMessageController.kt | 9 +--
.../FenixNimbusMessagingController.kt | 23 ------
.../messaging/MessageNotificationWorker.kt | 36 ++++-----
.../messaging/state/MessagingMiddleware.kt | 30 ++++----
.../messaging/DefaultMessageControllerTest.kt | 10 +--
.../state/MessagingMiddlewareTest.kt | 71 +++++++++++-------
14 files changed, 201 insertions(+), 155 deletions(-)
create mode 100644 android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerInterface.kt
delete mode 100644 fenix/app/src/main/java/org/mozilla/fenix/messaging/FenixNimbusMessagingController.kt
diff --git a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingController.kt b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingController.kt
index 4535f4dd5592..fef964358f17 100644
--- a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingController.kt
+++ b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingController.kt
@@ -6,6 +6,7 @@ package mozilla.components.service.nimbus.messaging
import android.content.Intent
import android.net.Uri
+import androidx.annotation.VisibleForTesting
import androidx.core.net.toUri
import mozilla.components.service.nimbus.GleanMetrics.Messaging as GleanMessaging
@@ -25,12 +26,13 @@ open class NimbusMessagingController(
"$deepLinkScheme://open?url=${Uri.encode(action)}".toUri()
},
private val now: () -> Long = { System.currentTimeMillis() },
-) {
+) : NimbusMessagingControllerInterface {
/**
* Called when a message is just about to be shown to the user.
*
* Update the display count, time shown and boot identifier metadata for the given [message].
*/
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun updateMessageAsDisplayed(message: Message, bootIdentifier: String? = null): Message {
val updatedMetadata = message.metadata.copy(
displayCount = message.metadata.displayCount + 1,
@@ -45,12 +47,14 @@ open class NimbusMessagingController(
/**
* Records telemetry and metadata for a newly processed displayed message.
*/
- suspend fun onMessageDisplayed(message: Message) {
- sendShownMessageTelemetry(message.id)
- if (message.isExpired) {
- sendExpiredMessageTelemetry(message.id)
+ override suspend fun onMessageDisplayed(displayedMessage: Message, bootIdentifier: String?): Message {
+ sendShownMessageTelemetry(displayedMessage.id)
+ val nextMessage = updateMessageAsDisplayed(displayedMessage, bootIdentifier)
+ if (nextMessage.isExpired) {
+ sendExpiredMessageTelemetry(nextMessage.id)
}
- messagingStorage.updateMetadata(message.metadata)
+ messagingStorage.updateMetadata(nextMessage.metadata)
+ return nextMessage
}
/**
@@ -59,7 +63,7 @@ open class NimbusMessagingController(
* Records a messageDismissed event, and records that the message
* has been dismissed.
*/
- suspend fun onMessageDismissed(message: Message) {
+ override suspend fun onMessageDismissed(message: Message) {
val messageMetadata = message.metadata
sendDismissedMessageTelemetry(messageMetadata.id)
val updatedMetadata = messageMetadata.copy(dismissed = true)
@@ -72,7 +76,7 @@ open class NimbusMessagingController(
* This records that the message has been clicked on, but does not record a
* glean event. That should be done via [processMessageActionToUri].
*/
- suspend fun onMessageClicked(message: Message) {
+ override suspend fun onMessageClicked(message: Message) {
val messageMetadata = message.metadata
val updatedMetadata = messageMetadata.copy(pressed = true)
messagingStorage.updateMetadata(updatedMetadata)
@@ -84,7 +88,7 @@ open class NimbusMessagingController(
* @param message the [Message] to create the [Intent] for.
* @return an [Intent] using the processed [Message].
*/
- fun getIntentForMessage(message: Message) = Intent(
+ override fun getIntentForMessage(message: Message) = Intent(
Intent.ACTION_VIEW,
processMessageActionToUri(message),
)
@@ -95,7 +99,7 @@ open class NimbusMessagingController(
* @param id the [Message.id] of the [Message] to try to match.
* @return the [Message] with a matching [id], or null if no [Message] has a matching [id].
*/
- suspend fun getMessage(id: String): Message? {
+ override suspend fun getMessage(id: String): Message? {
return messagingStorage.getMessage(id)
}
@@ -139,4 +143,13 @@ open class NimbusMessagingController(
} else {
action.toUri()
}
+
+ override suspend fun getMessages(): List =
+ messagingStorage.getMessages()
+
+ override suspend fun getNextMessage(surfaceId: MessageSurfaceId) =
+ getNextMessage(surfaceId, getMessages())
+
+ override fun getNextMessage(surfaceId: MessageSurfaceId, messages: List) =
+ messagingStorage.getNextMessage(surfaceId, messages)
}
diff --git a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerInterface.kt b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerInterface.kt
new file mode 100644
index 000000000000..0b7e08046fb5
--- /dev/null
+++ b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerInterface.kt
@@ -0,0 +1,73 @@
+/* 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.nimbus.messaging
+
+import android.content.Intent
+
+/**
+ * API for interacting with the messaging component.
+ *
+ * The primary methods for interacting with the component are:
+ * - [getNextMessage] to get the next [Message] for a given surface.
+ * - [onMessageDisplayed] to be called when the message is displayed.
+ * - [onMessageClicked] and [getIntentForMessage] to be called when the user taps on
+ * the message, and to get the action for the message.
+ * - [onMessageDismissed] to be called when the user dismisses the message.
+ */
+interface NimbusMessagingControllerInterface {
+ /**
+ * Get all messages currently on the system. This includes any that have expired,
+ * dismissed or clicked upon.
+ */
+ suspend fun getMessages(): List
+
+ /**
+ * Selects the next available message for the given surface from the given
+ * list of messages.
+ */
+ fun getNextMessage(surfaceId: MessageSurfaceId, messages: List): Message?
+
+ /**
+ * A convenience method for `getNextMessage(surfaceId, getMessages())`.
+ */
+ suspend fun getNextMessage(surfaceId: MessageSurfaceId): Message?
+
+ /**
+ * Records telemetry and metadata for a newly processed displayed message.
+ */
+ suspend fun onMessageDisplayed(displayedMessage: Message, bootIdentifier: String? = null): Message
+
+ /**
+ * Called when a message has been dismissed by the user.
+ *
+ * Records a messageDismissed event, and records that the message
+ * has been dismissed.
+ */
+ suspend fun onMessageDismissed(message: Message)
+
+ /**
+ * Called once the user has clicked on a message.
+ *
+ * This records that the message has been clicked on, but does not record a
+ * glean event. That should be done when calling [getIntentForMessage].
+ */
+ suspend fun onMessageClicked(message: Message)
+
+ /**
+ * Create and return the relevant [Intent] for the given [Message].
+ *
+ * @param message the [Message] to create the [Intent] for.
+ * @return an [Intent] using the processed [Message].
+ */
+ fun getIntentForMessage(message: Message): Intent
+
+ /**
+ * Will attempt to get the [Message] for the given [id].
+ *
+ * @param id the [Message.id] of the [Message] to try to match.
+ * @return the [Message] with a matching [id], or null if no [Message] has a matching [id].
+ */
+ suspend fun getMessage(id: String): Message?
+}
diff --git a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerTest.kt b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerTest.kt
index 0470fda0e66a..ae7053b6f664 100644
--- a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerTest.kt
+++ b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerTest.kt
@@ -97,7 +97,7 @@ class NimbusMessagingControllerTest {
@Test
fun `GIVEN message not expired WHEN calling onMessageDisplayed THEN record a messageShown event and update storage`() =
coroutineScope.runTest {
- val message = createMessage("id-1", style = StyleData(maxDisplayCount = 1))
+ val message = createMessage("id-1", style = StyleData(maxDisplayCount = 2))
// Assert telemetry is initially null
assertNull(GleanMessaging.messageShown.testGetValue())
assertNull(GleanMessaging.messageExpired.testGetValue())
@@ -113,14 +113,14 @@ class NimbusMessagingControllerTest {
// Expired telemetry
assertNull(GleanMessaging.messageExpired.testGetValue())
- verify(storage).updateMetadata(message.metadata)
+ verify(storage).updateMetadata(message.metadata.copy(displayCount = 1, lastTimeShown = MOCK_TIME_MILLIS))
}
@Test
fun `GIVEN message is expired WHEN calling onMessageDisplayed THEN record messageShown, messageExpired events and update storage`() =
coroutineScope.runTest {
val message =
- createMessage("id-1", style = StyleData(maxDisplayCount = 1), displayCount = 1)
+ createMessage("id-1", style = StyleData(maxDisplayCount = 1), displayCount = 0)
// Assert telemetry is initially null
assertNull(GleanMessaging.messageShown.testGetValue())
assertNull(GleanMessaging.messageExpired.testGetValue())
@@ -139,7 +139,7 @@ class NimbusMessagingControllerTest {
assertEquals(1, expiredEvent.size)
assertEquals(message.id, expiredEvent.single().extra!!["message_key"])
- verify(storage).updateMetadata(message.metadata)
+ verify(storage).updateMetadata(message.metadata.copy(displayCount = 1, lastTimeShown = MOCK_TIME_MILLIS))
}
@Test
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt
index c353b668f47a..4cbd0735c75d 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt
@@ -33,8 +33,8 @@ class NimbusMessagingMessageTest {
private lateinit var context: Context
- private val storage
- get() = context.components.nimbus.messagingStorage
+ private val messaging
+ get() = context.components.nimbus.messaging
@get:Rule
val activityTestRule =
@@ -54,7 +54,7 @@ class NimbusMessagingMessageTest {
*/
@Test
fun testAllMessageIntegrity() = runTest {
- val messages = storage.getMessages()
+ val messages = messaging.getMessages()
val rawMessages = feature.messages
assertTrue(rawMessages.isNotEmpty())
@@ -67,22 +67,6 @@ class NimbusMessagingMessageTest {
assertEquals(messages.size, rawMessages.size)
}
- /**
- * Check if the messages' triggers are well formed JEXL.
- */
- @Test
- fun testAllMessageTriggers() = runTest {
- val helper = context.components.nimbus.createJexlHelper()
- val messages = storage.getMessages()
- messages.forEach { message ->
- storage.isMessageEligible(message, helper)
- if (storage.malFormedMap.isNotEmpty()) {
- fail("${message.id} has a problem with its JEXL trigger: ${storage.malFormedMap.keys}")
- }
- }
- helper.destroy()
- }
-
private fun checkIsLocalized(string: String) {
assertFalse(string.isBlank())
// The check will almost always succeed, since the generated code
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 1bc06595f218..e218b2e13e65 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
@@ -121,7 +121,6 @@ import org.mozilla.fenix.home.intent.SpeechProcessingIntentProcessor
import org.mozilla.fenix.home.intent.StartSearchIntentProcessor
import org.mozilla.fenix.library.bookmarks.DesktopFolders
import org.mozilla.fenix.messaging.FenixMessageSurfaceId
-import org.mozilla.fenix.messaging.FenixNimbusMessagingController
import org.mozilla.fenix.messaging.MessageNotificationWorker
import org.mozilla.fenix.nimbus.FxNimbus
import org.mozilla.fenix.onboarding.ReEngagementNotificationWorker
@@ -1221,13 +1220,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
}
private suspend fun showFullscreenMessageIfNeeded(context: Context) {
- val messagingStorage = context.components.nimbus.messagingStorage
- val messages = messagingStorage.getMessages()
- val nextMessage =
- messagingStorage.getNextMessage(FenixMessageSurfaceId.SURVEY, messages)
- ?: return
-
- val fenixNimbusMessagingController = FenixNimbusMessagingController(messagingStorage)
+ val messaging = context.components.nimbus.messaging
+ val nextMessage = messaging.getNextMessage(FenixMessageSurfaceId.SURVEY) ?: return
val researchSurfaceDialogFragment = ResearchSurfaceDialogFragment.newInstance(
keyMessageText = nextMessage.text,
keyAcceptButtonText = nextMessage.buttonLabel,
@@ -1235,7 +1229,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
)
researchSurfaceDialogFragment.onAccept = {
- processIntent(fenixNimbusMessagingController.getIntentForMessage(nextMessage))
+ processIntent(messaging.getIntentForMessage(nextMessage))
components.appStore.dispatch(AppAction.MessagingAction.MessageClicked(nextMessage))
}
@@ -1252,15 +1246,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
// Update message as displayed.
val currentBootUniqueIdentifier = BootUtils.getBootIdentifier(context)
- val updatedMessage =
- fenixNimbusMessagingController.updateMessageAsDisplayed(
- nextMessage,
- currentBootUniqueIdentifier,
- )
-
- fenixNimbusMessagingController.onMessageDisplayed(updatedMessage)
- return
+ messaging.onMessageDisplayed(nextMessage, currentBootUniqueIdentifier)
}
companion object {
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 fd74fcb37827..4c806ae86476 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
@@ -232,7 +232,7 @@ class Components(private val context: Context) {
context.pocketStoriesSelectedCategoriesDataStore,
),
MessagingMiddleware(
- messagingStorage = nimbus.messagingStorage,
+ controller = nimbus.messaging,
),
MetricsMiddleware(metrics = analytics.metrics),
),
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/NimbusComponents.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/NimbusComponents.kt
index a83b3ef5948f..ad90042055a4 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/components/NimbusComponents.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/components/NimbusComponents.kt
@@ -7,6 +7,8 @@ package org.mozilla.fenix.components
import android.content.Context
import mozilla.components.service.nimbus.NimbusApi
import mozilla.components.service.nimbus.messaging.FxNimbusMessaging
+import mozilla.components.service.nimbus.messaging.NimbusMessagingController
+import mozilla.components.service.nimbus.messaging.NimbusMessagingControllerInterface
import mozilla.components.service.nimbus.messaging.NimbusMessagingStorage
import mozilla.components.service.nimbus.messaging.OnDiskMessageMetadataStorage
import org.mozilla.experiments.nimbus.NimbusEventStore
@@ -71,12 +73,23 @@ class NimbusComponents(private val context: Context) {
fun createJexlHelper(): NimbusMessagingHelperInterface =
messagingStorage.createMessagingHelper()
+ /**
+ * The main entry point for UI surfaces to interact with (get, click, dismiss) messages
+ * from the Nimbus Messaging component.
+ */
+ val messaging: NimbusMessagingControllerInterface by lazyMonitored {
+ NimbusMessagingController(
+ messagingStorage = messagingStorage,
+ deepLinkScheme = BuildConfig.DEEP_LINK_SCHEME,
+ )
+ }
+
/**
* Low level access to the messaging component.
*
* The app should access this through a [mozilla.components.service.nimbus.messaging.NimbusMessagingController].
*/
- val messagingStorage by lazyMonitored {
+ private val messagingStorage by lazyMonitored {
NimbusMessagingStorage(
context = context,
metadataStorage = OnDiskMessageMetadataStorage(context),
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 24fb5ec9ff0d..fccae3ff9973 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
@@ -117,7 +117,6 @@ import org.mozilla.fenix.home.toolbar.SearchSelectorBinding
import org.mozilla.fenix.home.toolbar.SearchSelectorMenuBinding
import org.mozilla.fenix.home.topsites.DefaultTopSitesView
import org.mozilla.fenix.messaging.DefaultMessageController
-import org.mozilla.fenix.messaging.FenixNimbusMessagingController
import org.mozilla.fenix.messaging.MessagingFeature
import org.mozilla.fenix.nimbus.FxNimbus
import org.mozilla.fenix.perf.MarkersFragmentLifecycleCallbacks
@@ -360,7 +359,7 @@ class HomeFragment : Fragment() {
engine = components.core.engine,
messageController = DefaultMessageController(
appStore = components.appStore,
- messagingController = FenixNimbusMessagingController(components.nimbus.messagingStorage),
+ messagingController = components.nimbus.messaging,
homeActivity = activity,
),
store = store,
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/messaging/DefaultMessageController.kt b/fenix/app/src/main/java/org/mozilla/fenix/messaging/DefaultMessageController.kt
index a006ab02bfb9..a72305c88c1b 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/messaging/DefaultMessageController.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/messaging/DefaultMessageController.kt
@@ -4,9 +4,8 @@
package org.mozilla.fenix.messaging
-import android.content.Intent
import mozilla.components.service.nimbus.messaging.Message
-import mozilla.components.service.nimbus.messaging.NimbusMessagingController
+import mozilla.components.service.nimbus.messaging.NimbusMessagingControllerInterface
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageClicked
@@ -17,13 +16,13 @@ import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageDi
*/
class DefaultMessageController(
private val appStore: AppStore,
- private val messagingController: NimbusMessagingController,
+ private val messagingController: NimbusMessagingControllerInterface,
private val homeActivity: HomeActivity,
) : MessageController {
override fun onMessagePressed(message: Message) {
- val actionUri = messagingController.processMessageActionToUri(message)
- homeActivity.processIntent(Intent(Intent.ACTION_VIEW, actionUri))
+ val intent = messagingController.getIntentForMessage(message)
+ homeActivity.processIntent(intent)
appStore.dispatch(MessageClicked(message))
}
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/messaging/FenixNimbusMessagingController.kt b/fenix/app/src/main/java/org/mozilla/fenix/messaging/FenixNimbusMessagingController.kt
deleted file mode 100644
index 6a1c31e9f022..000000000000
--- a/fenix/app/src/main/java/org/mozilla/fenix/messaging/FenixNimbusMessagingController.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.fenix.messaging
-
-import mozilla.components.service.nimbus.messaging.NimbusMessagingController
-import mozilla.components.service.nimbus.messaging.NimbusMessagingStorage
-import org.mozilla.fenix.BuildConfig
-
-/**
- * Bookkeeping for message actions in terms of Glean messages and the messaging store.
- * Specialized implementation of NimbusMessagingController defining the deepLinkScheme
- * used by Fenix
- */
-class FenixNimbusMessagingController(
- messagingStorage: NimbusMessagingStorage,
- now: () -> Long = { System.currentTimeMillis() },
-) : NimbusMessagingController(
- messagingStorage = messagingStorage,
- deepLinkScheme = BuildConfig.DEEP_LINK_SCHEME,
- now = now,
-)
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/messaging/MessageNotificationWorker.kt b/fenix/app/src/main/java/org/mozilla/fenix/messaging/MessageNotificationWorker.kt
index f75b4ef28113..173552066aee 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/messaging/MessageNotificationWorker.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/messaging/MessageNotificationWorker.kt
@@ -45,10 +45,10 @@ class MessageNotificationWorker(
override suspend fun doWork(): Result {
val context = applicationContext
- val messagingStorage = context.components.nimbus.messagingStorage
- val messages = messagingStorage.getMessages()
+ val messaging = context.components.nimbus.messaging
+
val nextMessage =
- messagingStorage.getNextMessage(FenixMessageSurfaceId.NOTIFICATION, messages)
+ messaging.getNextMessage(FenixMessageSurfaceId.NOTIFICATION)
?: return Result.success()
val currentBootUniqueIdentifier = BootUtils.getBootIdentifier(context)
@@ -57,23 +57,15 @@ class MessageNotificationWorker(
return Result.success()
}
- val nimbusMessagingController = FenixNimbusMessagingController(messagingStorage)
-
// Update message as displayed.
- val updatedMessage =
- nimbusMessagingController.updateMessageAsDisplayed(
- nextMessage,
- currentBootUniqueIdentifier,
- )
-
- nimbusMessagingController.onMessageDisplayed(updatedMessage)
+ messaging.onMessageDisplayed(nextMessage, currentBootUniqueIdentifier)
context.components.notificationsDelegate.notify(
MESSAGE_TAG,
- SharedIdsHelper.getIdForTag(context, updatedMessage.id),
+ SharedIdsHelper.getIdForTag(context, nextMessage.id),
buildNotification(
context,
- updatedMessage,
+ nextMessage,
),
)
@@ -177,18 +169,17 @@ class NotificationDismissedService : LifecycleService() {
super.onStartCommand(intent, flags, startId)
if (intent != null) {
- val nimbusMessagingController =
- FenixNimbusMessagingController(applicationContext.components.nimbus.messagingStorage)
+ val messaging = applicationContext.components.nimbus.messaging
lifecycleScope.launch {
// Get the relevant message.
val message = intent.getStringExtra(DISMISSED_MESSAGE_ID)?.let { messageId ->
- nimbusMessagingController.getMessage(messageId)
+ messaging.getMessage(messageId)
}
if (message != null) {
// Update message as 'dismissed'.
- nimbusMessagingController.onMessageDismissed(message)
+ messaging.onMessageDismissed(message)
}
}
}
@@ -208,21 +199,20 @@ class NotificationClickedReceiverActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- val nimbusMessagingController =
- FenixNimbusMessagingController(components.nimbus.messagingStorage)
+ val messaging = applicationContext.components.nimbus.messaging
lifecycleScope.launch {
// Get the relevant message.
val message = intent.getStringExtra(CLICKED_MESSAGE_ID)?.let { messageId ->
- nimbusMessagingController.getMessage(messageId)
+ messaging.getMessage(messageId)
}
if (message != null) {
// Update message as 'clicked'.
- nimbusMessagingController.onMessageClicked(message)
+ messaging.onMessageClicked(message)
// Create the intent.
- val intent = nimbusMessagingController.getIntentForMessage(message)
+ val intent = messaging.getIntentForMessage(message)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/messaging/state/MessagingMiddleware.kt b/fenix/app/src/main/java/org/mozilla/fenix/messaging/state/MessagingMiddleware.kt
index 4d8f79ad9c8f..5340996f45ad 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/messaging/state/MessagingMiddleware.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/messaging/state/MessagingMiddleware.kt
@@ -10,8 +10,7 @@ import kotlinx.coroutines.launch
import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.MiddlewareContext
import mozilla.components.service.nimbus.messaging.Message
-import mozilla.components.service.nimbus.messaging.NimbusMessagingController
-import mozilla.components.service.nimbus.messaging.NimbusMessagingStorage
+import mozilla.components.service.nimbus.messaging.NimbusMessagingControllerInterface
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.ConsumeMessageToShow
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.Evaluate
@@ -21,13 +20,11 @@ import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.Restore
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.UpdateMessageToShow
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.UpdateMessages
import org.mozilla.fenix.components.appstate.AppState
-import org.mozilla.fenix.messaging.FenixNimbusMessagingController
typealias AppStoreMiddlewareContext = MiddlewareContext
class MessagingMiddleware(
- private val messagingStorage: NimbusMessagingStorage,
- private val controller: NimbusMessagingController = FenixNimbusMessagingController(messagingStorage),
+ private val controller: NimbusMessagingControllerInterface,
private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO),
) : Middleware {
@@ -39,13 +36,13 @@ class MessagingMiddleware(
when (action) {
is Restore -> {
coroutineScope.launch {
- val messages = messagingStorage.getMessages()
+ val messages = controller.getMessages()
context.store.dispatch(UpdateMessages(messages))
}
}
is Evaluate -> {
- val message = messagingStorage.getNextMessage(
+ val message = controller.getNextMessage(
action.surface,
context.state.messaging.messages,
)
@@ -72,16 +69,15 @@ class MessagingMiddleware(
oldMessage: Message,
context: AppStoreMiddlewareContext,
) {
- val newMessage = controller.updateMessageAsDisplayed(oldMessage)
- val newMessages = if (!newMessage.isExpired) {
- updateMessage(context, oldMessage, newMessage)
- } else {
- consumeMessageToShowIfNeeded(context, oldMessage)
- removeMessage(context, oldMessage)
- }
- context.dispatch(UpdateMessages(newMessages))
coroutineScope.launch {
- controller.onMessageDisplayed(newMessage)
+ val newMessage = controller.onMessageDisplayed(oldMessage)
+ val newMessages = if (!newMessage.isExpired) {
+ updateMessage(context, oldMessage, newMessage)
+ } else {
+ consumeMessageToShowIfNeeded(context, oldMessage)
+ removeMessage(context, oldMessage)
+ }
+ context.store.dispatch(UpdateMessages(newMessages))
}
}
@@ -136,7 +132,7 @@ class MessagingMiddleware(
val actualMessageToShow = context.state.messaging.messageToShow[updatedMessage.surface]
if (actualMessageToShow?.id == oldMessage.id) {
- context.dispatch(UpdateMessageToShow(updatedMessage))
+ context.store.dispatch(UpdateMessageToShow(updatedMessage))
}
val oldMessageIndex = context.state.messaging.messages.indexOfFirst { it.id == updatedMessage.id }
val newList = context.state.messaging.messages.toMutableList()
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/messaging/DefaultMessageControllerTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/messaging/DefaultMessageControllerTest.kt
index 733d86de52be..aeced21c2caf 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/messaging/DefaultMessageControllerTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/messaging/DefaultMessageControllerTest.kt
@@ -4,13 +4,11 @@
package org.mozilla.fenix.messaging
-import androidx.core.net.toUri
-import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import mozilla.components.service.nimbus.messaging.Message
import mozilla.components.service.nimbus.messaging.MessageData
-import mozilla.components.service.nimbus.messaging.NimbusMessagingController
+import mozilla.components.service.nimbus.messaging.NimbusMessagingControllerInterface
import mozilla.components.support.test.robolectric.testContext
import mozilla.telemetry.glean.testing.GleanTestRule
import org.junit.Before
@@ -30,7 +28,7 @@ class DefaultMessageControllerTest {
val gleanTestRule = GleanTestRule(testContext)
private val homeActivity: HomeActivity = mockk(relaxed = true)
- private val messagingController: NimbusMessagingController = mockk(relaxed = true)
+ private val messagingController: NimbusMessagingControllerInterface = mockk(relaxed = true)
private lateinit var defaultMessageController: DefaultMessageController
private val appStore: AppStore = mockk(relaxed = true)
@@ -46,12 +44,10 @@ class DefaultMessageControllerTest {
@Test
fun `WHEN calling onMessagePressed THEN process the action intent and update the app store`() {
val message = mockMessage()
- val uri = "action".toUri()
- every { messagingController.processMessageActionToUri(message) }.returns(uri)
defaultMessageController.onMessagePressed(message)
- verify { messagingController.processMessageActionToUri(message) }
+ verify { messagingController.getIntentForMessage(message) }
verify { homeActivity.processIntent(any()) }
verify { appStore.dispatch(MessageClicked(message)) }
}
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingMiddlewareTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingMiddlewareTest.kt
index 9dd968590f84..3fc27ec6e9b4 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingMiddlewareTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingMiddlewareTest.kt
@@ -12,13 +12,13 @@ import kotlinx.coroutines.test.advanceUntilIdle
import mozilla.components.service.nimbus.messaging.Message
import mozilla.components.service.nimbus.messaging.MessageData
import mozilla.components.service.nimbus.messaging.NimbusMessagingController
-import mozilla.components.service.nimbus.messaging.NimbusMessagingStorage
import mozilla.components.service.nimbus.messaging.StyleData
import mozilla.components.support.test.ext.joinBlocking
import mozilla.components.support.test.libstate.ext.waitUntilIdle
import mozilla.components.support.test.rule.MainCoroutineRule
import mozilla.components.support.test.rule.runTestOnMain
import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
@@ -30,20 +30,17 @@ import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageDi
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.Restore
import org.mozilla.fenix.components.appstate.AppState
import org.mozilla.fenix.messaging.FenixMessageSurfaceId
-import org.mozilla.fenix.messaging.FenixNimbusMessagingController
import org.mozilla.fenix.messaging.MessagingState
class MessagingMiddlewareTest {
@get:Rule
val coroutinesTestRule = MainCoroutineRule()
private val coroutineScope = coroutinesTestRule.scope
- private lateinit var messagingStorage: NimbusMessagingStorage
private lateinit var controller: NimbusMessagingController
@Before
fun setUp() {
- messagingStorage = mockk(relaxed = true)
- controller = FenixNimbusMessagingController(messagingStorage) { 0 }
+ controller = mockk(relaxed = true)
}
@Test
@@ -55,12 +52,12 @@ class MessagingMiddlewareTest {
),
),
listOf(
- MessagingMiddleware(messagingStorage, controller, coroutineScope),
+ MessagingMiddleware(controller, coroutineScope),
),
)
val message = createMessage()
- coEvery { messagingStorage.getMessages() } returns listOf(message)
+ coEvery { controller.getMessages() } returns listOf(message)
store.dispatch(Restore).joinBlocking()
store.waitUntilIdle()
@@ -81,12 +78,12 @@ class MessagingMiddlewareTest {
),
),
listOf(
- MessagingMiddleware(messagingStorage, controller, coroutineScope),
+ MessagingMiddleware(controller, coroutineScope),
),
)
every {
- messagingStorage.getNextMessage(
+ controller.getNextMessage(
FenixMessageSurfaceId.HOMESCREEN,
any(),
)
@@ -111,7 +108,7 @@ class MessagingMiddlewareTest {
),
),
listOf(
- MessagingMiddleware(messagingStorage, controller, coroutineScope),
+ MessagingMiddleware(controller, coroutineScope),
),
)
@@ -121,7 +118,7 @@ class MessagingMiddlewareTest {
store.waitUntilIdle()
assertTrue(store.state.messaging.messages.isEmpty())
- coVerify { messagingStorage.updateMetadata(createMetadata(pressed = true)) }
+ coVerify { controller.onMessageClicked(message = message) }
}
@Test
@@ -135,14 +132,14 @@ class MessagingMiddlewareTest {
),
),
listOf(
- MessagingMiddleware(messagingStorage, controller, coroutineScope),
+ MessagingMiddleware(controller, coroutineScope),
),
)
store.dispatch(MessageDismissed(message)).joinBlocking()
store.waitUntilIdle()
assertTrue(store.state.messaging.messages.isEmpty())
- coVerify { messagingStorage.updateMetadata(metadata.copy(dismissed = true)) }
+ coVerify { controller.onMessageDismissed(message = message) }
}
@Test
@@ -158,7 +155,7 @@ class MessagingMiddlewareTest {
),
),
listOf(
- MessagingMiddleware(messagingStorage, controller, coroutineScope),
+ MessagingMiddleware(controller, coroutineScope),
),
)
@@ -184,7 +181,7 @@ class MessagingMiddlewareTest {
),
),
listOf(
- MessagingMiddleware(messagingStorage, controller, coroutineScope),
+ MessagingMiddleware(controller, coroutineScope),
),
)
@@ -198,6 +195,7 @@ class MessagingMiddlewareTest {
@Test
fun `WHEN updateMessage THEN update available messages`() = runTestOnMain {
val message = createMessage()
+ val messageDisplayed = message.copy(metadata = createMetadata(displayCount = 1))
val store = AppStore(
AppState(
messaging = MessagingState(
@@ -207,20 +205,25 @@ class MessagingMiddlewareTest {
),
),
listOf(
- MessagingMiddleware(messagingStorage, controller, coroutineScope),
+ MessagingMiddleware(controller, coroutineScope),
),
)
every {
- messagingStorage.getNextMessage(
+ controller.getNextMessage(
FenixMessageSurfaceId.HOMESCREEN,
any(),
)
} returns message
- store.dispatch(Evaluate(FenixMessageSurfaceId.HOMESCREEN))
+ coEvery {
+ controller.onMessageDisplayed(eq(message), any())
+ } returns messageDisplayed
+
+ store.dispatch(Evaluate(FenixMessageSurfaceId.HOMESCREEN)).joinBlocking()
store.waitUntilIdle()
+ assertEquals(1, store.state.messaging.messages.count())
assertEquals(1, store.state.messaging.messages.first().displayCount)
}
@@ -240,17 +243,21 @@ class MessagingMiddlewareTest {
),
),
listOf(
- MessagingMiddleware(messagingStorage, controller, coroutineScope),
+ MessagingMiddleware(controller, coroutineScope),
),
)
every {
- messagingStorage.getNextMessage(
+ controller.getNextMessage(
FenixMessageSurfaceId.HOMESCREEN,
any(),
)
} returns message1
+ coEvery {
+ controller.onMessageDisplayed(eq(message1), any())
+ } returns messageDisplayed1
+
store.dispatch(Evaluate(FenixMessageSurfaceId.HOMESCREEN)).joinBlocking()
store.waitUntilIdle()
@@ -272,17 +279,21 @@ class MessagingMiddlewareTest {
),
),
listOf(
- MessagingMiddleware(messagingStorage, controller, coroutineScope),
+ MessagingMiddleware(controller, coroutineScope),
),
)
every {
- messagingStorage.getNextMessage(
+ controller.getNextMessage(
FenixMessageSurfaceId.HOMESCREEN,
any(),
)
} returns message
+ coEvery {
+ controller.onMessageDisplayed(eq(message), any())
+ } returns messageDisplayed
+
store.dispatch(Evaluate(FenixMessageSurfaceId.HOMESCREEN)).joinBlocking()
store.waitUntilIdle()
@@ -291,7 +302,11 @@ class MessagingMiddlewareTest {
@Test
fun `GIVEN a message with that surpassed the maxDisplayCount WHEN onMessagedDisplayed THEN remove the message and consume it`() = runTestOnMain {
- val message = createMessage(createMetadata(displayCount = 6))
+ val message = createMessage(createMetadata(displayCount = 4))
+ val messageDisplayed = createMessage(createMetadata(displayCount = 5))
+ assertFalse(message.isExpired)
+ assertTrue(messageDisplayed.isExpired)
+
val store = AppStore(
AppState(
messaging = MessagingState(
@@ -302,17 +317,21 @@ class MessagingMiddlewareTest {
),
),
listOf(
- MessagingMiddleware(messagingStorage, controller, coroutineScope),
+ MessagingMiddleware(controller, coroutineScope),
),
)
every {
- messagingStorage.getNextMessage(
+ controller.getNextMessage(
FenixMessageSurfaceId.HOMESCREEN,
any(),
)
} returns message
+ coEvery {
+ controller.onMessageDisplayed(eq(message), any())
+ } returns messageDisplayed
+
store.dispatch(Evaluate(FenixMessageSurfaceId.HOMESCREEN)).joinBlocking()
store.waitUntilIdle()
@@ -322,7 +341,7 @@ class MessagingMiddlewareTest {
}
private fun createMessage(
metadata: Message.Metadata = createMetadata(),
- messageId: String = "control-id",
+ messageId: String = "message-id",
data: MessageData = mockk(relaxed = true),
action: String = "action",
styleData: StyleData = StyleData(),
From 228e4ea15f9c9f3486a0ad96614e46ef8bd45bd5 Mon Sep 17 00:00:00 2001
From: Roger Yang
Date: Wed, 21 Feb 2024 15:58:48 -0500
Subject: [PATCH 299/586] Bug 1881336 - Remove telemetry probes expiring in
v125
---
fenix/app/metrics.yaml | 19 -----
.../metrics/fonts/FontEnumerationWorker.kt | 72 -------------------
2 files changed, 91 deletions(-)
diff --git a/fenix/app/metrics.yaml b/fenix/app/metrics.yaml
index 636f46ff28c4..546aeea5a0aa 100644
--- a/fenix/app/metrics.yaml
+++ b/fenix/app/metrics.yaml
@@ -2654,25 +2654,6 @@ metrics:
metadata:
tags:
- Experiments
- font_list_json:
- type: text
- lifetime: ping
- description: |
- A JSON blob representing the installed fonts
- send_in_pings:
- - font-list
- bugs:
- - https://bugzilla.mozilla.org/show_bug.cgi?id=1858193
- data_reviews:
- - https://bugzilla.mozilla.org/show_bug.cgi?id=1858193#c2
- data_sensitivity:
- # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this
- # is more like 'technical' (per the Data Review), I'm marking highly sensitive.
- - highly_sensitive
- notification_emails:
- - android-probes@mozilla.com
- - tom@mozilla.com
- expires: 124
customize_home:
most_visited_sites:
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/fonts/FontEnumerationWorker.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/fonts/FontEnumerationWorker.kt
index 7722af20e2bd..afce9acb7e14 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/fonts/FontEnumerationWorker.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/fonts/FontEnumerationWorker.kt
@@ -5,11 +5,9 @@
package org.mozilla.fenix.components.metrics.fonts
import android.content.Context
-import android.content.res.Configuration
import android.graphics.fonts.Font
import android.graphics.fonts.SystemFonts
import android.os.Build
-import android.os.LocaleList
import androidx.work.BackoffPolicy
import androidx.work.CoroutineWorker
import androidx.work.ExistingWorkPolicy
@@ -18,15 +16,10 @@ import androidx.work.WorkManager
import androidx.work.WorkerParameters
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
-import org.json.JSONArray
-import org.json.JSONException
-import org.json.JSONObject
import org.mozilla.fenix.Config
-import org.mozilla.fenix.GleanMetrics.Metrics
import org.mozilla.fenix.GleanMetrics.Pings
import org.mozilla.fenix.ext.settings
import java.io.File
-import java.util.Locale
import java.util.concurrent.TimeUnit
import kotlin.time.Duration.Companion.hours
@@ -40,15 +33,12 @@ class FontEnumerationWorker(
) : CoroutineWorker(context, workerParameters) {
@Suppress("TooGenericExceptionCaught")
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
- val s: String
try {
readAllFonts()
- s = createJSONString()
} catch (e: Exception) {
return@withContext Result.retry()
}
- Metrics.fontListJson.set(s)
Pings.fontList.submit()
// To avoid getting multiple submissions from new installs, set directly
@@ -79,68 +69,6 @@ class FontEnumerationWorker(
}
}
- /**
- * This function creates a single JSON String containing
- * The user's phone information, as well as all the fonts and their information,
- * And the names of files that encountered a parsing error.
- */
- @Throws(JSONException::class)
- fun createJSONString(): String {
- val submission = JSONObject()
-
- run {
- submission.put("submission", kDesiredSubmissions)
- submission.put("brand", Build.BRAND)
- submission.put("device", Build.DEVICE)
- submission.put("hardware", Build.HARDWARE)
- submission.put("manufacturer", Build.MANUFACTURER)
- submission.put("model", Build.MODEL)
- submission.put("product", Build.PRODUCT)
- submission.put("release_version", Build.VERSION.RELEASE)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- submission.put("security_patch", Build.VERSION.SECURITY_PATCH)
- submission.put("base_os", Build.VERSION.BASE_OS)
- } else {
- submission.put("security_patch", "too-low-version")
- submission.put("base_os", "too-low-version")
- }
- val config: Configuration = this.applicationContext.resources.configuration
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- val supportedLocales: LocaleList = LocaleList.getDefault()
- val sb = StringBuilder()
- for (i in 0 until supportedLocales.size()) {
- val locale: Locale = supportedLocales.get(i)
- sb.append(locale.toString())
- sb.append(",")
- }
- submission.put("current_locale", config.locales[0].toString())
- submission.put("all_locales", sb.toString())
- } else {
- @Suppress("DEPRECATION")
- submission.put("current_locale", config.locale.toString())
- submission.put("all_locales", "too-low-version")
- }
- }
-
- val fontArr = JSONArray()
- for (fontDetails in fonts) {
- fontArr.put(fontDetails.toJson())
- }
-
- val errorArr = JSONArray()
- for (error in brokenFonts) {
- val errorObj = JSONObject()
- errorObj.put("path", error.first)
- errorObj.put("hash", error.second)
- errorArr.put(errorObj)
- }
-
- submission.put("fonts", fontArr)
- submission.put("errors", errorArr)
-
- return submission.toString()
- }
-
companion object {
private const val FONT_ENUMERATOR_WORK_NAME = "org.mozilla.fenix.metrics.font.work"
private val HOUR_MILLIS: Long = 1.hours.inWholeMilliseconds
From 7ddba650c512b72d0d1423a0bc038aa156904124 Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Thu, 22 Feb 2024 14:46:51 +0000
Subject: [PATCH 300/586] Update GeckoView (Nightly) to 125.0.20240222103314.
---
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 baa2bc44ae25..6092c4bca925 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 = "125.0.20240221213323"
+ const val version = "125.0.20240222103314"
/**
* GeckoView channel
From baf4505e9ec24962795827b5cec4cdccb81c76fb Mon Sep 17 00:00:00 2001
From: Roger Yang
Date: Wed, 21 Feb 2024 16:22:22 -0500
Subject: [PATCH 301/586] Bug 1881338 - Update telemetry expiry handling in
release checklist
---
docs/contribute/release_checklist.md | 22 ++++++----------------
1 file changed, 6 insertions(+), 16 deletions(-)
diff --git a/docs/contribute/release_checklist.md b/docs/contribute/release_checklist.md
index f58c52b67d4c..05ca2c936973 100644
--- a/docs/contribute/release_checklist.md
+++ b/docs/contribute/release_checklist.md
@@ -112,22 +112,12 @@ Now that we made the Beta cut, we can remove all the unused strings marked moz:r
### [Dev Team] Renew telemetry
-After the Beta cut, another task is to renew/remove all soon to expire telemetry probes. What we're looking for is to create a list of telemetry that will expire in `[nightly_version add 2]`. See [Firefox Release Calendar](https://whattrainisitnow.com/calendar/) for the current Release version. There is a script that will help with finding these soon to expire telemetry.
-
-1. Use the helper in tools folder `python3 data_renewal_generate.py [nightly_version add 2]` to detected and generate files that will help create the following files:
- - `[nightly_version add 2]`_expiry_list.csv
- - `[nightly_version add 2]`_renewal_request.txt
-2. Upload the `[nightly_version add 2]`_expiry_list.csv to Google sheet in this [shared Google Drive](https://drive.google.com/drive/folders/1_ertMvn59eE9JmN721RqOjW6nNtxq9oS?usp=sharing) and contact product to review. For each telemetry listed answer decide for:
- - Renew the metric (Recommendation is to use nightly_version + 12)
- - Choose not to renew (but not delete)
- - Choose to remove the metric
- - Renew the metric and set to never expire (this should only be for business critical metrics)
-3. Note that `metrics.yaml` is also modified. Once the review is over, continue to modify `metrics.yaml` to match the decision made in the Google sheet. Make sure to add the PR link and if the telemetry never expires, add the email of the owner as contact.
-4. File an issue for telemetry renewal so that a patch can target it and assign the issue to Product for increased visibility, as a reminder to to address the expiring metrics. See [issue 28190](https://github.com/mozilla-mobile/fenix/issues/28190) for an example.
-5. Create a PR for review. Modify `[nightly_version add 2]`_renewal_request.txt and paste it to the PR for data review. This comment can be auto-generated using the filled `[nightly_version add 2]`_expiry_list.csv and the `tools/data_renewal_request.py` helper. Copy the filled CSV into the tools directory and run the script to create a `[nightly_version add 2]`_filled_renewal_request.txt file that will contain the text required for data review. Make sure it includes (or add manually if necessary):
- - When will this collection now expire?
- - Why was the initial period of collection insufficient?
-6. Please also check if you're responsible for Focus telemetry renewal.
+After the Beta cut, another task is to remove all soon to expire telemetry probes. What we're looking for is to create a list of telemetry that will expire in `[nightly_version add 1]`. See [Firefox Release Calendar](https://whattrainisitnow.com/calendar/) for the current Release version. There is a script that will help with finding these soon to expire telemetry.
+
+1. Use the helper in tools folder `python3 data_renewal_generate.py [nightly_version add 1]` to detected and generate files that will help create the following files:
+ - `[nightly_version add 1]`_expiry_list.csv
+2. File an issue for removing expired telemetry to address the expired metrics. See [Bug 1881336](https://bugzilla.mozilla.org/show_bug.cgi?id=1881336) for an example.
+3. Remove the expired metrics. See [example](https://github.com/mozilla-mobile/firefox-android/pull/5700).
### Ask for Help
From 3a0cdea53bbc1f29f2cf2ab7192f986dba64c827 Mon Sep 17 00:00:00 2001
From: Ryan VanderMeulen
Date: Wed, 21 Feb 2024 15:07:49 -0500
Subject: [PATCH 302/586] Bug 1881326 - Update Sentry to version 7.4.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 b5e9ec8d3761..5d7ed460b11f 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.3.0"
+ const val sentry = "7.4.0"
const val zxing = "3.5.3"
From 3dcaf533848bdfd992b3a049d57d46aea4318948 Mon Sep 17 00:00:00 2001
From: sarah541
Date: Thu, 22 Feb 2024 11:19:14 -0500
Subject: [PATCH 303/586] Bug 1881561 - Update serp telemetry json dump
---
.../assets/search/search_telemetry_v2.json | 493 +++++++++++-------
1 file changed, 300 insertions(+), 193 deletions(-)
diff --git a/android-components/components/feature/search/src/main/assets/search/search_telemetry_v2.json b/android-components/components/feature/search/src/main/assets/search/search_telemetry_v2.json
index bee1c10b2761..a49d12ebb8cf 100644
--- a/android-components/components/feature/search/src/main/assets/search/search_telemetry_v2.json
+++ b/android-components/components/feature/search/src/main/assets/search/search_telemetry_v2.json
@@ -1,46 +1,18 @@
{
"data": [
{
- "schema": 1698656464939,
- "taggedCodes": [
- "monline_dg",
- "monline_3_dg",
- "monline_4_dg",
- "monline_7_dg"
- ],
- "telemetryId": "baidu",
- "organicCodes": [],
- "codeParamName": "tn",
- "queryParamName": "wd",
- "queryParamNames": [
- "wd",
- "word"
- ],
- "searchPageRegexp": "^https://(?:m|www)\\.baidu\\.com/(?:s|baidu)",
- "followOnParamNames": [
- "oq"
- ],
- "extraAdServersRegexps": [
- "^https?://www\\.baidu\\.com/baidu\\.php?"
- ],
- "id": "19c434a3-d173-4871-9743-290ac92a3f6a",
- "last_modified": 1698666532326
- },
- {
- "schema": 1698656463945,
+ "isSPA": true,
+ "schema": 1707523204491,
"components": [
{
- "type": "ad_carousel",
+ "type": "ad_image_row",
"included": {
"parent": {
- "selector": ".product-ads-carousel"
- },
- "related": {
- "selector": ".snippet__control"
+ "selector": "[data-testid='pam.container']"
},
"children": [
{
- "selector": ".product-ads-carousel__item",
+ "selector": "[data-slide-index]",
"countChildren": true
}
]
@@ -50,14 +22,8 @@
"type": "ad_link",
"included": {
"parent": {
- "selector": ".ad-result"
- },
- "children": [
- {
- "type": "ad_sitelink",
- "selector": ".result__extra-content .deep-links--descriptions"
- }
- ]
+ "selector": "[data-testid='adResult']"
+ }
}
},
{
@@ -65,14 +31,14 @@
"topDown": true,
"included": {
"parent": {
- "selector": "form.search-form"
+ "selector": "._1zdrb._1cR1n"
},
"related": {
- "selector": ".search-form__suggestions"
+ "selector": "#search-suggestions"
},
"children": [
{
- "selector": ".search-form__input, .search-form__submit"
+ "selector": "input[type='search']"
}
]
}
@@ -82,66 +48,83 @@
"default": true
}
],
- "shoppingTab": {
- "regexp": "/shopping?",
- "selector": "nav li[data-test-id='search-navigation-item-shopping'] a"
- },
"taggedCodes": [
- "mzl",
- "813cf1dd",
- "16eeffc4"
+ "brz-moz",
+ "firefoxqwant"
],
- "telemetryId": "ecosia",
+ "telemetryId": "qwant",
"organicCodes": [],
- "codeParamName": "tt",
+ "codeParamName": "client",
"queryParamName": "q",
"queryParamNames": [
"q"
],
- "searchPageRegexp": "^https://www\\.ecosia\\.org/",
- "filter_expression": "env.version|versionCompare(\"110.0a1\")>=0",
- "expectedOrganicCodes": [],
+ "searchPageRegexp": "^https://www\\.qwant\\.com/",
+ "filter_expression": "env.version|versionCompare(\"124.0a1\")>=0",
+ "followOnParamNames": [],
+ "defaultPageQueryParam": {
+ "key": "t",
+ "value": "web"
+ },
"extraAdServersRegexps": [
- "^https://www\\.bing\\.com/acli?c?k"
+ "^https://www\\.bing\\.com/acli?c?k",
+ "^https://api\\.qwant\\.com/v3/r/"
],
- "id": "9a487171-3a06-4647-8866-36250ec84f3a",
- "last_modified": 1698666532324
+ "id": "19c434a3-d173-4871-9743-290ac92a3f6b",
+ "last_modified": 1707833261849
},
{
- "schema": 1698656462833,
+ "schema": 1705948294201,
"components": [
{
"type": "ad_carousel",
"included": {
"parent": {
- "selector": ".adsMvCarousel"
+ "selector": ".pla-exp-container"
},
"related": {
- "selector": ".cr"
+ "selector": "g-right-button, g-left-button, .exp-button"
},
"children": [
{
- "selector": ".pa_item",
+ "selector": "[data-dtld]",
"countChildren": true
}
]
}
},
+ {
+ "type": "refined_search_buttons",
+ "topDown": true,
+ "included": {
+ "parent": {
+ "selector": "#appbar g-scrolling-carousel"
+ },
+ "related": {
+ "selector": "g-right-button, g-left-button"
+ },
+ "children": [
+ {
+ "selector": "a"
+ }
+ ]
+ }
+ },
{
"type": "ad_link",
"excluded": {
"parent": {
- "selector": "aside"
+ "selector": "#rhs"
}
},
"included": {
"parent": {
- "selector": ".sb_adTA"
+ "selector": "[data-text-ad='1']"
},
"children": [
{
"type": "ad_sitelink",
- "selector": ".b_vlist2col"
+ "selector": "[role='list']"
}
]
}
@@ -150,11 +133,11 @@
"type": "ad_sidebar",
"included": {
"parent": {
- "selector": "aside"
+ "selector": "#rhs"
},
"children": [
{
- "selector": ".pa_item, .sb_adTA",
+ "selector": ".pla-unit, .mnr-c",
"countChildren": true
}
]
@@ -165,14 +148,36 @@
"topDown": true,
"included": {
"parent": {
- "selector": "form#sb_form"
+ "selector": "form[role='search']"
},
"related": {
- "selector": "#sw_as"
+ "selector": "div.logo + div + div"
},
"children": [
{
- "selector": "input[name='q']"
+ "selector": "input[type='text']"
+ },
+ {
+ "selector": "textarea[name='q']"
+ }
+ ]
+ }
+ },
+ {
+ "type": "ad_image_row",
+ "excluded": {
+ "parent": {
+ "selector": ".pla-exp-container"
+ }
+ },
+ "included": {
+ "parent": {
+ "selector": ".top-pla-group-inner"
+ },
+ "children": [
+ {
+ "selector": "[data-dtld]",
+ "countChildren": true
}
]
}
@@ -183,59 +188,81 @@
}
],
"shoppingTab": {
- "regexp": "^/shop?",
- "selector": "#b-scopeListItem-shop a"
+ "regexp": "&tbm=shop",
+ "selector": "div[role='navigation'] a",
+ "inspectRegexpInSERP": true
},
"taggedCodes": [
- "MOZ2",
- "MOZ4",
- "MOZ5",
- "MOZA",
- "MOZB",
- "MOZD",
- "MOZE",
- "MOZI",
- "MOZL",
- "MOZM",
- "MOZO",
- "MOZR",
- "MOZT",
- "MOZW",
- "MOZX",
- "MZSL01",
- "MZSL02",
- "MZSL03"
+ "firefox-a",
+ "firefox-b",
+ "firefox-b-1",
+ "firefox-b-ab",
+ "firefox-b-1-ab",
+ "firefox-b-d",
+ "firefox-b-1-d",
+ "firefox-b-e",
+ "firefox-b-1-e",
+ "firefox-b-m",
+ "firefox-b-1-m",
+ "firefox-b-o",
+ "firefox-b-1-o",
+ "firefox-b-lm",
+ "firefox-b-1-lm",
+ "firefox-b-lg",
+ "firefox-b-huawei-h1611",
+ "firefox-b-is-oem1",
+ "firefox-b-oem1",
+ "firefox-b-oem2",
+ "firefox-b-tinno",
+ "firefox-b-pn-wt",
+ "firefox-b-pn-wt-us",
+ "ubuntu",
+ "ubuntu-sn"
],
- "telemetryId": "bing",
+ "telemetryId": "google",
"organicCodes": [],
- "codeParamName": "pc",
+ "codeParamName": "client",
"queryParamName": "q",
- "followOnCookies": [
- {
- "host": "www.bing.com",
- "name": "SRCHS",
- "codeParamName": "PC",
- "extraCodePrefixes": [
- "QBRE"
- ],
- "extraCodeParamName": "form"
- }
- ],
"queryParamNames": [
"q"
],
- "searchPageRegexp": "^https://www\\.bing\\.com/search",
+ "domainExtraction": {
+ "ads": [
+ {
+ "method": "data-attribute",
+ "options": {
+ "dataAttributeKey": "dtld"
+ },
+ "selectors": "[data-dtld]"
+ }
+ ],
+ "nonAds": [
+ {
+ "method": "href",
+ "selectors": "#rso div.g[jscontroller] > div > div > div > div a[data-usg]"
+ }
+ ]
+ },
+ "searchPageRegexp": "^https://www\\.google\\.(?:.+)/search",
"nonAdsLinkRegexps": [
- "^https://www.bing.com/ck/a"
+ "^https?://www\\.google\\.(?:.+)/url?(?:.+)&url="
+ ],
+ "adServerAttributes": [
+ "rw"
+ ],
+ "followOnParamNames": [
+ "oq",
+ "ved",
+ "ei"
],
"extraAdServersRegexps": [
- "^https://www\\.bing\\.com/acli?c?k"
+ "^https?://www\\.google(?:adservices)?\\.com/(?:pagead/)?aclk"
],
- "id": "e1eec461-f1f3-40de-b94b-3b670b78108c",
- "last_modified": 1698666532321
+ "id": "635a3325-1995-42d6-be09-dbe4b2a95453",
+ "last_modified": 1706198445460
},
{
- "schema": 1698656461540,
+ "schema": 1705363206938,
"components": [
{
"type": "ad_carousel",
@@ -337,6 +364,23 @@
"queryParamNames": [
"q"
],
+ "domainExtraction": {
+ "ads": [
+ {
+ "method": "href",
+ "options": {
+ "queryParamKey": "ad_domain"
+ },
+ "selectors": ".products-carousel a.js-carousel-item-title, [data-testid='ad'] a[data-testid='result-title-a']"
+ }
+ ],
+ "nonAds": [
+ {
+ "method": "href",
+ "selectors": "[data-layout='organic'] a[data-testid='result-title-a']"
+ }
+ ]
+ },
"searchPageRegexp": "^https://duckduckgo\\.com/",
"expectedOrganicCodes": [
"h_",
@@ -372,41 +416,131 @@
"^https://www\\.amazon\\.(?:[a-z.]{2,24}).*(?:tag=duckduckgo-)"
],
"id": "9dfd626b-26f2-4913-9d0a-27db6cb7d8ca",
- "last_modified": 1698666532318
+ "last_modified": 1706198445456
+ },
+ {
+ "schema": 1698656464939,
+ "taggedCodes": [
+ "monline_dg",
+ "monline_3_dg",
+ "monline_4_dg",
+ "monline_7_dg"
+ ],
+ "telemetryId": "baidu",
+ "organicCodes": [],
+ "codeParamName": "tn",
+ "queryParamName": "wd",
+ "queryParamNames": [
+ "wd",
+ "word"
+ ],
+ "searchPageRegexp": "^https://(?:m|www)\\.baidu\\.com/(?:s|baidu)",
+ "followOnParamNames": [
+ "oq"
+ ],
+ "extraAdServersRegexps": [
+ "^https?://www\\.baidu\\.com/baidu\\.php?"
+ ],
+ "id": "19c434a3-d173-4871-9743-290ac92a3f6a",
+ "last_modified": 1698666532326
},
{
- "schema": 1698333339811,
+ "schema": 1698656463945,
"components": [
{
"type": "ad_carousel",
"included": {
"parent": {
- "selector": ".pla-exp-container"
+ "selector": ".product-ads-carousel"
},
"related": {
- "selector": "g-right-button, g-left-button, .exp-button"
+ "selector": ".snippet__control"
},
"children": [
{
- "selector": "[data-dtld]",
+ "selector": ".product-ads-carousel__item",
"countChildren": true
}
]
}
},
{
- "type": "refined_search_buttons",
+ "type": "ad_link",
+ "included": {
+ "parent": {
+ "selector": ".ad-result"
+ },
+ "children": [
+ {
+ "type": "ad_sitelink",
+ "selector": ".result__extra-content .deep-links--descriptions"
+ }
+ ]
+ }
+ },
+ {
+ "type": "incontent_searchbox",
"topDown": true,
"included": {
"parent": {
- "selector": "#appbar g-scrolling-carousel"
+ "selector": "form.search-form"
},
"related": {
- "selector": "g-right-button, g-left-button"
+ "selector": ".search-form__suggestions"
},
"children": [
{
- "selector": "a"
+ "selector": ".search-form__input, .search-form__submit"
+ }
+ ]
+ }
+ },
+ {
+ "type": "ad_link",
+ "default": true
+ }
+ ],
+ "shoppingTab": {
+ "regexp": "/shopping?",
+ "selector": "nav li[data-test-id='search-navigation-item-shopping'] a"
+ },
+ "taggedCodes": [
+ "mzl",
+ "813cf1dd",
+ "16eeffc4"
+ ],
+ "telemetryId": "ecosia",
+ "organicCodes": [],
+ "codeParamName": "tt",
+ "queryParamName": "q",
+ "queryParamNames": [
+ "q"
+ ],
+ "searchPageRegexp": "^https://www\\.ecosia\\.org/",
+ "filter_expression": "env.version|versionCompare(\"110.0a1\")>=0",
+ "expectedOrganicCodes": [],
+ "extraAdServersRegexps": [
+ "^https://www\\.bing\\.com/acli?c?k"
+ ],
+ "id": "9a487171-3a06-4647-8866-36250ec84f3a",
+ "last_modified": 1698666532324
+ },
+ {
+ "schema": 1698656462833,
+ "components": [
+ {
+ "type": "ad_carousel",
+ "included": {
+ "parent": {
+ "selector": ".adsMvCarousel"
+ },
+ "related": {
+ "selector": ".cr"
+ },
+ "children": [
+ {
+ "selector": ".pa_item",
+ "countChildren": true
}
]
}
@@ -415,17 +549,17 @@
"type": "ad_link",
"excluded": {
"parent": {
- "selector": "#rhs"
+ "selector": "aside"
}
},
"included": {
"parent": {
- "selector": "[data-text-ad='1']"
+ "selector": ".sb_adTA"
},
"children": [
{
"type": "ad_sitelink",
- "selector": "[role='list']"
+ "selector": ".b_vlist2col"
}
]
}
@@ -434,11 +568,11 @@
"type": "ad_sidebar",
"included": {
"parent": {
- "selector": "#rhs"
+ "selector": "aside"
},
"children": [
{
- "selector": ".pla-unit, .mnr-c",
+ "selector": ".pa_item, .sb_adTA",
"countChildren": true
}
]
@@ -449,36 +583,14 @@
"topDown": true,
"included": {
"parent": {
- "selector": "form[role='search']"
+ "selector": "form#sb_form"
},
"related": {
- "selector": "div.logo + div + div"
- },
- "children": [
- {
- "selector": "input[type='text']"
- },
- {
- "selector": "textarea[name='q']"
- }
- ]
- }
- },
- {
- "type": "ad_image_row",
- "excluded": {
- "parent": {
- "selector": ".pla-exp-container"
- }
- },
- "included": {
- "parent": {
- "selector": ".top-pla-group-inner"
+ "selector": "#sw_as"
},
"children": [
{
- "selector": "[data-dtld]",
- "countChildren": true
+ "selector": "input[name='q']"
}
]
}
@@ -489,62 +601,57 @@
}
],
"shoppingTab": {
- "regexp": "&tbm=shop",
- "selector": "div[role='navigation'] a",
- "inspectRegexpInSERP": true
+ "regexp": "^/shop?",
+ "selector": "#b-scopeListItem-shop a"
},
"taggedCodes": [
- "firefox-a",
- "firefox-b",
- "firefox-b-1",
- "firefox-b-ab",
- "firefox-b-1-ab",
- "firefox-b-d",
- "firefox-b-1-d",
- "firefox-b-e",
- "firefox-b-1-e",
- "firefox-b-m",
- "firefox-b-1-m",
- "firefox-b-o",
- "firefox-b-1-o",
- "firefox-b-lm",
- "firefox-b-1-lm",
- "firefox-b-lg",
- "firefox-b-huawei-h1611",
- "firefox-b-is-oem1",
- "firefox-b-oem1",
- "firefox-b-oem2",
- "firefox-b-tinno",
- "firefox-b-pn-wt",
- "firefox-b-pn-wt-us",
- "ubuntu",
- "ubuntu-sn"
+ "MOZ2",
+ "MOZ4",
+ "MOZ5",
+ "MOZA",
+ "MOZB",
+ "MOZD",
+ "MOZE",
+ "MOZI",
+ "MOZL",
+ "MOZM",
+ "MOZO",
+ "MOZR",
+ "MOZT",
+ "MOZW",
+ "MOZX",
+ "MZSL01",
+ "MZSL02",
+ "MZSL03"
],
- "telemetryId": "google",
+ "telemetryId": "bing",
"organicCodes": [],
- "codeParamName": "client",
+ "codeParamName": "pc",
"queryParamName": "q",
+ "followOnCookies": [
+ {
+ "host": "www.bing.com",
+ "name": "SRCHS",
+ "codeParamName": "PC",
+ "extraCodePrefixes": [
+ "QBRE"
+ ],
+ "extraCodeParamName": "form"
+ }
+ ],
"queryParamNames": [
"q"
],
- "searchPageRegexp": "^https://www\\.google\\.(?:.+)/search",
+ "searchPageRegexp": "^https://www\\.bing\\.com/search",
"nonAdsLinkRegexps": [
- "^https?://www\\.google\\.(?:.+)/url?(?:.+)&url="
- ],
- "adServerAttributes": [
- "rw"
- ],
- "followOnParamNames": [
- "oq",
- "ved",
- "ei"
+ "^https://www.bing.com/ck/a"
],
"extraAdServersRegexps": [
- "^https?://www\\.google(?:adservices)?\\.com/(?:pagead/)?aclk"
+ "^https://www\\.bing\\.com/acli?c?k"
],
- "id": "635a3325-1995-42d6-be09-dbe4b2a95453",
- "last_modified": 1698666532316
+ "id": "e1eec461-f1f3-40de-b94b-3b670b78108c",
+ "last_modified": 1698666532321
}
],
- "timestamp": 1698666532326
+ "timestamp": 1707833261849
}
\ No newline at end of file
From d56e7e6cfd823d34c0b1a75c95c13b6674270863 Mon Sep 17 00:00:00 2001
From: sarah541
Date: Wed, 21 Feb 2024 11:59:19 -0500
Subject: [PATCH 304/586] Bug 1881296 - Add item to release checklist to add
search-telemtry-v2.json dump
m
---
docs/contribute/release_checklist.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/docs/contribute/release_checklist.md b/docs/contribute/release_checklist.md
index 05ca2c936973..6d50615d32fa 100644
--- a/docs/contribute/release_checklist.md
+++ b/docs/contribute/release_checklist.md
@@ -119,6 +119,11 @@ After the Beta cut, another task is to remove all soon to expire telemetry probe
2. File an issue for removing expired telemetry to address the expired metrics. See [Bug 1881336](https://bugzilla.mozilla.org/show_bug.cgi?id=1881336) for an example.
3. Remove the expired metrics. See [example](https://github.com/mozilla-mobile/firefox-android/pull/5700).
+### [Dev Team] Add SERP Telemetry json dump
+
+After the beta cut, another task is to add SERP telemetry json to the [search-telemetry-v2.json](https://github.com/mozilla-mobile/firefox-android/blob/main/android-components/components/feature/search/src/main/assets/search/search_telemetry_v2.json)
+The dump is to be fetched from the desktop telemetry dump located at [desktop-search-telemetry-v2.json](https://searchfox.org/mozilla-central/source/services/settings/dumps/main/search-telemetry-v2.json)
+
### Ask for Help
- Issues related to releases `#releaseduty` on Element
From e50575131b4ca48236ce502c6c3a2f92b03551a6 Mon Sep 17 00:00:00 2001
From: James Hugman
Date: Wed, 31 Jan 2024 13:43:49 +0000
Subject: [PATCH 305/586] =?UTF-8?q?Bug=201880476=20=E2=80=94=20Refactor=20?=
=?UTF-8?q?onMessageDisplayed=20bookkeeping?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../messaging/NimbusMessagingController.kt | 22 +------
.../messaging/NimbusMessagingStorage.kt | 54 ++++++++++++-----
.../NimbusMessagingControllerTest.kt | 59 +++----------------
.../messaging/NimbusMessagingStorageTest.kt | 46 ++++++++++++++-
.../messaging/DefaultMessageControllerTest.kt | 3 +
.../state/MessagingMiddlewareTest.kt | 20 ++++++-
6 files changed, 113 insertions(+), 91 deletions(-)
diff --git a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingController.kt b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingController.kt
index fef964358f17..8408c2faaf75 100644
--- a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingController.kt
+++ b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingController.kt
@@ -6,7 +6,6 @@ package mozilla.components.service.nimbus.messaging
import android.content.Intent
import android.net.Uri
-import androidx.annotation.VisibleForTesting
import androidx.core.net.toUri
import mozilla.components.service.nimbus.GleanMetrics.Messaging as GleanMessaging
@@ -25,35 +24,16 @@ open class NimbusMessagingController(
private val httpActionToDeepLinkUriConverter: (String) -> Uri = { action ->
"$deepLinkScheme://open?url=${Uri.encode(action)}".toUri()
},
- private val now: () -> Long = { System.currentTimeMillis() },
) : NimbusMessagingControllerInterface {
- /**
- * Called when a message is just about to be shown to the user.
- *
- * Update the display count, time shown and boot identifier metadata for the given [message].
- */
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- fun updateMessageAsDisplayed(message: Message, bootIdentifier: String? = null): Message {
- val updatedMetadata = message.metadata.copy(
- displayCount = message.metadata.displayCount + 1,
- lastTimeShown = now(),
- latestBootIdentifier = bootIdentifier,
- )
- return message.copy(
- metadata = updatedMetadata,
- )
- }
-
/**
* Records telemetry and metadata for a newly processed displayed message.
*/
override suspend fun onMessageDisplayed(displayedMessage: Message, bootIdentifier: String?): Message {
sendShownMessageTelemetry(displayedMessage.id)
- val nextMessage = updateMessageAsDisplayed(displayedMessage, bootIdentifier)
+ val nextMessage = messagingStorage.onMessageDisplayed(displayedMessage, bootIdentifier)
if (nextMessage.isExpired) {
sendExpiredMessageTelemetry(nextMessage.id)
}
- messagingStorage.updateMetadata(nextMessage.metadata)
return nextMessage
}
diff --git a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
index ff463104c9c8..d2337bbd595e 100644
--- a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
+++ b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
@@ -41,6 +41,7 @@ class NimbusMessagingStorage(
private val nimbus: NimbusMessagingInterface,
private val messagingFeature: FeatureHolder,
private val attributeProvider: JexlAttributeProvider? = null,
+ private val now: () -> Long = { System.currentTimeMillis() },
) {
/**
* Contains all malformed messages where they key can be the value or a trigger of the message
@@ -179,28 +180,17 @@ class NimbusMessagingStorage(
.filter { !excluded.contains(it.id) }
.firstOrNull { isMessageEligible(it, helper) } ?: return null
- val slug = message.data.experiment
- if (slug != null) {
- // We know that it's experimental, and we know which experiment it came from.
- messagingFeature.recordExperimentExposure(slug)
- } else if (message.data.isControl) {
- // It's not experimental, but it is a control. This is obviously malformed.
- reportMalformedMessage(message.id)
- }
-
// If this is an experimental message, but not a placebo, then just return the message.
if (!message.data.isControl) {
return message
}
- // If a message is a control then it's considered as displayed
- val updatedMetadata = message.metadata.copy(
- displayCount = message.metadata.displayCount + 1,
- lastTimeShown = System.currentTimeMillis(),
- )
-
+ // This is a control message which we're definitely not going to show to anyone,
+ // however, we need to do the bookkeeping and as if we were.
+ //
+ // Since no one is going to see it, then we need to do it ourselves, here.
runBlocking {
- updateMetadata(updatedMetadata)
+ onMessageDisplayed(message)
}
// This is a control, so we need to either return the next message (there may not be one)
@@ -240,6 +230,38 @@ class NimbusMessagingStorage(
Pair(uuid, url)
}
+ /**
+ * Record the time and optional [bootIdentifier] of the display of the given message.
+ *
+ * If the message is part of an experiment, then record an exposure event for that
+ * experiment.
+ *
+ * This is determined by the value in the [message.data.experiment] property.
+ */
+ suspend fun onMessageDisplayed(message: Message, bootIdentifier: String? = null): Message {
+ // Record an exposure event if this is an experimental message.
+ val slug = message.data.experiment
+ if (slug != null) {
+ // We know that it's experimental, and we know which experiment it came from.
+ messagingFeature.recordExperimentExposure(slug)
+ } else if (message.data.isControl) {
+ // It's not experimental, but it is a control. This is obviously malformed.
+ reportMalformedMessage(message.id)
+ }
+
+ // Now update the display counts.
+ val updatedMetadata = message.metadata.copy(
+ displayCount = message.metadata.displayCount + 1,
+ lastTimeShown = now(),
+ latestBootIdentifier = bootIdentifier,
+ )
+ val nextMessage = message.copy(
+ metadata = updatedMetadata,
+ )
+ updateMetadata(nextMessage.metadata)
+ return nextMessage
+ }
+
/**
* Updated the provided [metadata] in the storage.
*/
diff --git a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerTest.kt b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerTest.kt
index ae7053b6f664..be17d6405b47 100644
--- a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerTest.kt
+++ b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerTest.kt
@@ -7,10 +7,10 @@ package mozilla.components.service.nimbus.messaging
import android.content.Intent
import android.net.Uri
import androidx.core.net.toUri
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import mozilla.components.service.glean.testing.GleanTestRule
import mozilla.components.support.test.any
+import mozilla.components.support.test.eq
import mozilla.components.support.test.robolectric.testContext
import mozilla.components.support.test.rule.MainCoroutineRule
import org.junit.Assert.assertEquals
@@ -29,9 +29,6 @@ import org.robolectric.RobolectricTestRunner
import java.util.UUID
import mozilla.components.service.nimbus.GleanMetrics.Messaging as GleanMessaging
-private const val MOCK_TIME_MILLIS = 1000L
-
-@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(RobolectricTestRunner::class)
class NimbusMessagingControllerTest {
@@ -44,60 +41,20 @@ class NimbusMessagingControllerTest {
private val coroutineScope = coroutinesTestRule.scope
private val deepLinkScheme = "deepLinkScheme"
- private val controller = NimbusMessagingController(storage, deepLinkScheme) { MOCK_TIME_MILLIS }
+ private val controller = NimbusMessagingController(storage, deepLinkScheme)
@Before
fun setup() {
NullVariables.instance.setContext(testContext)
}
- @Test
- fun `WHEN calling updateMessageAsDisplayed with message & no boot id THEN metadata for count and lastTimeShown is updated`() =
- coroutineScope.runTest {
- val message = createMessage("id-1")
- assertEquals(0, message.metadata.displayCount)
- assertEquals(0L, message.metadata.lastTimeShown)
- assertNull(message.metadata.latestBootIdentifier)
-
- val expectedMessage = with(message) {
- copy(
- metadata = metadata.copy(
- displayCount = 1,
- lastTimeShown = MOCK_TIME_MILLIS,
- latestBootIdentifier = null,
- ),
- )
- }
-
- assertEquals(expectedMessage, controller.updateMessageAsDisplayed(message))
- }
-
- @Test
- fun `WHEN calling updateMessageAsDisplayed with message & boot id THEN metadata for count, lastTimeShown & latestBootIdentifier is updated`() =
- coroutineScope.runTest {
- val message = createMessage("id-1")
- assertEquals(0, message.metadata.displayCount)
- assertEquals(0L, message.metadata.lastTimeShown)
- assertNull(message.metadata.latestBootIdentifier)
-
- val bootId = "test boot id"
- val expectedMessage = with(message) {
- copy(
- metadata = metadata.copy(
- displayCount = 1,
- lastTimeShown = MOCK_TIME_MILLIS,
- latestBootIdentifier = bootId,
- ),
- )
- }
-
- assertEquals(expectedMessage, controller.updateMessageAsDisplayed(message, bootId))
- }
-
@Test
fun `GIVEN message not expired WHEN calling onMessageDisplayed THEN record a messageShown event and update storage`() =
coroutineScope.runTest {
val message = createMessage("id-1", style = StyleData(maxDisplayCount = 2))
+ val displayedMessage = createMessage("id-1", style = StyleData(maxDisplayCount = 2), displayCount = 1)
+ `when`(storage.onMessageDisplayed(eq(message), any())).thenReturn(displayedMessage)
+
// Assert telemetry is initially null
assertNull(GleanMessaging.messageShown.testGetValue())
assertNull(GleanMessaging.messageExpired.testGetValue())
@@ -113,7 +70,7 @@ class NimbusMessagingControllerTest {
// Expired telemetry
assertNull(GleanMessaging.messageExpired.testGetValue())
- verify(storage).updateMetadata(message.metadata.copy(displayCount = 1, lastTimeShown = MOCK_TIME_MILLIS))
+ verify(storage).onMessageDisplayed(eq(message), any())
}
@Test
@@ -121,6 +78,8 @@ class NimbusMessagingControllerTest {
coroutineScope.runTest {
val message =
createMessage("id-1", style = StyleData(maxDisplayCount = 1), displayCount = 0)
+ val displayedMessage = createMessage("id-1", style = StyleData(maxDisplayCount = 1), displayCount = 1)
+ `when`(storage.onMessageDisplayed(any(), any())).thenReturn(displayedMessage)
// Assert telemetry is initially null
assertNull(GleanMessaging.messageShown.testGetValue())
assertNull(GleanMessaging.messageExpired.testGetValue())
@@ -139,7 +98,7 @@ class NimbusMessagingControllerTest {
assertEquals(1, expiredEvent.size)
assertEquals(message.id, expiredEvent.single().extra!!["message_key"])
- verify(storage).updateMetadata(message.metadata.copy(displayCount = 1, lastTimeShown = MOCK_TIME_MILLIS))
+ verify(storage).onMessageDisplayed(message)
}
@Test
diff --git a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt
index c59736f8f048..08f081e9f185 100644
--- a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt
+++ b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt
@@ -38,6 +38,8 @@ import org.mozilla.experiments.nimbus.internal.FeatureHolder
import org.mozilla.experiments.nimbus.internal.NimbusException
import org.robolectric.RobolectricTestRunner
+private const val MOCK_TIME_MILLIS = 1000L
+
@RunWith(RobolectricTestRunner::class)
@kotlinx.coroutines.ExperimentalCoroutinesApi
class NimbusMessagingStorageTest {
@@ -84,7 +86,7 @@ class NimbusMessagingStorageTest {
reportMalformedMessage,
nimbus,
messagingFeature,
- )
+ ) { MOCK_TIME_MILLIS }
val helper: NimbusMessagingHelperInterface = mock()
`when`(helper.evalJexl(any())).thenReturn(true)
@@ -325,6 +327,44 @@ class NimbusMessagingStorageTest {
verify(metadataStorage).updateMetadata(any())
}
+ @Test
+ fun `WHEN calling onMessageDisplayed with message & boot id THEN metadata for count, lastTimeShown & latestBootIdentifier is updated`() =
+ runTest {
+ val message = storage.getMessage("message-1")!!
+ assertEquals(0, message.displayCount)
+
+ val bootId = "test boot id"
+ val expectedMessage = message.copy(
+ metadata = Message.Metadata(
+ id = "message-1",
+ displayCount = 1,
+ lastTimeShown = MOCK_TIME_MILLIS,
+ latestBootIdentifier = bootId,
+ ),
+ )
+
+ assertEquals(expectedMessage, storage.onMessageDisplayed(message, bootId))
+ }
+
+ @Test
+ fun `WHEN calling onMessageDisplayed with message THEN metadata for count, lastTimeShown is updated`() =
+ runTest {
+ val message = storage.getMessage("message-1")!!
+ assertEquals(0, message.displayCount)
+
+ val bootId = null
+ val expectedMessage = message.copy(
+ metadata = Message.Metadata(
+ id = "message-1",
+ displayCount = 1,
+ lastTimeShown = MOCK_TIME_MILLIS,
+ latestBootIdentifier = bootId,
+ ),
+ )
+
+ assertEquals(expectedMessage, storage.onMessageDisplayed(message, bootId))
+ }
+
@Test
fun `GIVEN a valid action WHEN calling sanitizeAction THEN return the action`() {
val actionsMap = mapOf("action-1" to "action-1-url")
@@ -510,7 +550,7 @@ class NimbusMessagingStorageTest {
}
@Test
- fun `GIVEN a message under experiment WHEN calling getNextMessage THEN call recordExposureEvent`() {
+ fun `GIVEN a message under experiment WHEN calling onMessageDisplayed THEN call recordExposureEvent`() = runTest {
val spiedStorage = spy(storage)
val experiment = "my-experiment"
val messageData: MessageData = createMessageData(isControl = false, experiment = experiment)
@@ -527,7 +567,9 @@ class NimbusMessagingStorageTest {
doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any())
val result = spiedStorage.getNextMessage(HOMESCREEN, listOf(message))
+ verify(featuresInterface, never()).recordExposureEvent("messaging", experiment)
+ spiedStorage.onMessageDisplayed(message)
verify(featuresInterface).recordExposureEvent("messaging", experiment)
assertEquals(message.id, result!!.id)
}
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/messaging/DefaultMessageControllerTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/messaging/DefaultMessageControllerTest.kt
index aeced21c2caf..35d5d8b48804 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/messaging/DefaultMessageControllerTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/messaging/DefaultMessageControllerTest.kt
@@ -4,6 +4,8 @@
package org.mozilla.fenix.messaging
+import android.content.Intent
+import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import mozilla.components.service.nimbus.messaging.Message
@@ -44,6 +46,7 @@ class DefaultMessageControllerTest {
@Test
fun `WHEN calling onMessagePressed THEN process the action intent and update the app store`() {
val message = mockMessage()
+ every { messagingController.getIntentForMessage(message) }.returns(Intent())
defaultMessageController.onMessagePressed(message)
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingMiddlewareTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingMiddlewareTest.kt
index 3fc27ec6e9b4..b4f72cd14afc 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingMiddlewareTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingMiddlewareTest.kt
@@ -232,7 +232,7 @@ class MessagingMiddlewareTest {
val message1 = createMessage()
val message2 = message1.copy(id = "message2", action = "action2")
// An updated message1 that has been displayed once.
- val messageDisplayed1 = message1.copy(metadata = createMetadata(displayCount = 1))
+ val messageDisplayed1 = incrementDisplayCount(message1)
val store = AppStore(
AppState(
messaging = MessagingState(
@@ -253,6 +253,9 @@ class MessagingMiddlewareTest {
any(),
)
} returns message1
+ coEvery {
+ controller.onMessageDisplayed(message1, any())
+ } returns messageDisplayed1
coEvery {
controller.onMessageDisplayed(eq(message1), any())
@@ -269,7 +272,7 @@ class MessagingMiddlewareTest {
fun `GIVEN a message has not surpassed the maxDisplayCount WHEN evaluate THEN update the message displayCount`() = runTestOnMain {
val message = createMessage()
// An updated message that has been displayed once.
- val messageDisplayed = message.copy(metadata = createMetadata(displayCount = 1))
+ val messageDisplayed = incrementDisplayCount(message)
val store = AppStore(
AppState(
messaging = MessagingState(
@@ -289,6 +292,9 @@ class MessagingMiddlewareTest {
any(),
)
} returns message
+ coEvery {
+ controller.onMessageDisplayed(message, any())
+ } returns messageDisplayed
coEvery {
controller.onMessageDisplayed(eq(message), any())
@@ -327,6 +333,9 @@ class MessagingMiddlewareTest {
any(),
)
} returns message
+ coEvery {
+ controller.onMessageDisplayed(message, any())
+ } returns incrementDisplayCount(message)
coEvery {
controller.onMessageDisplayed(eq(message), any())
@@ -363,3 +372,10 @@ private fun createMetadata(
lastTimeShown,
latestBootIdentifier,
)
+
+private fun incrementDisplayCount(message: Message) =
+ message.copy(
+ metadata = createMetadata(
+ displayCount = message.displayCount + 1,
+ ),
+ )
From af453b242d8af209d3a89f66d740bf8eadb540af Mon Sep 17 00:00:00 2001
From: github-actions
Date: Fri, 23 Feb 2024 00:03:13 +0000
Subject: [PATCH 306/586] Import translations from android-l10n
---
.../menu/src/main/res/values-fur/strings.xml | 2 +
.../src/main/res/values-hy-rAM/strings.xml | 2 +
.../menu/src/main/res/values-sl/strings.xml | 2 +
.../src/main/res/values-fur/strings.xml | 20 +-
.../src/main/res/values-hy-rAM/strings.xml | 20 +-
.../addons/src/main/res/values-sl/strings.xml | 2 +
.../media/src/main/res/values-tr/strings.xml | 2 +-
fenix/app/src/main/res/values-azb/strings.xml | 261 ++++++++++++++++++
fenix/app/src/main/res/values-sl/strings.xml | 3 +
fenix/app/src/main/res/values-tr/strings.xml | 2 +-
.../app/src/main/res/values-oc/strings.xml | 8 +-
.../app/src/main/res/values-sl/strings.xml | 8 +-
12 files changed, 310 insertions(+), 22 deletions(-)
diff --git a/android-components/components/browser/menu/src/main/res/values-fur/strings.xml b/android-components/components/browser/menu/src/main/res/values-fur/strings.xml
index a445c4c7ef80..1ce7850e634d 100644
--- a/android-components/components/browser/menu/src/main/res/values-fur/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-fur/strings.xml
@@ -10,4 +10,6 @@
Gjestôr comp. adizionâiNavighe in sù
+
+ Components adizionâi, torne indaûr
diff --git a/android-components/components/browser/menu/src/main/res/values-hy-rAM/strings.xml b/android-components/components/browser/menu/src/main/res/values-hy-rAM/strings.xml
index d45b1b860e58..c8c30cda9522 100644
--- a/android-components/components/browser/menu/src/main/res/values-hy-rAM/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-hy-rAM/strings.xml
@@ -10,4 +10,6 @@
Հավելումների կառավարիչՆավարկել վերև
+
+ Հավելումներ, նավարկեք վերև
diff --git a/android-components/components/browser/menu/src/main/res/values-sl/strings.xml b/android-components/components/browser/menu/src/main/res/values-sl/strings.xml
index 0dc947f3cf7a..440d35ead603 100644
--- a/android-components/components/browser/menu/src/main/res/values-sl/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-sl/strings.xml
@@ -10,4 +10,6 @@
Upravitelj dodatkovPojdi gor
+
+ Dodatki, pomakni se gor
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 dd7b3d5fd757..dc601e337f8d 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
@@ -98,6 +98,8 @@
Permet in navigazion privadeEseguìs in navigazion privade
+
+ No consintût in barcons privâtsAbilitât
@@ -137,13 +139,17 @@
Anule
- Instale component adizionâl
+ Instale component adizionâl
+
+ Instale %1$sAnuleRecensions: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Valutazion: %1$.02f su 5Components adizionâi
@@ -244,10 +250,14 @@
Stât:%1$s al è stât zontât a %2$s
-
- Vierzilu tal menù
+
+ Vierzilu tal menù
+
+ Jentre in %1$s dal menù di %2$s.
+
+ Va ben, capît
- Va ben, capît
+ Va benPlui informazions
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 2b5dec004340..a34c6e28494e 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
@@ -98,6 +98,8 @@
Թույլատրել Գաղտնի դիտարկմամբԱշխատեցնել Գաղտնի դիտարկմամբ
+
+ Թույլատրված չէ գաղտնի պատուհանումՄիացված է
@@ -137,13 +139,17 @@
Չեղարկել
- Տեղադրել հավելումներ
+ Տեղադրել հավելումներ
+
+ Տեղադրել %1$s-ըՉեղարկելԿարծիքներ. %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Վարկանիշ՝ %1$.02f-ը 5-իցՀավելումներ
@@ -244,10 +250,14 @@
Վիճակ.%1$s-ը ավելացվել է %2$s-ում
-
- Բացեք այն ցանկում
+
+ Բացեք այն ցանկում
+
+ Մատչում %1$s-ին %2$s-ի ցանկից։
+
+ Հասկանալի է:
- Հասկանալի է:
+ ԼավԻմանալ ավելին
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 41c8811d9693..fda0a566ea6d 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
@@ -140,6 +140,8 @@
PrekličiNamesti dodatek
+
+ Namesti %1$sPrekliči
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 c137298b46db..b4c583a8311b 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
@@ -19,7 +19,7 @@
- Anımsatıcı: %1$s hâlâ kameranızı kullanıyor. Sekmeyi açmak için dokunun.
+ Anımsatma: %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.
diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml
index 033094275637..39348b26c140 100644
--- a/fenix/app/src/main/res/values-azb/strings.xml
+++ b/fenix/app/src/main/res/values-azb/strings.xml
@@ -923,20 +923,137 @@
آچیق تاغلاریْ اوْتوماتیک باغلا
+
+
+ آچیلیش اکرانیآنایارپاق
+
+ سوْن تاغ
+
+ دؤرد ساعاتلیق حرکتسیزلیکدن سونرا آچیلان اصلی صفحهال ایله باغلاییْنبیر گۆندن سوْنرا باغلایین
+
+ بیر هفته سونرا باغلا
+
+ بیر آی سونرا باغلا
+
+ آنایارپاقدا آچ
+
+ سون تاغدا آچ
+
+ دؤرد ساعاتدان سونرا آنایارپاقدا آچ
+
+
+
+ کؤهنه تاغلاری ایشده اولمایان تاغا آپار
+
+ ایکی هفتهده باخمادیغینیز تاغلار ایشده اولمایان بؤلومه آپاریلیر.
+
قالدیر
+
+ ایشده
+
+
+ %1$s ایمکانی وار هردن بیر آراشدیرمالاری نصب ائلیه و چالیشدیرا.
+
+ آرتیق بیلین
+
+
+ دگیشمهلری یئرینه سالماق اوچون اپلیکیشندن چیخاجاق
+
+ تامام
+
+ لغو
+
+ دگیشمهلری یئرینه سالماق اوچون اپلیکیشندن چیْخیلیر…
+
+
+
+ آچیْق تاغلار
+
+ گیزلی تاغلار
+
+ دؤنگللنمیش تاغلار
+
+ تاغ آرتیر
+
+ گیزلی تاغ آرتیر
+
+ گیزلی
+
+ دؤنگل
+
+ بوتون تاغلاری پایلاش
+
+ سوْن باغلانان تاغلار
+
+ سون باغلانانلار
+
+ حساب تنظیملری
+
+ تاغ تنظیملری
+
+ بوتون تاغلاریْ باغلا
+
+ بوکمارک
+
+ باغلا
+
+
+ سئچیلمیش تاغلاری پایلاش
+
+ سئچیلن تاغلار منوسو
+
+ تاغی مجموعهدن چیخار
+
+ تاغلاری سئچین
+
+ تاغی باغلا
+
+ %s تاغی باغلا
+
+ آچیق تاغلار منوسونو آچ
+
+ تاغلاریْ مجموعهده ساخلاییْن
+
+ مجموعهنی سیل
+
+
+ مجموعهنی یئنیدن آدلاندیْر
+
+ تاغلاریْ آچ
+
+ مجموعه آدیْ
+
+ یئنیدن آدلاندیْر
+
+ قالدیر
+
+ گئچمیشدن سیل
+
+
+ %1$s (گیزلی حالت)
+
+
+
+ آختاریش شرطلرینی گیر
+
+ گئچمیشی سیل
+
+ گئچمیش سیلیندی
+
+ %1$s سیلیندیسیلباغیشلایین، %1$s بو صفحهنی دولدورا بیلمهدی.
+
+ سیْنماق راپورتونو موْزیلایا گؤندر
+
+ تاغی باغلا
+
+ تاغی گئنه آل
+
+
+
+ بو قوْولوغو سیلمک ایستهدیگینیزه آرخایینسیز؟
+
+ %s سئچیلن موریدلری سیلهجک.لغو
+
+ قوْولوق اکله
+
+ بوکمارک ساخلاندی!
+
+ دوزهلیشدوزهلیش
+
+ کوْپی
+
+ پایلاش
+
+
+ یئنی تاغدا آچ
+
+ گیزلی تاغدا آچ
+
+ هامیْسینی یئنی تاغلاردا آچ
+
+ هامیْسینی گیزلی تاغلاردا آچ
+
+ سیل
+
+ ساخلا
+
+ %1$d سئچیلیدی
+
+ بوکمارک دوزهلیشی
+
+ قوْولوق دوزهلیشی
+
+ دؤنگل ائدیلن بوکمارکلاری گؤرمک اوچون اوْتوروُم آچین
+
+ URL
+
+ قوْولوق
+
+ آد
+
+ قوْولوق اکله
+
+ قوْولوق سئچ
+
+
+ بیر عنوان وئرمهلیسیز
+
+ گئچرسیز URL
+
+ هئچ بوکمارک بوردا یوخ
+
+ %1$s سیلیندی
+
+ بوکمارکلار سیلیندی
+
+ سئچیلن قوْولوق سیلینیر
+
+ لغو
+
+
+ آختاریش شرطلرینی گیر
+
+
+
+ تنظیملره گئدین
+
+ یئیین تنظیملر صفحهسی
+
+ توصیه اولموش
+
+ ایجازهلری پوز
+
+ تامام
+
+ لغو
+
+ ایجازهنی پوْز
+
+
+ تامام
+
+ لغو
+
+ بوتون سایتلارداکی ایجازهلری پوْز
+
+ اؤزاؤزونه چالما
+
+
+ کامرا
+
+ میکروفون
+
+ قونوم
+
+ بیلدیریش
+
+ قالیجی ساخلاما
+
+ سایتلار آراسی کوکیلر
+
+ DRM ایله کونترول اولونان موحتوا
+
+
+ ایجازه ایستهیین
+
+ مسدود اوْلوندو
+
+ ایجازه وئریلدی
+
+ اندروید طرفیندن مسدود اوْلوندو
+
+ آیریْ توُتمالار
+
+
+ باغلیْ
+
+ استاندارد
+
+ بَرک
+
+ اؤزل
+
+
+ سس و ویدئویا ایجازه وئر
+
+ سس و ویدئویا ایجازه وئر
+
+
+ سیزین اوچون اؤنملی اولان شئیلری یئغین. \n داها سوْنرا یئیین گیریش اوچون اوْخشار آختاریشلاریْ، سایتلاریْ و تاغلاریْ قروُپلاشدیرین.
+
diff --git a/fenix/app/src/main/res/values-sl/strings.xml b/fenix/app/src/main/res/values-sl/strings.xml
index 91d638d45655..4abd63817401 100644
--- a/fenix/app/src/main/res/values-sl/strings.xml
+++ b/fenix/app/src/main/res/values-sl/strings.xml
@@ -2170,6 +2170,9 @@
Iskalnik %s
+
+
+ Zamenjajte privzeti brskalnikNastavite, 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-tr/strings.xml b/fenix/app/src/main/res/values-tr/strings.xml
index c273ae92ea24..115191558507 100644
--- a/fenix/app/src/main/res/values-tr/strings.xml
+++ b/fenix/app/src/main/res/values-tr/strings.xml
@@ -714,7 +714,7 @@
Son eşitleme: %s
- Son eşitleme: hiç
+ Son eşitleme: yok
- NovetatsParamètresA prepausAjuda
@@ -84,10 +83,9 @@
sharing an URL. -->
Partejar via
-
+ Escafar l’istoric de navegacion ?
+ Tocatz aquesta notificacion o suprimissètz-la per escafar l’istoric de navegacion d’una manièra segura.
+
Netejar l’istoric de navegacion
diff --git a/focus-android/app/src/main/res/values-sl/strings.xml b/focus-android/app/src/main/res/values-sl/strings.xml
index fbe55b1296ca..05647575d723 100644
--- a/focus-android/app/src/main/res/values-sl/strings.xml
+++ b/focus-android/app/src/main/res/values-sl/strings.xml
@@ -53,7 +53,6 @@
Odstrani iz bližnjic
- Kaj je novegaNastavitvePredstavitevPomoč
@@ -84,10 +83,9 @@
sharing an URL. -->
Deli preko
-
+ Izbrišem zgodovino brskanja?
+ Tapnite ali odstranite to obvestilo za varen izbris zgodovine brskanja.
+
Počisti zgodovino brskanja
From 937e94b6cb4f63bd8d138e2780103f9d74ff8401 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Wed, 21 Feb 2024 17:20:49 +0200
Subject: [PATCH 307/586] Bug 1881489 - Add logs to
SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot
---
...MenuLoginsAndPasswordOptionsToSaveRobot.kt | 25 ++++++++++++++++---
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot.kt
index d424ee845df4..f107104f9d3b 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot.kt
@@ -4,6 +4,7 @@
package org.mozilla.fenix.ui.robots
+import android.util.Log
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions.matches
@@ -13,10 +14,10 @@ import androidx.test.espresso.matcher.ViewMatchers.isChecked
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
-import org.hamcrest.CoreMatchers
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.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.itemContainingText
@@ -26,55 +27,71 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
class SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot {
fun verifySaveLoginsOptionsView() {
+ Log.i(TAG, "verifySaveLoginsOptionsView: Trying to verify that the \"Ask to save\" option is visible")
onView(withText("Ask to save"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
-
+ Log.i(TAG, "verifySaveLoginsOptionsView: Verified that the \"Ask to save\" option is visible")
+ Log.i(TAG, "verifySaveLoginsOptionsView: Trying to verify that the \"Never save\" option is visible")
onView(withText("Never save"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
+ Log.i(TAG, "verifySaveLoginsOptionsView: Verified that the \"Never save\" option is visible")
}
fun verifyAskToSaveRadioButton(isChecked: Boolean) {
if (isChecked) {
+ Log.i(TAG, "verifyAskToSaveRadioButton: Trying to verify that the \"Ask to save\" option is checked")
onView(
allOf(
withId(R.id.radio_button),
hasSibling(withText(R.string.preferences_passwords_save_logins_ask_to_save)),
),
).check(matches(isChecked()))
+ Log.i(TAG, "verifyAskToSaveRadioButton: Verified that the \"Ask to save\" option is checked")
} else {
+ Log.i(TAG, "verifyAskToSaveRadioButton: Trying to verify that the \"Ask to save\" option is not checked")
onView(
allOf(
withId(R.id.radio_button),
hasSibling(withText(R.string.preferences_passwords_save_logins_ask_to_save)),
),
).check(matches(not(isChecked())))
+ Log.i(TAG, "verifyAskToSaveRadioButton: Verified that the \"Ask to save\" option is not checked")
}
}
fun verifyNeverSaveSaveRadioButton(isChecked: Boolean) {
if (isChecked) {
+ Log.i(TAG, "verifyNeverSaveSaveRadioButton: Trying to verify that the \"Never save\" option is checked")
onView(
allOf(
withId(R.id.radio_button),
hasSibling(withText(R.string.preferences_passwords_save_logins_never_save)),
),
).check(matches(isChecked()))
+ Log.i(TAG, "verifyNeverSaveSaveRadioButton: Verified that the \"Never save\" option is checked")
} else {
+ Log.i(TAG, "verifyNeverSaveSaveRadioButton: Trying to verify that the \"Never save\" option is not checked")
onView(
allOf(
withId(R.id.radio_button),
hasSibling(withText(R.string.preferences_passwords_save_logins_never_save)),
),
).check(matches(not(isChecked())))
+ Log.i(TAG, "verifyNeverSaveSaveRadioButton: Verified that the \"Never save\" option is not checked")
}
}
- fun clickNeverSaveOption() =
+ fun clickNeverSaveOption() {
+ Log.i(TAG, "clickNeverSaveOption: Trying to click the \"Never save\" option")
itemContainingText(getStringResource(R.string.preferences_passwords_save_logins_never_save)).click()
+ Log.i(TAG, "clickNeverSaveOption: Clicked the \"Never save\" option")
+ }
class Transition {
fun goBack(interact: SettingsSubMenuLoginsAndPasswordRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordRobot.Transition {
+ Log.i(TAG, "goBack: Trying to click the navigate up button")
goBackButton().perform(ViewActions.click())
+ Log.i(TAG, "goBack: Clicked the navigate up button")
SettingsSubMenuLoginsAndPasswordRobot().interact()
return SettingsSubMenuLoginsAndPasswordRobot.Transition()
@@ -83,4 +100,4 @@ class SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot {
}
private fun goBackButton() =
- onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up")))
+ onView(allOf(ViewMatchers.withContentDescription("Navigate up")))
From 174bd77aba335a6165718cc2378e3e7ca704a765 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Wed, 21 Feb 2024 19:43:50 +0200
Subject: [PATCH 308/586] Bug 1881491 - Convert private variables to functions
so they don't get initialised
---
.../SettingsSubMenuLoginsAndPasswordRobot.kt | 38 +++++++++----------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt
index e0cb6d16874a..ea0cfbb71900 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt
@@ -37,12 +37,12 @@ class SettingsSubMenuLoginsAndPasswordRobot {
fun verifyDefaultView() {
mDevice.waitNotNull(Until.findObjects(By.text("Save logins and passwords")), TestAssetHelper.waitingTime)
- saveLoginsAndPasswordButton.check(matches(isDisplayed()))
- autofillInFirefoxOption.check(matches(isDisplayed()))
- autofillInOtherAppsOption.check(matches(isDisplayed()))
- syncLoginsButton.check(matches(isDisplayed()))
- savedLoginsButton.check(matches(isDisplayed()))
- loginExceptionsButton.check(matches(isDisplayed()))
+ saveLoginsAndPasswordButton().check(matches(isDisplayed()))
+ autofillInFirefoxOption().check(matches(isDisplayed()))
+ autofillInOtherAppsOption().check(matches(isDisplayed()))
+ syncLoginsButton().check(matches(isDisplayed()))
+ savedLoginsButton().check(matches(isDisplayed()))
+ loginExceptionsButton().check(matches(isDisplayed()))
}
fun verifyDefaultViewBeforeSyncComplete() {
@@ -55,10 +55,10 @@ class SettingsSubMenuLoginsAndPasswordRobot {
fun verifyDefaultValueAutofillLogins(context: Context) = assertDefaultValueAutofillLogins(context)
- fun clickAutofillInFirefoxOption() = autofillInFirefoxOption.click()
+ fun clickAutofillInFirefoxOption() = autofillInFirefoxOption().click()
fun verifyAutofillInFirefoxToggle(enabled: Boolean) {
- autofillInFirefoxOption
+ autofillInFirefoxOption()
.check(
matches(
hasCousin(
@@ -75,7 +75,7 @@ class SettingsSubMenuLoginsAndPasswordRobot {
)
}
fun verifyAutofillLoginsInOtherAppsToggle(enabled: Boolean) {
- autofillInOtherAppsOption
+ autofillInOtherAppsOption()
.check(
matches(
hasCousin(
@@ -102,28 +102,28 @@ class SettingsSubMenuLoginsAndPasswordRobot {
}
fun openSavedLogins(interact: SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition {
- savedLoginsButton.click()
+ savedLoginsButton().click()
SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot().interact()
return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition()
}
fun openLoginExceptions(interact: SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition {
- loginExceptionsButton.click()
+ loginExceptionsButton().click()
SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot().interact()
return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition()
}
fun openSyncLogins(interact: SettingsTurnOnSyncRobot.() -> Unit): SettingsTurnOnSyncRobot.Transition {
- syncLoginsButton.click()
+ syncLoginsButton().click()
SettingsTurnOnSyncRobot().interact()
return SettingsTurnOnSyncRobot.Transition()
}
fun openSaveLoginsAndPasswordsOptions(interact: SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot.Transition {
- saveLoginsAndPasswordButton.click()
+ saveLoginsAndPasswordButton().click()
SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot().interact()
return SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot.Transition()
@@ -136,13 +136,13 @@ fun settingsSubMenuLoginsAndPassword(interact: SettingsSubMenuLoginsAndPasswordR
return SettingsSubMenuLoginsAndPasswordRobot.Transition()
}
-private val saveLoginsAndPasswordButton = onView(withText("Save logins and passwords"))
+private fun saveLoginsAndPasswordButton() = onView(withText("Save logins and passwords"))
-private val savedLoginsButton = onView(withText("Saved logins"))
+private fun savedLoginsButton() = onView(withText("Saved logins"))
-private val syncLoginsButton = onView(withText("Sync logins across devices"))
+private fun syncLoginsButton() = onView(withText("Sync logins across devices"))
-private val loginExceptionsButton = onView(withText("Exceptions"))
+private fun loginExceptionsButton() = onView(withText("Exceptions"))
private fun goBackButton() =
onView(allOf(ViewMatchers.withContentDescription("Navigate up")))
@@ -157,6 +157,6 @@ private fun assertDefaultValueAutofillLogins(context: Context) = onView(
)
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
-private val autofillInFirefoxOption = onView(withText("Autofill in $appName"))
+private fun autofillInFirefoxOption() = onView(withText("Autofill in $appName"))
-private val autofillInOtherAppsOption = onView(withText("Autofill in other apps"))
+private fun autofillInOtherAppsOption() = onView(withText("Autofill in other apps"))
From 7ec283bfb534920991902f14b1cf8d95038351a2 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Wed, 21 Feb 2024 20:14:16 +0200
Subject: [PATCH 309/586] Bug 1881491 - Add logs to
SettingsSubMenuLoginsAndPasswordRobot
---
.../SettingsSubMenuLoginsAndPasswordRobot.kt | 61 ++++++++++++++-----
1 file changed, 47 insertions(+), 14 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt
index ea0cfbb71900..50695607d9ae 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt
@@ -7,8 +7,9 @@
package org.mozilla.fenix.ui.robots
import android.content.Context
+import android.util.Log
import androidx.test.espresso.Espresso.onView
-import androidx.test.espresso.action.ViewActions
+import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.isChecked
@@ -23,6 +24,7 @@ import androidx.test.uiautomator.Until
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.endsWith
import org.mozilla.fenix.R
+import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestHelper.appName
import org.mozilla.fenix.helpers.TestHelper.hasCousin
@@ -37,12 +39,24 @@ class SettingsSubMenuLoginsAndPasswordRobot {
fun verifyDefaultView() {
mDevice.waitNotNull(Until.findObjects(By.text("Save logins and passwords")), TestAssetHelper.waitingTime)
+ Log.i(TAG, "verifyDefaultView: Trying to verify that the \"Save logins and passwords\" button is displayed")
saveLoginsAndPasswordButton().check(matches(isDisplayed()))
+ Log.i(TAG, "verifyDefaultView: Verified that the \"Save logins and passwords\" button is displayed")
+ Log.i(TAG, "verifyDefaultView: Trying to verify that the Autofill in Firefox option is displayed")
autofillInFirefoxOption().check(matches(isDisplayed()))
+ Log.i(TAG, "verifyDefaultView: Verified that the Autofill in Firefox option is displayed")
+ Log.i(TAG, "verifyDefaultView: Trying to verify that the \"Autofill in other apps\" option is displayed")
autofillInOtherAppsOption().check(matches(isDisplayed()))
+ Log.i(TAG, "verifyDefaultView: Verified that the \"Autofill in other apps\" option is displayed")
+ Log.i(TAG, "verifyDefaultView: Trying to verify that the \"Sync logins across devices\" button is displayed")
syncLoginsButton().check(matches(isDisplayed()))
+ Log.i(TAG, "verifyDefaultView: Verified that the \"Sync logins across devices\" button is displayed")
+ Log.i(TAG, "verifyDefaultView: Trying to verify that the \"Saved logins\" button is displayed")
savedLoginsButton().check(matches(isDisplayed()))
+ Log.i(TAG, "verifyDefaultView: Verified that the \"Saved logins\" button is displayed")
+ Log.i(TAG, "verifyDefaultView: Trying to verify that the \"Exceptions\" button is displayed")
loginExceptionsButton().check(matches(isDisplayed()))
+ Log.i(TAG, "verifyDefaultView: Verified that the \"Exceptions\" button is displayed")
}
fun verifyDefaultViewBeforeSyncComplete() {
@@ -53,11 +67,27 @@ class SettingsSubMenuLoginsAndPasswordRobot {
mDevice.waitNotNull(Until.findObjects(By.text("On")), TestAssetHelper.waitingTime)
}
- fun verifyDefaultValueAutofillLogins(context: Context) = assertDefaultValueAutofillLogins(context)
+ fun verifyDefaultValueAutofillLogins(context: Context) {
+ Log.i(TAG, "verifyDefaultValueAutofillLogins: Trying to verify that the Autofill in Firefox option is displayed")
+ onView(
+ withText(
+ context.getString(
+ R.string.preferences_passwords_autofill2,
+ context.getString(R.string.app_name),
+ ),
+ ),
+ ).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
+ Log.i(TAG, "verifyDefaultValueAutofillLogins: Verified that the Autofill in Firefox option is displayed")
+ }
- fun clickAutofillInFirefoxOption() = autofillInFirefoxOption().click()
+ fun clickAutofillInFirefoxOption() {
+ Log.i(TAG, "clickAutofillInFirefoxOption: Trying to click the Autofill in Firefox option")
+ autofillInFirefoxOption().click()
+ Log.i(TAG, "clickAutofillInFirefoxOption: Clicked the Autofill in Firefox option")
+ }
fun verifyAutofillInFirefoxToggle(enabled: Boolean) {
+ Log.i(TAG, "verifyAutofillInFirefoxToggle: Trying to verify that the Autofill in Firefox toggle is enabled: $enabled")
autofillInFirefoxOption()
.check(
matches(
@@ -73,8 +103,10 @@ class SettingsSubMenuLoginsAndPasswordRobot {
),
),
)
+ Log.i(TAG, "verifyAutofillInFirefoxToggle: Verified that the Autofill in Firefox toggle is enabled: $enabled")
}
fun verifyAutofillLoginsInOtherAppsToggle(enabled: Boolean) {
+ Log.i(TAG, "verifyAutofillLoginsInOtherAppsToggle: Trying to verify that the \"Autofill in other apps\" toggle is enabled: $enabled")
autofillInOtherAppsOption()
.check(
matches(
@@ -90,40 +122,51 @@ class SettingsSubMenuLoginsAndPasswordRobot {
),
),
)
+ Log.i(TAG, "verifyAutofillLoginsInOtherAppsToggle: Verified that the \"Autofill in other apps\" toggle is enabled: $enabled")
}
class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
- goBackButton().perform(ViewActions.click())
+ Log.i(TAG, "goBack: Trying to click the navigate up button")
+ goBackButton().perform(click())
+ Log.i(TAG, "goBack: Clicked the navigate up button")
SettingsRobot().interact()
return SettingsRobot.Transition()
}
fun openSavedLogins(interact: SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition {
+ Log.i(TAG, "openSavedLogins: Trying to click the \"Saved logins\" button")
savedLoginsButton().click()
+ Log.i(TAG, "openSavedLogins: Clicked the \"Saved logins\" button")
SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot().interact()
return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition()
}
fun openLoginExceptions(interact: SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition {
+ Log.i(TAG, "openLoginExceptions: Trying to click the \"Exceptions\" button")
loginExceptionsButton().click()
+ Log.i(TAG, "openLoginExceptions: Clicked the \"Exceptions\" button")
SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot().interact()
return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition()
}
fun openSyncLogins(interact: SettingsTurnOnSyncRobot.() -> Unit): SettingsTurnOnSyncRobot.Transition {
+ Log.i(TAG, "openSyncLogins: Trying to click the \"Sync logins across devices\" button")
syncLoginsButton().click()
+ Log.i(TAG, "openSyncLogins: Clicked the \"Sync logins across devices\" button")
SettingsTurnOnSyncRobot().interact()
return SettingsTurnOnSyncRobot.Transition()
}
fun openSaveLoginsAndPasswordsOptions(interact: SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot.Transition {
+ Log.i(TAG, "openSaveLoginsAndPasswordsOptions: Trying to click the \"Save logins and passwords\" button")
saveLoginsAndPasswordButton().click()
+ Log.i(TAG, "openSaveLoginsAndPasswordsOptions: Clicked the \"Save logins and passwords\" button")
SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot().interact()
return SettingsSubMenuLoginsAndPasswordOptionsToSaveRobot.Transition()
@@ -147,16 +190,6 @@ private fun loginExceptionsButton() = onView(withText("Exceptions"))
private fun goBackButton() =
onView(allOf(ViewMatchers.withContentDescription("Navigate up")))
-private fun assertDefaultValueAutofillLogins(context: Context) = onView(
- ViewMatchers.withText(
- context.getString(
- R.string.preferences_passwords_autofill2,
- context.getString(R.string.app_name),
- ),
- ),
-)
- .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
-
private fun autofillInFirefoxOption() = onView(withText("Autofill in $appName"))
private fun autofillInOtherAppsOption() = onView(withText("Autofill in other apps"))
From 60305a5fd2d579b0c90e3688bbb9200c3abc4ef9 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Thu, 22 Feb 2024 14:13:02 +0200
Subject: [PATCH 310/586] Bug 1881733 - Convert private variables to functions
so they don't get initialised
---
...bMenuLoginsAndPasswordsSavedLoginsRobot.kt | 42 +++++++++----------
1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt
index e358ca9e8835..d668c9727eda 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt
@@ -70,18 +70,18 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
fun verifyAddNewLoginView() {
assertUIObjectExists(
- siteHeader,
- siteTextInput,
- usernameHeader,
- usernameTextInput,
- passwordHeader,
- passwordTextInput,
- siteDescription,
+ siteHeader(),
+ siteTextInput(),
+ usernameHeader(),
+ usernameTextInput(),
+ passwordHeader(),
+ passwordTextInput(),
+ siteDescription(),
)
- siteTextInputHint.check(matches(withHint(R.string.add_login_hostname_hint_text)))
+ siteTextInputHint().check(matches(withHint(R.string.add_login_hostname_hint_text)))
}
- fun enterSiteCredential(website: String) = siteTextInput.setText(website)
+ fun enterSiteCredential(website: String) = siteTextInput().setText(website)
fun verifyHostnameErrorMessage() =
assertUIObjectExists(itemContainingText(getStringResource(R.string.add_login_hostname_invalid_text_2)))
@@ -149,11 +149,11 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
fun clickCancelDeleteLogin() =
onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog()).click()
- fun setNewUserName(userName: String) = usernameTextInput.setText(userName)
+ fun setNewUserName(userName: String) = usernameTextInput().setText(userName)
fun clickClearUserNameButton() = itemWithResId("$packageName:id/clearUsernameTextButton").click()
- fun setNewPassword(password: String) = passwordTextInput.setText(password)
+ fun setNewPassword(password: String) = passwordTextInput().setText(password)
fun clickClearPasswordButton() = itemWithResId("$packageName:id/clearPasswordTextButton").click()
@@ -206,7 +206,7 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
}
fun goToSavedWebsite(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
- openWebsiteButton.click()
+ openWebsiteButton().click()
BrowserRobot().interact()
return BrowserRobot.Transition()
@@ -225,13 +225,13 @@ private fun assertSavedLoginAppears() =
onView(withText("https://accounts.google.com"))
.check(matches(isDisplayed()))
-private val openWebsiteButton = onView(withId(R.id.openWebAddress))
+private fun openWebsiteButton() = onView(withId(R.id.openWebAddress))
-private val siteHeader = itemWithResId("$packageName:id/hostnameHeaderText")
-private val siteTextInput = itemWithResId("$packageName:id/hostnameText")
-private val siteDescription = itemContainingText(getStringResource(R.string.add_login_hostname_invalid_text_3))
-private val siteTextInputHint = onView(withId(R.id.hostnameText))
-private val usernameHeader = itemWithResId("$packageName:id/usernameHeader")
-private val usernameTextInput = itemWithResId("$packageName:id/usernameText")
-private val passwordHeader = itemWithResId("$packageName:id/passwordHeader")
-private val passwordTextInput = itemWithResId("$packageName:id/passwordText")
+private fun siteHeader() = itemWithResId("$packageName:id/hostnameHeaderText")
+private fun siteTextInput() = itemWithResId("$packageName:id/hostnameText")
+private fun siteDescription() = itemContainingText(getStringResource(R.string.add_login_hostname_invalid_text_3))
+private fun siteTextInputHint() = onView(withId(R.id.hostnameText))
+private fun usernameHeader() = itemWithResId("$packageName:id/usernameHeader")
+private fun usernameTextInput() = itemWithResId("$packageName:id/usernameText")
+private fun passwordHeader() = itemWithResId("$packageName:id/passwordHeader")
+private fun passwordTextInput() = itemWithResId("$packageName:id/passwordText")
From 342e231b296f8872d0db76aabe385fbd3c7e1b84 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Thu, 22 Feb 2024 14:42:02 +0200
Subject: [PATCH 311/586] Bug 1881733 - Remove redundant assertion functions
from SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot
---
...sSubMenuLoginsAndPasswordsSavedLoginsRobot.kt | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt
index d668c9727eda..d8b1d9cf6d16 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt
@@ -30,7 +30,6 @@ import org.mozilla.fenix.helpers.MatcherHelper.checkedItemWithResId
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithClassNameAndIndex
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
-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
@@ -42,7 +41,8 @@ import org.mozilla.fenix.helpers.ext.waitNotNull
*/
class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
- fun verifySecurityPromptForLogins() = assertSavedLoginsView()
+ fun verifySecurityPromptForLogins() =
+ onView(withText("Secure your logins and passwords")).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
fun verifyEmptySavedLoginsListView() {
onView(withText(getStringResource(R.string.preferences_passwords_saved_logins_description_empty_text)))
@@ -58,9 +58,9 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
fun verifySavedLoginsAfterSync() {
mDevice.waitNotNull(
Until.findObjects(By.text("https://accounts.google.com")),
- TestAssetHelper.waitingTime,
+ waitingTime,
)
- assertSavedLoginAppears()
+ onView(withText("https://accounts.google.com")).check(matches(isDisplayed()))
}
fun tapSetupLater() = onView(withText("Later")).perform(ViewActions.click())
@@ -217,14 +217,6 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
private fun goBackButton() =
onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up")))
-private fun assertSavedLoginsView() =
- onView(withText("Secure your logins and passwords"))
- .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
-
-private fun assertSavedLoginAppears() =
- onView(withText("https://accounts.google.com"))
- .check(matches(isDisplayed()))
-
private fun openWebsiteButton() = onView(withId(R.id.openWebAddress))
private fun siteHeader() = itemWithResId("$packageName:id/hostnameHeaderText")
From 831c09c810e32d3d18107f5e10c0c76c48fabe84 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Thu, 22 Feb 2024 15:28:07 +0200
Subject: [PATCH 312/586] Bug 1881733 - Add logs to
SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot
---
...bMenuLoginsAndPasswordsSavedLoginsRobot.kt | 170 +++++++++++++++---
1 file changed, 142 insertions(+), 28 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt
index d8b1d9cf6d16..86e985524acd 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt
@@ -4,6 +4,7 @@
package org.mozilla.fenix.ui.robots
+import android.util.Log
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
import androidx.test.espresso.action.ViewActions
@@ -22,6 +23,7 @@ import androidx.test.uiautomator.Until
import org.hamcrest.CoreMatchers
import org.hamcrest.CoreMatchers.containsString
import org.mozilla.fenix.R
+import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper.assertItemIsEnabledAndVisible
@@ -41,18 +43,31 @@ import org.mozilla.fenix.helpers.ext.waitNotNull
*/
class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
- fun verifySecurityPromptForLogins() =
- onView(withText("Secure your logins and passwords")).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
+ fun verifySecurityPromptForLogins() {
+ Log.i(TAG, "verifySecurityPromptForLogins: Trying to verify that the \"Secure your logins and passwords\" dialog is visible")
+ onView(withText("Secure your logins and passwords")).check(
+ matches(
+ withEffectiveVisibility(
+ ViewMatchers.Visibility.VISIBLE,
+ ),
+ ),
+ )
+ Log.i(TAG, "verifySecurityPromptForLogins: Verified that the \"Secure your logins and passwords\" dialog is visible")
+ }
fun verifyEmptySavedLoginsListView() {
+ Log.i(TAG, "verifyEmptySavedLoginsListView: Trying to verify that the saved logins section description is displayed")
onView(withText(getStringResource(R.string.preferences_passwords_saved_logins_description_empty_text)))
.check(matches(isDisplayed()))
-
+ Log.i(TAG, "verifyEmptySavedLoginsListView: Verified that the saved logins section description is displayed")
+ Log.i(TAG, "verifyEmptySavedLoginsListView: Trying to verify that the \"Learn more about Sync\" link is displayed")
onView(withText(R.string.preferences_passwords_saved_logins_description_empty_learn_more_link))
.check(matches(isDisplayed()))
-
+ Log.i(TAG, "verifyEmptySavedLoginsListView: Verified that the \"Learn more about Sync\" link is displayed")
+ Log.i(TAG, "verifyEmptySavedLoginsListView: Trying to verify that the \"Add login\" button is displayed")
onView(withText(R.string.preferences_logins_add_login))
.check(matches(isDisplayed()))
+ Log.i(TAG, "verifyEmptySavedLoginsListView: Verified that the \"Add login\" button is displayed")
}
fun verifySavedLoginsAfterSync() {
@@ -60,13 +75,22 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
Until.findObjects(By.text("https://accounts.google.com")),
waitingTime,
)
+ Log.i(TAG, "verifySavedLoginsAfterSync: Trying to verify that the \"https://accounts.google.comn\" login is displayed")
onView(withText("https://accounts.google.com")).check(matches(isDisplayed()))
+ Log.i(TAG, "verifySavedLoginsAfterSync: Verified that the \"https://accounts.google.comn\" login is displayed")
}
- fun tapSetupLater() = onView(withText("Later")).perform(ViewActions.click())
+ fun tapSetupLater() {
+ Log.i(TAG, "tapSetupLater: Trying to click the \"Later\" dialog button")
+ onView(withText("Later")).perform(ViewActions.click())
+ Log.i(TAG, "tapSetupLater: Clicked the \"Later\" dialog button")
+ }
- fun clickAddLoginButton() =
+ fun clickAddLoginButton() {
+ Log.i(TAG, "clickAddLoginButton: Trying to click the \"Add login\" button")
itemContainingText(getStringResource(R.string.preferences_logins_add_login)).click()
+ Log.i(TAG, "clickAddLoginButton: Clicked the \"Add login\" button")
+ }
fun verifyAddNewLoginView() {
assertUIObjectExists(
@@ -78,10 +102,16 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
passwordTextInput(),
siteDescription(),
)
+ Log.i(TAG, "verifyAddNewLoginView: Trying to verify the \"https://www.example.com\" site text box hint")
siteTextInputHint().check(matches(withHint(R.string.add_login_hostname_hint_text)))
+ Log.i(TAG, "verifyAddNewLoginView: Verified the \"https://www.example.com\" site text box hint")
}
- fun enterSiteCredential(website: String) = siteTextInput().setText(website)
+ fun enterSiteCredential(website: String) {
+ Log.i(TAG, "enterSiteCredential: Trying to set the \"Site\" text box text to: $website")
+ siteTextInput().setText(website)
+ Log.i(TAG, "enterSiteCredential: The \"Site\" text box text was set to: $website")
+ }
fun verifyHostnameErrorMessage() =
assertUIObjectExists(itemContainingText(getStringResource(R.string.add_login_hostname_invalid_text_2)))
@@ -95,17 +125,28 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
fun verifyHostnameClearButtonEnabled() =
assertItemIsEnabledAndVisible(itemWithResId("$packageName:id/clearHostnameTextButton"))
- fun clickSearchLoginButton() = itemWithResId("$packageName:id/search").click()
+ fun clickSearchLoginButton() {
+ Log.i(TAG, "clickSearchLoginButton: Trying to click the search logins button")
+ itemWithResId("$packageName:id/search").click()
+ Log.i(TAG, "clickSearchLoginButton: Clicked the search logins button")
+ }
- fun clickSavedLoginsChevronIcon() = itemWithResId("$packageName:id/toolbar_chevron_icon").click()
+ fun clickSavedLoginsChevronIcon() {
+ Log.i(TAG, "clickSavedLoginsChevronIcon: Trying to click the \"Saved logins\" chevron button")
+ itemWithResId("$packageName:id/toolbar_chevron_icon").click()
+ Log.i(TAG, "clickSavedLoginsChevronIcon: Clicked the \"Saved logins\" chevron button")
+ }
fun verifyLoginsSortingOptions() {
assertUIObjectExists(itemContainingText(getStringResource(R.string.saved_logins_sort_strategy_alphabetically)))
assertUIObjectExists(itemContainingText(getStringResource(R.string.saved_logins_sort_strategy_last_used)))
}
- fun clickLastUsedSortingOption() =
+ fun clickLastUsedSortingOption() {
+ Log.i(TAG, "clickLastUsedSortingOption: Trying to click the \"Last used\" sorting option")
itemContainingText(getStringResource(R.string.saved_logins_sort_strategy_last_used)).click()
+ Log.i(TAG, "clickLastUsedSortingOption: Clicked the \"Last used\" sorting option")
+ }
fun verifySortedLogin(position: Int, loginTitle: String) =
assertUIObjectExists(
@@ -117,47 +158,99 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
),
)
- fun searchLogin(searchTerm: String) =
+ fun searchLogin(searchTerm: String) {
+ Log.i(TAG, "searchLogin: Trying to set the search bar text to: $searchTerm")
itemWithResId("$packageName:id/search").setText(searchTerm)
+ Log.i(TAG, "searchLogin: Search bar text was set to: $searchTerm")
+ }
fun verifySavedLoginsSectionUsername(username: String) =
mDevice.waitNotNull(Until.findObjects(By.text(username)))
fun verifyLoginItemUsername(username: String) = assertUIObjectExists(itemContainingText(username))
- fun verifyNotSavedLoginFromPrompt() = onView(withText("test@example.com"))
- .check(ViewAssertions.doesNotExist())
+ fun verifyNotSavedLoginFromPrompt() {
+ Log.i(TAG, "verifyNotSavedLoginFromPrompt: Trying to verify that \"test@example.com\" does not exist in the saved logins list")
+ onView(withText("test@example.com"))
+ .check(ViewAssertions.doesNotExist())
+ Log.i(TAG, "verifyNotSavedLoginFromPrompt: Verified that \"test@example.com\" does not exist in the saved logins list")
+ }
- fun verifyLocalhostExceptionAdded() = onView(withText(containsString("localhost")))
- .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
+ fun verifyLocalhostExceptionAdded() {
+ Log.i(TAG, "verifyLocalhostExceptionAdded: Trying to verify that \"localhost\" is visible in the exceptions list")
+ onView(withText(containsString("localhost")))
+ .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
+ Log.i(TAG, "verifyLocalhostExceptionAdded: Verified that \"localhost\" is visible in the exceptions list")
+ }
- fun viewSavedLoginDetails(loginUserName: String) = onView(withText(loginUserName)).click()
+ fun viewSavedLoginDetails(loginUserName: String) {
+ Log.i(TAG, "viewSavedLoginDetails: Trying to click $loginUserName saved login")
+ onView(withText(loginUserName)).click()
+ Log.i(TAG, "viewSavedLoginDetails: Clicked $loginUserName saved login")
+ }
- fun clickThreeDotButton(activityTestRule: HomeActivityIntentTestRule) =
+ fun clickThreeDotButton(activityTestRule: HomeActivityIntentTestRule) {
+ Log.i(TAG, "clickThreeDotButton: Trying to click the three dot button")
openActionBarOverflowOrOptionsMenu(activityTestRule.activity)
+ Log.i(TAG, "clickThreeDotButton: Clicked the three dot button")
+ }
- fun clickEditLoginButton() = itemContainingText("Edit").click()
+ fun clickEditLoginButton() {
+ Log.i(TAG, "clickEditLoginButton: Trying to click the \"Edit\" button")
+ itemContainingText("Edit").click()
+ Log.i(TAG, "clickEditLoginButton: Clicked the \"Edit\" button")
+ }
- fun clickDeleteLoginButton() = itemContainingText("Delete").click()
+ fun clickDeleteLoginButton() {
+ Log.i(TAG, "clickDeleteLoginButton: Trying to click the \"Delete\" button")
+ itemContainingText("Delete").click()
+ Log.i(TAG, "clickDeleteLoginButton: Clicked the \"Delete\" button")
+ }
fun verifyLoginDeletionPrompt() =
assertUIObjectExists(itemContainingText(getStringResource(R.string.login_deletion_confirmation)))
- fun clickConfirmDeleteLogin() =
+ fun clickConfirmDeleteLogin() {
+ Log.i(TAG, "clickConfirmDeleteLogin: Trying to click the \"Delete\" dialog button")
onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog()).click()
+ Log.i(TAG, "clickConfirmDeleteLogin: Clicked the \"Delete\" dialog button")
+ }
- fun clickCancelDeleteLogin() =
+ fun clickCancelDeleteLogin() {
+ Log.i(TAG, "clickCancelDeleteLogin: Trying to click the \"Cancel\" dialog button")
onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog()).click()
+ Log.i(TAG, "clickCancelDeleteLogin: Clicked the \"Cancel\" dialog button")
+ }
- fun setNewUserName(userName: String) = usernameTextInput().setText(userName)
+ fun setNewUserName(userName: String) {
+ Log.i(TAG, "setNewUserName: Trying to set \"Username\" text box to: $userName")
+ usernameTextInput().setText(userName)
+ Log.i(TAG, "setNewUserName: \"Username\" text box was set to: $userName")
+ }
- fun clickClearUserNameButton() = itemWithResId("$packageName:id/clearUsernameTextButton").click()
+ fun clickClearUserNameButton() {
+ Log.i(TAG, "clickClearUserNameButton: Trying to click the clear username button")
+ itemWithResId("$packageName:id/clearUsernameTextButton").click()
+ Log.i(TAG, "clickClearUserNameButton: Clicked the clear username button")
+ }
- fun setNewPassword(password: String) = passwordTextInput().setText(password)
+ fun setNewPassword(password: String) {
+ Log.i(TAG, "setNewPassword: Trying to set \"Password\" text box to: $password")
+ passwordTextInput().setText(password)
+ Log.i(TAG, "setNewPassword: \"Password\" text box was set to: $password")
+ }
- fun clickClearPasswordButton() = itemWithResId("$packageName:id/clearPasswordTextButton").click()
+ fun clickClearPasswordButton() {
+ Log.i(TAG, "clickClearPasswordButton: Trying to click the clear password button")
+ itemWithResId("$packageName:id/clearPasswordTextButton").click()
+ Log.i(TAG, "clickClearPasswordButton: Clicked the clear password button")
+ }
- fun saveEditedLogin() = itemWithResId("$packageName:id/save_login_button").click()
+ fun saveEditedLogin() {
+ Log.i(TAG, "saveEditedLogin: Trying to click the toolbar save button")
+ itemWithResId("$packageName:id/save_login_button").click()
+ Log.i(TAG, "saveEditedLogin: Clicked the toolbar save button")
+ }
fun verifySaveLoginButtonIsEnabled(isEnabled: Boolean) =
assertUIObjectExists(
@@ -165,10 +258,17 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
exists = isEnabled,
)
- fun revealPassword() = onView(withId(R.id.revealPasswordButton)).click()
+ fun revealPassword() {
+ Log.i(TAG, "revealPassword: Trying to click the reveal password button")
+ onView(withId(R.id.revealPasswordButton)).click()
+ Log.i(TAG, "revealPassword: Clicked the reveal password button")
+ }
- fun verifyPasswordSaved(password: String) =
+ fun verifyPasswordSaved(password: String) {
+ Log.i(TAG, "verifyPasswordSaved: Trying to verify that the \"Password\" text box is set to $password")
onView(withId(R.id.passwordText)).check(matches(withText(password)))
+ Log.i(TAG, "verifyPasswordSaved: Verified that the \"Password\" text box is set to $password")
+ }
fun verifyUserNameRequiredErrorMessage() =
assertUIObjectExists(itemContainingText(getStringResource(R.string.saved_login_username_required)))
@@ -180,33 +280,47 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
fun clickCopyUserNameButton() =
itemWithResId("$packageName:id/copyUsername").also {
+ Log.i(TAG, "clickCopyUserNameButton: Waiting for $waitingTime ms for the copy username button to exist")
it.waitForExists(waitingTime)
+ Log.i(TAG, "clickCopyUserNameButton: Waited for $waitingTime ms for the copy username button to exist")
+ Log.i(TAG, "clickCopyUserNameButton:Trying to click the copy username button")
it.click()
+ Log.i(TAG, "clickCopyUserNameButton:Clicked the copy username button")
}
fun clickCopyPasswordButton() =
itemWithResId("$packageName:id/copyPassword").also {
+ Log.i(TAG, "clickCopyPasswordButton: Waiting for $waitingTime ms for the copy password button to exist")
it.waitForExists(waitingTime)
+ Log.i(TAG, "clickCopyPasswordButton: Waited for $waitingTime ms for the copy password button to exist")
+ Log.i(TAG, "clickCopyPasswordButton:Trying to click the copy password button")
it.click()
+ Log.i(TAG, "clickCopyPasswordButton:Clicked the copy password button")
}
class Transition {
fun goBack(interact: SettingsSubMenuLoginsAndPasswordRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordRobot.Transition {
+ Log.i(TAG, "goBack: Trying to click the navigate up button")
goBackButton().perform(ViewActions.click())
+ Log.i(TAG, "goBack: Clicked the navigate up button")
SettingsSubMenuLoginsAndPasswordRobot().interact()
return SettingsSubMenuLoginsAndPasswordRobot.Transition()
}
fun goBackToSavedLogins(interact: SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition {
+ Log.i(TAG, "goBackToSavedLogins: Trying to click the navigate up button")
goBackButton().perform(ViewActions.click())
+ Log.i(TAG, "goBackToSavedLogins: Clicked the navigate up button")
SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot().interact()
return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition()
}
fun goToSavedWebsite(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
+ Log.i(TAG, "goToSavedWebsite: Trying to click the open web site button")
openWebsiteButton().click()
+ Log.i(TAG, "goToSavedWebsite: Clicked the open web site button")
BrowserRobot().interact()
return BrowserRobot.Transition()
From eb211b4d54be2be350350bf8b39226126e5de472 Mon Sep 17 00:00:00 2001
From: Ryan VanderMeulen
Date: Wed, 21 Feb 2024 17:21:35 -0500
Subject: [PATCH 313/586] Bug 1881347 - Update Compose Compiler to version
1.5.10
---
.../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 5d7ed460b11f..942ef23867c2 100644
--- a/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt
+++ b/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt
@@ -52,7 +52,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_compiler = "1.5.9"
+ const val compose_compiler = "1.5.10"
object AndroidX {
const val activityCompose = "1.7.2"
From 11821d557bdbbc6bf39c7b565cd910b971dc230e Mon Sep 17 00:00:00 2001
From: Alexandru2909
Date: Tue, 13 Jun 2023 10:53:52 +0300
Subject: [PATCH 314/586] Bug 1804636 - Allow search terms to be refined in
content
---
.../engine/gecko/GeckoEngineSession.kt | 3 +-
.../engine/gecko/GeckoEngineSessionTest.kt | 45 +++++++++-------
.../browser/engine/system/SystemEngineView.kt | 4 +-
.../engine/system/SystemEngineViewTest.kt | 9 +++-
.../browser/state/action/BrowserAction.kt | 6 ++-
.../browser/state/engine/EngineObserver.kt | 4 +-
.../state/reducer/ContentStateReducer.kt | 5 ++
.../browser/state/action/ContentActionTest.kt | 22 ++++++++
.../state/engine/EngineObserverTest.kt | 53 +++++++++++++------
.../concept/engine/EngineSession.kt | 2 +-
.../concept/engine/EngineSessionTest.kt | 50 ++++++++---------
android-components/config/detekt-baseline.xml | 3 +-
.../dependencies/src/main/java/Gecko.kt | 2 +-
docs/changelog.md | 3 ++
14 files changed, 138 insertions(+), 73 deletions(-)
diff --git a/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt b/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt
index 92eb0c0658c7..e6907c6ddec6 100644
--- a/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt
+++ b/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt
@@ -1107,6 +1107,7 @@ class GeckoEngineSession(
session: GeckoSession,
url: String?,
geckoPermissions: List,
+ hasUserGesture: Boolean,
) {
this@GeckoEngineSession.geckoPermissions = geckoPermissions
if (url == null) {
@@ -1140,7 +1141,7 @@ class GeckoEngineSession(
}
// Reset the status of current page being product or not when user navigates away.
notifyObservers { onProductUrlChange(false) }
- notifyObservers { onLocationChange(url) }
+ notifyObservers { onLocationChange(url, hasUserGesture) }
}
override fun onLoadRequest(
diff --git a/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineSessionTest.kt b/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineSessionTest.kt
index 687c4298db79..87849440b60c 100644
--- a/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineSessionTest.kt
+++ b/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineSessionTest.kt
@@ -298,13 +298,17 @@ class GeckoEngineSessionTest {
val engineSession = GeckoEngineSession(runtime, geckoSessionProvider = geckoSessionProvider)
var observedUrl = ""
+ var observedUserGesture = true
var observedCanGoBack = false
var observedCanGoForward = false
var cookieBanner = CookieBannerHandlingStatus.HANDLED
var displaysProduct = false
engineSession.register(
object : EngineSession.Observer {
- override fun onLocationChange(url: String) { observedUrl = url }
+ override fun onLocationChange(url: String, hasUserGesture: Boolean) {
+ observedUrl = url
+ observedUserGesture = hasUserGesture
+ }
override fun onNavigationStateChange(canGoBack: Boolean?, canGoForward: Boolean?) {
canGoBack?.let { observedCanGoBack = canGoBack }
canGoForward?.let { observedCanGoForward = canGoForward }
@@ -320,8 +324,9 @@ class GeckoEngineSessionTest {
captureDelegates()
- navigationDelegate.value.onLocationChange(mock(), "http://mozilla.org", emptyList())
+ navigationDelegate.value.onLocationChange(mock(), "http://mozilla.org", emptyList(), false)
assertEquals("http://mozilla.org", observedUrl)
+ assertEquals(false, observedUserGesture)
assertEquals(CookieBannerHandlingStatus.NO_DETECTED, cookieBanner)
// TO DO: add a positive test case after a test endpoint is implemented in desktop (Bug 1846341)
assertEquals(false, displaysProduct)
@@ -858,22 +863,22 @@ class GeckoEngineSessionTest {
var observedUrl = ""
engineSession.register(
object : EngineSession.Observer {
- override fun onLocationChange(url: String) { observedUrl = url }
+ override fun onLocationChange(url: String, hasUserGesture: Boolean) { observedUrl = url }
},
)
captureDelegates()
- navigationDelegate.value.onLocationChange(mock(), "about:blank", emptyList())
+ navigationDelegate.value.onLocationChange(mock(), "about:blank", emptyList(), false)
assertEquals("", observedUrl)
- navigationDelegate.value.onLocationChange(mock(), "about:blank", emptyList())
+ navigationDelegate.value.onLocationChange(mock(), "about:blank", emptyList(), false)
assertEquals("", observedUrl)
- navigationDelegate.value.onLocationChange(mock(), "https://www.mozilla.org", emptyList())
+ navigationDelegate.value.onLocationChange(mock(), "https://www.mozilla.org", emptyList(), false)
assertEquals("https://www.mozilla.org", observedUrl)
- navigationDelegate.value.onLocationChange(mock(), "about:blank", emptyList())
+ navigationDelegate.value.onLocationChange(mock(), "about:blank", emptyList(), false)
assertEquals("about:blank", observedUrl)
}
@@ -883,7 +888,7 @@ class GeckoEngineSessionTest {
captureDelegates()
assertTrue(session.initialLoad)
- navigationDelegate.value.onLocationChange(mock(), "https://mozilla.org", emptyList())
+ navigationDelegate.value.onLocationChange(mock(), "https://mozilla.org", emptyList(), false)
assertFalse(session.initialLoad)
navigationDelegate.value.onLoadRequest(mock(), mockLoadRequest("moz-extension://1234-test"))
@@ -892,16 +897,16 @@ class GeckoEngineSessionTest {
var observedUrl = ""
session.register(
object : EngineSession.Observer {
- override fun onLocationChange(url: String) { observedUrl = url }
+ override fun onLocationChange(url: String, hasUserGesture: Boolean) { observedUrl = url }
},
)
- navigationDelegate.value.onLocationChange(mock(), "about:blank", emptyList())
+ navigationDelegate.value.onLocationChange(mock(), "about:blank", emptyList(), false)
assertEquals("", observedUrl)
- navigationDelegate.value.onLocationChange(mock(), "https://www.mozilla.org", emptyList())
+ navigationDelegate.value.onLocationChange(mock(), "https://www.mozilla.org", emptyList(), false)
assertEquals("https://www.mozilla.org", observedUrl)
- navigationDelegate.value.onLocationChange(mock(), "about:blank", emptyList())
+ navigationDelegate.value.onLocationChange(mock(), "about:blank", emptyList(), false)
assertEquals("about:blank", observedUrl)
}
@@ -931,10 +936,10 @@ class GeckoEngineSessionTest {
geckoResult.complete(true)
assertNull(engineSession.currentUrl)
- navigationDelegate.value.onLocationChange(geckoSession, "https://www.mozilla.org", emptyList())
+ navigationDelegate.value.onLocationChange(geckoSession, "https://www.mozilla.org", emptyList(), false)
assertEquals("https://www.mozilla.org", engineSession.currentUrl)
- navigationDelegate.value.onLocationChange(geckoSession, "https://www.firefox.com", emptyList())
+ navigationDelegate.value.onLocationChange(geckoSession, "https://www.firefox.com", emptyList(), false)
assertEquals("https://www.firefox.com", engineSession.currentUrl)
}
@@ -944,7 +949,7 @@ class GeckoEngineSessionTest {
captureDelegates()
- navigationDelegate.value.onLocationChange(geckoSession, "https://www.mozilla.org", listOf(mock()))
+ navigationDelegate.value.onLocationChange(geckoSession, "https://www.mozilla.org", listOf(mock()), false)
assertTrue(engineSession.geckoPermissions.isNotEmpty())
}
@@ -955,7 +960,7 @@ class GeckoEngineSessionTest {
captureDelegates()
- navigationDelegate.value.onLocationChange(geckoSession, null, listOf(mock()))
+ navigationDelegate.value.onLocationChange(geckoSession, null, listOf(mock()), false)
assertTrue(engineSession.geckoPermissions.isNotEmpty())
}
@@ -981,7 +986,7 @@ class GeckoEngineSessionTest {
verify(historyTrackingDelegate, never()).onTitleChanged(anyString(), anyString())
// This sets the currentUrl.
- navigationDelegate.value.onLocationChange(geckoSession, "https://www.mozilla.com", emptyList())
+ navigationDelegate.value.onLocationChange(geckoSession, "https://www.mozilla.com", emptyList(), false)
contentDelegate.value.onTitleChange(geckoSession, "Hello World!")
verify(historyTrackingDelegate).onTitleChanged(eq("https://www.mozilla.com"), eq("Hello World!"))
@@ -1038,7 +1043,7 @@ class GeckoEngineSessionTest {
engineSession.register(
object : EngineSession.Observer {
- override fun onLocationChange(url: String) { observedUrl = url }
+ override fun onLocationChange(url: String, hasUserGesture: Boolean) { observedUrl = url }
override fun onTitleChange(title: String) { observedTitle = title }
},
)
@@ -1072,7 +1077,7 @@ class GeckoEngineSessionTest {
),
)
- navigationDelegate.value.onLocationChange(geckoSession, emptyPageUrl, emptyList())
+ navigationDelegate.value.onLocationChange(geckoSession, emptyPageUrl, emptyList(), false)
contentDelegate.value.onTitleChange(geckoSession, emptyPageUrl)
historyDelegate.value.onVisited(
@@ -1112,7 +1117,7 @@ class GeckoEngineSessionTest {
verify(historyTrackingDelegate, never()).onPreviewImageChange(anyString(), anyString())
// This sets the currentUrl.
- navigationDelegate.value.onLocationChange(geckoSession, "https://www.mozilla.com", emptyList())
+ navigationDelegate.value.onLocationChange(geckoSession, "https://www.mozilla.com", emptyList(), false)
contentDelegate.value.onPreviewImage(geckoSession, previewImageUrl)
verify(historyTrackingDelegate).onPreviewImageChange(eq("https://www.mozilla.com"), eq(previewImageUrl))
diff --git a/android-components/components/browser/engine-system/src/main/java/mozilla/components/browser/engine/system/SystemEngineView.kt b/android-components/components/browser/engine-system/src/main/java/mozilla/components/browser/engine/system/SystemEngineView.kt
index d4339c101fc8..d0a5a6af8ede 100644
--- a/android-components/components/browser/engine-system/src/main/java/mozilla/components/browser/engine/system/SystemEngineView.kt
+++ b/android-components/components/browser/engine-system/src/main/java/mozilla/components/browser/engine/system/SystemEngineView.kt
@@ -169,7 +169,7 @@ class SystemEngineView @JvmOverloads constructor(
session?.currentUrl = url
session?.internalNotifyObservers {
onLoadingStateChange(true)
- onLocationChange(it)
+ onLocationChange(it, false)
onNavigationStateChange(view.canGoBack(), view.canGoForward())
}
}
@@ -179,7 +179,7 @@ class SystemEngineView @JvmOverloads constructor(
url?.let {
val cert = view?.certificate
session?.internalNotifyObservers {
- onLocationChange(it)
+ onLocationChange(it, false)
onLoadingStateChange(false)
onSecurityChange(
secure = cert != null,
diff --git a/android-components/components/browser/engine-system/src/test/java/mozilla/components/browser/engine/system/SystemEngineViewTest.kt b/android-components/components/browser/engine-system/src/test/java/mozilla/components/browser/engine/system/SystemEngineViewTest.kt
index 4b0fe4a329ed..95cfbd225351 100644
--- a/android-components/components/browser/engine-system/src/test/java/mozilla/components/browser/engine/system/SystemEngineViewTest.kt
+++ b/android-components/components/browser/engine-system/src/test/java/mozilla/components/browser/engine/system/SystemEngineViewTest.kt
@@ -108,12 +108,16 @@ class SystemEngineViewTest {
engineView.render(engineSession)
var observedUrl = ""
+ var observedUserGesture = true
var observedLoadingState = false
var observedSecurityChange: Triple = Triple(false, null, null)
engineSession.register(
object : EngineSession.Observer {
override fun onLoadingStateChange(loading: Boolean) { observedLoadingState = loading }
- override fun onLocationChange(url: String) { observedUrl = url }
+ override fun onLocationChange(url: String, hasUserGesture: Boolean) {
+ observedUrl = url
+ observedUserGesture = hasUserGesture
+ }
override fun onSecurityChange(secure: Boolean, host: String?, issuer: String?) {
observedSecurityChange = Triple(secure, host, issuer)
}
@@ -127,6 +131,7 @@ class SystemEngineViewTest {
observedLoadingState = true
engineSession.webView.webViewClient.onPageFinished(null, "http://mozilla.org")
assertEquals("http://mozilla.org", observedUrl)
+ assertEquals(false, observedUserGesture)
assertFalse(observedLoadingState)
assertEquals(Triple(false, null, null), observedSecurityChange)
@@ -1016,7 +1021,7 @@ class SystemEngineViewTest {
engineSession.register(
object : EngineSession.Observer {
override fun onLoadingStateChange(loading: Boolean) { observedLoadingState = loading }
- override fun onLocationChange(url: String) { observedUrl = url }
+ override fun onLocationChange(url: String, hasUserGesture: Boolean) { observedUrl = url }
override fun onSecurityChange(secure: Boolean, host: String?, issuer: String?) {
observedSecurityChange = Triple(secure, host, issuer)
}
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 e2861b0c3e0d..86259c316833 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
@@ -456,7 +456,11 @@ sealed class ContentAction : BrowserAction() {
/**
* Updates the URL of the [ContentState] with the given [sessionId].
*/
- data class UpdateUrlAction(val sessionId: String, val url: String) : ContentAction()
+ data class UpdateUrlAction(
+ val sessionId: String,
+ val url: String,
+ val hasUserGesture: Boolean = false,
+ ) : ContentAction()
/**
* Updates the progress of the [ContentState] with the given [sessionId].
diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/EngineObserver.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/EngineObserver.kt
index c406b105ff94..7c6c110a1253 100644
--- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/EngineObserver.kt
+++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/engine/EngineObserver.kt
@@ -86,8 +86,8 @@ internal class EngineObserver(
store.dispatch(ContentAction.UpdateFirstContentfulPaintStateAction(tabId, false))
}
- override fun onLocationChange(url: String) {
- store.dispatch(ContentAction.UpdateUrlAction(tabId, url))
+ override fun onLocationChange(url: String, hasUserGesture: Boolean) {
+ store.dispatch(ContentAction.UpdateUrlAction(tabId, url, hasUserGesture))
}
@Suppress("DEPRECATION") // Session observable is deprecated
diff --git a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/ContentStateReducer.kt b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/ContentStateReducer.kt
index a581e6051e3e..45165477b38c 100644
--- a/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/ContentStateReducer.kt
+++ b/android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/ContentStateReducer.kt
@@ -57,6 +57,11 @@ internal object ContentStateReducer {
} else {
it.permissionRequestsList
},
+ searchTerms = if (action.hasUserGesture) {
+ ""
+ } else {
+ it.searchTerms
+ },
)
}
is ContentAction.UpdateProgressAction -> updateContentState(state, action.sessionId) {
diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/ContentActionTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/ContentActionTest.kt
index 353dba909498..d62157da48a3 100644
--- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/ContentActionTest.kt
+++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/action/ContentActionTest.kt
@@ -131,6 +131,28 @@ class ContentActionTest {
assertEquals(icon, tab.content.icon)
}
+ @Test
+ fun `WHEN UpdateUrlAction is dispatched by user gesture THEN the search terms are cleared`() {
+ val searchTerms = "Firefox"
+ store.dispatch(
+ ContentAction.UpdateSearchTermsAction(tab.id, searchTerms),
+ ).joinBlocking()
+
+ assertEquals(searchTerms, tab.content.searchTerms)
+
+ store.dispatch(
+ ContentAction.UpdateUrlAction(tab.id, "https://www.mozilla.org", false),
+ ).joinBlocking()
+
+ assertEquals(searchTerms, tab.content.searchTerms)
+
+ store.dispatch(
+ ContentAction.UpdateUrlAction(tab.id, "https://www.mozilla.org/firefox", true),
+ ).joinBlocking()
+
+ assertEquals("", tab.content.searchTerms)
+ }
+
@Test
fun `UpdateLoadingStateAction updates loading state`() {
assertFalse(tab.content.loading)
diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/EngineObserverTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/EngineObserverTest.kt
index 9f92dd69e41e..2967d43fbf51 100644
--- a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/EngineObserverTest.kt
+++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/engine/EngineObserverTest.kt
@@ -147,7 +147,7 @@ class EngineObserverTest {
override fun exitFullScreenMode() {}
override fun purgeHistory() {}
override fun loadData(data: String, mimeType: String, encoding: String) {
- notifyObservers { onLocationChange(data) }
+ notifyObservers { onLocationChange(data, false) }
notifyObservers { onProgress(100) }
notifyObservers { onLoadingStateChange(true) }
notifyObservers { onNavigationStateChange(true, true) }
@@ -160,7 +160,7 @@ class EngineObserverTest {
flags: LoadUrlFlags,
additionalHeaders: Map?,
) {
- notifyObservers { onLocationChange(url) }
+ notifyObservers { onLocationChange(url, false) }
notifyObservers { onProgress(100) }
notifyObservers { onLoadingStateChange(true) }
notifyObservers { onNavigationStateChange(true, true) }
@@ -494,7 +494,7 @@ class EngineObserverTest {
assertEquals("Mozilla", store.state.tabs[0].content.title)
- observer.onLocationChange("https://getpocket.com")
+ observer.onLocationChange("https://getpocket.com", false)
store.waitUntilIdle()
assertEquals("", store.state.tabs[0].content.title)
@@ -521,7 +521,7 @@ class EngineObserverTest {
assertEquals("Mozilla", store.state.tabs[0].content.title)
- observer.onLocationChange("https://www.mozilla.org")
+ observer.onLocationChange("https://www.mozilla.org", false)
store.waitUntilIdle()
assertEquals("Mozilla", store.state.tabs[0].content.title)
@@ -548,7 +548,7 @@ class EngineObserverTest {
assertEquals("Mozilla", store.state.tabs[0].content.title)
- observer.onLocationChange("https://www.mozilla.org/#something")
+ observer.onLocationChange("https://www.mozilla.org/#something", false)
store.waitUntilIdle()
assertEquals("Mozilla", store.state.tabs[0].content.title)
@@ -575,7 +575,7 @@ class EngineObserverTest {
assertEquals(previewImageUrl, store.state.tabs[0].content.previewImageUrl)
- observer.onLocationChange("https://getpocket.com")
+ observer.onLocationChange("https://getpocket.com", false)
store.waitUntilIdle()
assertNull(store.state.tabs[0].content.previewImageUrl)
@@ -603,12 +603,12 @@ class EngineObserverTest {
assertEquals(previewImageUrl, store.state.tabs[0].content.previewImageUrl)
- observer.onLocationChange("https://www.mozilla.org")
+ observer.onLocationChange("https://www.mozilla.org", false)
store.waitUntilIdle()
assertEquals(previewImageUrl, store.state.tabs[0].content.previewImageUrl)
- observer.onLocationChange("https://www.mozilla.org/#something")
+ observer.onLocationChange("https://www.mozilla.org/#something", false)
store.waitUntilIdle()
assertEquals(previewImageUrl, store.state.tabs[0].content.previewImageUrl)
@@ -696,7 +696,7 @@ class EngineObserverTest {
assertEquals(manifest, store.state.tabs[0].content.webAppManifest)
- observer.onLocationChange("https://getpocket.com")
+ observer.onLocationChange("https://getpocket.com", false)
store.waitUntilIdle()
assertNull(store.state.tabs[0].content.webAppManifest)
@@ -724,7 +724,7 @@ class EngineObserverTest {
assertEquals(listOf(request), store.state.tabs[0].content.permissionRequestsList)
- observer.onLocationChange("https://getpocket.com")
+ observer.onLocationChange("https://getpocket.com", false)
store.waitUntilIdle()
assertEquals(emptyList(), store.state.tabs[0].content.permissionRequestsList)
@@ -752,7 +752,7 @@ class EngineObserverTest {
assertEquals(listOf(request), store.state.tabs[0].content.permissionRequestsList)
- observer.onLocationChange("https://www.mozilla.org/hello.html")
+ observer.onLocationChange("https://www.mozilla.org/hello.html", false)
store.waitUntilIdle()
assertEquals(listOf(request), store.state.tabs[0].content.permissionRequestsList)
@@ -780,7 +780,7 @@ class EngineObserverTest {
assertEquals(manifest, store.state.tabs[0].content.webAppManifest)
- observer.onLocationChange("https://www.mozilla.org/hello.html")
+ observer.onLocationChange("https://www.mozilla.org/hello.html", false)
store.waitUntilIdle()
assertEquals(manifest, store.state.tabs[0].content.webAppManifest)
@@ -812,12 +812,12 @@ class EngineObserverTest {
assertEquals(manifest, store.state.tabs[0].content.webAppManifest)
- observer.onLocationChange("https://www.mozilla.org/hello/page2.html")
+ observer.onLocationChange("https://www.mozilla.org/hello/page2.html", false)
store.waitUntilIdle()
assertEquals(manifest, store.state.tabs[0].content.webAppManifest)
- observer.onLocationChange("https://www.mozilla.org/hello.html")
+ observer.onLocationChange("https://www.mozilla.org/hello.html", false)
store.waitUntilIdle()
assertNull(store.state.tabs[0].content.webAppManifest)
}
@@ -1527,7 +1527,7 @@ class EngineObserverTest {
)
val observer = EngineObserver("test-id", store)
- observer.onLocationChange("https://www.mozilla.org/en-US/")
+ observer.onLocationChange("https://www.mozilla.org/en-US/", false)
store.waitUntilIdle()
@@ -1712,13 +1712,34 @@ class EngineObserverTest {
observer.onLoadUrl()
store.waitUntilIdle()
- middleware.assertNotDispatched(ContentAction.UpdateSearchTermsAction::class)
middleware.assertLastAction(ContentAction.UpdateIsSearchAction::class) { action ->
assertEquals(false, action.isSearch)
assertEquals("test-id", action.sessionId)
}
}
+ @Test
+ fun `GIVEN a search is performed WHEN the location is changed without user interaction THEN the search terms are not cleared`() {
+ val middleware = CaptureActionsMiddleware()
+ val store = BrowserStore(
+ initialState = BrowserState(
+ tabs = listOf(
+ createTab("https://www.mozilla.org", id = "test-id"),
+ ),
+ ),
+ middleware = listOf(middleware),
+ )
+
+ store.dispatch(ContentAction.UpdateIsSearchAction("test-id", true))
+ store.waitUntilIdle()
+
+ val observer = EngineObserver("test-id", store)
+ observer.onLocationChange("testUrl", false)
+ store.waitUntilIdle()
+
+ middleware.assertNotDispatched(ContentAction.UpdateSearchTermsAction::class)
+ }
+
@Test
fun `onHistoryStateChanged dispatches UpdateHistoryStateAction`() {
val store: BrowserStore = mock()
diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/EngineSession.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/EngineSession.kt
index de3efe02ead1..1250f0f35c87 100644
--- a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/EngineSession.kt
+++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/EngineSession.kt
@@ -48,7 +48,7 @@ abstract class EngineSession(
*/
fun onScrollChange(scrollX: Int, scrollY: Int) = Unit
- fun onLocationChange(url: String) = Unit
+ fun onLocationChange(url: String, hasUserGesture: Boolean) = Unit
fun onTitleChange(title: String) = Unit
/**
diff --git a/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/EngineSessionTest.kt b/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/EngineSessionTest.kt
index f1abaf14b614..440cb53cb33b 100644
--- a/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/EngineSessionTest.kt
+++ b/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/EngineSessionTest.kt
@@ -52,8 +52,8 @@ class EngineSessionTest {
session.notifyInternalObservers { onScrollChange(1234, 4321) }
session.notifyInternalObservers { onScrollChange(2345, 5432) }
- session.notifyInternalObservers { onLocationChange("https://www.mozilla.org") }
- session.notifyInternalObservers { onLocationChange("https://www.firefox.com") }
+ session.notifyInternalObservers { onLocationChange("https://www.mozilla.org", false) }
+ session.notifyInternalObservers { onLocationChange("https://www.firefox.com", false) }
session.notifyInternalObservers { onProgress(25) }
session.notifyInternalObservers { onProgress(100) }
session.notifyInternalObservers { onLoadingStateChange(true) }
@@ -85,8 +85,8 @@ class EngineSessionTest {
session.notifyInternalObservers { onProcessKilled() }
session.notifyInternalObservers { onShowDynamicToolbar() }
- verify(observer).onLocationChange("https://www.mozilla.org")
- verify(observer).onLocationChange("https://www.firefox.com")
+ verify(observer).onLocationChange("https://www.mozilla.org", false)
+ verify(observer).onLocationChange("https://www.firefox.com", false)
verify(observer).onScrollChange(1234, 4321)
verify(observer).onScrollChange(2345, 5432)
verify(observer).onProgress(25)
@@ -136,7 +136,7 @@ class EngineSessionTest {
session.register(observer)
session.notifyInternalObservers { onScrollChange(1234, 4321) }
- session.notifyInternalObservers { onLocationChange("https://www.mozilla.org") }
+ session.notifyInternalObservers { onLocationChange("https://www.mozilla.org", false) }
session.notifyInternalObservers { onProgress(25) }
session.notifyInternalObservers { onLoadingStateChange(true) }
session.notifyInternalObservers { onSecurityChange(true, "mozilla.org", "issuer") }
@@ -165,7 +165,7 @@ class EngineSessionTest {
val mediaSessionElementMetadata: MediaSession.ElementMetadata = mock()
session.notifyInternalObservers { onScrollChange(2345, 5432) }
- session.notifyInternalObservers { onLocationChange("https://www.firefox.com") }
+ session.notifyInternalObservers { onLocationChange("https://www.firefox.com", false) }
session.notifyInternalObservers { onProgress(100) }
session.notifyInternalObservers { onLoadingStateChange(false) }
session.notifyInternalObservers { onSecurityChange(false, "", "") }
@@ -195,7 +195,7 @@ class EngineSessionTest {
session.notifyInternalObservers { onShowDynamicToolbar() }
verify(observer).onScrollChange(1234, 4321)
- verify(observer).onLocationChange("https://www.mozilla.org")
+ verify(observer).onLocationChange("https://www.mozilla.org", false)
verify(observer).onProgress(25)
verify(observer).onLoadingStateChange(true)
verify(observer).onSecurityChange(true, "mozilla.org", "issuer")
@@ -216,7 +216,7 @@ class EngineSessionTest {
verify(observer).onLaunchIntentRequest("https://www.mozilla.org", null)
verify(observer).onShowDynamicToolbar()
verify(observer, never()).onScrollChange(2345, 5432)
- verify(observer, never()).onLocationChange("https://www.firefox.com")
+ verify(observer, never()).onLocationChange("https://www.firefox.com", false)
verify(observer, never()).onProgress(100)
verify(observer, never()).onLoadingStateChange(false)
verify(observer, never()).onSecurityChange(false, "", "")
@@ -261,7 +261,7 @@ class EngineSessionTest {
session.register(otherObserver)
session.notifyInternalObservers { onScrollChange(1234, 4321) }
- session.notifyInternalObservers { onLocationChange("https://www.mozilla.org") }
+ session.notifyInternalObservers { onLocationChange("https://www.mozilla.org", false) }
session.notifyInternalObservers { onProgress(25) }
session.notifyInternalObservers { onLoadingStateChange(true) }
session.notifyInternalObservers { onSecurityChange(true, "mozilla.org", "issuer") }
@@ -288,7 +288,7 @@ class EngineSessionTest {
val mediaSessionElementMetadata: MediaSession.ElementMetadata = mock()
session.notifyInternalObservers { onScrollChange(2345, 5432) }
- session.notifyInternalObservers { onLocationChange("https://www.firefox.com") }
+ session.notifyInternalObservers { onLocationChange("https://www.firefox.com", false) }
session.notifyInternalObservers { onProgress(100) }
session.notifyInternalObservers { onLoadingStateChange(false) }
session.notifyInternalObservers { onSecurityChange(false, "", "") }
@@ -315,7 +315,7 @@ class EngineSessionTest {
session.notifyInternalObservers { onShowDynamicToolbar() }
verify(observer).onScrollChange(1234, 4321)
- verify(observer).onLocationChange("https://www.mozilla.org")
+ verify(observer).onLocationChange("https://www.mozilla.org", false)
verify(observer).onProgress(25)
verify(observer).onLoadingStateChange(true)
verify(observer).onSecurityChange(true, "mozilla.org", "issuer")
@@ -333,7 +333,7 @@ class EngineSessionTest {
verify(observer).onWindowRequest(windowRequest)
verify(observer).onShowDynamicToolbar()
verify(observer, never()).onScrollChange(2345, 5432)
- verify(observer, never()).onLocationChange("https://www.firefox.com")
+ verify(observer, never()).onLocationChange("https://www.firefox.com", false)
verify(observer, never()).onProgress(100)
verify(observer, never()).onLoadingStateChange(false)
verify(observer, never()).onSecurityChange(false, "", "")
@@ -358,7 +358,7 @@ class EngineSessionTest {
verify(observer, never()).onMediaMuteChanged(true)
verify(observer, never()).onMediaFullscreenChanged(true, mediaSessionElementMetadata)
verify(otherObserver, never()).onScrollChange(2345, 5432)
- verify(otherObserver, never()).onLocationChange("https://www.firefox.com")
+ verify(otherObserver, never()).onLocationChange("https://www.firefox.com", false)
verify(otherObserver, never()).onProgress(100)
verify(otherObserver, never()).onLoadingStateChange(false)
verify(otherObserver, never()).onSecurityChange(false, "", "")
@@ -398,7 +398,7 @@ class EngineSessionTest {
session.register(observer)
session.notifyInternalObservers { onScrollChange(1234, 4321) }
- session.notifyInternalObservers { onLocationChange("https://www.mozilla.org") }
+ session.notifyInternalObservers { onLocationChange("https://www.mozilla.org", false) }
session.notifyInternalObservers { onProgress(25) }
session.notifyInternalObservers { onLoadingStateChange(true) }
session.notifyInternalObservers { onSecurityChange(true, "mozilla.org", "issuer") }
@@ -425,7 +425,7 @@ class EngineSessionTest {
val mediaSessionElementMetadata: MediaSession.ElementMetadata = mock()
session.notifyInternalObservers { onScrollChange(2345, 5432) }
- session.notifyInternalObservers { onLocationChange("https://www.firefox.com") }
+ session.notifyInternalObservers { onLocationChange("https://www.firefox.com", false) }
session.notifyInternalObservers { onProgress(100) }
session.notifyInternalObservers { onLoadingStateChange(false) }
session.notifyInternalObservers { onSecurityChange(false, "", "") }
@@ -452,7 +452,7 @@ class EngineSessionTest {
session.notifyInternalObservers { onShowDynamicToolbar() }
verify(observer).onScrollChange(1234, 4321)
- verify(observer).onLocationChange("https://www.mozilla.org")
+ verify(observer).onLocationChange("https://www.mozilla.org", false)
verify(observer).onProgress(25)
verify(observer).onLoadingStateChange(true)
verify(observer).onSecurityChange(true, "mozilla.org", "issuer")
@@ -470,7 +470,7 @@ class EngineSessionTest {
verify(observer).onWindowRequest(windowRequest)
verify(observer).onShowDynamicToolbar()
verify(observer, never()).onScrollChange(2345, 5432)
- verify(observer, never()).onLocationChange("https://www.firefox.com")
+ verify(observer, never()).onLocationChange("https://www.firefox.com", false)
verify(observer, never()).onProgress(100)
verify(observer, never()).onLoadingStateChange(false)
verify(observer, never()).onSecurityChange(false, "", "")
@@ -513,8 +513,8 @@ class EngineSessionTest {
session.register(observer)
otherSession.notifyInternalObservers { onScrollChange(1234, 4321) }
- otherSession.notifyInternalObservers { onLocationChange("https://www.mozilla.org") }
- otherSession.notifyInternalObservers { onLocationChange("https://www.mozilla.org") }
+ otherSession.notifyInternalObservers { onLocationChange("https://www.mozilla.org", false) }
+ otherSession.notifyInternalObservers { onLocationChange("https://www.mozilla.org", false) }
otherSession.notifyInternalObservers { onProgress(25) }
otherSession.notifyInternalObservers { onLoadingStateChange(true) }
otherSession.notifyInternalObservers { onSecurityChange(true, "mozilla.org", "issuer") }
@@ -540,7 +540,7 @@ class EngineSessionTest {
otherSession.notifyInternalObservers { onMediaFullscreenChanged(true, mediaSessionElementMetadata) }
otherSession.notifyInternalObservers { onShowDynamicToolbar() }
verify(observer, never()).onScrollChange(1234, 4321)
- verify(observer, never()).onLocationChange("https://www.mozilla.org")
+ verify(observer, never()).onLocationChange("https://www.mozilla.org", false)
verify(observer, never()).onProgress(25)
verify(observer, never()).onLoadingStateChange(true)
verify(observer, never()).onSecurityChange(true, "mozilla.org", "issuer")
@@ -567,7 +567,7 @@ class EngineSessionTest {
verify(observer, never()).onShowDynamicToolbar()
session.notifyInternalObservers { onScrollChange(1234, 4321) }
- session.notifyInternalObservers { onLocationChange("https://www.mozilla.org") }
+ session.notifyInternalObservers { onLocationChange("https://www.mozilla.org", false) }
session.notifyInternalObservers { onProgress(25) }
session.notifyInternalObservers { onLoadingStateChange(true) }
session.notifyInternalObservers { onSecurityChange(true, "mozilla.org", "issuer") }
@@ -593,7 +593,7 @@ class EngineSessionTest {
session.notifyInternalObservers { onMediaFullscreenChanged(true, mediaSessionElementMetadata) }
session.notifyInternalObservers { onShowDynamicToolbar() }
verify(observer, times(1)).onScrollChange(1234, 4321)
- verify(observer, times(1)).onLocationChange("https://www.mozilla.org")
+ verify(observer, times(1)).onLocationChange("https://www.mozilla.org", false)
verify(observer, times(1)).onProgress(25)
verify(observer, times(1)).onLoadingStateChange(true)
verify(observer, times(1)).onSecurityChange(true, "mozilla.org", "issuer")
@@ -837,7 +837,7 @@ class EngineSessionTest {
defaultObserver.onTitleChange("")
defaultObserver.onScrollChange(0, 0)
- defaultObserver.onLocationChange("")
+ defaultObserver.onLocationChange("", false)
defaultObserver.onPreviewImageChange("")
defaultObserver.onLongPress(HitResult.UNKNOWN(""))
defaultObserver.onExternalResource("", "")
@@ -945,8 +945,8 @@ class EngineSessionTest {
val tracker: Tracker = mock()
observer.onScrollChange(1234, 4321)
- observer.onLocationChange("https://www.mozilla.org")
- observer.onLocationChange("https://www.firefox.com")
+ observer.onLocationChange("https://www.mozilla.org", false)
+ observer.onLocationChange("https://www.firefox.com", false)
observer.onProgress(25)
observer.onProgress(100)
observer.onLoadingStateChange(true)
diff --git a/android-components/config/detekt-baseline.xml b/android-components/config/detekt-baseline.xml
index 1d29791b39c6..e779572390d9 100644
--- a/android-components/config/detekt-baseline.xml
+++ b/android-components/config/detekt-baseline.xml
@@ -92,7 +92,6 @@
UndocumentedPublicClass:Request.kt$Request$RedirectUndocumentedPublicClass:RequestInterceptor.kt$RequestInterceptor.InterceptionResponse$AppIntent : InterceptionResponseUndocumentedPublicClass:RequestInterceptor.kt$RequestInterceptor.InterceptionResponse$Content : InterceptionResponse
- UndocumentedPublicClass:RequestInterceptor.kt$RequestInterceptor.InterceptionResponse$Url : InterceptionResponseUndocumentedPublicClass:RustLog.kt$RustLogUndocumentedPublicClass:SampleApplication.kt$SampleApplication : ApplicationUndocumentedPublicClass:SampleToolbarHelpers.kt$ConfigurationAdapter : Adapter
@@ -184,7 +183,7 @@
UndocumentedPublicFunction:EngineSession.kt$EngineSession.Observer$fun onFindResult(activeMatchOrdinal: Int, numberOfMatches: Int, isDoneCounting: Boolean)UndocumentedPublicFunction:EngineSession.kt$EngineSession.Observer$fun onFullScreenChange(enabled: Boolean)UndocumentedPublicFunction:EngineSession.kt$EngineSession.Observer$fun onLoadingStateChange(loading: Boolean)
- UndocumentedPublicFunction:EngineSession.kt$EngineSession.Observer$fun onLocationChange(url: String)
+ UndocumentedPublicFunction:EngineSession.kt$EngineSession.Observer$fun onLocationChange(url: String, hasUserGesture: Boolean)UndocumentedPublicFunction:EngineSession.kt$EngineSession.Observer$fun onLongPress(hitResult: HitResult)UndocumentedPublicFunction:EngineSession.kt$EngineSession.Observer$fun onNavigateBack()UndocumentedPublicFunction:EngineSession.kt$EngineSession.Observer$fun onNavigationStateChange(canGoBack: Boolean? = null, canGoForward: Boolean? = null)
diff --git a/android-components/plugins/dependencies/src/main/java/Gecko.kt b/android-components/plugins/dependencies/src/main/java/Gecko.kt
index 6092c4bca925..65f450748bb9 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 = "125.0.20240222103314"
+ const val version = "125.0.20240223095502"
/**
* GeckoView channel
diff --git a/docs/changelog.md b/docs/changelog.md
index 83af2915513e..d98a09ad76a4 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -10,6 +10,9 @@ permalink: /changelog/
* [Gecko](https://github.com/mozilla-mobile/firefox-android/blob/main/android-components/plugins/dependencies/src/main/java/Gecko.kt)
* [Configuration](https://github.com/mozilla-mobile/firefox-android/blob/main/android-components/.config.yml)
+* **concept-engine**
+ * Added `onLocationChange#hasUserGesture` parameter. This indicates if a location change was requested while a user gesture was active. [bug #1804636](https://bugzilla.mozilla.org/show_bug.cgi?id=1804636)
+
# 124.0
* [Commits](https://github.com/mozilla-mobile/firefox-android/compare/releases_v123..releases_v124)
* [Dependencies](https://github.com/mozilla-mobile/firefox-android/blob/releases_v124/android-components/plugins/dependencies/src/main/java/DependenciesPlugin.kt)
From 13b08c4c4d535f87dc43973f7f37057cd4851e6f Mon Sep 17 00:00:00 2001
From: github-actions
Date: Sat, 24 Feb 2024 00:03:11 +0000
Subject: [PATCH 315/586] Import translations from android-l10n
---
.../menu/src/main/res/values-th/strings.xml | 2 +
.../addons/src/main/res/values-bs/strings.xml | 2 +
.../addons/src/main/res/values-cs/strings.xml | 2 +
.../addons/src/main/res/values-th/strings.xml | 24 +++++--
.../src/main/res/values-zh-rCN/strings.xml | 2 +
.../src/main/res/values-sl/strings.xml | 2 +
.../src/main/res/values-th/strings.xml | 36 ++++++++++
fenix/app/src/main/res/values-azb/strings.xml | 68 +++++++++++++++++++
fenix/app/src/main/res/values-el/strings.xml | 2 +-
fenix/app/src/main/res/values-th/strings.xml | 45 ++++++++++++
fenix/app/src/main/res/values-tr/strings.xml | 4 +-
.../app/src/main/res/values-bs/strings.xml | 6 +-
.../app/src/main/res/values-de/strings.xml | 6 +-
.../app/src/main/res/values-dsb/strings.xml | 6 +-
.../app/src/main/res/values-el/strings.xml | 6 +-
.../src/main/res/values-es-rAR/strings.xml | 6 +-
.../app/src/main/res/values-fr/strings.xml | 6 +-
.../app/src/main/res/values-hsb/strings.xml | 6 +-
.../app/src/main/res/values-it/strings.xml | 6 +-
.../app/src/main/res/values-kk/strings.xml | 6 +-
.../src/main/res/values-pt-rBR/strings.xml | 22 +++---
.../src/main/res/values-sv-rSE/strings.xml | 6 +-
.../src/main/res/values-zh-rCN/strings.xml | 6 +-
23 files changed, 248 insertions(+), 29 deletions(-)
diff --git a/android-components/components/browser/menu/src/main/res/values-th/strings.xml b/android-components/components/browser/menu/src/main/res/values-th/strings.xml
index 58955eab56e6..0af929872008 100644
--- a/android-components/components/browser/menu/src/main/res/values-th/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-th/strings.xml
@@ -10,4 +10,6 @@
ตัวจัดการส่วนเสริมนำทางขึ้นไปด้านบน
+
+ ส่วนเสริม, นำทางไปด้านบน
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 884830a8d1aa..ea54af17c1db 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
@@ -98,6 +98,8 @@
Dozvoli u privatnom surfanjuPokreni u privatnom surfanju
+
+ Nije dozvoljeno u privatnim prozorimaOmogućen
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 cbeb480b6608..6a9a44278b23 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
@@ -98,6 +98,8 @@
Povolit v režimu anonymního prohlíženíPovoleno v režimu anonymního prohlížení
+
+ Doplněk není povolený v anonymních oknechPovoleno
diff --git a/android-components/components/feature/addons/src/main/res/values-th/strings.xml b/android-components/components/feature/addons/src/main/res/values-th/strings.xml
index 84c21d0958f2..2762a7f43957 100644
--- a/android-components/components/feature/addons/src/main/res/values-th/strings.xml
+++ b/android-components/components/feature/addons/src/main/res/values-th/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 @@
ผู้สร้าง
- ผู้สร้าง
+ ผู้สร้างอัปเดตล่าสุด
@@ -96,6 +98,8 @@
อนุญาตในการเรียกดูแบบส่วนตัวเรียกใช้ในการเรียกดูแบบส่วนตัว
+
+ ไม่อนุญาตในหน้าต่างส่วนตัวถูกเปิดใช้งาน
@@ -135,13 +139,17 @@
ยกเลิก
- ติดตั้งส่วนเสริม
+ ติดตั้งส่วนเสริม
+
+ ติดตั้ง %1$sยกเลิกบทวิจารณ์: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ คะแนน: %1$.02f จาก 5ส่วนเสริม
@@ -242,10 +250,14 @@
สถานะ:%1$s ได้ถูกเพิ่มไปยัง %2$s แล้ว
-
- เปิดในเมนู
+
+ เปิดในเมนู
+
+ เข้าถึง %1$s ได้จากเมนู %2$s
+
+ ตกลง เข้าใจแล้ว
- ตกลง เข้าใจแล้ว
+ ตกลงเรียนรู้เพิ่มเติม
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 b6061e1ea1d4..22ea005d71fa 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
@@ -98,6 +98,8 @@
允许运行于隐私浏览模式在隐私浏览中运行
+
+ 不允许在隐私窗口中运行已启用
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 e77ba5c0e4ac..dec932c1c506 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
@@ -93,6 +93,8 @@
Nastavi časUpravljanje prijav
+
+ Upravljanje geselRazširi predlagane prijave
diff --git a/android-components/components/feature/prompts/src/main/res/values-th/strings.xml b/android-components/components/feature/prompts/src/main/res/values-th/strings.xml
index e2245ccc5ae3..b8bf2bd77c34 100644
--- a/android-components/components/feature/prompts/src/main/res/values-th/strings.xml
+++ b/android-components/components/feature/prompts/src/main/res/values-th/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 39348b26c140..d317cc475360 100644
--- a/fenix/app/src/main/res/values-azb/strings.xml
+++ b/fenix/app/src/main/res/values-azb/strings.xml
@@ -1238,9 +1238,77 @@
سس و ویدئویا ایجازه وئر
+
+ یالنیز موبایل سلولاردا سس و ویدئونو بلوْکلا
+
+ سس و ویدئو وایفای اوستونده چالیناجاق
+
+ یالنیز سس مسدودو
+
+ یالنیز سس مسدودو
+
+ سس و ویدئویو مسدود ائله
+
+ سس و ویدئویو مسدود ائله
+
+ آچیق
+
+ باغلیْ
+
+ آچیق
+
+ باغلیْ
+
+
+
+ مجموعهلر
+
+ مجموعهلر منوسوسیزین اوچون اؤنملی اولان شئیلری یئغین. \n داها سوْنرا یئیین گیریش اوچون اوْخشار آختاریشلاریْ، سایتلاریْ و تاغلاریْ قروُپلاشدیرین.
+
+ تاغلاری سئچین
+
+ مجموعه سئچین
+
+ مجموعه آدی
+
+ یئنی مجموعه اکله
+
+
+ هامیسینی سئچ
+
+ هامیسینی سئچمه
+
+ ساخلاناجاق تاغلاری سئچ
+
+ %d تاغ سئچیلدی
+
+ %d تاغ سئچیلدی
+
+ تاغلار ساخلاندیْ!
+
+ مجموعه ساخلاندیْ!
+
+
+ تاغ ساخلاندیْ!
+
+ باغلا
+
+ ساخلا
+
+ گؤستر
+
+ تامام
+
+ لغو
+
+
+ %d مجموعهسی
+
diff --git a/fenix/app/src/main/res/values-el/strings.xml b/fenix/app/src/main/res/values-el/strings.xml
index f99fb52bdcce..4de3758d74a4 100644
--- a/fenix/app/src/main/res/values-el/strings.xml
+++ b/fenix/app/src/main/res/values-el/strings.xml
@@ -1562,7 +1562,7 @@
Απομόνωση cookie μεταξύ ιστοτόπων
- Αποστολή αιτήματος μη πώλησης και κοινοποίησης των δεδομένων μου στους ιστοτόπους
+ Αποστολή αιτήματος μη πώλησης και κοινοποίησης δεδομένων στους ιστοτόπουςΠεριεχόμενο καταγραφής
diff --git a/fenix/app/src/main/res/values-th/strings.xml b/fenix/app/src/main/res/values-th/strings.xml
index 152ab7fc32e5..f37d2d2b506d 100644
--- a/fenix/app/src/main/res/values-th/strings.xml
+++ b/fenix/app/src/main/res/values-th/strings.xml
@@ -250,6 +250,9 @@
history and go back to the home screen. -->
ล้างประวัติการเรียกดู
+
+ แปลหน้า
+
ภาษาที่เลือก
@@ -1714,8 +1717,12 @@
ข้อยกเว้นการเข้าสู่ระบบและรหัสผ่านที่ไม่ได้บันทึกจะถูกแสดงที่นี่
+
+ %s จะไม่บันทึกรหัสผ่านสำหรับไซต์ที่แสดงอยู่ที่นี่การเข้าสู่ระบบและรหัสผ่านจะไม่ถูกบันทึกสำหรับไซต์เหล่านี้
+
+ %s จะไม่บันทึกรหัสผ่านสำหรับไซต์เหล่านี้ลบข้อยกเว้นทั้งหมด
@@ -1754,8 +1761,12 @@
ปลดล็อกเพื่อดูรหัสผ่านที่บันทึกไว้ของคุณรักษาความปลอดภัยการเข้าสู่ระบบและรหัสผ่านของคุณ
+
+ รักษาความปลอดภัยให้กับรหัสผ่านที่บันทึกไว้ของคุณตั้งค่ารูปแบบการล็อกอุปกรณ์, PIN, หรือรหัสผ่านเพื่อปกป้องไม่ให้ใครเข้าถึงการเข้าสู่ระบบและรหัสผ่านที่บันทึกไว้ของคุณหากคนอื่นมีอุปกรณ์ของคุณ
+
+ ตั้งค่ารูปแบบการล็อกอุปกรณ์, PIN, หรือรหัสผ่านเพื่อปกป้องไม่ให้ใครเข้าถึงรหัสผ่านที่บันทึกไว้ของคุณหากคนอื่นมีอุปกรณ์ของคุณภายหลัง
@@ -1775,6 +1786,9 @@
เรียงเมนูเข้าสู่ระบบ
+
+ เมนูเรียงลำดับรหัสผ่าน
+
การเติมอัตโนมัติ
@@ -1790,6 +1804,8 @@
บันทึกและเติมวิธีการชำระเงินข้อมูลถูกเข้ารหัส
+
+ %s จะเข้ารหัสลับวิธีการชำระเงินทั้งหมดที่คุณบันทึกไว้ซิงค์บัตรระหว่างอุปกรณ์
@@ -1864,8 +1880,12 @@
ปลดล็อกเพื่อดูบัตรเครดิตที่บันทึกไว้ของคุณรักษาความปลอดภัยให้กับบัตรเครดิตของคุณ
+
+ รักษาความปลอดภัยให้กับวิธีการชำระเงินที่บันทึกไว้ของคุณตั้งค่ารูปแบบการล็อกอุปกรณ์, PIN, หรือรหัสผ่านเพื่อปกป้องไม่ให้ใครเข้าถึงบัตรเครดิตที่บันทึกไว้ของคุณหากคนอื่นมีอุปกรณ์ของคุณ
+
+ ตั้งค่ารูปแบบการล็อกอุปกรณ์, PIN, หรือรหัสผ่านเพื่อปกป้องไม่ให้ใครเข้าถึงวิธีการชำระเงินที่บันทึกไว้ของคุณหากคนอื่นมีอุปกรณ์ของคุณตั้งค่าตอนนี้
@@ -1875,6 +1895,8 @@
ปลดล็อกเพื่อใช้ข้อมูลบัตรเครดิตที่เก็บไว้
+
+ ปลดล็อกเพื่อใช้วิธีการชำระเงินที่บันทึกไว้เพิ่มที่อยู่
@@ -1912,6 +1934,8 @@
คุณแน่ใจหรือไม่ว่าต้องการลบที่อยู่นี้?
+
+ ลบที่อยู่นี้หรือไม่?ลบ
@@ -2010,18 +2034,28 @@
แก้ไขคุณแน่ใจหรือไม่ที่ต้องการจะลบการเข้าสู่ระบบนี้?
+
+ คุณแน่ใจหรือไม่ว่าต้องการลบรหัสผ่านนี้?ลบยกเลิกตัวเลือกการเข้าสู่ระบบ
+
+ ตัวเลือกรหัสผ่านช่องข้อความที่แก้ไขได้สำหรับที่อยู่เว็บของการเข้าสู่ระบบ
+
+ ช่องข้อความที่แก้ไขได้สำหรับที่อยู่เว็บไซต์ช่องข้อความที่แก้ไขได้สำหรับชื่อผู้ใช้ของการเข้าสู่ระบบ
+
+ ช่องข้อความที่แก้ไขได้สำหรับชื่อผู้ใช้ช่องข้อความที่แก้ไขได้สำหรับรหัสผ่านของการเข้าสู่ระบบ
+
+ ช่องข้อความที่แก้ไขได้สำหรับรหัสผ่านบันทึกการเปลี่ยนแปลงเพื่อเข้าสู่ระบบ
@@ -2040,6 +2074,8 @@
ใส่รหัสผ่านต้องการชื่อผู้ใช้
+
+ ป้อนชื่อผู้ใช้ต้องการชื่อโฮสต์
@@ -2140,6 +2176,9 @@
ค้นหาด้วย %s
+
+ เปลี่ยนเบราว์เซอร์เริ่มต้นของคุณ
+
ตั้งลิงก์จากเว็บไซต์ อีเมล และข้อความให้เปิดโดยอัตโนมัติใน Firefox
@@ -2395,6 +2434,8 @@
กำลังแปลอยู่ระหว่างการแปล
+
+ เลือกภาษาเกิดปัญหาในการแปล โปรดลองอีกครั้ง
@@ -2416,6 +2457,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 115191558507..747d552756a5 100644
--- a/fenix/app/src/main/res/values-tr/strings.xml
+++ b/fenix/app/src/main/res/values-tr/strings.xml
@@ -2258,7 +2258,7 @@
Ayarlar
- Değerlendirme denetleyicisinde reklamları göster
+ Değerlendirme kontrolcüsünde reklamları gösterAra sıra ilgili ürünlerin reklamlarını görebilirsiniz. Yalnızca güvenilir değerlendirmeleri olan ürünlerin reklamlarını kabul ediyoruz. %s
@@ -2284,7 +2284,7 @@
Ürün mevcut değil
- Bu ürünün yeniden stoğa girdiğini görürseniz bize bildirin, biz de değerlendirmeleri kontrol etmeye çalışalım.
+ Bu ürünün yeniden stoka girdiğini görürseniz bize bildirin, biz de değerlendirmeleri kontrol etmeye çalışalım.Ürünün stokta olduğunu bildir
diff --git a/focus-android/app/src/main/res/values-bs/strings.xml b/focus-android/app/src/main/res/values-bs/strings.xml
index 370b26bb3cd4..fe9e8ad22f9f 100644
--- a/focus-android/app/src/main/res/values-bs/strings.xml
+++ b/focus-android/app/src/main/res/values-bs/strings.xml
@@ -84,7 +84,11 @@
Dijeli putemIzbrisati historiju pretraživanja?
- Dodirnite ili izbrišite ovo obavještenje da sigurno izbrišete svoju historiju pretraživanja.
+ Dodirnite ili izbrišite ovo obavještenje da sigurno izbrišete svoju historiju pretraživanja.
+
+
+ Dodirnite ili povucite ovo obavještenje da sigurno izbrišete svoju historiju pretraživanja.Izbrišite historiju pretraživanja
diff --git a/focus-android/app/src/main/res/values-de/strings.xml b/focus-android/app/src/main/res/values-de/strings.xml
index 59b45cc6d1a8..4610dab3c246 100644
--- a/focus-android/app/src/main/res/values-de/strings.xml
+++ b/focus-android/app/src/main/res/values-de/strings.xml
@@ -84,7 +84,11 @@
Teilen überBrowser-Chronik löschen?
- Tippen oder löschen Sie diese Benachrichtigung, um Ihre Browser-Chronik sicher zu löschen.
+ Tippen oder löschen Sie diese Benachrichtigung, um Ihre Browser-Chronik sicher zu löschen.
+
+
+ Tippen oder wischen Sie diese Benachrichtigung, um Ihre Browser-Chronik sicher zu löschen.Browser-Chronik löschen
diff --git a/focus-android/app/src/main/res/values-dsb/strings.xml b/focus-android/app/src/main/res/values-dsb/strings.xml
index 2902e8d8be14..ad8f675190c7 100644
--- a/focus-android/app/src/main/res/values-dsb/strings.xml
+++ b/focus-android/app/src/main/res/values-dsb/strings.xml
@@ -84,7 +84,11 @@
Źěliś pśezPśeglědowańsku historiju lašowaś?
- Pótusniśo toś tu powěźeńku abo lašujśo ju, aby swóju pśeglědowańsku historiju wěsće wulašował.
+ Pótusniśo toś tu powěźeńku abo lašujśo ju, aby swóju pśeglědowańsku historiju wěsće wulašował.
+
+
+ Pótusniśo toś tu powěźeńku abo zjěźćo pśez ju, aby swóju pśeglědowańsku historiju wěsće wulašował.Pśeglědowańsku historiju lašowaś
diff --git a/focus-android/app/src/main/res/values-el/strings.xml b/focus-android/app/src/main/res/values-el/strings.xml
index 63aaf840c98c..d9167ba04cb8 100644
--- a/focus-android/app/src/main/res/values-el/strings.xml
+++ b/focus-android/app/src/main/res/values-el/strings.xml
@@ -86,7 +86,11 @@
Κοινοποίηση μέσωΔιαγραφή ιστορικού περιήγησης;
- Πατήστε ή εκκαθαρίστε αυτήν την ειδοποίηση για να διαγράψετε με ασφάλεια το ιστορικό περιήγησής σας.
+ Πατήστε ή εκκαθαρίστε αυτήν την ειδοποίηση για να διαγράψετε με ασφάλεια το ιστορικό περιήγησής σας.
+
+
+ Πατήστε ή σύρετε αυτήν την ειδοποίηση για να διαγράψετε με ασφάλεια το ιστορικό περιήγησής σας.Διαγραφή ιστορικού περιήγησης
diff --git a/focus-android/app/src/main/res/values-es-rAR/strings.xml b/focus-android/app/src/main/res/values-es-rAR/strings.xml
index f29c85326074..3a483e160b8d 100644
--- a/focus-android/app/src/main/res/values-es-rAR/strings.xml
+++ b/focus-android/app/src/main/res/values-es-rAR/strings.xml
@@ -84,7 +84,11 @@
Compartir vía¿Borrar historial de navegación?
- Tocá o borrá esta notificación para eliminar de forma segura tu historial de navegación.
+ Tocá o borrá esta notificación para eliminar de forma segura tu historial de navegación.
+
+
+ Toca o desliza esta notificación para borrar de forma segura tu historial de navegación.Borrar historial de navegación
diff --git a/focus-android/app/src/main/res/values-fr/strings.xml b/focus-android/app/src/main/res/values-fr/strings.xml
index 3a0157284663..5472048ce40b 100644
--- a/focus-android/app/src/main/res/values-fr/strings.xml
+++ b/focus-android/app/src/main/res/values-fr/strings.xml
@@ -85,7 +85,11 @@
Partager avecEffacer l’historique de navigation ?
- Appuyez sur cette notification ou supprimez-la pour effacer votre historique de navigation de façon sécurisée.
+ Appuyez sur cette notification ou supprimez-la pour effacer votre historique de navigation de façon sécurisée.
+
+
+ Appuyez sur cette notification ou faites-la glisser pour effacer votre historique de navigation de façon sécurisée.Effacer l’historique de navigation
diff --git a/focus-android/app/src/main/res/values-hsb/strings.xml b/focus-android/app/src/main/res/values-hsb/strings.xml
index 4db20e068ff3..89cb23f53aaf 100644
--- a/focus-android/app/src/main/res/values-hsb/strings.xml
+++ b/focus-android/app/src/main/res/values-hsb/strings.xml
@@ -84,7 +84,11 @@
Dźělić přezPřehladowansku historiju zhašeć?
- Podótkńće so tuteje zdźělenki abo zhašejće ju, zo byšće swoju přehladowansku historiju wěsće zhašał.
+ Podótkńće so tuteje zdźělenki abo zhašejće ju, zo byšće swoju přehladowansku historiju wěsće zhašał.
+
+
+ Podótkńće so tuteje zdźělenki abo zjědźće přez ju, zo byšće swoju přehladowansku historiju wěsće zhašał.Přehladowansku historiju zhašeć
diff --git a/focus-android/app/src/main/res/values-it/strings.xml b/focus-android/app/src/main/res/values-it/strings.xml
index beff7d973c79..cf0e6b6abd63 100644
--- a/focus-android/app/src/main/res/values-it/strings.xml
+++ b/focus-android/app/src/main/res/values-it/strings.xml
@@ -85,7 +85,11 @@
Condividi conEliminare la cronologia di navigazione?
- Tocca o cancella questa notifica per eliminare in modo sicuro la cronologia di navigazione.
+ Tocca o cancella questa notifica per eliminare in modo sicuro la cronologia di navigazione.
+
+
+ Tocca o fai scorrere questa notifica per eliminare in modo sicuro la cronologia di navigazione.Elimina cronologia di navigazione
diff --git a/focus-android/app/src/main/res/values-kk/strings.xml b/focus-android/app/src/main/res/values-kk/strings.xml
index a21db438bbd4..f3d7a9e74c8c 100644
--- a/focus-android/app/src/main/res/values-kk/strings.xml
+++ b/focus-android/app/src/main/res/values-kk/strings.xml
@@ -85,7 +85,11 @@
Шолу тарихын өшіру керек пе?
- Шолу журналын қауіпсіз түрде өшіру үшін осы хабарландыруды шертіңіз немесе тазартыңыз.
+ Шолу журналын қауіпсіз түрде өшіру үшін осы хабарландыруды шертіңіз немесе тазартыңыз.
+
+
+ Шолу журналын қауіпсіз түрде өшіру үшін осы хабарландыруды шертіңіз немесе сырғытыңыз.Шолу тарихын өшіру
diff --git a/focus-android/app/src/main/res/values-pt-rBR/strings.xml b/focus-android/app/src/main/res/values-pt-rBR/strings.xml
index 7689306525fe..31a8fe7df374 100644
--- a/focus-android/app/src/main/res/values-pt-rBR/strings.xml
+++ b/focus-android/app/src/main/res/values-pt-rBR/strings.xml
@@ -15,7 +15,7 @@
Pesquise ou digite um endereço
- Navegação privativa automática.\nNavegar. Apagar. Repetir.
+ Navegação privativa automática.\nNavegar. Limpar. Repetir.Seu histórico de navegação foi apagado.
@@ -84,36 +84,40 @@
Compartilhar viaLimpar histórico de navegação?
- Toque ou remova esta notificação para limpar com segurança o histórico de navegação.
+ Toque ou remova esta notificação para limpar com segurança o histórico de navegação.
- Apagar histórico de navegação
+
+ Toque ou deslize esta notificação para limpar com segurança o histórico de navegação.
+
+ Limpar histórico de navegaçãoAbrir
- Apagar e abrir
+ Limpar e abrir
- Apagar
+ Limpar
- Apagar histórico de navegação
+ Limpar histórico de navegação
- Apagar e abrir
+ Limpar e abrir
- Apagar e abrir %1$s
+ Limpar e abrir %1$s
- Apagar histórico de navegação
+ Limpar histórico de navegação
+ Tryck på eller svep den här aviseringen för att säkert radera din webbhistorik.Radera webbhistorik
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 37409520f81a..a2fbdb979641 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
@@ -84,7 +84,11 @@
分享方式需要清除浏览历史吗?
- 点按或清除此通知,即可安全清除浏览历史。
+ 点按或清除此通知,即可安全清除浏览历史。
+
+
+ 点按或轻扫此通知,即可安全清除浏览历史。清除浏览历史
From 6e9370b1de0d91ebd5bfb9ba298bc01362e3405a Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Sat, 24 Feb 2024 00:15:42 +0000
Subject: [PATCH 316/586] Update GeckoView (Nightly) to 125.0.20240223210323.
---
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 65f450748bb9..897aeaf6a095 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 = "125.0.20240223095502"
+ const val version = "125.0.20240223210323"
/**
* GeckoView channel
From be01a10630d5e0898979d27bac5f40258ae43749 Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Sat, 24 Feb 2024 14:30:05 +0000
Subject: [PATCH 317/586] Update GeckoView (Nightly) to 125.0.20240224093754.
---
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 897aeaf6a095..f3beab2d65f1 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 = "125.0.20240223210323"
+ const val version = "125.0.20240224093754"
/**
* GeckoView channel
From 72721a4d2eebb912320fa4f934f8f7c4aa7ff301 Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Sun, 25 Feb 2024 00:48:38 +0000
Subject: [PATCH 318/586] Update GeckoView (Nightly) to 125.0.20240224211946.
---
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 f3beab2d65f1..d49cd9906523 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 = "125.0.20240224093754"
+ const val version = "125.0.20240224211946"
/**
* GeckoView channel
From ff9e2a1d4e61d9e2430bfab46e8fdf7553b52532 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Sun, 25 Feb 2024 00:03:43 +0000
Subject: [PATCH 319/586] Import translations from android-l10n
---
.../menu/src/main/res/values-hu/strings.xml | 2 ++
.../addons/src/main/res/values-hu/strings.xml | 20 ++++++++++++++-----
fenix/app/src/main/res/values-hu/strings.xml | 4 ++--
.../src/main/res/values-en-rGB/strings.xml | 6 +++++-
.../app/src/main/res/values-fi/strings.xml | 6 +++++-
.../app/src/main/res/values-gl/strings.xml | 12 ++++++-----
.../app/src/main/res/values-hu/strings.xml | 6 +++++-
.../app/src/main/res/values-iw/strings.xml | 6 +++++-
.../src/main/res/values-nn-rNO/strings.xml | 6 ++++++
.../src/main/res/values-pa-rIN/strings.xml | 6 +++++-
.../app/src/main/res/values-tr/strings.xml | 6 +++++-
.../app/src/main/res/values-vi/strings.xml | 6 +++++-
.../src/main/res/values-zh-rTW/strings.xml | 6 +++++-
13 files changed, 72 insertions(+), 20 deletions(-)
diff --git a/android-components/components/browser/menu/src/main/res/values-hu/strings.xml b/android-components/components/browser/menu/src/main/res/values-hu/strings.xml
index 041da77050bd..65f04da351c8 100644
--- a/android-components/components/browser/menu/src/main/res/values-hu/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-hu/strings.xml
@@ -10,4 +10,6 @@
KiegészítőkezelőNavigálás fel
+
+ Kiegészítők, navigáció felfelé
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 f9eefc6f90d7..5e905e11ef71 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
@@ -98,6 +98,8 @@
Engedélyezés privát böngészésbenFuttatás privát böngészésben
+
+ Privát ablakokban nem engedélyezettEngedélyezve
@@ -137,13 +139,17 @@
Mégse
- Kiegészítő telepítése
+ Kiegészítő telepítése
+
+ A(z) %1$s telepítéseMégseÉrtékelések: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Értékelés: %1$.02f az 5-bőlKiegészítők
@@ -244,10 +250,14 @@
Állapot:A(z) %1$s hozzá lett adva ehhez: %2$s.
-
- Nyissa meg a menüben
+
+ Nyissa meg a menüben
+
+ Érje el a(z) %1$s kiegészítőt a %2$s menüjéből.
+
+ Rendben, értem
- Rendben, értem
+ RendbenTovábbi tudnivalók
diff --git a/fenix/app/src/main/res/values-hu/strings.xml b/fenix/app/src/main/res/values-hu/strings.xml
index fad21e3e8ee2..38ba20bd661d 100644
--- a/fenix/app/src/main/res/values-hu/strings.xml
+++ b/fenix/app/src/main/res/values-hu/strings.xml
@@ -799,9 +799,9 @@
Görgetés az eszköztár elrejtéséhez
- Eszköztár oldalra seprése a lapok közti váltáshoz
+ Eszköztár oldalra csúsztatása a lapok közti váltáshoz
- Eszköztár felfelé seprése a lapok megnyitásához
+ Eszköztár felfelé csúsztatása a lapok megnyitásához
diff --git a/focus-android/app/src/main/res/values-en-rGB/strings.xml b/focus-android/app/src/main/res/values-en-rGB/strings.xml
index 94bddecd22cc..48fb8ef313cf 100644
--- a/focus-android/app/src/main/res/values-en-rGB/strings.xml
+++ b/focus-android/app/src/main/res/values-en-rGB/strings.xml
@@ -84,7 +84,11 @@
Share viaErase 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
diff --git a/focus-android/app/src/main/res/values-fi/strings.xml b/focus-android/app/src/main/res/values-fi/strings.xml
index 97f8aa38a45d..34399986dd8a 100644
--- a/focus-android/app/src/main/res/values-fi/strings.xml
+++ b/focus-android/app/src/main/res/values-fi/strings.xml
@@ -84,7 +84,11 @@
Jaa palvelullaPoistetaanko selaushistoria?
- Napauta tai tyhjennä tämä ilmoitus tyhjentääksesi selaushistoriasi turvallisesti.
+ Napauta tai tyhjennä tämä ilmoitus tyhjentääksesi selaushistoriasi turvallisesti.
+
+
+ Napauta tai pyyhkäise tämä ilmoitus tyhjentääksesi selaushistoriasi turvallisesti.Tyhjennä selaushistoria
diff --git a/focus-android/app/src/main/res/values-gl/strings.xml b/focus-android/app/src/main/res/values-gl/strings.xml
index 490d9745c60f..1008df7889fb 100644
--- a/focus-android/app/src/main/res/values-gl/strings.xml
+++ b/focus-android/app/src/main/res/values-gl/strings.xml
@@ -54,7 +54,6 @@
Retirar dos atallos
- NovidadesAxustesSobreAxuda
@@ -85,10 +84,13 @@
sharing an URL. -->
Compartir por
-
+ Quere borrar o historial de navegación?
+ Tocar ou borrar esta notificación para borrar de forma segura o seu historial de navegación.
+
+
+ Tocar ou deslizar esta notificación para borrar de forma segura o seu historial de navegación.
+
Borrar o historial de navegación
diff --git a/focus-android/app/src/main/res/values-hu/strings.xml b/focus-android/app/src/main/res/values-hu/strings.xml
index 4665dc4affca..220f06b576db 100644
--- a/focus-android/app/src/main/res/values-hu/strings.xml
+++ b/focus-android/app/src/main/res/values-hu/strings.xml
@@ -84,7 +84,11 @@
Megosztás ezzelTörli a böngészési előzményeket?
- Koppintson vagy törölje ezt az értesítést a böngészési előzmények biztonságos törléséhez.
+ Koppintson vagy törölje ezt az értesítést a böngészési előzmények biztonságos törléséhez.
+
+
+ Koppintson vagy csúsztassa oldalra ezt az értesítést a böngészési előzmények biztonságos törléséhez.Előzmények törlése
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 404587cd5062..341da731a3be 100644
--- a/focus-android/app/src/main/res/values-iw/strings.xml
+++ b/focus-android/app/src/main/res/values-iw/strings.xml
@@ -85,7 +85,11 @@
למחוק את היסטוריית הגלישה?
- יש להקיש או לנקות התרעה זו כדי למחוק בצורה מאובטחת את היסטוריית הגלישה שלך.
+ יש להקיש או לנקות התרעה זו כדי למחוק בצורה מאובטחת את היסטוריית הגלישה שלך.
+
+
+ יש להקיש או להחליק על התרעה זו כדי למחוק בצורה מאובטחת את היסטוריית הגלישה שלך.מחיקת היסטורית גלישה
diff --git a/focus-android/app/src/main/res/values-nn-rNO/strings.xml b/focus-android/app/src/main/res/values-nn-rNO/strings.xml
index 753f4d7d530b..161e4d491905 100644
--- a/focus-android/app/src/main/res/values-nn-rNO/strings.xml
+++ b/focus-android/app/src/main/res/values-nn-rNO/strings.xml
@@ -86,6 +86,12 @@
Slette nettlesarhistorikk?
+ Trykk eller fjern dette varselet for å slette nettlesarhistorikken din på ein trygg måte.
+
+
+ Trykk eller sveip dette varselet for å slette nettlesarhistorikken din på ein trygg måte.
+
Slett nettlesarhistorikk
diff --git a/focus-android/app/src/main/res/values-pa-rIN/strings.xml b/focus-android/app/src/main/res/values-pa-rIN/strings.xml
index e8bf2c5f0628..e036343bb920 100644
--- a/focus-android/app/src/main/res/values-pa-rIN/strings.xml
+++ b/focus-android/app/src/main/res/values-pa-rIN/strings.xml
@@ -85,7 +85,11 @@
ਇਸ ਰਾਹੀਂ ਸਾਂਝਾ ਕਰੋਬਰਾਊਜ਼ ਕਰਨ ਦੇ ਅਤੀਤ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?
- ਤੁਹਾਡੇ ਬਰਾਊਜ਼ ਕਰਨ ਦੇ ਅਤੀਤ ਨੂੰ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਮਿਟਾਉਣ ਲਈ ਇਸ ਨੋਟੀਫਿਕੇਸ਼ਨ ਨੂੰ ਛੂਹੋ ਜਾਂ ਸਾਫ਼ ਕਰੋ।
+ ਤੁਹਾਡੇ ਬਰਾਊਜ਼ ਕਰਨ ਦੇ ਅਤੀਤ ਨੂੰ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਮਿਟਾਉਣ ਲਈ ਇਸ ਨੋਟੀਫਿਕੇਸ਼ਨ ਨੂੰ ਛੂਹੋ ਜਾਂ ਸਾਫ਼ ਕਰੋ।
+
+
+ ਤੁਹਾਡੇ ਬਰਾਊਜ਼ ਕਰਨ ਦੇ ਅਤੀਤ ਨੂੰ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਮਿਟਾਉਣ ਲਈ ਇਸ ਨੋਟੀਫਿਕੇਸ਼ਨ ਨੂੰ ਛੂਹੋ ਜਾਂ ਸਰਕਾਓ।ਬਰਾਊਜ਼ਰ ਕਰਨ ਦੇ ਅਤੀਤ ਨੂੰ ਮਿਟਾਓ
diff --git a/focus-android/app/src/main/res/values-tr/strings.xml b/focus-android/app/src/main/res/values-tr/strings.xml
index fcf1369d7f30..5198021e0bb7 100644
--- a/focus-android/app/src/main/res/values-tr/strings.xml
+++ b/focus-android/app/src/main/res/values-tr/strings.xml
@@ -84,7 +84,11 @@
PaylaşGezinti geçmişi silinsin mi?
- Gezinti geçmişinizi güvenli bir şekilde silmek için bu bildirime dokunun veya bildirimi temizleyin.
+ Gezinti geçmişinizi güvenli bir şekilde silmek için bu bildirime dokunun veya bildirimi temizleyin.
+
+
+ Gezinti geçmişinizi güvenli bir şekilde silmek için bu bildirime dokunun veya bildirimi kaydırın.Gezinti geçmişini sil
diff --git a/focus-android/app/src/main/res/values-vi/strings.xml b/focus-android/app/src/main/res/values-vi/strings.xml
index c0cf8034bc89..a36de696539e 100644
--- a/focus-android/app/src/main/res/values-vi/strings.xml
+++ b/focus-android/app/src/main/res/values-vi/strings.xml
@@ -84,7 +84,11 @@
Chia sẻ quaXóa lịch sử duyệt web?
- Nhấn hoặc xóa thông báo này để xóa lịch sử duyệt web của bạn một cách an toàn.
+ Nhấn hoặc xóa thông báo này để xóa lịch sử duyệt web của bạn một cách an toàn.
+
+
+ Nhấn hoặc vuốt thông báo này để xóa lịch sử duyệt web của bạn một cách an toàn.Xóa lịch sử duyệt web
diff --git a/focus-android/app/src/main/res/values-zh-rTW/strings.xml b/focus-android/app/src/main/res/values-zh-rTW/strings.xml
index bec717121834..544e8ddf9fc3 100644
--- a/focus-android/app/src/main/res/values-zh-rTW/strings.xml
+++ b/focus-android/app/src/main/res/values-zh-rTW/strings.xml
@@ -84,7 +84,11 @@
透過下列程式分享要清除瀏覽紀錄嗎?
- 點擊或滑掉這則通知,即可安全地清除您的瀏覽紀錄。
+ 點擊或滑掉這則通知,即可安全地清除您的瀏覽紀錄。
+
+
+ 點擊或滑掉這則通知,即可安全地清除您的瀏覽紀錄。清除瀏覽紀錄
From 8bdc4e0e4e5716977ba07ea7ec9f06ccf3c63c5a Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Sun, 25 Feb 2024 12:50:05 +0000
Subject: [PATCH 320/586] Update GeckoView (Nightly) to 125.0.20240225092952.
---
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 d49cd9906523..1e9efb920978 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 = "125.0.20240224211946"
+ const val version = "125.0.20240225092952"
/**
* GeckoView channel
From 375c3b11bf6378300b41798120cfa5ee0fd57c10 Mon Sep 17 00:00:00 2001
From: Gregory Mierzwinski
Date: Sun, 25 Feb 2024 16:04:28 -0500
Subject: [PATCH 321/586] Bug 1881976 - Replace web-de with bild-de pageload
test.
---
taskcluster/ci/browsertime/kind.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/taskcluster/ci/browsertime/kind.yml b/taskcluster/ci/browsertime/kind.yml
index 72abff3d53c1..7f7d8565deca 100644
--- a/taskcluster/ci/browsertime/kind.yml
+++ b/taskcluster/ci/browsertime/kind.yml
@@ -117,7 +117,7 @@ tasks:
- reddit
- sina
- [stackoverflow, stacko]
- - web-de
+ - bild-de
- cnn
- [google-search-restaurants, gsearch-r]
From 759b0e68b51e809baa11bb3e2c3c126522415490 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Mon, 26 Feb 2024 00:03:51 +0000
Subject: [PATCH 322/586] Import translations from android-l10n
---
.../menu/src/main/res/values-cak/strings.xml | 2 +
.../menu/src/main/res/values-mix/strings.xml | 4 ++
.../src/main/res/values-cak/strings.xml | 20 ++++++---
.../src/main/res/values-es-rES/strings.xml | 2 +
.../src/main/res/values-nn-rNO/strings.xml | 14 +++---
.../src/main/res/values-cak/strings.xml | 12 +++++
fenix/app/src/main/res/values-azb/strings.xml | 44 +++++++++++++++++++
.../src/main/res/values-es-rES/strings.xml | 13 ++++++
.../app/src/main/res/values-co/strings.xml | 6 ++-
.../src/main/res/values-es-rES/strings.xml | 6 ++-
.../app/src/main/res/values-mix/strings.xml | 18 +++++---
.../app/src/main/res/values-sk/strings.xml | 6 ++-
12 files changed, 128 insertions(+), 19 deletions(-)
diff --git a/android-components/components/browser/menu/src/main/res/values-cak/strings.xml b/android-components/components/browser/menu/src/main/res/values-cak/strings.xml
index b8b9d28a2fda..0cfe779409e6 100644
--- a/android-components/components/browser/menu/src/main/res/values-cak/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-cak/strings.xml
@@ -10,4 +10,6 @@
Kinuk\'samajel taq Tz\'aqatTib\'an okem ajsik
+
+ Taq tz\'aqat, tijote\' chi rokem
diff --git a/android-components/components/browser/menu/src/main/res/values-mix/strings.xml b/android-components/components/browser/menu/src/main/res/values-mix/strings.xml
index 814f5c33bab9..29660dc2255a 100644
--- a/android-components/components/browser/menu/src/main/res/values-mix/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-mix/strings.xml
@@ -8,4 +8,8 @@
Add-onsKomplementos
+
+ Ku\'ntyeé kutyi
+
+ Complemento, ku\'ntyeé kutyi
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 0ff4c47a6e43..12c845c5683e 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
@@ -98,6 +98,8 @@
Tiya\' q\'ij chi re pa ichinan okem pa k\'amaya\'lTisamajïx pa ichinan okem pa k\'amaya\'l
+
+ Man okel ta pa ichinan rutzuwächTzijon
@@ -137,13 +139,17 @@
Tiq\'at
- Tiyak ri Tz\'aqat
+ Tiyak ri Tz\'aqat
+
+ Tiyak %1$sTiq\'atTaq nik\'oxïk: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Rajlab\'al: %1$.02f richin 5Taq tz\'aqat
@@ -244,10 +250,14 @@
Rub\'anikil:%1$s xtz\'aqatisäx pa %2$s.
-
- Tijaq pa k\'utsamaj
+
+ Tijaq pa k\'utsamaj
+
+ Tok pa %1$s chupam ri %2$s cholsamaj.
+
+ Ütz, Xq\'ax pa nuwi\'
- Ütz, Xq\'ax pa nuwi\'
+ ÜTZTetamäx ch\'aqa\' chik
diff --git a/android-components/components/feature/addons/src/main/res/values-es-rES/strings.xml b/android-components/components/feature/addons/src/main/res/values-es-rES/strings.xml
index 75611b757341..401ec4fbe942 100644
--- a/android-components/components/feature/addons/src/main/res/values-es-rES/strings.xml
+++ b/android-components/components/feature/addons/src/main/res/values-es-rES/strings.xml
@@ -98,6 +98,8 @@
Permitir en navegación privadaEjecutar en navegación privada
+
+ No permitido en ventanas privadasActivado
diff --git a/android-components/components/feature/addons/src/main/res/values-nn-rNO/strings.xml b/android-components/components/feature/addons/src/main/res/values-nn-rNO/strings.xml
index 5b468abcf000..72aa3cbdac54 100644
--- a/android-components/components/feature/addons/src/main/res/values-nn-rNO/strings.xml
+++ b/android-components/components/feature/addons/src/main/res/values-nn-rNO/strings.xml
@@ -75,7 +75,7 @@
Utviklar
- Utviklarar
+ UtviklararSist oppdatert
@@ -96,6 +96,8 @@
Tillat i privat nettlesingKøyr i privat nettlesing
+
+ Ikkje tillate i private vindaugePåslått
@@ -135,13 +137,13 @@
Avbryt
- Installer tillegg
+ Installer tilleggAvbrytOmtalar: %1$s
- %1$.02f/5
+ %1$.02f/5Tillegg
@@ -242,10 +244,10 @@
Status:%1$s er lagt til i %2$s
-
- Opne det i menyen
+
+ Opne det i menyen
- Ok, eg forstår
+ Ok, eg forstårLes meir
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 81a8705c8e0a..04ab88dc0cfa 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
@@ -101,8 +101,12 @@
Kenuk\'samajïx ewan taq tzijKerik\' ri chilab\'en tikirib\'äl taq molojri\'ïl
+
+ Kerik\' kij ri yakon ewan taq tzijKek\'ol ri chilab\'en tikirib\'äl taq molojri\'ïl
+
+ Kek\'ol ri yakon ewan taq tzijChilab\'en taq molojri\'ïl
@@ -131,8 +135,12 @@
Tokisäx yakon tarjeta\'Kerik\' ri chilab\'en rutarjeta\' kre\ito\'
+
+ Kerik yakon taq tarjeta\'Kek\'ol ri chilab\'en rutarjeta\' kre\ito\'
+
+ Kek\'ol yakon taq tarjeta\'Kenuk\'samajïx kikre\'ito\' taq tarjeta\'
@@ -151,8 +159,12 @@
Ticha\' ochochib\'älKerik\' ri chilab\'en ochochib\'äl
+
+ Kerik\' yakon taq ochochib\'älKek\'ol ri chilab\'en ochochib\'äl
+
+ Kek\'ol yakon taq ochochib\'älKenuk\'samajïx taq ochochib\'äl
diff --git a/fenix/app/src/main/res/values-azb/strings.xml b/fenix/app/src/main/res/values-azb/strings.xml
index d317cc475360..eaf9def6d220 100644
--- a/fenix/app/src/main/res/values-azb/strings.xml
+++ b/fenix/app/src/main/res/values-azb/strings.xml
@@ -1309,6 +1309,50 @@
%d مجموعهسی
+
+
+ پایلاش
+
+ پایلاش
+
+ PDF اولاراق ساخلا
+
+ PDF یارادیلانمادیْ
+
+ باغلا
+
+ بو صفحه پرینت اوْلانمیر
+
+ پرینت
+
+ جهازا گؤندر
+
+ بوتون عمللر
+
+ یاخیندا ایشلهدیلمیش
+
+ کلیپبوردا کوْپی ائله
+
+ کلیپبوْردا کوْپی اوْلوندو
+
+ دؤنگله گیریش
+
+ دیتا دؤنگلی و ساخلاماسی
+
+ بوتون جهازلارا گؤندر
+
+ دونگلی کَس
+
+ آفلاین
+
+ باشقا جهازا باغلا
+
+
+ بیر تاغ گؤندرمک اوچون آزی بیر باشقا جهازدا فایرفاکسا داخیل اوْلون.
+
+ آنلادیم
+
diff --git a/fenix/app/src/main/res/values-es-rES/strings.xml b/fenix/app/src/main/res/values-es-rES/strings.xml
index 5f00a5e888b5..e9888675a7ed 100644
--- a/fenix/app/src/main/res/values-es-rES/strings.xml
+++ b/fenix/app/src/main/res/values-es-rES/strings.xml
@@ -2106,8 +2106,12 @@
Introduce una contraseñaSe requiere nombre de usuario
+
+ Introduce un nombre de usuarioSe requiere nombre de servidor
+
+ Introduce una dirección webBúsqueda por voz
@@ -2203,6 +2207,9 @@
Buscar con %s
+
+
+ Cambia tu navegador predeterminadoConfigura enlaces de sitios web, correos electrónicos y mensajes para que se abran automáticamente en Firefox.
@@ -2460,6 +2467,8 @@
Traducción en curso
+
+ Selecciona un idiomaHa surgido un problema al traducir. Por favor inténtalo de nuevo.
@@ -2480,6 +2489,10 @@
No traducir nunca %1$sNo traducir nunca este sitio
+
+ Anula todas las demás configuraciones
+
+ Anula las ofertas de traducciónAjustes de traducción
diff --git a/focus-android/app/src/main/res/values-co/strings.xml b/focus-android/app/src/main/res/values-co/strings.xml
index 3bc90bc2bc8d..ab83478c6f11 100644
--- a/focus-android/app/src/main/res/values-co/strings.xml
+++ b/focus-android/app/src/main/res/values-co/strings.xml
@@ -84,7 +84,11 @@
Sparte cùSquassà a cronolugia di navigazione ?
- Picchichjate o spazzate sta nutificazione per squassà di manera sicura a vostra cronolugia di navigazione.
+ Picchichjate o spazzate sta nutificazione per squassà di manera sicura a vostra cronolugia di navigazione.
+
+
+ Picchichjate sta nutificazione o fatela sguillà per squassà di manera sicura a vostra cronolugia di navigazione.Squassà a cronolugia di navigazione
diff --git a/focus-android/app/src/main/res/values-es-rES/strings.xml b/focus-android/app/src/main/res/values-es-rES/strings.xml
index ef6a229e321a..9e2aa7413a02 100644
--- a/focus-android/app/src/main/res/values-es-rES/strings.xml
+++ b/focus-android/app/src/main/res/values-es-rES/strings.xml
@@ -85,7 +85,11 @@
Compartir vía¿Eliminar historial de navegación?
- Toca o elimina esta notificación para borrar de forma segura tu historial de navegación.
+ Toca o elimina esta notificación para borrar de forma segura tu historial de navegación.
+
+
+ Toca o desliza esta notificación para borrar de forma segura tu historial de navegación.Eliminar historial de navegación
diff --git a/focus-android/app/src/main/res/values-mix/strings.xml b/focus-android/app/src/main/res/values-mix/strings.xml
index 7fbd90972480..03d0e45ea322 100644
--- a/focus-android/app/src/main/res/values-mix/strings.xml
+++ b/focus-android/app/src/main/res/values-mix/strings.xml
@@ -54,7 +54,6 @@
Stoó ña xina
- Ña tsa\'aNu samuTsaa ñaChinchee
@@ -85,10 +84,8 @@
sharing an URL. -->
Kua’a nu\'u
-
+ Stòo ña ndúkuku sata
+
Stòo ña ntukuku sata
@@ -1051,9 +1048,20 @@
close button from promote search widget dialog. -->
Kasi
+
+ Dnuku Widget
+
¡Koo ña ntsinu ! 🎉
+
+ Kitsa tsi sesión ku ntyeé seé tya ku kasiko ku rastreador tsi ntyi ka ña\'a.
+
+
+ Te dejaremos con tu navegación privada, pero podés conseguir un inicio más rápido la próxima vez con el widget de %1$s en la pantalla de inicio.
+
Chika\'a nu pantalla xina
diff --git a/focus-android/app/src/main/res/values-sk/strings.xml b/focus-android/app/src/main/res/values-sk/strings.xml
index 910917b5fd57..886c54f665a2 100644
--- a/focus-android/app/src/main/res/values-sk/strings.xml
+++ b/focus-android/app/src/main/res/values-sk/strings.xml
@@ -85,7 +85,11 @@
Zdieľať cezVymazať históriu prehliadania?
- Ťuknutím alebo vymazaním tohto upozornenia bezpečne vymažete svoju históriu prehliadania.
+ Ťuknutím alebo vymazaním tohto upozornenia bezpečne vymažete svoju históriu prehliadania.
+
+
+ Ťuknutím alebo potiahnutím tohto upozornenia bezpečne vymažete históriu prehliadania.Vymazať históriu prehliadania
From 79426f6000436307899adf927233b9eec6466081 Mon Sep 17 00:00:00 2001
From: rahulsainani
Date: Fri, 23 Feb 2024 11:21:27 +0100
Subject: [PATCH 323/586] Bug 1881703 - Notify app store of mode change from
TabsTray
---
.../java/org/mozilla/fenix/tabstray/TabsTrayController.kt | 4 +++-
.../mozilla/fenix/tabstray/DefaultTabsTrayControllerTest.kt | 3 +++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayController.kt b/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayController.kt
index 8c73da20bfd2..a48e1d622f67 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayController.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayController.kt
@@ -536,7 +536,9 @@ class DefaultTabsTrayController(
selected.isEmpty() && tabsTrayStore.state.mode.isSelect().not() -> {
TabsTray.openedExistingTab.record(TabsTray.OpenedExistingTabExtra(source ?: "unknown"))
tabsUseCases.selectTab(tab.id)
- browsingModeManager.mode = BrowsingMode.fromBoolean(tab.content.private)
+ val mode = BrowsingMode.fromBoolean(tab.content.private)
+ browsingModeManager.mode = mode
+ appStore.dispatch(AppAction.ModeChange(mode))
handleNavigateToBrowser()
}
tab.id in selected.map { it.id } -> handleTabUnselected(tab)
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/tabstray/DefaultTabsTrayControllerTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/tabstray/DefaultTabsTrayControllerTest.kt
index 82d73cd67484..3f522dea4193 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/tabstray/DefaultTabsTrayControllerTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/tabstray/DefaultTabsTrayControllerTest.kt
@@ -63,6 +63,7 @@ import org.mozilla.fenix.collections.CollectionsDialog
import org.mozilla.fenix.collections.show
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.TabCollectionStorage
+import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.components.bookmarks.BookmarksUseCase
import org.mozilla.fenix.ext.maxActiveTime
import org.mozilla.fenix.ext.potentialInactiveTabs
@@ -958,6 +959,7 @@ class DefaultTabsTrayControllerTest {
assertEquals(privateTab.id, browserStore.state.selectedTabId)
assertEquals(true, browsingModeManager.mode.isPrivate)
+ verify { appStore.dispatch(AppAction.ModeChange(BrowsingMode.Private)) }
controller.handleTabDeletion("privateTab")
browserStore.dispatch(TabListAction.SelectTabAction(normalTab.id)).joinBlocking()
@@ -965,6 +967,7 @@ class DefaultTabsTrayControllerTest {
assertEquals(normalTab.id, browserStore.state.selectedTabId)
assertEquals(false, browsingModeManager.mode.isPrivate)
+ verify { appStore.dispatch(AppAction.ModeChange(BrowsingMode.Normal)) }
} finally {
unmockkStatic("mozilla.components.browser.state.selector.SelectorsKt")
}
From 1898c06871975502ad5fbdc96a93844b669c059c Mon Sep 17 00:00:00 2001
From: "oana.horvath"
Date: Tue, 13 Feb 2024 15:41:33 +0200
Subject: [PATCH 324/586] Bug 1879525 - Create TestSetup helper: Compose Test
classes
---
.../fenix/helpers/AppAndSystemHelper.kt | 55 +++++++++++++++++--
.../org/mozilla/fenix/helpers/TestSetup.kt | 47 +++++++++++-----
.../mozilla/fenix/ui/ComposeBookmarksTest.kt | 34 +-----------
.../mozilla/fenix/ui/ComposeCollectionTest.kt | 26 +--------
.../fenix/ui/ComposeContextMenusTest.kt | 31 ++---------
.../mozilla/fenix/ui/ComposeHistoryTest.kt | 44 ++-------------
.../mozilla/fenix/ui/ComposeHomeScreenTest.kt | 27 +--------
.../fenix/ui/ComposeMediaNotificationTest.kt | 34 +-----------
.../fenix/ui/ComposeNavigationToolbarTest.kt | 28 +---------
.../org/mozilla/fenix/ui/ComposeSearchTest.kt | 11 ++--
...oseSettingsDeleteBrowsingDataOnQuitTest.kt | 26 +--------
.../ComposeSettingsDeleteBrowsingDataTest.kt | 22 +-------
.../fenix/ui/ComposeTabbedBrowsingTest.kt | 34 +-----------
.../mozilla/fenix/ui/ComposeTopSitesTest.kt | 27 +--------
.../mozilla/fenix/ui/robots/HistoryRobot.kt | 2 +-
15 files changed, 123 insertions(+), 325 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 bc10b79abdf5..6162bbf0f386 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
@@ -34,6 +34,9 @@ import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
import junit.framework.AssertionFailedError
import kotlinx.coroutines.runBlocking
+import mozilla.appservices.places.BookmarkRoot
+import mozilla.components.browser.storage.sync.PlacesBookmarksStorage
+import mozilla.components.browser.storage.sync.PlacesHistoryStorage
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.mozilla.fenix.Config
@@ -43,6 +46,7 @@ import org.mozilla.fenix.helpers.Constants.PackageName.PIXEL_LAUNCHER
import org.mozilla.fenix.helpers.Constants.PackageName.YOUTUBE_APP
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
+import org.mozilla.fenix.helpers.TestHelper.appContext
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.ext.waitNotNull
import org.mozilla.fenix.helpers.idlingresource.NetworkConnectionIdlingResource
@@ -70,7 +74,7 @@ object AppAndSystemHelper {
fun deleteDownloadedFileOnStorage(fileName: String) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
val storageManager: StorageManager? =
- TestHelper.appContext.getSystemService(Context.STORAGE_SERVICE) as StorageManager?
+ appContext.getSystemService(Context.STORAGE_SERVICE) as StorageManager?
val storageVolumes = storageManager!!.storageVolumes
val storageVolume: StorageVolume = storageVolumes[0]
val file = File(storageVolume.directory!!.path + "/Download/" + fileName)
@@ -110,7 +114,7 @@ object AppAndSystemHelper {
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?
+ appContext.getSystemService(Context.STORAGE_SERVICE) as StorageManager?
val storageVolumes = storageManager!!.storageVolumes
val storageVolume: StorageVolume = storageVolumes[0]
val downloadsFolder = File(storageVolume.directory!!.path + "/Download/")
@@ -121,16 +125,26 @@ object AppAndSystemHelper {
val files = downloadsFolder.listFiles()
// Check if the folder is not empty
+ // If you run this method before a test, files.isNotEmpty() will always return false.
if (files != null && files.isNotEmpty()) {
Log.i(
TAG,
- "clearDownloadsFolder: Verified that \"DOWNLOADS\" folder is not empty",
+ "clearDownloadsFolder: Before cleanup: Downloads storage contains: ${files.size} file(s)",
)
// Delete all files in the folder
for (file in files) {
file.delete()
- Log.i(TAG, "clearDownloadsFolder: Deleted $file from \"DOWNLOADS\" folder")
+ Log.i(
+ TAG,
+ "clearDownloadsFolder: Deleted $file from \"DOWNLOADS\" folder." +
+ " Downloads storage contains ${files.size} file(s): $file",
+ )
}
+ } else {
+ Log.i(
+ TAG,
+ "clearDownloadsFolder: Downloads storage is empty.",
+ )
}
}
} else {
@@ -139,6 +153,7 @@ object AppAndSystemHelper {
Log.i(TAG, "clearDownloadsFolder: Verifying if any download files exist.")
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.listFiles()?.forEach {
+ Log.i(TAG, "clearDownloadsFolder: Downloads storage contains: $it.")
it.delete()
Log.i(TAG, "clearDownloadsFolder: Download file $it deleted.")
}
@@ -146,6 +161,36 @@ object AppAndSystemHelper {
}
}
+ suspend fun deleteHistoryStorage() {
+ val historyStorage = PlacesHistoryStorage(appContext.applicationContext)
+ Log.i(
+ TAG,
+ "deleteHistoryStorage before cleanup: History storage contains: ${historyStorage.getVisited()}",
+ )
+ if (historyStorage.getVisited().isNotEmpty()) {
+ Log.i(TAG, "deleteHistoryStorage: Trying to delete all history storage.")
+ historyStorage.deleteEverything()
+ Log.i(
+ TAG,
+ "deleteHistoryStorage after cleanup: History storage contains: ${historyStorage.getVisited()}",
+ )
+ }
+ }
+
+ suspend fun deleteBookmarksStorage() {
+ val bookmarksStorage = PlacesBookmarksStorage(appContext.applicationContext)
+ val bookmarks = bookmarksStorage.getTree(BookmarkRoot.Mobile.id)?.children
+ Log.i(TAG, "deleteBookmarksStorage before cleanup: Bookmarks storage contains: $bookmarks")
+ if (bookmarks?.isNotEmpty() == true) {
+ bookmarks.forEach {
+ Log.i(TAG, "deleteBookmarksStorage: Trying to delete $it bookmark from storage.")
+ 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, "deleteBookmarksStorage: Bookmark deleted. Bookmarks storage contains: $bookmarks")
+ }
+ }
+ }
+
fun setNetworkEnabled(enabled: Boolean) {
val networkDisconnectedIdlingResource = NetworkConnectionIdlingResource(false)
val networkConnectedIdlingResource = NetworkConnectionIdlingResource(true)
@@ -228,7 +273,7 @@ object AppAndSystemHelper {
*/
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
+ val activityManager = appContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
mDevice.waitForIdle(TestAssetHelper.waitingTimeShort)
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
index b080154c4a1b..02b24f439bed 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/TestSetup.kt
@@ -1,41 +1,51 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.helpers
import android.util.Log
import kotlinx.coroutines.runBlocking
-import mozilla.appservices.places.BookmarkRoot
-import mozilla.components.browser.storage.sync.PlacesBookmarksStorage
+import mozilla.components.browser.state.store.BrowserStore
import okhttp3.mockwebserver.MockWebServer
+import org.junit.After
import org.junit.Before
+import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.TestHelper.appContext
import org.mozilla.fenix.ui.robots.notificationShade
+/**
+ * Standard Test setup and tear down methods to run before each test.
+ * Some extra clean-up is required when we're using the org.mozilla.fenix.helpers.RetryTestRule (the instrumentation does not do that in this case).
+ *
+ */
open class TestSetup {
lateinit var mockWebServer: MockWebServer
- private val bookmarksStorage = PlacesBookmarksStorage(appContext.applicationContext)
+ lateinit var browserStore: BrowserStore
@Before
- fun setUp() {
+ open fun setUp() {
Log.i(TAG, "TestSetup: Starting the @Before setup")
- // Clear pre-existing notifications
+ // Initializing this as part of class construction, below the rule would throw a NPE.
+ // So we are initializing this here instead of in all related tests.
+ Log.i(TAG, "TestSetup: Initializing the browserStore instance")
+ browserStore = appContext.components.core.store
+ // Clear pre-existing notifications.
notificationShade {
cancelAllShownNotifications()
}
runBlocking {
// Reset locale to EN-US if needed.
AppAndSystemHelper.resetSystemLocaleToEnUS()
- // Check and clear the downloads folder
+ // Check and clear the downloads folder, in case the tearDown method is not executed.
+ // This will only work in case of a RetryTestRule execution.
AppAndSystemHelper.clearDownloadsFolder()
- // Make sure the Wifi and Mobile Data connections are on
+ // 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")
- }
+ // Clear bookmarks left after a failed test, before a retry.
+ AppAndSystemHelper.deleteBookmarksStorage()
+ // Clear history left after a failed test, before a retry.
+ AppAndSystemHelper.deleteHistoryStorage()
}
mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher()
@@ -49,4 +59,11 @@ open class TestSetup {
mockWebServer.start()
}
}
+
+ @After
+ open fun tearDown() {
+ Log.i(TAG, "TestSetup: Starting the @After tearDown methods.")
+ // Check and clear the downloads folder.
+ AppAndSystemHelper.clearDownloadsFolder()
+ }
}
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 26d31d920f28..263a30f932d8 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
@@ -8,18 +8,10 @@ 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.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.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
@@ -28,7 +20,9 @@ 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.mDevice
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
@@ -38,9 +32,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
/**
* Tests for verifying basic functionality of bookmarks
*/
-class ComposeBookmarksTest {
- private lateinit var mockWebServer: MockWebServer
- private lateinit var mDevice: UiDevice
+class ComposeBookmarksTest : TestSetup() {
private val bookmarksFolderName = "New Folder"
private val testBookmark = object {
var title: String = "Bookmark title"
@@ -59,26 +51,6 @@ class ComposeBookmarksTest {
@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/ComposeCollectionTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeCollectionTest.kt
index a18366cc7453..e570ae59e604 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
@@ -5,19 +5,15 @@
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.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.composeTabDrawer
@@ -29,9 +25,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
*
*/
-class ComposeCollectionTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
+class ComposeCollectionTest : TestSetup() {
private val firstCollectionName = "testcollection_1"
private val secondCollectionName = "testcollection_2"
private val collectionName = "First Collection"
@@ -51,20 +45,6 @@ class ComposeCollectionTest {
),
) { 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/ComposeContextMenusTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeContextMenusTest.kt
index 5e554b49d0a2..0261c72d896d 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
@@ -6,15 +6,8 @@ package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.core.net.toUri
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
-import okhttp3.mockwebserver.MockWebServer
-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
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
@@ -23,7 +16,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
@@ -45,15 +40,14 @@ import org.mozilla.fenix.ui.robots.shareOverlay
*
*/
-class ComposeContextMenusTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
+class ComposeContextMenusTest : TestSetup() {
@get:Rule(order = 0)
val composeTestRule =
AndroidComposeTestRule(
- HomeActivityIntentTestRule.withDefaultSettingsOverrides(
+ HomeActivityIntentTestRule(
tabsTrayRewriteEnabled = true,
+ isJumpBackInCFREnabled = false,
),
) { it.activity }
@@ -61,21 +55,6 @@ class ComposeContextMenusTest {
@JvmField
val retryTestRule = RetryTestRule(3)
- @Before
- fun setUp() {
- composeTestRule.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/ComposeHistoryTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHistoryTest.kt
index 138ffa7c300a..d3b17f57d929 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
@@ -4,31 +4,23 @@
package org.mozilla.fenix.ui
-import android.content.Context
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
-import androidx.test.uiautomator.UiDevice
-import kotlinx.coroutines.runBlocking
-import mozilla.components.browser.storage.sync.PlacesHistoryStorage
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
import org.mozilla.fenix.customannotations.SmokeTest
-import org.mozilla.fenix.ext.settings
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
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.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.historyMenu
import org.mozilla.fenix.ui.robots.homeScreen
@@ -39,42 +31,16 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
* Tests for verifying basic functionality of history
*
*/
-class ComposeHistoryTest {
- private lateinit var mockWebServer: MockWebServer
- private lateinit var mDevice: UiDevice
-
+class ComposeHistoryTest : TestSetup() {
@get:Rule
val activityTestRule =
AndroidComposeTestRule(
- HomeActivityIntentTestRule.withDefaultSettingsOverrides(
+ HomeActivityIntentTestRule(
tabsTrayRewriteEnabled = true,
+ isJumpBackInCFREnabled = false,
),
) { it.activity }
- @Before
- fun setUp() {
- InstrumentationRegistry.getInstrumentation().targetContext.settings()
- .shouldShowJumpBackInCFR = false
-
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- // Clearing all history data after each test to avoid overlapping data
- val applicationContext: Context = activityTestRule.activity.applicationContext
- val historyStorage = PlacesHistoryStorage(applicationContext)
-
- runBlocking {
- historyStorage.deleteEverything()
- }
- }
-
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243285
@Test
fun verifyEmptyHistoryMenuTest() {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHomeScreenTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHomeScreenTest.kt
index e6930672a92e..38ed0da774ea 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHomeScreenTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeHomeScreenTest.kt
@@ -5,19 +5,14 @@
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.customannotations.SmokeTest
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.RetryTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
@@ -28,10 +23,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
*
*/
-class ComposeHomeScreenTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
-
+class ComposeHomeScreenTest : TestSetup() {
@get:Rule(order = 0)
val activityTestRule =
AndroidComposeTestRule(
@@ -44,21 +36,6 @@ class ComposeHomeScreenTest {
@JvmField
val retryTestRule = RetryTestRule(3)
- @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/235396
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1844580")
@Test
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeMediaNotificationTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeMediaNotificationTest.kt
index 63c0ad07b675..c673cbe3deeb 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeMediaNotificationTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeMediaNotificationTest.kt
@@ -5,23 +5,17 @@
package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
-import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.mediasession.MediaSession
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
-import org.mozilla.fenix.ext.components
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.MatcherHelper
import org.mozilla.fenix.helpers.RetryTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
+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.clickPageObject
import org.mozilla.fenix.ui.robots.homeScreen
@@ -34,11 +28,7 @@ import org.mozilla.fenix.ui.robots.notificationShade
* - a media notification icon is displayed on the homescreen for the tab playing media content
* Note: this test only verifies media notifications, not media itself
*/
-class ComposeMediaNotificationTest {
- private lateinit var mockWebServer: MockWebServer
- private lateinit var mDevice: UiDevice
- private lateinit var browserStore: BrowserStore
-
+class ComposeMediaNotificationTest : TestSetup() {
@get:Rule(order = 0)
val composeTestRule =
AndroidComposeTestRule(
@@ -51,24 +41,6 @@ class ComposeMediaNotificationTest {
@JvmField
val retryTestRule = RetryTestRule(3)
- @Before
- fun setUp() {
- // Initializing this as part of class construction, below the rule would throw a NPE
- // So we are initializing this here instead of in all tests.
- browserStore = composeTestRule.activity.components.core.store
-
- 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/1347033
@SmokeTest
@Test
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeNavigationToolbarTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeNavigationToolbarTest.kt
index ee4964197f6f..2ff866316b57 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeNavigationToolbarTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeNavigationToolbarTest.kt
@@ -5,19 +5,13 @@
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.AppAndSystemHelper.resetSystemLocaleToEnUS
import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithSystemLocaleChanged
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.navigationToolbar
import java.util.Locale
@@ -31,10 +25,7 @@ import java.util.Locale
* - Find in page
*/
-class ComposeNavigationToolbarTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
-
+class ComposeNavigationToolbarTest : TestSetup() {
@get:Rule
val composeTestRule =
AndroidComposeTestRule(
@@ -43,21 +34,6 @@ class ComposeNavigationToolbarTest {
),
) { it.activity }
- @Before
- fun setUp() {
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- resetSystemLocaleToEnUS()
- }
-
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/987326
// Swipes the nav bar left/right to switch between tabs
@SmokeTest
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 27f46d84fd63..eaa76b148196 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
@@ -32,6 +32,7 @@ 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.helpers.TestSetup
import org.mozilla.fenix.ui.robots.clickContextMenuItem
import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.homeScreen
@@ -50,8 +51,8 @@ import org.mozilla.fenix.ui.robots.searchScreen
*
*/
-class ComposeSearchTest {
- lateinit var searchMockServer: MockWebServer
+class ComposeSearchTest : TestSetup() {
+ private lateinit var searchMockServer: MockWebServer
private val queryString: String = "firefox"
private val generalEnginesList = listOf("DuckDuckGo", "Google", "Bing")
private val topicEnginesList = listOf("Amazon.com", "Wikipedia", "eBay")
@@ -70,7 +71,8 @@ class ComposeSearchTest {
) { it.activity }
@Before
- fun setUp() {
+ override fun setUp() {
+ super.setUp()
searchMockServer = MockWebServer().apply {
dispatcher = SearchDispatcher()
start()
@@ -78,7 +80,8 @@ class ComposeSearchTest {
}
@After
- fun tearDown() {
+ override fun tearDown() {
+ super.tearDown()
searchMockServer.shutdown()
}
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataOnQuitTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataOnQuitTest.kt
index 6994cd450442..21521871b363 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataOnQuitTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataOnQuitTest.kt
@@ -9,15 +9,10 @@ import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.core.net.toUri
import androidx.test.espresso.Espresso.pressBack
import androidx.test.rule.GrantPermissionRule
-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.clearDownloadsFolder
import org.mozilla.fenix.helpers.AppAndSystemHelper.setNetworkEnabled
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
@@ -27,6 +22,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper.getStorageTestAsset
import org.mozilla.fenix.helpers.TestHelper.exitMenu
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.restartApp
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.downloadRobot
import org.mozilla.fenix.ui.robots.homeScreen
@@ -37,9 +33,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
* Delete Browsing Data on quit
*
*/
-class ComposeSettingsDeleteBrowsingDataOnQuitTest {
- private lateinit var mockWebServer: MockWebServer
-
+class ComposeSettingsDeleteBrowsingDataOnQuitTest : TestSetup() {
@get:Rule(order = 0)
val composeTestRule =
AndroidComposeTestRule(
@@ -55,22 +49,6 @@ class ComposeSettingsDeleteBrowsingDataOnQuitTest {
Manifest.permission.RECORD_AUDIO,
)
- @Before
- fun setUp() {
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
-
- // Check and clear the downloads folder
- clearDownloadsFolder()
- }
-
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416048
@Test
fun deleteBrowsingDataOnQuitSettingTest() {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataTest.kt
index 49c809a7c25d..7b1fc996b25e 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeSettingsDeleteBrowsingDataTest.kt
@@ -5,14 +5,10 @@
package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
import org.mozilla.fenix.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.HomeActivityIntentTestRule
@@ -22,6 +18,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper.getStorageTestAsset
import org.mozilla.fenix.helpers.TestHelper.exitMenu
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.restartApp
+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.homeScreen
@@ -33,9 +30,7 @@ import org.mozilla.fenix.ui.robots.settingsScreen
* Delete Browsing Data
*/
-class ComposeSettingsDeleteBrowsingDataTest {
- private lateinit var mockWebServer: MockWebServer
-
+class ComposeSettingsDeleteBrowsingDataTest : TestSetup() {
@get:Rule
val composeTestRule =
AndroidComposeTestRule(
@@ -45,19 +40,6 @@ class ComposeSettingsDeleteBrowsingDataTest {
),
) { it.activity }
- @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/937561
@Test
fun deleteBrowsingDataOptionStatesTest() {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeTabbedBrowsingTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeTabbedBrowsingTest.kt
index 0137600492fa..7ef151353214 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeTabbedBrowsingTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ComposeTabbedBrowsingTest.kt
@@ -5,27 +5,21 @@
package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
import com.google.android.material.bottomsheet.BottomSheetBehavior
-import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.mediasession.MediaSession
-import okhttp3.mockwebserver.MockWebServer
-import 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.ext.components
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper
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.closeApp
+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.browserScreen
import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.homeScreen
@@ -49,11 +43,7 @@ import org.mozilla.fenix.ui.robots.notificationShade
* - Shortcut context menu navigation
*/
-class ComposeTabbedBrowsingTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
- private lateinit var browserStore: BrowserStore
-
+class ComposeTabbedBrowsingTest : TestSetup() {
@get:Rule(order = 0)
val composeTestRule =
AndroidComposeTestRule(
@@ -67,24 +57,6 @@ class ComposeTabbedBrowsingTest {
@JvmField
val retryTestRule = RetryTestRule(3)
- @Before
- fun setUp() {
- // Initializing this as part of class construction, below the rule would throw a NPE
- // So we are initializing this here instead of in all related tests.
- browserStore = composeTestRule.activity.components.core.store
-
- 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/903599
@Test
fun closeAllTabsTest() {
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 50bfadce1205..16ea4b127508 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
@@ -5,23 +5,19 @@
package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
import org.mozilla.fenix.customannotations.SmokeTest
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.DataGenerationHelper.generateRandomString
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.mDevice
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
import org.mozilla.fenix.helpers.TestHelper.waitUntilSnackbarGone
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.homeScreenWithComposeTopSites
@@ -36,10 +32,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
* - Verifies existence of default top sites available on the home-screen
*/
-class ComposeTopSitesTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
-
+class ComposeTopSitesTest : TestSetup() {
@get:Rule
val composeTestRule =
AndroidComposeTestRule(
@@ -48,20 +41,6 @@ class ComposeTopSitesTest {
),
) { 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/532598
@SmokeTest
@Test
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 fc6ee4d1ad2f..8229bf18801f 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
@@ -223,7 +223,7 @@ fun historyMenu(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition {
return HistoryRobot.Transition()
}
-private fun testPageTitle() = onView(allOf(withId(R.id.title), withText("Test_Page_1")))
+private fun testPageTitle() = onView(withId(R.id.title))
private fun pageUrl(url: String) = onView(allOf(withId(R.id.url), withText(url)))
From c260a08bc7d4ddb4094c48c7f11fc1da58343e6c Mon Sep 17 00:00:00 2001
From: iorgamgabriel
Date: Fri, 23 Feb 2024 17:23:46 +0200
Subject: [PATCH 325/586] Bug 1878921 - Translations CouldNotLoadLanguagesError
UI "Try Again"
---
.../fenix/translations/TranslationsDialogFragment.kt | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
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 b28fcbb8e5ab..c8c6034c1a25 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
@@ -29,6 +29,7 @@ import androidx.navigation.fragment.navArgs
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import mozilla.components.browser.state.store.BrowserStore
+import mozilla.components.concept.engine.translate.TranslationError
import mozilla.components.lib.state.ext.observeAsComposableState
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import org.mozilla.fenix.BrowserDirection
@@ -212,7 +213,11 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
onSettingClicked = onSettingClicked,
onLearnMoreClicked = { openBrowserAndLoad(learnMoreUrl) },
onPositiveButtonClicked = {
- translationsDialogStore.dispatch(TranslationsDialogAction.TranslateAction)
+ if (state.error is TranslationError.CouldNotLoadLanguagesError) {
+ translationsDialogStore.dispatch(TranslationsDialogAction.FetchSupportedLanguages)
+ } else {
+ translationsDialogStore.dispatch(TranslationsDialogAction.TranslateAction)
+ }
},
onNegativeButtonClicked = {
if (state.isTranslated) {
From baa7120c95c59f5792ba6d54873e101321d5d7d7 Mon Sep 17 00:00:00 2001
From: iorgamgabriel
Date: Wed, 14 Feb 2024 17:44:22 +0200
Subject: [PATCH 326/586] Bug 1875817 - Translations Integration Toolbar
Showing
---
.../components/concept/toolbar/Toolbar.kt | 52 ++++--
.../concept/toolbar/ActionButtonTest.kt | 11 ++
docs/changelog.md | 3 +
.../mozilla/fenix/browser/BrowserFragment.kt | 72 +++++---
.../fenix/browser/TranslationsBinding.kt | 72 ++++++++
fenix/app/src/main/res/values/strings.xml | 4 +
.../fenix/browser/TranslationsBindingTest.kt | 168 ++++++++++++++++++
7 files changed, 344 insertions(+), 38 deletions(-)
create mode 100644 fenix/app/src/main/java/org/mozilla/fenix/browser/TranslationsBinding.kt
create mode 100644 fenix/app/src/test/java/org/mozilla/fenix/browser/TranslationsBindingTest.kt
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 398acca62d72..4d101048c662 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
@@ -279,26 +279,46 @@ interface Toolbar : ScrollableToolbar {
private val longClickListener: (() -> Unit)? = null,
private val listener: () -> Unit,
) : Action {
+ private var view: WeakReference? = null
+
+ override fun createView(parent: ViewGroup): View =
+ AppCompatImageButton(parent.context).also { imageButton ->
+ view = WeakReference(imageButton)
+
+ imageButton.setImageDrawable(imageDrawable)
+ imageButton.contentDescription = contentDescription
+ imageButton.setTintResource(iconTintColorResource)
+ imageButton.setOnClickListener { listener.invoke() }
+ imageButton.setOnLongClickListener {
+ longClickListener?.invoke()
+ true
+ }
+ imageButton.isLongClickable = longClickListener != null
- override fun createView(parent: ViewGroup): View = AppCompatImageButton(parent.context).also { imageButton ->
- imageButton.setImageDrawable(imageDrawable)
- imageButton.contentDescription = contentDescription
- imageButton.setTintResource(iconTintColorResource)
- imageButton.setOnClickListener { listener.invoke() }
- imageButton.setOnLongClickListener {
- longClickListener?.invoke()
- true
- }
- imageButton.isLongClickable = longClickListener != null
+ val backgroundResource = if (background == 0) {
+ parent.context.theme.resolveAttribute(android.R.attr.selectableItemBackgroundBorderless)
+ } else {
+ background
+ }
- val backgroundResource = if (background == 0) {
- parent.context.theme.resolveAttribute(android.R.attr.selectableItemBackgroundBorderless)
- } else {
- background
+ imageButton.setBackgroundResource(backgroundResource)
+ padding?.let { imageButton.setPadding(it) }
}
- imageButton.setBackgroundResource(backgroundResource)
- padding?.let { imageButton.setPadding(it) }
+ /**
+ * Changes the content description and the tint colour of the view.
+ *
+ * @param contentDescription The content description to use.
+ * @param tintColorResource ID of color resource to tint the icon.
+ */
+ fun updateView(
+ contentDescription: String? = null,
+ @ColorRes tintColorResource: Int = ViewGroup.NO_ID,
+ ) {
+ view?.get()?.let {
+ it.contentDescription = contentDescription
+ it.setTintResource(tintColorResource)
+ }
}
override fun bind(view: View) = Unit
diff --git a/android-components/components/concept/toolbar/src/test/java/mozilla/components/concept/toolbar/ActionButtonTest.kt b/android-components/components/concept/toolbar/src/test/java/mozilla/components/concept/toolbar/ActionButtonTest.kt
index f5bb24dcab76..6b33deac2580 100644
--- a/android-components/components/concept/toolbar/src/test/java/mozilla/components/concept/toolbar/ActionButtonTest.kt
+++ b/android-components/components/concept/toolbar/src/test/java/mozilla/components/concept/toolbar/ActionButtonTest.kt
@@ -54,4 +54,15 @@ class ActionButtonTest {
val buttonVisibility = Toolbar.ActionButton(mock(), "image") {}
assertEquals(true, buttonVisibility.visible())
}
+
+ @Test
+ fun `set contentDescription`() {
+ val button = Toolbar.ActionButton(mock(), "image") { }
+ val linearLayout = LinearLayout(testContext)
+ val view = button.createView(linearLayout)
+
+ button.updateView("contentDescription")
+
+ assertEquals("contentDescription", view.contentDescription)
+ }
}
diff --git a/docs/changelog.md b/docs/changelog.md
index d98a09ad76a4..ca2ac8da8c61 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -10,6 +10,9 @@ permalink: /changelog/
* [Gecko](https://github.com/mozilla-mobile/firefox-android/blob/main/android-components/plugins/dependencies/src/main/java/Gecko.kt)
* [Configuration](https://github.com/mozilla-mobile/firefox-android/blob/main/android-components/.config.yml)
+* **concept-toolabar**:
+ * Added a new method for `ActionButton` to update the contentDescription and the iconTint, see [Bug 1875817](https://bugzilla.mozilla.org/show_bug.cgi?id=1875817).
+
* **concept-engine**
* Added `onLocationChange#hasUserGesture` parameter. This indicates if a location change was requested while a user gesture was active. [bug #1804636](https://bugzilla.mozilla.org/show_bug.cgi?id=1804636)
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
index 0d37c0847bde..f4faa1c12d12 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
@@ -25,6 +25,7 @@ import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.browser.thumbnails.BrowserThumbnails
import mozilla.components.browser.toolbar.BrowserToolbar
import mozilla.components.concept.engine.permission.SitePermissions
+import mozilla.components.concept.toolbar.Toolbar
import mozilla.components.feature.app.links.AppLinksUseCases
import mozilla.components.feature.contextmenu.ContextMenuCandidate
import mozilla.components.feature.readerview.ReaderViewFeature
@@ -67,6 +68,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
private val standardSnackbarErrorBinding =
ViewBoundFeatureWrapper()
private val reviewQualityCheckFeature = ViewBoundFeatureWrapper()
+ private val translationsBinding = ViewBoundFeatureWrapper()
private var readerModeAvailable = false
private var reviewQualityCheckAvailable = false
@@ -150,7 +152,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
browserToolbarView.view.addPageAction(readerModeAction)
- initTranslationsAction(context)
+ initTranslationsAction(context, view)
initReviewQualityCheck(context, view)
thumbnailsFeature.set(
@@ -236,32 +238,58 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
}
}
- private fun initTranslationsAction(context: Context) {
+ private fun initTranslationsAction(context: Context, view: View) {
if (!context.settings().enableTranslations) {
return
}
- val translationsAction =
- BrowserToolbar.ToggleButton(
- image = AppCompatResources.getDrawable(
- context,
- R.drawable.mozac_ic_translate_24,
- )!!.apply {
- setTint(ContextCompat.getColor(context, R.color.fx_mobile_text_color_primary))
- },
- imageSelected = AppCompatResources.getDrawable(
- context,
- R.drawable.mozac_ic_translate_24,
- )!!,
- contentDescription = context.getString(R.string.browser_toolbar_translate),
- contentDescriptionSelected = "",
- visible = {
- translationsAvailable || context.settings().enableTranslations
- },
- listener = { browserToolbarInteractor.onTranslationsButtonClicked() },
- )
-
+ val translationsAction = Toolbar.ActionButton(
+ AppCompatResources.getDrawable(
+ context,
+ R.drawable.mozac_ic_translate_24,
+ )!!.apply {
+ setTint(ContextCompat.getColor(context, R.color.fx_mobile_text_color_primary))
+ },
+ contentDescription = context.getString(R.string.browser_toolbar_translate),
+ visible = { translationsAvailable },
+ listener = {
+ browserToolbarInteractor.onTranslationsButtonClicked()
+ },
+ )
browserToolbarView.view.addPageAction(translationsAction)
+
+ getCurrentTab()?.let {
+ translationsBinding.set(
+ feature = TranslationsBinding(
+ browserStore = context.components.core.store,
+ sessionId = it.id,
+ onStateUpdated = { isVisible, isTranslated, fromSelectedLanguage, toSelectedLanguage ->
+ translationsAvailable = isVisible
+
+ translationsAction.updateView(
+ tintColorResource = if (isTranslated) {
+ R.color.fx_mobile_icon_color_accent_violet
+ } else {
+ R.color.fx_mobile_text_color_primary
+ },
+ contentDescription = if (isTranslated) {
+ context.getString(
+ R.string.browser_toolbar_translated_successfully,
+ fromSelectedLanguage?.localizedDisplayName,
+ toSelectedLanguage?.localizedDisplayName,
+ )
+ } else {
+ context.getString(R.string.browser_toolbar_translate)
+ },
+ )
+
+ safeInvalidateBrowserToolbarView()
+ },
+ ),
+ owner = this,
+ view = view,
+ )
+ }
}
private fun initReviewQualityCheck(context: Context, view: View) {
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/browser/TranslationsBinding.kt b/fenix/app/src/main/java/org/mozilla/fenix/browser/TranslationsBinding.kt
new file mode 100644
index 000000000000..433657da3de7
--- /dev/null
+++ b/fenix/app/src/main/java/org/mozilla/fenix/browser/TranslationsBinding.kt
@@ -0,0 +1,72 @@
+/* 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.browser
+
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChangedBy
+import kotlinx.coroutines.flow.mapNotNull
+import mozilla.components.browser.state.selector.findTab
+import mozilla.components.browser.state.state.BrowserState
+import mozilla.components.browser.state.state.TranslationsState
+import mozilla.components.browser.state.store.BrowserStore
+import mozilla.components.concept.engine.translate.Language
+import mozilla.components.concept.engine.translate.initialFromLanguage
+import mozilla.components.concept.engine.translate.initialToLanguage
+import mozilla.components.lib.state.helpers.AbstractBinding
+
+/**
+ * A binding for observing [TranslationsState] changes
+ * from the [BrowserStore] and updating the translations action button.
+ *
+ * @param browserStore [BrowserStore] observed for any changes related to [TranslationsState].
+ * @param sessionId Current open tab session id.
+ * @param onStateUpdated Invoked when the translations action button should be updated with the new translations state.
+ */
+class TranslationsBinding(
+ private val browserStore: BrowserStore,
+ private val sessionId: String,
+ private val onStateUpdated: (
+ isVisible: Boolean,
+ isTranslated: Boolean,
+ fromSelectedLanguage: Language?,
+ toSelectedLanguage: Language?,
+ ) -> Unit,
+) : AbstractBinding(browserStore) {
+
+ override suspend fun onState(flow: Flow) {
+ flow.mapNotNull { state -> state.findTab(sessionId) }.distinctUntilChangedBy {
+ it.translationsState
+ }.collect { sessionState ->
+ val translationsState = sessionState.translationsState
+
+ if (translationsState.isTranslated) {
+ val fromSelected = translationsState.translationEngineState?.initialFromLanguage(
+ translationsState.supportedLanguages?.fromLanguages,
+ )
+ val toSelected = translationsState.translationEngineState?.initialToLanguage(
+ translationsState.supportedLanguages?.toLanguages,
+ )
+
+ if (fromSelected != null && toSelected != null) {
+ onStateUpdated(
+ true,
+ true,
+ fromSelected,
+ toSelected,
+ )
+ }
+ } else if (translationsState.isExpectedTranslate) {
+ onStateUpdated(
+ true,
+ false,
+ null,
+ null,
+ )
+ } else {
+ onStateUpdated(false, false, null, null)
+ }
+ }
+ }
+}
diff --git a/fenix/app/src/main/res/values/strings.xml b/fenix/app/src/main/res/values/strings.xml
index 194a28d3c989..fd77f620b067 100644
--- a/fenix/app/src/main/res/values/strings.xml
+++ b/fenix/app/src/main/res/values/strings.xml
@@ -242,6 +242,10 @@
Erase browsing historyTranslate page
+
+ Page translated from %1$s to %2$s.
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/browser/TranslationsBindingTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/browser/TranslationsBindingTest.kt
new file mode 100644
index 000000000000..b58169f98bf7
--- /dev/null
+++ b/fenix/app/src/test/java/org/mozilla/fenix/browser/TranslationsBindingTest.kt
@@ -0,0 +1,168 @@
+/* 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.browser
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.browser.state.action.TranslationsAction
+import mozilla.components.browser.state.state.BrowserState
+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.TranslationOperation
+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.rule.MainCoroutineRule
+import mozilla.components.support.test.rule.runTestOnMain
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
+
+@RunWith(AndroidJUnit4::class)
+class TranslationsBindingTest {
+ @get:Rule
+ val coroutineRule = MainCoroutineRule()
+
+ lateinit var browserStore: BrowserStore
+
+ private val tabId = "1"
+ private val tab = createTab(url = tabId, id = tabId)
+ private val onIconChanged: (
+ isVisible: Boolean,
+ isTranslated: Boolean,
+ fromSelectedLanguage: Language?,
+ toSelectedLanguage: Language?,
+ ) -> Unit = spy()
+
+ @Test
+ fun `GIVEN translationState WHEN translation status isTranslated THEN invoke onIconChanged callback`() =
+ runTestOnMain {
+ val englishLanguage = Language("en", "English")
+ val spanishLanguage = Language("es", "Spanish")
+
+ browserStore = BrowserStore(
+ BrowserState(
+ tabs = listOf(tab),
+ selectedTabId = tabId,
+ ),
+ )
+
+ val binding = TranslationsBinding(
+ browserStore = browserStore,
+ sessionId = tabId,
+ onStateUpdated = onIconChanged,
+ )
+ binding.start()
+
+ val detectedLanguages = DetectedLanguages(
+ documentLangTag = englishLanguage.code,
+ supportedDocumentLang = true,
+ userPreferredLangTag = spanishLanguage.code,
+ )
+
+ val translationEngineState = TranslationEngineState(
+ detectedLanguages = detectedLanguages,
+ error = null,
+ isEngineReady = true,
+ requestedTranslationPair = TranslationPair(
+ fromLanguage = englishLanguage.code,
+ toLanguage = spanishLanguage.code,
+ ),
+ )
+
+ val supportLanguages = TranslationSupport(
+ fromLanguages = listOf(englishLanguage),
+ toLanguages = listOf(spanishLanguage),
+ )
+
+ browserStore.dispatch(
+ TranslationsAction.SetSupportedLanguagesAction(
+ tabId = tab.id,
+ supportedLanguages = supportLanguages,
+ ),
+ ).joinBlocking()
+
+ browserStore.dispatch(
+ TranslationsAction.TranslateStateChangeAction(
+ tabId = tabId,
+ translationEngineState = translationEngineState,
+ ),
+ ).joinBlocking()
+
+ browserStore.dispatch(
+ TranslationsAction.TranslateSuccessAction(
+ tabId = tab.id,
+ operation = TranslationOperation.TRANSLATE,
+ ),
+ ).joinBlocking()
+
+ verify(onIconChanged).invoke(
+ true,
+ true,
+ englishLanguage,
+ spanishLanguage,
+ )
+ }
+
+ @Test
+ fun `GIVEN translationState WHEN translation status isExpectedTranslate THEN invoke onIconChanged callback`() =
+ runTestOnMain {
+ browserStore = BrowserStore(
+ BrowserState(
+ tabs = listOf(tab),
+ selectedTabId = tabId,
+ ),
+ )
+
+ val binding = TranslationsBinding(
+ browserStore = browserStore,
+ sessionId = tabId,
+ onStateUpdated = onIconChanged,
+ )
+ binding.start()
+
+ browserStore.dispatch(
+ TranslationsAction.TranslateExpectedAction(
+ tabId = tabId,
+ ),
+ ).joinBlocking()
+
+ verify(onIconChanged).invoke(
+ true,
+ false,
+ null,
+ null,
+ )
+ }
+
+ @Test
+ fun `GIVEN translationState WHEN translation status is not isExpectedTranslate or isTranslated THEN invoke onIconChanged callback`() =
+ runTestOnMain {
+ browserStore = BrowserStore(
+ BrowserState(
+ tabs = listOf(tab),
+ selectedTabId = tabId,
+ ),
+ )
+
+ val binding = TranslationsBinding(
+ browserStore = browserStore,
+ sessionId = tabId,
+ onStateUpdated = onIconChanged,
+ )
+ binding.start()
+
+ verify(onIconChanged).invoke(
+ false,
+ false,
+ null,
+ null,
+ )
+ }
+}
From e7ec19745b69e4ed606e6c4590f3d8eb7a1c37ce Mon Sep 17 00:00:00 2001
From: "oana.horvath"
Date: Mon, 26 Feb 2024 12:54:14 +0200
Subject: [PATCH 327/586] Bug 1882035 - Disable non-sponsored suggestions UI
tests in FirefoxSuggestTest
---
.../java/org/mozilla/fenix/ui/FirefoxSuggestTest.kt | 4 ++++
1 file changed, 4 insertions(+)
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 1f8b929fc522..ae384d0632a6 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,6 +5,7 @@
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
@@ -192,6 +193,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
+ @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1882035")
@SmokeTest
@Test
fun verifyFirefoxSuggestNonSponsoredSearchResultsTest() {
@@ -219,6 +221,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
+ @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1882035")
@Test
fun verifyFirefoxSuggestNonSponsoredSearchResultsWithPartialKeywordTest() {
runWithCondition(TestHelper.appContext.settings().enableFxSuggest) {
@@ -239,6 +242,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
+ @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1882035")
@Test
fun openFirefoxSuggestNonSponsoredSearchResultsTest() {
runWithCondition(TestHelper.appContext.settings().enableFxSuggest) {
From 0e306e0879363032b5b25de159501f9ca9bc610b Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Mon, 26 Feb 2024 13:17:35 +0000
Subject: [PATCH 328/586] Update GeckoView (Nightly) to 125.0.20240226091922.
---
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 1e9efb920978..785c58163864 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 = "125.0.20240225092952"
+ const val version = "125.0.20240226091922"
/**
* GeckoView channel
From 00689b4684d74fb8ee6dd00ce9c039440f835c0d Mon Sep 17 00:00:00 2001
From: Aaron Train
Date: Mon, 5 Feb 2024 13:09:56 -0500
Subject: [PATCH 329/586] Bug 1878386 - Rewrite ui-test.sh into Python
---
taskcluster/ci/startup-test/kind.yml | 8 +-
taskcluster/ci/ui-test-apk/kind.yml | 19 ++-
taskcluster/scripts/tests/test-lab.py | 217 ++++++++++++++++++++++++++
3 files changed, 230 insertions(+), 14 deletions(-)
create mode 100644 taskcluster/scripts/tests/test-lab.py
diff --git a/taskcluster/ci/startup-test/kind.yml b/taskcluster/ci/startup-test/kind.yml
index cd2c487c4971..9baf8400f0b8 100644
--- a/taskcluster/ci/startup-test/kind.yml
+++ b/taskcluster/ci/startup-test/kind.yml
@@ -47,7 +47,7 @@ tasks:
- ["cd", "fenix"]
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk ]
- - [automation/taskcluster/androidTest/robo-test.sh, arm-start-test-robo, app.apk]
+ - [python3, ../taskcluster/scripts/tests/test-lab.py, arm-start-test-robo, app.apk]
treeherder:
symbol: fenix-nightly(startup-arm-robo-opt)
worker:
@@ -71,7 +71,7 @@ tasks:
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- [wget, {artifact-reference: ''}, '-O', android-test.apk]
- - [automation/taskcluster/androidTest/ui-test.sh, arm-start-test, app.apk, android-test.apk, '1']
+ - [python3, ../taskcluster/scripts/tests/test-lab.py, arm-start-test, app.apk, --apk_test, android-test.apk]
treeherder:
symbol: fenix-nightly(startup-arm)
worker:
@@ -95,7 +95,7 @@ tasks:
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- [wget, {artifact-reference: ''}, '-O', android-test.apk]
- - [automation/taskcluster/androidTest/ui-test.sh, arm-start-test, app.apk, android-test.apk, '1']
+ - [python3, ../taskcluster/scripts/tests/test-lab.py, arm-start-test, app.apk, --apk_test, android-test.apk]
treeherder:
symbol: focus-nightly(startup-arm)
worker:
@@ -118,7 +118,7 @@ tasks:
- ["cd", "focus-android"]
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- - [automation/taskcluster/androidTest/robo-test.sh, arm-start-test-robo, app.apk]
+ - [python3, ../taskcluster/scripts/tests/test-lab.py, arm-start-test-robo, app.apk]
treeherder:
symbol: focus-nightly(startup-arm-robo-opt)
worker:
diff --git a/taskcluster/ci/ui-test-apk/kind.yml b/taskcluster/ci/ui-test-apk/kind.yml
index f841eb7ae233..afe05fb9b182 100644
--- a/taskcluster/ci/ui-test-apk/kind.yml
+++ b/taskcluster/ci/ui-test-apk/kind.yml
@@ -115,7 +115,7 @@ tasks:
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- [wget, {artifact-reference: ''}, '-O', android-test.apk]
- - ['automation/taskcluster/androidTest/ui-test.sh', 'arm64-v8a', 'app.apk', 'android-test.apk', '50']
+ - [python3, ../taskcluster/scripts/tests/test-lab.py, arm64-v8a, app.apk, --apk_test, android-test.apk]
dependencies:
# key is arbitrary, the value corresponds to -
signed-apk-debug-apk: signing-apk-focus-debug
@@ -147,7 +147,7 @@ tasks:
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- [wget, {artifact-reference: ''}, '-O', android-test.apk]
- - ['automation/taskcluster/androidTest/ui-test.sh', 'arm-start-test', 'app.apk', 'android-test.apk', '1']
+ - [python3, ../taskcluster/scripts/tests/test-lab.py, arm-start-test, app.apk, --apk_test, android-test.apk]
treeherder:
platform: 'focus-ui-test/opt'
symbol: focus-nightly(ui-test-arm-nightly)
@@ -175,7 +175,7 @@ tasks:
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- [wget, {artifact-reference: ''}, '-O', android-test.apk]
- - ['automation/taskcluster/androidTest/ui-test.sh', 'arm-beta-tests', 'app.apk', 'android-test.apk', '1']
+ - [python3, ../taskcluster/scripts/tests/test-lab.py, arm-beta-tests, app.apk, --apk_test, android-test.apk]
treeherder:
platform: 'focus-ui-test/opt'
symbol: focus-beta(ui-test-arm-beta)
@@ -202,7 +202,7 @@ tasks:
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- [wget, {artifact-reference: ''}, '-O', android-test.apk]
- - [automation/taskcluster/androidTest/ui-test.sh, arm64-v8a, app.apk, android-test.apk, '100']
+ - [python3, ../taskcluster/scripts/tests/test-lab.py, arm64-v8a, app.apk, --apk_test, android-test.apk]
treeherder:
platform: 'fenix-ui-test/opt'
symbol: fenix-debug(ui-test-arm)
@@ -230,7 +230,7 @@ tasks:
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- [wget, {artifact-reference: ''}, '-O', android-test.apk]
- - [automation/taskcluster/androidTest/ui-test.sh, arm-screenshots-tests, app.apk, android-test.apk, '1']
+ - [python3, ../taskcluster/scripts/tests/test-lab.py, arm-screenshots-tests, app.apk, --apk_test, android-test.apk]
treeherder:
platform: 'fenix-ui-test/opt'
symbol: fenix-debug(screenshots-arm)
@@ -258,7 +258,7 @@ tasks:
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- [wget, {artifact-reference: ''}, '-O', android-test.apk]
- - [automation/taskcluster/androidTest/ui-test.sh, arm-beta-tests, app.apk, android-test.apk, '2']
+ - [python3, ../taskcluster/scripts/tests/test-lab.py, arm-beta-tests, app.apk, --apk_test, android-test.apk]
treeherder:
platform: 'fenix-ui-test/opt'
symbol: fenix-beta(ui-test-arm-beta)
@@ -286,7 +286,7 @@ tasks:
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- [wget, {artifact-reference: ''}, '-O', android-test.apk]
- - [automation/taskcluster/androidTest/ui-test.sh, arm-start-test, app.apk, android-test.apk, '2']
+ - [python3, ../taskcluster/scripts/tests/test-lab.py, arm-start-test, app.apk, --apk_test, android-test.apk]
treeherder:
platform: 'fenix-ui-test/opt'
symbol: fenix-nightly(ui-test-arm-nightly)
@@ -315,14 +315,13 @@ tasks:
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- [wget, {artifact-reference: ''}, '-O', android-test.apk]
- - [automation/taskcluster/androidTest/ui-test.sh, arm-legacy-api-tests, app.apk, android-test.apk, '50']
+ - [python3, ../taskcluster/scripts/tests/test-lab.py, arm-legacy-api-tests, app.apk, --apk_test, android-test.apk]
treeherder:
platform: 'fenix-ui-test/opt'
symbol: fenix-debug(legacy-arm)
worker:
env:
GOOGLE_PROJECT: moz-fenix
-
fenix-robo-arm-debug:
attributes:
shipping-product: fenix
@@ -342,7 +341,7 @@ tasks:
- ["cd", "fenix"]
commands:
- [wget, {artifact-reference: ''}, '-O', app.apk]
- - [automation/taskcluster/androidTest/robo-test.sh, arm-robo-test, app.apk]
+ - [python3, ../taskcluster/scripts/tests/test-lab.py, arm-robo-test, app.apk]
treeherder:
platform: 'fenix-ui-test/opt'
symbol: fenix-debug(robo-arm)
diff --git a/taskcluster/scripts/tests/test-lab.py b/taskcluster/scripts/tests/test-lab.py
new file mode 100644
index 000000000000..abc9820fc2d2
--- /dev/null
+++ b/taskcluster/scripts/tests/test-lab.py
@@ -0,0 +1,217 @@
+#!/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/.
+
+# Firebase Test Lab (Flank) test runner script for Taskcluster
+# This script is used to run UI tests on Firebase Test Lab using Flank
+# It requires a service account key file to authenticate with Firebase Test Lab
+# It also requires the `gcloud` command line tool to be installed and configured
+# Lastly it requires the `flank.jar` file to be present in the `test-tools` directory set up in the task definition
+# The service account key file is stored in the `secrets` section of the task definition
+
+# Flank: https://flank.github.io/flank/
+
+import argparse
+import logging
+import os
+import subprocess
+import sys
+from enum import Enum
+from pathlib import Path
+from typing import List, Optional, Union
+
+
+# Worker paths and binaries
+class Worker(Enum):
+ JAVA_BIN = "/usr/bin/java"
+ FLANK_BIN = "/builds/worker/test-tools/flank.jar"
+ RESULTS_DIR = "/builds/worker/artifacts/results"
+ ARTIFACTS_DIR = "/builds/worker/artifacts"
+
+
+ANDROID_TEST = "./automation/taskcluster/androidTest"
+
+
+def setup_logging():
+ """Configure logging for the script."""
+ log_format = "%(message)s"
+ logging.basicConfig(level=logging.INFO, format=log_format)
+
+
+def run_command(
+ command: List[Union[str, bytes]], log_path: Optional[str] = None
+) -> int:
+ """Execute a command, log its output, and check for errors.
+
+ Args:
+ command: The command to execute
+ log_path: The path to a log file to write the command output to
+ Returns:
+ int: The exit code of the command
+ """
+
+ with subprocess.Popen(
+ command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True
+ ) as process:
+ if log_path:
+ with open(log_path, "a") as log_file:
+ for line in process.stdout:
+ sys.stdout.write(line)
+ log_file.write(line)
+ else:
+ for line in process.stdout:
+ sys.stdout.write(line)
+ process.wait()
+ sys.stdout.flush()
+ if process.returncode != 0:
+ error_message = f"Command {' '.join(command)} failed with exit code {process.returncode}"
+ logging.error(msg=error_message)
+ return process.returncode
+
+
+def setup_environment():
+ """Configure Google Cloud project and authenticate with the service account."""
+ project_id = os.getenv("GOOGLE_PROJECT")
+ credentials_file = os.getenv("GOOGLE_APPLICATION_CREDENTIALS")
+ if not project_id or not credentials_file:
+ logging.error(
+ msg="Error: GOOGLE_PROJECT and GOOGLE_APPLICATION_CREDENTIALS environment variables must be set."
+ )
+ sys.exit(1)
+
+ run_command(["gcloud", "config", "set", "project", project_id])
+ run_command(
+ ["gcloud", "auth", "activate-service-account", "--key-file", credentials_file]
+ )
+
+
+def execute_tests(
+ flank_config: str, apk_app: Path, apk_test: Optional[Path] = None
+) -> int:
+ """Run UI tests on Firebase Test Lab using Flank.
+
+ Args:
+ flank_config: The YML configuration for Flank to use e.g, automation/taskcluster/androidTest/flank-.yml
+ apk_app: Absolute path to a Android APK application package (optional) for robo test or instrumentation test
+ apk_test: Absolute path to a Android APK androidTest package
+ Returns:
+ int: The exit code of the command
+ """
+
+ run_command([Worker.JAVA_BIN.value, "-jar", Worker.FLANK_BIN.value, "--version"])
+
+ flank_command = [
+ Worker.JAVA_BIN.value,
+ "-jar",
+ Worker.FLANK_BIN.value,
+ "android",
+ "run",
+ "--config",
+ f"{ANDROID_TEST}/flank-{flank_config}.yml",
+ "--app",
+ str(apk_app),
+ "--local-result-dir",
+ Worker.RESULTS_DIR.value,
+ "--project",
+ os.environ.get("GOOGLE_PROJECT"),
+ "--client-details",
+ f'matrixLabel={os.environ.get("PULL_REQUEST_NUMBER", "None")}',
+ ]
+
+ # Add androidTest APK if provided (optional) as robo test or instrumentation test
+ if apk_test:
+ flank_command.extend(["--test", str(apk_test)])
+
+ exit_code = run_command(flank_command, "flank.log")
+ if exit_code == 0:
+ logging.info(msg="All UI test(s) have passed!")
+ return exit_code
+
+
+def process_results(flank_config: str, test_type: str = "instrumentation") -> None:
+ """Process and parse test results.
+
+ Args:
+ flank_config: The YML configuration for Flank to use e.g, automation/taskcluster/androidTest/flank-.yml
+ """
+
+ # Ensure directories exist and scripts are executable
+ github_dir = os.path.join(Worker.ARTIFACTS_DIR.value, "github")
+ os.makedirs(github_dir, exist_ok=True)
+
+ parse_ui_test_script = os.path.join(ANDROID_TEST, "parse-ui-test.py")
+ parse_ui_test_fromfile_script = os.path.join(
+ ANDROID_TEST, "parse-ui-test-fromfile.py"
+ )
+
+ os.chmod(parse_ui_test_script, 0o755)
+ os.chmod(parse_ui_test_fromfile_script, 0o755)
+
+ # Run parsing scripts and check for errors
+ run_command(
+ [
+ parse_ui_test_script,
+ "--exit-code",
+ str(0),
+ "--log",
+ "flank.log",
+ "--results",
+ Worker.RESULTS_DIR.value,
+ "--output-md",
+ os.path.join(github_dir, "customCheckRunText.md"),
+ "--device-type",
+ flank_config,
+ ],
+ "flank.log",
+ )
+
+ # Process the results differently based on the test type: robo or instrumentation
+ # Currently, robo test does not have a test file artifact to parse
+ if test_type == "instrumentation":
+ run_command(
+ [parse_ui_test_fromfile_script, "--results", Worker.RESULTS_DIR.value],
+ "flank.log",
+ )
+
+
+def main():
+ """Parse command line arguments and execute the test runner."""
+ parser = argparse.ArgumentParser(
+ description="Run UI tests on Firebase Test Lab using Flank as a test runner"
+ )
+ parser.add_argument(
+ "flank_config",
+ help="The YML configuration for Flank to use e.g, automation/taskcluster/androidTest/flank-.yml",
+ )
+ parser.add_argument(
+ "apk_app", help="Absolute path to a Android APK application package"
+ )
+ parser.add_argument(
+ "--apk_test",
+ help="Absolute path to a Android APK androidTest package",
+ default=None,
+ )
+ args = parser.parse_args()
+
+ setup_environment()
+
+ # Only resolve apk_test if it is provided
+ apk_test_path = Path(args.apk_test).resolve() if args.apk_test else None
+ exit_code = execute_tests(
+ flank_config=args.flank_config,
+ apk_app=Path(args.apk_app).resolve(),
+ apk_test=apk_test_path,
+ )
+
+ # Determine the instrumentation type to process the results differently
+ instrumentation_type = "instrumentation" if args.apk_test else "robo"
+ process_results(flank_config=args.flank_config, test_type=instrumentation_type)
+
+ sys.exit(exit_code)
+
+
+if __name__ == "__main__":
+ setup_logging()
+ main()
From 7b64eb2835d6b8b5c9e623a76a13df03157005de Mon Sep 17 00:00:00 2001
From: James Hugman
Date: Fri, 26 Jan 2024 22:12:38 +0000
Subject: [PATCH 330/586] =?UTF-8?q?Bug=201880483=20=E2=80=94=C2=A0Add=20in?=
=?UTF-8?q?verse=20triggers=20to=20messaging=20component?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is a breaking change.
This changes the `trigger` key to `trigger-if-all` to document that all
triggers in this list must evaluate to true.
It also adds `exclude-if-any`, a list of triggers which, if any are true
will exclude the message.
This will remove the need for triggers like `I_AM_NOT_BROWSER_DEFAULT`.
---
.../service/nimbus/messaging.fml.yaml | 11 +++-
.../service/nimbus/messaging/Message.kt | 14 +++--
.../messaging/NimbusMessagingStorage.kt | 48 +++++++++++------
.../NimbusMessagingControllerTest.kt | 3 +-
.../messaging/NimbusMessagingStorageTest.kt | 53 ++++++++++---------
.../app/messaging-evergreen-messages.fml.yaml | 10 ++--
.../fenix/ui/NimbusMessagingHomescreenTest.kt | 2 +-
.../mozilla/fenix/components/AppStoreTest.kt | 1 +
.../messaging/DefaultMessageControllerTest.kt | 3 +-
.../state/MessagingMiddlewareTest.kt | 3 +-
.../messaging/state/MessagingReducerTest.kt | 2 +-
11 files changed, 94 insertions(+), 56 deletions(-)
diff --git a/android-components/components/service/nimbus/messaging.fml.yaml b/android-components/components/service/nimbus/messaging.fml.yaml
index 734fd0bda7f7..639bac1320e5 100644
--- a/android-components/components/service/nimbus/messaging.fml.yaml
+++ b/android-components/components/service/nimbus/messaging.fml.yaml
@@ -133,13 +133,20 @@ objects:
The surface identifier for this message.
type: SurfaceName
default: homescreen
- trigger:
+ trigger-if-all:
type: List
description: >
A list of strings corresponding to
targeting expressions. The message will be
- shown if all expressions `true`.
+ shown if all expressions are `true`.
default: []
+ exclude-if-any:
+ type: List
+ description: >
+ A list of strings corresponding to
+ targeting expressions. The message will not be
+ shown if any of the expressions are `true`.
+ default: [ ]
StyleData:
description: >
A group of properties (predominantly visual) to
diff --git a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/Message.kt b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/Message.kt
index 58a959d9390d..46aa647c92b3 100644
--- a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/Message.kt
+++ b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/Message.kt
@@ -7,15 +7,20 @@ package mozilla.components.service.nimbus.messaging
import androidx.annotation.VisibleForTesting
/**
- * A data class that holds a representation of GleanPlum message from Nimbus.
+ * A data class that holds a representation of a message from Nimbus.
+ *
+ * In order to be eligible to be shown, all `triggerIfAll` expressions
+ * AND none of the `excludeIfAny` expressions must evaluate to `true`.
*
* @param id identifies a message as unique.
* @param data Data information provided from Nimbus.
* @param action A strings that represents which action should be performed
* after a message is clicked.
* @param style Indicates how a message should be styled.
- * @param triggers A list of strings corresponding to targeting expressions. The message
- * will be shown if all expressions `true`.
+ * @param triggerIfAll A list of strings corresponding to JEXL targeting expressions. The message
+ * will be shown if _all_ expressions evaluate to `true`.
+ * @param excludeIfAny A list of strings corresponding to JEXL targeting expressions. The message
+ * will _not_ be shown if _any_ expressions evaluate to `true`.
* @param metadata Metadata that help to identify if a message should shown.
*/
data class Message(
@@ -23,7 +28,8 @@ data class Message(
internal val data: MessageData,
internal val action: String,
internal val style: StyleData,
- internal val triggers: List,
+ internal val triggerIfAll: List,
+ internal val excludeIfAny: List = listOf(),
internal val metadata: Metadata,
) {
val text: String
diff --git a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
index d2337bbd595e..b24d8a45a83a 100644
--- a/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
+++ b/android-components/components/service/nimbus/src/main/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorage.kt
@@ -91,8 +91,10 @@ class NimbusMessagingStorage(
"CONTROL_ACTION"
}
- val trigger = sanitizeTriggers(message.trigger, featureValue.triggers) ?: return null
+ val triggerIfAll = sanitizeTriggers(message.triggerIfAll, featureValue.triggers) ?: return null
+ val excludeIfAny = sanitizeTriggers(message.excludeIfAny, featureValue.triggers) ?: return null
val style = sanitizeStyle(message.style, featureValue.styles) ?: return null
+
val storageMetadata = metadataStorage.getMetadata()
return Message(
@@ -100,8 +102,9 @@ class NimbusMessagingStorage(
data = message,
action = action,
style = style,
+ triggerIfAll = triggerIfAll,
+ excludeIfAny = excludeIfAny,
metadata = storageMetadata[key] ?: addMetadata(key),
- triggers = trigger,
)
}
@@ -178,7 +181,14 @@ class NimbusMessagingStorage(
): Message? {
val message = availableMessages
.filter { !excluded.contains(it.id) }
- .firstOrNull { isMessageEligible(it, helper) } ?: return null
+ .firstOrNull {
+ try {
+ isMessageEligible(it, helper)
+ } catch (e: NimbusException) {
+ reportMalformedMessage(it.id)
+ false
+ }
+ } ?: return null
// If this is an experimental message, but not a placebo, then just return the message.
if (!message.data.isControl) {
@@ -319,21 +329,29 @@ class NimbusMessagingStorage(
message: Message,
helper: NimbusMessagingHelperInterface,
): Boolean {
- return message.triggers.all { condition ->
- try {
- if (malFormedMap.containsKey(condition)) {
- return false
- }
- helper.evalJexl(condition)
- } catch (e: NimbusException.EvaluationException) {
- reportMalformedMessage(message.id)
- malFormedMap[condition] = message.id
- logger.info("Unable to evaluate $condition")
- false
- }
+ return message.triggerIfAll.all { condition ->
+ evalJexl(message, helper, condition)
+ } && !message.excludeIfAny.any { condition ->
+ evalJexl(message, helper, condition)
}
}
+ private fun evalJexl(
+ message: Message,
+ helper: NimbusMessagingHelperInterface,
+ condition: String,
+ ): Boolean =
+ try {
+ if (malFormedMap.containsKey(condition)) {
+ throw NimbusException.EvaluationException(condition)
+ }
+ helper.evalJexl(condition)
+ } catch (e: NimbusException) {
+ malFormedMap[condition] = message.id
+ logger.info("Unable to evaluate ${message.id} trigger: $condition")
+ throw NimbusException.EvaluationException(condition)
+ }
+
@VisibleForTesting
internal fun getOnControlBehavior(): ControlMessageBehavior = messagingFeature.value().onControl
diff --git a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerTest.kt b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerTest.kt
index be17d6405b47..e956b4269bea 100644
--- a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerTest.kt
+++ b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingControllerTest.kt
@@ -273,7 +273,8 @@ class NimbusMessagingControllerTest {
data = messageData,
style = style,
metadata = Message.Metadata(id, displayCount),
- triggers = emptyList(),
+ triggerIfAll = emptyList(),
+ excludeIfAny = emptyList(),
action = action,
)
}
diff --git a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt
index 08f081e9f185..3ff19ef91248 100644
--- a/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt
+++ b/android-components/components/service/nimbus/src/test/java/mozilla/components/service/nimbus/messaging/NimbusMessagingStorageTest.kt
@@ -16,6 +16,7 @@ import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
+import org.junit.Assert.assertThrows
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
@@ -427,7 +428,7 @@ class NimbusMessagingStorageTest {
action = "action",
mock(),
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
`when`(helper.evalJexl(any())).thenReturn(true)
@@ -455,18 +456,18 @@ class NimbusMessagingStorageTest {
action = "action",
mock(),
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
`when`(helper.evalJexl(any())).then { throw NimbusException.EvaluationException("") }
- val result = storage.isMessageEligible(message, helper)
-
- assertFalse(result)
+ assertThrows(NimbusException.EvaluationException::class.java) {
+ storage.isMessageEligible(message, helper)
+ }
}
@Test
- fun `GIVEN a previously malformed trigger WHEN calling isMessageEligible THEN return false and not evaluate`() {
+ fun `GIVEN a previously malformed trigger WHEN calling isMessageEligible THEN throw and not evaluate`() {
val helper: NimbusMessagingHelperInterface = mock()
val message = Message(
"same-id",
@@ -474,22 +475,22 @@ class NimbusMessagingStorageTest {
action = "action",
mock(),
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
storage.malFormedMap["trigger"] = "same-id"
`when`(helper.evalJexl(any())).then { throw NimbusException.EvaluationException("") }
- val result = storage.isMessageEligible(message, helper)
+ assertThrows(NimbusException.EvaluationException::class.java) {
+ storage.isMessageEligible(message, helper)
+ }
- assertFalse(result)
verify(helper, never()).evalJexl("trigger")
- assertFalse(malformedWasReported)
}
@Test
- fun `GIVEN a non previously malformed trigger WHEN calling isMessageEligible THEN return false and not evaluate`() {
+ fun `GIVEN a non previously malformed trigger WHEN calling isMessageEligible THEN throw and not evaluate`() {
val helper: NimbusMessagingHelperInterface = mock()
val message = Message(
"same-id",
@@ -497,18 +498,18 @@ class NimbusMessagingStorageTest {
action = "action",
mock(),
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
`when`(helper.evalJexl(any())).then { throw NimbusException.EvaluationException("") }
assertFalse(storage.malFormedMap.containsKey("trigger"))
- val result = storage.isMessageEligible(message, helper)
+ assertThrows(NimbusException.EvaluationException::class.java) {
+ storage.isMessageEligible(message, helper)
+ }
- assertFalse(result)
assertTrue(storage.malFormedMap.containsKey("trigger"))
- assertTrue(malformedWasReported)
}
@Test
@@ -520,7 +521,7 @@ class NimbusMessagingStorageTest {
action = "action",
mock(),
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
doReturn(false).`when`(spiedStorage).isMessageEligible(any(), any())
@@ -539,7 +540,7 @@ class NimbusMessagingStorageTest {
action = "action",
style = displayOnceStyle,
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any())
@@ -561,7 +562,7 @@ class NimbusMessagingStorageTest {
action = "action",
style = displayOnceStyle,
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any())
@@ -589,7 +590,7 @@ class NimbusMessagingStorageTest {
action = "action",
style = displayOnceStyle,
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
val controlMessage = Message(
@@ -598,7 +599,7 @@ class NimbusMessagingStorageTest {
action = "action",
style = displayOnceStyle,
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any())
@@ -627,7 +628,7 @@ class NimbusMessagingStorageTest {
action = "action",
style = displayOnceStyle,
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
val controlMessage = Message(
@@ -636,7 +637,7 @@ class NimbusMessagingStorageTest {
action = "action",
style = displayOnceStyle,
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any())
@@ -667,7 +668,7 @@ class NimbusMessagingStorageTest {
action = "action",
style = displayOnceStyle,
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
val incorrectMessage = Message(
@@ -676,7 +677,7 @@ class NimbusMessagingStorageTest {
action = "action",
style = displayOnceStyle,
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
val controlMessage = Message(
@@ -685,7 +686,7 @@ class NimbusMessagingStorageTest {
action = "action",
style = displayOnceStyle,
listOf("trigger"),
- Message.Metadata("same-id"),
+ metadata = Message.Metadata("same-id"),
)
doReturn(true).`when`(spiedStorage).isMessageEligible(any(), any())
@@ -800,7 +801,7 @@ class NimbusMessagingStorageTest {
) = MessageData(
action = Res.string(action),
style = style,
- trigger = triggers,
+ triggerIfAll = triggers,
surface = surface,
isControl = isControl,
text = Res.string(text),
diff --git a/fenix/app/messaging-evergreen-messages.fml.yaml b/fenix/app/messaging-evergreen-messages.fml.yaml
index 36e7d2b15ba1..3c63e3ed90fb 100644
--- a/fenix/app/messaging-evergreen-messages.fml.yaml
+++ b/fenix/app/messaging-evergreen-messages.fml.yaml
@@ -29,9 +29,10 @@ import:
text: default_browser_experiment_card_text
surface: homescreen
action: "MAKE_DEFAULT_BROWSER"
- trigger:
- - I_AM_NOT_DEFAULT_BROWSER
+ trigger-if-all:
- USER_ESTABLISHED_INSTALL
+ exclude-if-any:
+ - I_AM_DEFAULT_BROWSER
style: PERSISTENT
button-label: preferences_set_as_default_browser
@@ -47,7 +48,8 @@ import:
text: nimbus_notification_default_browser_text
surface: notification
style: NOTIFICATION
- trigger:
- - I_AM_NOT_DEFAULT_BROWSER
+ trigger-if-all:
- DAY_3_AFTER_INSTALL
+ exclude-if-any:
+ - I_AM_DEFAULT_BROWSER
action: MAKE_DEFAULT_BROWSER
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt
index 3fcdeaf4e12f..f71784acc59c 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt
@@ -66,7 +66,7 @@ class NimbusMessagingHomescreenTest {
buttonLabel = Res.string(messageButtonLabel),
text = Res.string(messageText),
title = Res.string(messageTitle),
- trigger = listOf("ALWAYS"),
+ triggerIfAll = listOf("ALWAYS"),
),
),
styles = mapOf(
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/components/AppStoreTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/components/AppStoreTest.kt
index 78d0fabae938..cfd2e2876689 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/components/AppStoreTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/components/AppStoreTest.kt
@@ -113,6 +113,7 @@ class AppStoreTest {
"action",
mockk(),
emptyList(),
+ emptyList(),
mockk(),
)
appStore.dispatch(UpdateMessageToShow(message)).join()
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/messaging/DefaultMessageControllerTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/messaging/DefaultMessageControllerTest.kt
index 35d5d8b48804..d94c96dfc40d 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/messaging/DefaultMessageControllerTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/messaging/DefaultMessageControllerTest.kt
@@ -69,7 +69,8 @@ class DefaultMessageControllerTest {
data = data,
style = mockk(relaxed = true),
action = "action",
- triggers = emptyList(),
+ triggerIfAll = emptyList(),
+ excludeIfAny = emptyList(),
metadata = Message.Metadata(
id = "id",
displayCount = 0,
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingMiddlewareTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingMiddlewareTest.kt
index b4f72cd14afc..88b9161583e4 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingMiddlewareTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingMiddlewareTest.kt
@@ -355,7 +355,8 @@ private fun createMessage(
action: String = "action",
styleData: StyleData = StyleData(),
triggers: List = listOf("triggers"),
-) = Message(messageId, data, action, styleData, triggers, metadata)
+ except: List = listOf(),
+) = Message(messageId, data, action, styleData, triggers, except, metadata)
private fun createMetadata(
displayCount: Int = 0,
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingReducerTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingReducerTest.kt
index dbb111eb4339..43d1f44e9473 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingReducerTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/messaging/state/MessagingReducerTest.kt
@@ -52,7 +52,7 @@ class MessagingReducerTest {
data = MessageData(surface = surface),
action = action,
style = StyleData(),
- triggers = listOf(),
+ triggerIfAll = listOf(),
metadata = Message.Metadata(id = id),
)
From aec235a17a43d6d6e19a44303d99ae4f3b2fda22 Mon Sep 17 00:00:00 2001
From: ohall-m
Date: Thu, 22 Feb 2024 15:44:02 -0500
Subject: [PATCH 331/586] Bug 1881604 - Helper for Transforming BCP 47 code to
defined Language
This patch adds a helper for converting BCP 47 codes to translations
supported languages.
Adds:
* `toLanguageMap` - maps a map of BCP 47 code (key) to Language (value)
* `findLanguage` - finds a language using the `toLanguageMap`
* `mapLanguageSettings` - makes a new display ready map for converting
the language settings from Map?) to Map
---
.../state/state/TranslationSupportTest.kt | 141 ++++++++++++++++++
.../engine/translate/TranslationSupport.kt | 42 ++++++
2 files changed, 183 insertions(+)
create mode 100644 android-components/components/browser/state/src/test/java/mozilla/components/browser/state/state/TranslationSupportTest.kt
diff --git a/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/state/TranslationSupportTest.kt b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/state/TranslationSupportTest.kt
new file mode 100644
index 000000000000..9d134ff5e4bf
--- /dev/null
+++ b/android-components/components/browser/state/src/test/java/mozilla/components/browser/state/state/TranslationSupportTest.kt
@@ -0,0 +1,141 @@
+/* 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.Language
+import mozilla.components.concept.engine.translate.LanguageSetting
+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 mozilla.components.concept.engine.translate.TranslationSupport
+import mozilla.components.concept.engine.translate.findLanguage
+import mozilla.components.concept.engine.translate.mapLanguageSettings
+import mozilla.components.concept.engine.translate.toLanguageMap
+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 TranslationSupportTest {
+
+ private val spanish = Language(code = "es", "Spanish")
+ private val english = Language(code = "en", "English")
+ private val german = Language(code = "de", "German")
+
+ @Test
+ fun `GIVEN a populated TranslationSupport THEN map to a language map`() {
+ val translationsSupport = TranslationSupport(
+ fromLanguages = listOf(english, spanish),
+ toLanguages = listOf(english, spanish),
+ )
+
+ val map = translationsSupport.toLanguageMap()
+
+ assertTrue(map!!.contains(spanish.code))
+ assertTrue(map.contains(english.code))
+ assertEquals(map.size, 2)
+ }
+
+ @Test
+ fun `GIVEN a partially populated TranslationSupport THEN map to a language map`() {
+ val supportToPopulated = TranslationSupport(
+ fromLanguages = null,
+ toLanguages = listOf(english, spanish),
+ )
+
+ val toMap = supportToPopulated.toLanguageMap()
+ assertTrue(toMap!!.contains(spanish.code))
+ assertTrue(toMap.contains(english.code))
+ assertEquals(toMap.size, 2)
+
+ val supportFromPopulated = TranslationSupport(
+ fromLanguages = listOf(english, spanish),
+ toLanguages = null,
+ )
+
+ val fromMap = supportFromPopulated.toLanguageMap()
+ assertTrue(fromMap!!.contains(spanish.code))
+ assertTrue(fromMap.contains(english.code))
+ assertEquals(fromMap.size, 2)
+ }
+
+ @Test
+ fun `GIVEN a null TranslationSupport THEN map to a null language map`() {
+ val translationsSupport = TranslationSupport(
+ fromLanguages = null,
+ toLanguages = null,
+ )
+
+ val map = translationsSupport.toLanguageMap()
+ assertNull(map)
+ }
+
+ @Test
+ fun `GIVEN a populated TranslationSupport THEN find a language`() {
+ val translationsSupport = TranslationSupport(
+ fromLanguages = listOf(spanish, english),
+ toLanguages = listOf(spanish, english),
+ )
+
+ assertEquals(translationsSupport.findLanguage("es"), spanish)
+ assertEquals(translationsSupport.findLanguage("en"), english)
+ assertNull(translationsSupport.findLanguage("de"))
+ }
+
+ @Test
+ fun `GIVEN a null TranslationSupport THEN do not find a language`() {
+ val translationsSupport = TranslationSupport(
+ fromLanguages = null,
+ toLanguages = null,
+ )
+
+ assertNull(translationsSupport.findLanguage("es"))
+ }
+
+ @Test
+ fun `GIVEN a populated TranslationSupport THEN map the language settings`() {
+ val translationsSupport = TranslationSupport(
+ fromLanguages = listOf(spanish, english, german),
+ toLanguages = listOf(spanish, english),
+ )
+
+ val languageSettings = mapOf(
+ spanish.code to ALWAYS,
+ english.code to NEVER,
+ german.code to OFFER,
+ "some unknown code" to OFFER,
+ "some unknown code2" to OFFER,
+ )
+
+ val map = translationsSupport.mapLanguageSettings(languageSettings)
+ assertTrue(map!!.contains(spanish))
+ assertTrue(map.contains(english))
+ assertTrue(map.contains(german))
+ assertEquals(map.size, 3)
+ }
+
+ @Test
+ fun `GIVEN an unpopulated TranslationSupport THEN map the language settings`() {
+ val translationsSupport = TranslationSupport(
+ fromLanguages = null,
+ toLanguages = null,
+ )
+
+ val languageSettings = mapOf(
+ spanish.code to ALWAYS,
+ english.code to NEVER,
+ german.code to OFFER,
+ "some unknown code" to OFFER,
+ "some unknown code2" to OFFER,
+ )
+
+ val map = translationsSupport.mapLanguageSettings(languageSettings)
+ assertFalse(map!!.contains(spanish))
+ assertFalse(map.contains(english))
+ assertFalse(map.contains(german))
+ assertEquals(map.size, 0)
+ }
+}
diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationSupport.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationSupport.kt
index cb624922c1e2..033f55bb3964 100644
--- a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationSupport.kt
+++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/translate/TranslationSupport.kt
@@ -16,3 +16,45 @@ data class TranslationSupport(
val fromLanguages: List? = null,
val toLanguages: List? = null,
)
+
+/**
+ * Convenience method to convert [this.fromLanguages] and [this.toLanguages] to a single language
+ * map for BCP 47 code to [Language] lookup.
+ *
+ * @return A combined map of the language options with the BCP 47 language as the key and the
+ * [Language] object as the value or null.
+ */
+fun TranslationSupport.toLanguageMap(): Map? {
+ val fromLanguagesMap = fromLanguages?.associate { it.code to it }
+ val toLanguagesMap = toLanguages?.associate { it.code to it }
+
+ return if (toLanguagesMap != null && fromLanguagesMap != null) {
+ toLanguagesMap + fromLanguagesMap
+ } else {
+ toLanguagesMap
+ ?: fromLanguagesMap
+ }
+}
+
+/**
+ * Convenience method to find a [Language] given a BCP 47 language code.
+ *
+ * @param languageCode The BCP 47 language code.
+ *
+ * @return The [Language] associated with the language code or null.
+ */
+fun TranslationSupport.findLanguage(languageCode: String): Language? {
+ return toLanguageMap()?.get(languageCode)
+}
+
+/**
+ * Convenience method to convert a language setting map using a BCP 47 code as a key to a map using
+ * [Language] as a key.
+ *
+ * @param languageSettings The map of language settings, where the key, [String], is a BCP 47 code.
+ */
+fun TranslationSupport.mapLanguageSettings(
+ languageSettings: Map?,
+): Map? {
+ return languageSettings?.mapKeys { findLanguage(it.key) }?.filterKeys { it != null }
+}
From 58ffd07680b825790ee0b7896c04e19a3f2f6846 Mon Sep 17 00:00:00 2001
From: William Durand
Date: Thu, 15 Feb 2024 10:49:00 +0100
Subject: [PATCH 332/586] Bug 1870339 - Make list of add-ons more accessible
---
.../feature/addons/ui/AddonsManagerAdapter.kt | 28 ++++++++++++
.../addons/ui/AddonsManagerAdapterTest.kt | 43 +++++++++++++++++--
.../SettingsSubMenuAddonsManagerRobot.kt | 21 ++++++---
.../fenix/addons/AddonsManagementFragment.kt | 24 +++++++++++
4 files changed, 107 insertions(+), 9 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 2b0ed6ed0225..33b35e8adda8 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
@@ -6,9 +6,11 @@ package mozilla.components.feature.addons.ui
import android.annotation.SuppressLint
import android.graphics.Typeface
+import android.os.Build
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.view.accessibility.AccessibilityNodeInfo
import android.widget.ImageView
import android.widget.RatingBar
import android.widget.TextView
@@ -184,6 +186,32 @@ class AddonsManagerAdapter(
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
val item = getItem(position)
+ // Configure an accessibility delegate for each item.
+ holder.itemView.accessibilityDelegate = object : View.AccessibilityDelegate() {
+ override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) {
+ super.onInitializeAccessibilityNodeInfo(host, info)
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ info.collectionItemInfo = AccessibilityNodeInfo.CollectionItemInfo(
+ holder.bindingAdapterPosition,
+ 1,
+ 1,
+ 1,
+ holder is SectionViewHolder,
+ )
+ } else {
+ @Suppress("DEPRECATION")
+ info.collectionItemInfo = AccessibilityNodeInfo.CollectionItemInfo.obtain(
+ holder.bindingAdapterPosition,
+ 1,
+ 1,
+ 1,
+ holder is SectionViewHolder,
+ )
+ }
+ }
+ }
+
when (holder) {
is SectionViewHolder -> bindSection(holder, item as Section, position)
is AddonViewHolder -> bindAddon(holder, item as Addon)
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 6dac9c9f69df..70fb2da94821 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
@@ -5,6 +5,7 @@
package mozilla.components.feature.addons.ui
import android.view.View
+import android.view.accessibility.AccessibilityNodeInfo
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
@@ -32,6 +33,7 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.any
+import org.mockito.Mockito.argThat
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
@@ -187,7 +189,7 @@ class AddonsManagerAdapterTest {
fun `bind section`() {
val titleView: TextView = mock()
val divider: View = mock()
- val addonViewHolder = CustomViewHolder.SectionViewHolder(View(testContext), titleView, divider)
+ val sectionViewHolder = CustomViewHolder.SectionViewHolder(View(testContext), titleView, divider)
val position = 0
whenever(titleView.context).thenReturn(testContext)
@@ -197,13 +199,28 @@ class AddonsManagerAdapterTest {
sectionsTypeFace = mock(),
)
val adapter = AddonsManagerAdapter(mock(), emptyList(), style, emptyList(), mock())
+ // Force-add a Section item in the list.
+ adapter.submitList(null)
+ adapter.submitList(listOf(Section(R.string.mozac_feature_addons_disabled_section)))
+ // Make sure we have the Footer item in the list.
+ assertEquals(1, adapter.itemCount)
- adapter.bindSection(addonViewHolder, Section(R.string.mozac_feature_addons_disabled_section), position)
+ // Use the "public" method to bind the section.
+ adapter.bindViewHolder(sectionViewHolder, position)
verify(titleView).setText(R.string.mozac_feature_addons_disabled_section)
verify(titleView).typeface = style.sectionsTypeFace
verify(titleView).setTextColor(ContextCompat.getColor(testContext, style.sectionsTextColor!!))
verify(divider).isVisible = style.visibleDividers && position != 0
+ assertNotNull(sectionViewHolder.itemView.accessibilityDelegate)
+
+ val nodeInfo: AccessibilityNodeInfo = mock()
+ sectionViewHolder.itemView.accessibilityDelegate.onInitializeAccessibilityNodeInfo(mock(), nodeInfo)
+ verify(nodeInfo).collectionItemInfo = argThat {
+ // We cannot verify `rowIndex` because we're using `bindingAdapterPosition`.
+ @Suppress("DEPRECATION")
+ it.rowSpan == 1 && it.columnIndex == 1 && it.columnSpan == 1 && it.isHeading
+ }
}
@Test
@@ -354,6 +371,10 @@ class AddonsManagerAdapterTest {
assertEquals(addon.version, adapter.addonsMap[addon.id]!!.version)
verify(adapter).submitList(any())
+
+ // Once the list is submitted, we should have the right item count on the adapter.
+ // In this case, we have 1 heading and 1 add-on.
+ assertEquals(2, adapter.itemCount)
}
@Test
@@ -476,13 +497,27 @@ class AddonsManagerAdapterTest {
fun bindFooterButton() {
val addonsManagerAdapterDelegate: AddonsManagerAdapterDelegate = mock()
val adapter = AddonsManagerAdapter(addonsManagerAdapterDelegate, emptyList(), mock(), emptyList(), mock())
-
val view = View(testContext)
val viewHolder = CustomViewHolder.FooterViewHolder(view)
- adapter.bindFooterButton(viewHolder)
+ // Make sure we have the Footer item in the list.
+ adapter.submitList(null)
+ adapter.submitList(listOf(AddonsManagerAdapter.FooterSection))
+ assertEquals(1, adapter.itemCount)
+
+ // Use the "public" method to bind the footer.
+ adapter.onBindViewHolder(viewHolder, 0)
viewHolder.itemView.performClick()
verify(addonsManagerAdapterDelegate).onFindMoreAddonsButtonClicked()
+ assertNotNull(viewHolder.itemView.accessibilityDelegate)
+
+ val nodeInfo: AccessibilityNodeInfo = mock()
+ viewHolder.itemView.accessibilityDelegate.onInitializeAccessibilityNodeInfo(mock(), nodeInfo)
+ verify(nodeInfo).collectionItemInfo = argThat {
+ // We cannot verify `rowIndex` because we're using `bindingAdapterPosition`.
+ @Suppress("DEPRECATION")
+ it.rowSpan == 1 && it.columnIndex == 1 && it.columnSpan == 1 && !it.isHeading
+ }
}
@Test
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 95ea5f4c431c..96d23ec27ed6 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
@@ -36,6 +36,7 @@ import org.mozilla.fenix.helpers.Constants.RETRY_COUNT
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
+import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong
@@ -43,7 +44,6 @@ import org.mozilla.fenix.helpers.TestHelper.appName
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.packageName
import org.mozilla.fenix.helpers.TestHelper.restartApp
-import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText
import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.ext.waitNotNull
@@ -120,7 +120,7 @@ class SettingsSubMenuAddonsManagerRobot {
homeScreen {
}.openThreeDotMenu {
}.openAddonsManagerMenu {
- scrollToElementByText(addonName)
+ scrollToAddon(addonName)
clickInstallAddon(addonName)
verifyAddonPermissionPrompt(addonName)
acceptPermissionToInstallAddon()
@@ -152,7 +152,7 @@ class SettingsSubMenuAddonsManagerRobot {
}
fun verifyAddonIsInstalled(addonName: String) {
- scrollToElementByText(addonName)
+ scrollToAddon(addonName)
Log.i(TAG, "verifyAddonIsInstalled: Trying to verify that the $addonName add-on was installed")
onView(
allOf(
@@ -199,7 +199,7 @@ class SettingsSubMenuAddonsManagerRobot {
Log.i(TAG, "verifyAddonsItems: Verified that all uBlock Origin items are completely displayed")
}
fun verifyAddonCanBeInstalled(addonName: String) {
- scrollToElementByText(addonName)
+ scrollToAddon(addonName)
mDevice.waitNotNull(Until.findObject(By.text(addonName)), waitingTime)
Log.i(TAG, "verifyAddonCanBeInstalled: Trying to verify that the install $addonName button is visible")
onView(
@@ -250,7 +250,7 @@ class SettingsSubMenuAddonsManagerRobot {
addonName: String,
interact: SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.() -> Unit,
): SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.Transition {
- scrollToElementByText(addonName)
+ scrollToAddon(addonName)
Log.i(TAG, "openDetailedMenuForAddon: Trying to verify that the $addonName add-on is visible")
addonItem(addonName).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
Log.i(TAG, "openDetailedMenuForAddon: Verified that the $addonName add-on is visible")
@@ -297,6 +297,17 @@ fun addonsMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): Settings
return SettingsSubMenuAddonsManagerRobot.Transition()
}
+private fun scrollToAddon(addonName: String) {
+ Log.i(TAG, "scrollToAddon: Trying to scroll into view add-on: $addonName")
+ addonsList().scrollIntoView(
+ itemWithResIdContainingText(
+ resourceId = "$packageName:id/add_on_name",
+ text = addonName,
+ ),
+ )
+ Log.i(TAG, "scrollToAddon: Scrolled into view add-on: $addonName")
+}
+
private fun addonItem(addonName: String) =
onView(
allOf(
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt
index e7c73943316d..1103b008a518 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt
@@ -11,6 +11,7 @@ import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.accessibility.AccessibilityEvent
+import android.view.accessibility.AccessibilityNodeInfo
import androidx.annotation.VisibleForTesting
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
@@ -115,6 +116,29 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
binding?.addOnsEmptyMessage?.isVisible = false
recyclerView?.adapter = adapter
+ recyclerView?.accessibilityDelegate = object : View.AccessibilityDelegate() {
+ override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) {
+ super.onInitializeAccessibilityNodeInfo(host, info)
+
+ adapter?.let {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ info.collectionInfo = AccessibilityNodeInfo.CollectionInfo(
+ it.itemCount,
+ 1,
+ false,
+ )
+ } else {
+ @Suppress("DEPRECATION")
+ info.collectionInfo = AccessibilityNodeInfo.CollectionInfo.obtain(
+ it.itemCount,
+ 1,
+ false,
+ )
+ }
+ }
+ }
+ }
+
if (shouldRefresh) {
adapter?.updateAddons(addons)
}
From 8b6a24525c11f686a0ff0d22cbf0d1f2ed12083e Mon Sep 17 00:00:00 2001
From: Issam Mani
Date: Tue, 13 Feb 2024 02:38:45 +0100
Subject: [PATCH 333/586] Bug 1880075 - Use single name field for addresses
---
.../browser/engine/gecko/ext/Address.kt | 9 +-
.../gecko/prompt/GeckoPromptDelegateTest.kt | 4 +-
.../engine/prompt/PromptRequestTest.kt | 4 +-
.../storage/CreditCardsAddressesStorage.kt | 25 +----
.../components/concept/storage/AddressTest.kt | 47 +-------
.../prompts/address/AddressAdapterTest.kt | 4 +-
.../prompts/address/AddressPickerTest.kt | 4 +-
.../prompts/address/AddressSelectBarTest.kt | 4 +-
.../components/service/sync/autofill/Types.kt | 8 +-
...AutofillCreditCardsAddressesStorageTest.kt | 40 ++-----
.../src/main/java/ApplicationServices.kt | 2 +-
.../mozilla/fenix/ui/AddressAutofillTest.kt | 52 +++------
.../ui/robots/SettingsSubMenuAutofillRobot.kt | 45 +++-----
.../fenix/settings/address/ext/Address.kt | 9 --
.../address/view/AddressEditorView.kt | 12 +--
.../settings/address/view/AddressList.kt | 7 +-
.../res/layout/fragment_address_editor.xml | 102 ++----------------
fenix/app/src/main/res/values/strings.xml | 8 +-
.../settings/address/AddressEditorViewTest.kt | 16 +--
.../DefaultAddressEditorControllerTest.kt | 4 +-
.../fenix/settings/address/ext/AddressTest.kt | 47 +-------
.../DefaultAddressEditorInteractorTest.kt | 4 +-
22 files changed, 83 insertions(+), 374 deletions(-)
diff --git a/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/ext/Address.kt b/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/ext/Address.kt
index eebf1965c506..2378326ed0d1 100644
--- a/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/ext/Address.kt
+++ b/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/ext/Address.kt
@@ -12,9 +12,7 @@ import org.mozilla.geckoview.Autocomplete
*/
fun Autocomplete.Address.toAddress() = Address(
guid = guid ?: "",
- givenName = givenName,
- additionalName = additionalName,
- familyName = familyName,
+ name = name,
organization = organization,
streetAddress = streetAddress,
addressLevel3 = addressLevel3,
@@ -31,10 +29,7 @@ fun Autocomplete.Address.toAddress() = Address(
*/
fun Address.toAutocompleteAddress() = Autocomplete.Address.Builder()
.guid(guid)
- .name(fullName)
- .givenName(givenName)
- .additionalName(additionalName)
- .familyName(familyName)
+ .name(name)
.organization(organization)
.streetAddress(streetAddress)
.addressLevel3(addressLevel3)
diff --git a/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/prompt/GeckoPromptDelegateTest.kt b/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/prompt/GeckoPromptDelegateTest.kt
index c52d81ec51ea..8c5c058055e8 100644
--- a/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/prompt/GeckoPromptDelegateTest.kt
+++ b/android-components/components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/prompt/GeckoPromptDelegateTest.kt
@@ -1853,9 +1853,7 @@ class GeckoPromptDelegateTest {
val address = Address(
guid = "1",
- givenName = "Firefox",
- additionalName = "-",
- familyName = "-",
+ name = "Firefox",
organization = "-",
streetAddress = "street",
addressLevel3 = "address3",
diff --git a/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/prompt/PromptRequestTest.kt b/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/prompt/PromptRequestTest.kt
index 7c6f567bc0aa..5c63c242023a 100644
--- a/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/prompt/PromptRequestTest.kt
+++ b/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/prompt/PromptRequestTest.kt
@@ -322,9 +322,7 @@ class PromptRequestTest {
fun `WHEN calling confirm or dismiss on the SelectAddress prompt request THEN the respective callback is invoked`() {
val address = Address(
guid = "1",
- givenName = "Firefox",
- additionalName = "-",
- familyName = "-",
+ name = "Firefox",
organization = "-",
streetAddress = "street",
addressLevel3 = "address3",
diff --git a/android-components/components/concept/storage/src/main/java/mozilla/components/concept/storage/CreditCardsAddressesStorage.kt b/android-components/components/concept/storage/src/main/java/mozilla/components/concept/storage/CreditCardsAddressesStorage.kt
index 1268c3b5aef9..f619a9d1e99b 100644
--- a/android-components/components/concept/storage/src/main/java/mozilla/components/concept/storage/CreditCardsAddressesStorage.kt
+++ b/android-components/components/concept/storage/src/main/java/mozilla/components/concept/storage/CreditCardsAddressesStorage.kt
@@ -332,9 +332,7 @@ data class UpdatableCreditCardFields(
* Information about a address.
*
* @property guid The unique identifier for this address.
- * @property givenName First name.
- * @property additionalName Middle name.
- * @property familyName Last name.
+ * @property name A person's full name, typically made up of a first, middle and last name, e.g. John Joe Doe.
* @property organization Organization.
* @property streetAddress Street address.
* @property addressLevel3 Sublocality (Suburb) name type.
@@ -353,9 +351,7 @@ data class UpdatableCreditCardFields(
@Parcelize
data class Address(
val guid: String,
- val givenName: String,
- val additionalName: String,
- val familyName: String,
+ val name: String,
val organization: String,
val streetAddress: String,
val addressLevel3: String,
@@ -370,15 +366,6 @@ data class Address(
val timeLastModified: Long = 0L,
val timesUsed: Long = 0L,
) : Parcelable {
- /**
- * Returns the full name for the [Address]. The combination of names is based on desktop code
- * found here:
- * https://searchfox.org/mozilla-central/rev/d989c65584ded72c2de85cb40bede7ac2f176387/toolkit/components/formautofill/FormAutofillNameUtils.jsm#400
- */
- val fullName: String
- get() = listOf(givenName, additionalName, familyName)
- .filter { it.isNotEmpty() }
- .joinToString(" ")
/**
* Returns a label for the [Address]. The ordering is based on the
@@ -408,9 +395,7 @@ data class Address(
/**
* Information about a new address. This is what you pass to create or update an address.
*
- * @property givenName First name.
- * @property additionalName Middle name.
- * @property familyName Last name.
+ * @property name A person's full name, typically made up of a first, middle and last name, e.g. John Joe Doe.
* @property organization Organization.
* @property streetAddress Street address.
* @property addressLevel3 Sublocality (Suburb) name type.
@@ -422,9 +407,7 @@ data class Address(
* @property email E-mail address.
*/
data class UpdatableAddressFields(
- val givenName: String,
- val additionalName: String,
- val familyName: String,
+ val name: String,
val organization: String,
val streetAddress: String,
val addressLevel3: String,
diff --git a/android-components/components/concept/storage/src/test/java/mozilla/components/concept/storage/AddressTest.kt b/android-components/components/concept/storage/src/test/java/mozilla/components/concept/storage/AddressTest.kt
index 413c830e7ec4..9d775d417b0e 100644
--- a/android-components/components/concept/storage/src/test/java/mozilla/components/concept/storage/AddressTest.kt
+++ b/android-components/components/concept/storage/src/test/java/mozilla/components/concept/storage/AddressTest.kt
@@ -10,41 +10,6 @@ import org.junit.Test
class AddressTest {
- @Test
- fun `WHEN all name fields are populated THEN full name includes all names`() {
- val address = generateAddress()
- val fullName = address.fullName
-
- assertEquals(
- "${address.givenName} ${address.additionalName} ${address.familyName}",
- fullName,
- )
- }
-
- @Test
- fun `WHEN additional name is missing THEN full name is given and family name combined`() {
- val address = generateAddress(additionalName = "")
- val fullName = address.fullName
-
- assertEquals("${address.givenName} ${address.familyName}", fullName)
- }
-
- @Test
- fun `WHEN only additional and family name are available THEN full name is additional and family name combined`() {
- val address = generateAddress(givenName = "")
- val fullName = address.fullName
-
- assertEquals("${address.additionalName} ${address.familyName}", fullName)
- }
-
- @Test
- fun `WHEN only family name is available THEN full name is family name`() {
- val address = generateAddress(givenName = "", additionalName = "")
- val fullName = address.fullName
-
- assertEquals(address.familyName, fullName)
- }
-
@Test
fun `WHEN all address properties are present THEN full address present in label`() {
val address = generateAddress()
@@ -73,9 +38,7 @@ class AddressTest {
@Test
fun `WHEN no address properties are present THEN label is the empty string`() {
val address = generateAddress(
- givenName = "",
- additionalName = "",
- familyName = "",
+ name = "",
organization = "",
streetAddress = "",
addressLevel3 = "",
@@ -103,9 +66,7 @@ class AddressTest {
private fun generateAddress(
guid: String = "",
- givenName: String = "Firefox",
- additionalName: String = "The",
- familyName: String = "Browser",
+ name: String = "Firefox The Browser",
organization: String = "Mozilla",
streetAddress: String = "street",
addressLevel3: String = "3",
@@ -117,9 +78,7 @@ class AddressTest {
email: String = "email",
) = Address(
guid = guid,
- givenName = givenName,
- additionalName = additionalName,
- familyName = familyName,
+ name = name,
organization = organization,
streetAddress = streetAddress,
addressLevel3 = addressLevel3,
diff --git a/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressAdapterTest.kt b/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressAdapterTest.kt
index f9e5d1060663..5423741dab9f 100644
--- a/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressAdapterTest.kt
+++ b/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressAdapterTest.kt
@@ -21,9 +21,7 @@ class AddressAdapterTest {
private val address = Address(
guid = "1",
- givenName = "Location",
- additionalName = "Location",
- familyName = "Location",
+ name = "Jane Marie Doe",
organization = "Mozilla",
streetAddress = "1230 Main st",
addressLevel3 = "Location3",
diff --git a/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressPickerTest.kt b/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressPickerTest.kt
index 841261211cd9..7469f498c47b 100644
--- a/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressPickerTest.kt
+++ b/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressPickerTest.kt
@@ -33,9 +33,7 @@ class AddressPickerTest {
private val address = Address(
guid = "1",
- givenName = "Location",
- additionalName = "Location",
- familyName = "Location",
+ name = "Jane Marie Doe",
organization = "Mozilla",
streetAddress = "1230 Main st",
addressLevel3 = "Location3",
diff --git a/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressSelectBarTest.kt b/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressSelectBarTest.kt
index 7f9cb0b049ac..fbffde17c800 100644
--- a/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressSelectBarTest.kt
+++ b/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/address/AddressSelectBarTest.kt
@@ -37,9 +37,7 @@ class AddressSelectBarTest {
private val address = Address(
guid = "1",
- givenName = "Location",
- additionalName = "Location",
- familyName = "Location",
+ name = "Jane Marie Doe",
organization = "Mozilla",
streetAddress = "1230 Main st",
addressLevel3 = "Location3",
diff --git a/android-components/components/service/sync-autofill/src/main/java/mozilla/components/service/sync/autofill/Types.kt b/android-components/components/service/sync-autofill/src/main/java/mozilla/components/service/sync/autofill/Types.kt
index 6508f0cfe551..5e222e2ea1de 100644
--- a/android-components/components/service/sync-autofill/src/main/java/mozilla/components/service/sync/autofill/Types.kt
+++ b/android-components/components/service/sync-autofill/src/main/java/mozilla/components/service/sync/autofill/Types.kt
@@ -18,9 +18,7 @@ import mozilla.components.concept.storage.UpdatableCreditCardFields
*/
internal fun UpdatableAddressFields.into(): mozilla.appservices.autofill.UpdatableAddressFields {
return mozilla.appservices.autofill.UpdatableAddressFields(
- givenName = this.givenName,
- additionalName = this.additionalName,
- familyName = this.familyName,
+ name = this.name,
organization = this.organization,
streetAddress = this.streetAddress,
addressLevel3 = this.addressLevel3,
@@ -57,9 +55,7 @@ internal fun UpdatableCreditCardFields.into(): mozilla.appservices.autofill.Upda
internal fun mozilla.appservices.autofill.Address.into(): Address {
return Address(
guid = this.guid,
- givenName = this.givenName,
- additionalName = this.additionalName,
- familyName = this.familyName,
+ name = this.name,
organization = this.organization,
streetAddress = this.streetAddress,
addressLevel3 = this.addressLevel3,
diff --git a/android-components/components/service/sync-autofill/src/test/java/mozilla/components/service/sync/autofill/AutofillCreditCardsAddressesStorageTest.kt b/android-components/components/service/sync-autofill/src/test/java/mozilla/components/service/sync/autofill/AutofillCreditCardsAddressesStorageTest.kt
index e10f69e0a3ef..3fa18c40ca3e 100644
--- a/android-components/components/service/sync-autofill/src/test/java/mozilla/components/service/sync/autofill/AutofillCreditCardsAddressesStorageTest.kt
+++ b/android-components/components/service/sync-autofill/src/test/java/mozilla/components/service/sync/autofill/AutofillCreditCardsAddressesStorageTest.kt
@@ -224,9 +224,7 @@ class AutofillCreditCardsAddressesStorageTest {
@Test
fun `add address`() = runTest {
val addressFields = UpdatableAddressFields(
- givenName = "John",
- additionalName = "",
- familyName = "Smith",
+ name = "John Smith",
organization = "Mozilla",
streetAddress = "123 Sesame Street",
addressLevel3 = "",
@@ -241,9 +239,7 @@ class AutofillCreditCardsAddressesStorageTest {
assertNotNull(address)
- assertEquals(addressFields.givenName, address.givenName)
- assertEquals(addressFields.additionalName, address.additionalName)
- assertEquals(addressFields.familyName, address.familyName)
+ assertEquals(addressFields.name, address.name)
assertEquals(addressFields.organization, address.organization)
assertEquals(addressFields.streetAddress, address.streetAddress)
assertEquals(addressFields.addressLevel3, address.addressLevel3)
@@ -258,9 +254,7 @@ class AutofillCreditCardsAddressesStorageTest {
@Test
fun `get address`() = runTest {
val addressFields = UpdatableAddressFields(
- givenName = "John",
- additionalName = "",
- familyName = "Smith",
+ name = "John Smith",
organization = "Mozilla",
streetAddress = "123 Sesame Street",
addressLevel3 = "",
@@ -284,9 +278,7 @@ class AutofillCreditCardsAddressesStorageTest {
@Test
fun `get all addresses`() = runTest {
val addressFields1 = UpdatableAddressFields(
- givenName = "John",
- additionalName = "",
- familyName = "Smith",
+ name = "John Smith",
organization = "Mozilla",
streetAddress = "123 Sesame Street",
addressLevel3 = "",
@@ -298,9 +290,7 @@ class AutofillCreditCardsAddressesStorageTest {
email = "foo@bar.com",
)
val addressFields2 = UpdatableAddressFields(
- givenName = "Mary",
- additionalName = "",
- familyName = "Sue",
+ name = "Mary Sue",
organization = "",
streetAddress = "1 New St",
addressLevel3 = "",
@@ -312,9 +302,7 @@ class AutofillCreditCardsAddressesStorageTest {
email = "mary@example.com",
)
val addressFields3 = UpdatableAddressFields(
- givenName = "Timothy",
- additionalName = "João",
- familyName = "Berners-Lee",
+ name = "Timothy João Berners-Lee",
organization = "World Wide Web Consortium",
streetAddress = "Rua Adalberto Pajuaba, 404",
addressLevel3 = "Campos Elísios",
@@ -342,9 +330,7 @@ class AutofillCreditCardsAddressesStorageTest {
@Test
fun `update address`() = runTest {
val addressFields = UpdatableAddressFields(
- givenName = "John",
- additionalName = "",
- familyName = "Smith",
+ name = "John Smith",
organization = "Mozilla",
streetAddress = "123 Sesame Street",
addressLevel3 = "",
@@ -359,9 +345,7 @@ class AutofillCreditCardsAddressesStorageTest {
var address = storage.addAddress(addressFields)
val newAddressFields = UpdatableAddressFields(
- givenName = "Mary",
- additionalName = "",
- familyName = "Sue",
+ name = "Mary Sue",
organization = "",
streetAddress = "1 New St",
addressLevel3 = "",
@@ -377,9 +361,7 @@ class AutofillCreditCardsAddressesStorageTest {
address = storage.getAddress(address.guid)!!
- assertEquals(newAddressFields.givenName, address.givenName)
- assertEquals(newAddressFields.additionalName, address.additionalName)
- assertEquals(newAddressFields.familyName, address.familyName)
+ assertEquals(newAddressFields.name, address.name)
assertEquals(newAddressFields.organization, address.organization)
assertEquals(newAddressFields.streetAddress, address.streetAddress)
assertEquals(newAddressFields.addressLevel3, address.addressLevel3)
@@ -394,9 +376,7 @@ class AutofillCreditCardsAddressesStorageTest {
@Test
fun `delete address`() = runTest {
val addressFields = UpdatableAddressFields(
- givenName = "John",
- additionalName = "",
- familyName = "Smith",
+ name = "John Smith",
organization = "Mozilla",
streetAddress = "123 Sesame Street",
addressLevel3 = "",
diff --git a/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt b/android-components/plugins/dependencies/src/main/java/ApplicationServices.kt
index 83235e1feff6..fa2b1aa61e54 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 = "125.20240222050253"
+val VERSION = "125.20240226160923"
val CHANNEL = ApplicationServicesChannel.NIGHTLY
object ApplicationServicesConfig {
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..61a3c0b7fc4f 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
@@ -24,9 +24,7 @@ class AddressAutofillTest : TestSetup() {
var navigateToAutofillSettings = true
var isAddressAutofillEnabled = true
var userHasSavedAddress = false
- var firstName = "Mozilla"
- var middleName = "Fenix"
- var lastName = "Firefox"
+ var name = "Mozilla Fenix Firefox"
var streetAddress = "Harrison Street"
var city = "San Francisco"
var state = "Alaska"
@@ -38,9 +36,7 @@ class AddressAutofillTest : TestSetup() {
object SecondAddressAutofillDetails {
var navigateToAutofillSettings = false
- var firstName = "Android"
- var middleName = "Test"
- var lastName = "Name"
+ var name = "Android Test Name"
var streetAddress = "Fort Street"
var city = "San Jose"
var state = "Arizona"
@@ -65,9 +61,7 @@ class AddressAutofillTest : TestSetup() {
navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings,
isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled,
userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress,
- firstName = FirstAddressAutofillDetails.firstName,
- middleName = FirstAddressAutofillDetails.middleName,
- lastName = FirstAddressAutofillDetails.lastName,
+ name = FirstAddressAutofillDetails.name,
streetAddress = FirstAddressAutofillDetails.streetAddress,
city = FirstAddressAutofillDetails.city,
state = FirstAddressAutofillDetails.state,
@@ -102,9 +96,7 @@ class AddressAutofillTest : TestSetup() {
navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings,
isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled,
userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress,
- firstName = FirstAddressAutofillDetails.firstName,
- middleName = FirstAddressAutofillDetails.middleName,
- lastName = FirstAddressAutofillDetails.lastName,
+ name = FirstAddressAutofillDetails.name,
streetAddress = FirstAddressAutofillDetails.streetAddress,
city = FirstAddressAutofillDetails.city,
state = FirstAddressAutofillDetails.state,
@@ -145,9 +137,7 @@ class AddressAutofillTest : TestSetup() {
navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings,
isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled,
userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress,
- firstName = FirstAddressAutofillDetails.firstName,
- middleName = FirstAddressAutofillDetails.middleName,
- lastName = FirstAddressAutofillDetails.lastName,
+ name = FirstAddressAutofillDetails.name,
streetAddress = FirstAddressAutofillDetails.streetAddress,
city = FirstAddressAutofillDetails.city,
state = FirstAddressAutofillDetails.state,
@@ -173,9 +163,7 @@ class AddressAutofillTest : TestSetup() {
navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings,
isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled,
userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress,
- firstName = FirstAddressAutofillDetails.firstName,
- middleName = FirstAddressAutofillDetails.middleName,
- lastName = FirstAddressAutofillDetails.lastName,
+ name = FirstAddressAutofillDetails.name,
streetAddress = FirstAddressAutofillDetails.streetAddress,
city = FirstAddressAutofillDetails.city,
state = FirstAddressAutofillDetails.state,
@@ -219,9 +207,7 @@ class AddressAutofillTest : TestSetup() {
navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings,
isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled,
userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress,
- firstName = FirstAddressAutofillDetails.firstName,
- middleName = FirstAddressAutofillDetails.middleName,
- lastName = FirstAddressAutofillDetails.lastName,
+ name = FirstAddressAutofillDetails.name,
streetAddress = FirstAddressAutofillDetails.streetAddress,
city = FirstAddressAutofillDetails.city,
state = FirstAddressAutofillDetails.state,
@@ -256,9 +242,7 @@ class AddressAutofillTest : TestSetup() {
navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings,
isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled,
userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress,
- firstName = FirstAddressAutofillDetails.firstName,
- middleName = FirstAddressAutofillDetails.middleName,
- lastName = FirstAddressAutofillDetails.lastName,
+ name = FirstAddressAutofillDetails.name,
streetAddress = FirstAddressAutofillDetails.streetAddress,
city = FirstAddressAutofillDetails.city,
state = FirstAddressAutofillDetails.state,
@@ -271,9 +255,7 @@ class AddressAutofillTest : TestSetup() {
clickAddAddressButton()
fillAndSaveAddress(
navigateToAutofillSettings = SecondAddressAutofillDetails.navigateToAutofillSettings,
- firstName = SecondAddressAutofillDetails.firstName,
- middleName = SecondAddressAutofillDetails.middleName,
- lastName = SecondAddressAutofillDetails.lastName,
+ name = SecondAddressAutofillDetails.name,
streetAddress = SecondAddressAutofillDetails.streetAddress,
city = SecondAddressAutofillDetails.city,
state = SecondAddressAutofillDetails.state,
@@ -319,9 +301,7 @@ class AddressAutofillTest : TestSetup() {
navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings,
isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled,
userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress,
- firstName = FirstAddressAutofillDetails.firstName,
- middleName = FirstAddressAutofillDetails.middleName,
- lastName = FirstAddressAutofillDetails.lastName,
+ name = FirstAddressAutofillDetails.name,
streetAddress = FirstAddressAutofillDetails.streetAddress,
city = FirstAddressAutofillDetails.city,
state = FirstAddressAutofillDetails.state,
@@ -334,9 +314,7 @@ class AddressAutofillTest : TestSetup() {
clickSavedAddress("Mozilla")
fillAndSaveAddress(
navigateToAutofillSettings = SecondAddressAutofillDetails.navigateToAutofillSettings,
- firstName = SecondAddressAutofillDetails.firstName,
- middleName = SecondAddressAutofillDetails.middleName,
- lastName = SecondAddressAutofillDetails.lastName,
+ name = SecondAddressAutofillDetails.name,
streetAddress = SecondAddressAutofillDetails.streetAddress,
city = SecondAddressAutofillDetails.city,
state = SecondAddressAutofillDetails.state,
@@ -377,9 +355,7 @@ class AddressAutofillTest : TestSetup() {
navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings,
isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled,
userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress,
- firstName = FirstAddressAutofillDetails.firstName,
- middleName = FirstAddressAutofillDetails.middleName,
- lastName = FirstAddressAutofillDetails.lastName,
+ name = FirstAddressAutofillDetails.name,
streetAddress = FirstAddressAutofillDetails.streetAddress,
city = FirstAddressAutofillDetails.city,
state = FirstAddressAutofillDetails.state,
@@ -416,9 +392,7 @@ class AddressAutofillTest : TestSetup() {
navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings,
isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled,
userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress,
- firstName = FirstAddressAutofillDetails.firstName,
- middleName = FirstAddressAutofillDetails.middleName,
- lastName = FirstAddressAutofillDetails.lastName,
+ name = FirstAddressAutofillDetails.name,
streetAddress = FirstAddressAutofillDetails.streetAddress,
city = FirstAddressAutofillDetails.city,
state = FirstAddressAutofillDetails.state,
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt
index c9af2fdc6dff..d73d99f95e17 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt
@@ -153,12 +153,10 @@ class SettingsSubMenuAutofillRobot {
addAddressToolbarTitle(),
navigateBackButton(),
toolbarCheckmarkButton(),
- firstNameTextInput(),
- middleNameTextInput(),
+ nameTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_street_address))
assertUIObjectExists(
- lastNameTextInput(),
streetAddressTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_country))
@@ -215,12 +213,10 @@ class SettingsSubMenuAutofillRobot {
navigateBackButton(),
toolbarDeleteAddressButton(),
toolbarCheckmarkButton(),
- firstNameTextInput(),
- middleNameTextInput(),
+ nameTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_street_address))
assertUIObjectExists(
- lastNameTextInput(),
streetAddressTextInput(),
)
scrollToElementByText(getStringResource(R.string.addresses_country))
@@ -257,10 +253,10 @@ class SettingsSubMenuAutofillRobot {
manageAddressesButton().click()
Log.i(TAG, "clickManageAddressesButton: Clicked the \"Manage addresses\" button")
}
- fun clickSavedAddress(firstName: String) {
- Log.i(TAG, "clickSavedAddress: Trying to click the $firstName saved address and and wait for $waitingTime ms for a new window")
- savedAddress(firstName).clickAndWaitForNewWindow(waitingTime)
- Log.i(TAG, "clickSavedAddress: Clicked the $firstName saved address and and waited for $waitingTime ms for a new window")
+ fun clickSavedAddress(name: String) {
+ Log.i(TAG, "clickSavedAddress: Trying to click the $name saved address and and wait for $waitingTime ms for a new window")
+ savedAddress(name).clickAndWaitForNewWindow(waitingTime)
+ Log.i(TAG, "clickSavedAddress: Clicked the $name saved address and and waited for $waitingTime ms for a new window")
}
fun clickDeleteAddressButton() {
Log.i(TAG, "clickDeleteAddressButton: Waiting for $waitingTime ms for the delete address toolbar button to exist")
@@ -307,9 +303,7 @@ class SettingsSubMenuAutofillRobot {
navigateToAutofillSettings: Boolean,
isAddressAutofillEnabled: Boolean = true,
userHasSavedAddress: Boolean = false,
- firstName: String,
- middleName: String,
- lastName: String,
+ name: String,
streetAddress: String,
city: String,
state: String,
@@ -327,21 +321,15 @@ class SettingsSubMenuAutofillRobot {
clickAddAddressButton()
}
}
- Log.i(TAG, "fillAndSaveAddress: Waiting for $waitingTime ms for \"First Name\" text field to exist")
- firstNameTextInput().waitForExists(waitingTime)
- Log.i(TAG, "fillAndSaveAddress: Waited for $waitingTime ms for \"First Name\" text field to exist")
+ Log.i(TAG, "fillAndSaveAddress: Waiting for $waitingTime ms for \"Name\" text field to exist")
+ nameTextInput().waitForExists(waitingTime)
+ Log.i(TAG, "fillAndSaveAddress: Waited for $waitingTime ms for \"Name\" text field to exist")
Log.i(TAG, "fillAndSaveAddress: Trying to click device back button to dismiss keyboard using device back button")
mDevice.pressBack()
Log.i(TAG, "fillAndSaveAddress: Clicked device back button to dismiss keyboard using device back button")
- Log.i(TAG, "fillAndSaveAddress: Trying to set \"First Name\" to $firstName")
- firstNameTextInput().setText(firstName)
- Log.i(TAG, "fillAndSaveAddress: \"First Name\" was set to $firstName")
- Log.i(TAG, "fillAndSaveAddress: Trying to set \"Middle Name\" to $middleName")
- middleNameTextInput().setText(middleName)
- Log.i(TAG, "fillAndSaveAddress: \"Middle Name\" was set to $middleName")
- Log.i(TAG, "fillAndSaveAddress: Trying to set \"Last Name\" to $lastName")
- lastNameTextInput().setText(lastName)
- Log.i(TAG, "fillAndSaveAddress: \"Last Name\" was set to $lastName")
+ Log.i(TAG, "fillAndSaveAddress: Trying to set \"Name\" to $name")
+ nameTextInput().setText(name)
+ Log.i(TAG, "fillAndSaveAddress: \"Name\" was set to $name")
Log.i(TAG, "fillAndSaveAddress: Trying to set \"Street Address\" to $streetAddress")
streetAddressTextInput().setText(streetAddress)
Log.i(TAG, "fillAndSaveAddress: \"Street Address\" was set to $streetAddress")
@@ -616,13 +604,12 @@ private fun manageAddressesButton() =
.resourceId("android:id/title")
.text(getStringResource(R.string.preferences_addresses_manage_addresses)),
)
+
private fun addAddressToolbarTitle() = itemContainingText(getStringResource(R.string.addresses_add_address))
private fun editAddressToolbarTitle() = itemContainingText(getStringResource(R.string.addresses_edit_address))
private fun toolbarCheckmarkButton() = itemWithResId("$packageName:id/save_address_button")
private fun navigateBackButton() = itemWithDescription(getStringResource(R.string.action_bar_up_description))
-private fun firstNameTextInput() = itemWithResId("$packageName:id/first_name_input")
-private fun middleNameTextInput() = itemWithResId("$packageName:id/middle_name_input")
-private fun lastNameTextInput() = itemWithResId("$packageName:id/last_name_input")
+private fun nameTextInput() = itemWithResId("$packageName:id/name_input")
private fun streetAddressTextInput() = itemWithResId("$packageName:id/street_address_input")
private fun cityTextInput() = itemWithResId("$packageName:id/city_input")
private fun subRegionDropDown() = itemWithResId("$packageName:id/subregion_drop_down")
@@ -657,7 +644,7 @@ private fun confirmDeleteCreditCardButton() = onView(withId(android.R.id.button1
private fun cancelDeleteCreditCardButton() = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog())
private fun securedCreditCardsLaterButton() = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog())
-private fun savedAddress(firstName: String) = mDevice.findObject(UiSelector().textContains(firstName))
+private fun savedAddress(name: String) = mDevice.findObject(UiSelector().textContains(name))
private fun subRegionOption(subRegion: String) = mDevice.findObject(UiSelector().textContains(subRegion))
private fun countryOption(country: String) = mDevice.findObject(UiSelector().textContains(country))
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/settings/address/ext/Address.kt b/fenix/app/src/main/java/org/mozilla/fenix/settings/address/ext/Address.kt
index 49cf591e8ef8..95a2fa638a5b 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/settings/address/ext/Address.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/settings/address/ext/Address.kt
@@ -7,15 +7,6 @@ package org.mozilla.fenix.settings.address.ext
import androidx.annotation.VisibleForTesting
import mozilla.components.concept.storage.Address
-/**
- * Generate a label item text for an [Address]. The combination of names is based on desktop code
- * found here:
- * https://searchfox.org/mozilla-central/rev/d989c65584ded72c2de85cb40bede7ac2f176387/toolkit/components/formautofill/FormAutofillNameUtils.jsm#400
- */
-fun Address.getFullName(): String = listOf(givenName, additionalName, familyName)
- .filter { it.isNotEmpty() }
- .joinToString(" ")
-
/**
* Generate a description item text for an [Address]. The element ordering is based on the
* priorities defined by the desktop code found here:
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/settings/address/view/AddressEditorView.kt b/fenix/app/src/main/java/org/mozilla/fenix/settings/address/view/AddressEditorView.kt
index 18858e0cebed..e57ad0d87319 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/settings/address/view/AddressEditorView.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/settings/address/view/AddressEditorView.kt
@@ -47,7 +47,7 @@ class AddressEditorView(
* Binds the view in the [AddressEditorFragment], using the current [Address] if available.
*/
fun bind() {
- binding.firstNameInput.apply {
+ binding.nameInput.apply {
requestFocus()
placeCursorAtEnd()
showKeyboard()
@@ -64,11 +64,7 @@ class AddressEditorView(
address?.let { address ->
binding.emailInput.setText(address.email)
binding.phoneInput.setText(address.tel)
-
- binding.firstNameInput.setText(address.givenName)
- binding.middleNameInput.setText(address.additionalName)
- binding.lastNameInput.setText(address.familyName)
-
+ binding.nameInput.setText(address.name)
binding.streetAddressInput.setText(address.streetAddress)
binding.cityInput.setText(address.addressLevel2)
binding.zipInput.setText(address.postalCode)
@@ -88,9 +84,7 @@ class AddressEditorView(
binding.root.hideKeyboard()
val addressFields = UpdatableAddressFields(
- givenName = binding.firstNameInput.text.toString(),
- additionalName = binding.middleNameInput.text.toString(),
- familyName = binding.lastNameInput.text.toString(),
+ name = binding.nameInput.text.toString(),
organization = "",
streetAddress = binding.streetAddressInput.text.toString(),
addressLevel3 = "",
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/settings/address/view/AddressList.kt b/fenix/app/src/main/java/org/mozilla/fenix/settings/address/view/AddressList.kt
index a24d8d8376d0..c00010605f1f 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/settings/address/view/AddressList.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/settings/address/view/AddressList.kt
@@ -20,7 +20,6 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.compose.list.IconListItem
import org.mozilla.fenix.compose.list.TextListItem
import org.mozilla.fenix.settings.address.ext.getAddressLabel
-import org.mozilla.fenix.settings.address.ext.getFullName
import org.mozilla.fenix.theme.FirefoxTheme
/**
@@ -39,7 +38,7 @@ fun AddressList(
LazyColumn {
items(addresses) { address ->
TextListItem(
- label = address.getFullName(),
+ label = address.name,
modifier = Modifier.padding(start = 56.dp),
description = address.getAddressLabel(),
maxDescriptionLines = 2,
@@ -66,9 +65,7 @@ private fun AddressListPreview() {
addresses = listOf(
Address(
guid = "1",
- givenName = "Banana",
- additionalName = "",
- familyName = "Apple",
+ name = "Banana Apple",
organization = "Mozilla",
streetAddress = "123 Sesame Street",
addressLevel3 = "",
diff --git a/fenix/app/src/main/res/layout/fragment_address_editor.xml b/fenix/app/src/main/res/layout/fragment_address_editor.xml
index 82d559b65c42..4f6e4e14d714 100644
--- a/fenix/app/src/main/res/layout/fragment_address_editor.xml
+++ b/fenix/app/src/main/res/layout/fragment_address_editor.xml
@@ -14,24 +14,24 @@
android:layout_height="wrap_content"
android:layout_margin="16dp">
-
+
+ app:layout_constraintTop_toBottomOf="@+id/name_title">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ app:layout_constraintTop_toBottomOf="@+id/name_layout" />
Manage addresses
- First Name
+ First Name
- Middle Name
+ Middle Name
- Last Name
+ Last Name
+
+ NameStreet Address
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/settings/address/AddressEditorViewTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/settings/address/AddressEditorViewTest.kt
index 550cc1c65f2a..1705d773b737 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/settings/address/AddressEditorViewTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/settings/address/AddressEditorViewTest.kt
@@ -68,9 +68,7 @@ class AddressEditorViewTest {
addressEditorView.saveAddress()
val expected = UpdatableAddressFields(
- givenName = address.givenName,
- additionalName = address.additionalName,
- familyName = address.familyName,
+ name = address.name,
organization = "",
streetAddress = address.streetAddress,
addressLevel3 = "",
@@ -95,9 +93,7 @@ class AddressEditorViewTest {
addressEditorView.saveAddress()
val expected = UpdatableAddressFields(
- givenName = "",
- additionalName = "",
- familyName = "",
+ name = "",
organization = "",
streetAddress = "",
addressLevel3 = "",
@@ -137,9 +133,7 @@ class AddressEditorViewTest {
assertEquals(address.addressLevel1, binding.subregionDropDown.selectedItem.toString())
assertEquals("City", binding.cityInput.text.toString())
assertEquals("Street", binding.streetAddressInput.text.toString())
- assertEquals("Family", binding.lastNameInput.text.toString())
- assertEquals("Given", binding.firstNameInput.text.toString())
- assertEquals("Additional", binding.middleNameInput.text.toString())
+ assertEquals("Name", binding.nameInput.text.toString())
assertEquals("email@mozilla.com", binding.emailInput.text.toString())
assertEquals("Telephone", binding.phoneInput.text.toString())
}
@@ -334,9 +328,7 @@ class AddressEditorViewTest {
private fun generateAddress(country: String = "US", addressLevel1: String = "Oregon") = Address(
guid = "123",
- givenName = "Given",
- additionalName = "Additional",
- familyName = "Family",
+ name = "Name",
organization = "Organization",
streetAddress = "Street",
addressLevel3 = "Suburb",
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/settings/address/controller/DefaultAddressEditorControllerTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/settings/address/controller/DefaultAddressEditorControllerTest.kt
index 3046b3a399a8..887dfad34f78 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/settings/address/controller/DefaultAddressEditorControllerTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/settings/address/controller/DefaultAddressEditorControllerTest.kt
@@ -53,9 +53,7 @@ class DefaultAddressEditorControllerTest {
@Test
fun `GIVEN a new address record WHEN save address is called THEN save the new address record to storage`() = runTestOnMain {
val addressFields = UpdatableAddressFields(
- givenName = "John",
- additionalName = "",
- familyName = "Smith",
+ name = "John Smith",
organization = "Mozilla",
streetAddress = "123 Sesame Street",
addressLevel3 = "",
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/settings/address/ext/AddressTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/settings/address/ext/AddressTest.kt
index 3672386431b0..a41d0c707da8 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/settings/address/ext/AddressTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/settings/address/ext/AddressTest.kt
@@ -9,41 +9,6 @@ import org.junit.Assert.assertEquals
import org.junit.Test
class AddressTest {
- @Test
- fun `WHEN all names are populated THEN label includes all names`() {
- val addr = generateAddress()
-
- val label = addr.getFullName()
-
- assertEquals("${addr.givenName} ${addr.additionalName} ${addr.familyName}", label)
- }
-
- @Test
- fun `WHEN middle name is missing THEN label is given and family combined`() {
- val addr = generateAddress(additionalName = "")
-
- val label = addr.getFullName()
-
- assertEquals("${addr.givenName} ${addr.familyName}", label)
- }
-
- @Test
- fun `WHEN only family and middle name are available THEN label is middle and family combined`() {
- val addr = generateAddress(givenName = "")
-
- val label = addr.getFullName()
-
- assertEquals("${addr.additionalName} ${addr.familyName}", label)
- }
-
- @Test
- fun `WHEN only family name is available THEN label is family name`() {
- val addr = generateAddress(givenName = "", additionalName = "")
-
- val label = addr.getFullName()
-
- assertEquals(addr.familyName, label)
- }
@Test
fun `WHEN all properties are present THEN all properties present in description`() {
@@ -76,9 +41,7 @@ class AddressTest {
@Test
fun `WHEN everything is missing THEN description is empty`() {
val addr = generateAddress(
- givenName = "",
- additionalName = "",
- familyName = "",
+ name = "",
organization = "",
streetAddress = "",
addressLevel3 = "",
@@ -109,9 +72,7 @@ class AddressTest {
}
private fun generateAddress(
- givenName: String = "Firefox",
- additionalName: String = "The",
- familyName: String = "Browser",
+ name: String = "Firefox The Browser",
organization: String = "Mozilla",
streetAddress: String = "street",
addressLevel3: String = "3",
@@ -123,9 +84,7 @@ class AddressTest {
email: String = "email",
) = Address(
guid = "",
- givenName = givenName,
- additionalName = additionalName,
- familyName = familyName,
+ name = name,
organization = organization,
streetAddress = streetAddress,
addressLevel3 = addressLevel3,
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/settings/address/interactor/DefaultAddressEditorInteractorTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/settings/address/interactor/DefaultAddressEditorInteractorTest.kt
index ff5ba12397f8..515d97d3ce7c 100644
--- a/fenix/app/src/test/java/org/mozilla/fenix/settings/address/interactor/DefaultAddressEditorInteractorTest.kt
+++ b/fenix/app/src/test/java/org/mozilla/fenix/settings/address/interactor/DefaultAddressEditorInteractorTest.kt
@@ -31,9 +31,7 @@ class DefaultAddressEditorInteractorTest {
@Test
fun `WHEN save button is clicked THEN forward to controller handler`() {
val addressFields = UpdatableAddressFields(
- givenName = "John",
- additionalName = "",
- familyName = "Smith",
+ name = "John Smith",
organization = "Mozilla",
streetAddress = "123 Sesame Street",
addressLevel3 = "",
From f19d8304843ba605bca9f62032198908ce280e8e Mon Sep 17 00:00:00 2001
From: Jackie Johnson <107960801+jjSDET@users.noreply.github.com>
Date: Mon, 26 Feb 2024 15:12:25 -0600
Subject: [PATCH 334/586] Bug 1882170 - Disable Auto-Fill View Tests After
Address Fields Were Consolidated
---
.../java/org/mozilla/fenix/ui/AddressAutofillTest.kt | 3 +++
1 file changed, 3 insertions(+)
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 61a3c0b7fc4f..7cfcdafd6fc8 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,6 +4,7 @@
package org.mozilla.fenix.ui
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
@@ -116,6 +117,7 @@ class AddressAutofillTest : TestSetup() {
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836840
+ @Ignore("Disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1882170")
@Test
fun verifyAddAddressViewTest() {
homeScreen {
@@ -130,6 +132,7 @@ class AddressAutofillTest : TestSetup() {
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836841
+ @Ignore("Disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1882170")
@Test
fun verifyEditAddressViewTest() {
autofillScreen {
From 7ad1697e4676a1da5325dae3cd87c437329c7d32 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Tue, 27 Feb 2024 00:03:55 +0000
Subject: [PATCH 335/586] Import translations from android-l10n
---
.../src/main/res/values-nb-rNO/strings.xml | 2 +
.../addons/src/main/res/values-es/strings.xml | 2 +
.../addons/src/main/res/values-fr/strings.xml | 2 +
.../src/main/res/values-nb-rNO/strings.xml | 20 +-
fenix/app/src/main/res/values-es/strings.xml | 13 ++
.../src/main/res/values-nb-rNO/strings.xml | 203 +++++++++++++++++-
.../src/main/res/values-es-rAR/strings.xml | 2 +-
.../src/main/res/values-es-rCL/strings.xml | 6 +-
.../app/src/main/res/values-fur/strings.xml | 6 +-
.../src/main/res/values-nb-rNO/strings.xml | 6 +-
.../app/src/main/res/values-sl/strings.xml | 6 +-
11 files changed, 257 insertions(+), 11 deletions(-)
diff --git a/android-components/components/browser/menu/src/main/res/values-nb-rNO/strings.xml b/android-components/components/browser/menu/src/main/res/values-nb-rNO/strings.xml
index e5e23a0bb22e..4700543a00f8 100644
--- a/android-components/components/browser/menu/src/main/res/values-nb-rNO/strings.xml
+++ b/android-components/components/browser/menu/src/main/res/values-nb-rNO/strings.xml
@@ -10,4 +10,6 @@
TilleggsbehandlerNaviger opp
+
+ Tillegg, naviger opp
diff --git a/android-components/components/feature/addons/src/main/res/values-es/strings.xml b/android-components/components/feature/addons/src/main/res/values-es/strings.xml
index 75611b757341..401ec4fbe942 100644
--- a/android-components/components/feature/addons/src/main/res/values-es/strings.xml
+++ b/android-components/components/feature/addons/src/main/res/values-es/strings.xml
@@ -98,6 +98,8 @@
Permitir en navegación privadaEjecutar en navegación privada
+
+ No permitido en ventanas privadasActivado
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 b06ef39e07ac..8d07e369a231 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
@@ -98,6 +98,8 @@
Autoriser en navigation privéeExécuter en navigation privée
+
+ Non autorisé dans les fenêtres de navigation privéeActivé
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 50cd987ac8e7..8ebbfd30557a 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
@@ -98,6 +98,8 @@
Tillat i privat nettlesingKjør i privat nettlesing
+
+ Ikke tillatt i private vinduerPåslått
@@ -137,13 +139,17 @@
Avbryt
- Installer utvidelse
+ Installer utvidelse
+
+ Installer %1$sAvbrytOmtaler: %1$s
- %1$.02f/5
+ %1$.02f/5
+
+ Rangering: %1$.02f av 5Utvidelser
@@ -244,10 +250,14 @@
Status:%1$s er lagt til i %2$s
-
- Åpne det i menyen
+
+ Åpne det i menyen
+
+ Få tilgang til %1$s fra %2$s-menyen.
+
+ Ok, jeg forstår
- Ok, jeg forstår
+ OKLes mer
diff --git a/fenix/app/src/main/res/values-es/strings.xml b/fenix/app/src/main/res/values-es/strings.xml
index 5f00a5e888b5..e9888675a7ed 100644
--- a/fenix/app/src/main/res/values-es/strings.xml
+++ b/fenix/app/src/main/res/values-es/strings.xml
@@ -2106,8 +2106,12 @@
Introduce una contraseñaSe requiere nombre de usuario
+
+ Introduce un nombre de usuarioSe requiere nombre de servidor
+
+ Introduce una dirección webBúsqueda por voz
@@ -2203,6 +2207,9 @@
Buscar con %s
+
+
+ Cambia tu navegador predeterminadoConfigura enlaces de sitios web, correos electrónicos y mensajes para que se abran automáticamente en Firefox.
@@ -2460,6 +2467,8 @@
Traducción en curso
+
+ Selecciona un idiomaHa surgido un problema al traducir. Por favor inténtalo de nuevo.
@@ -2480,6 +2489,10 @@
No traducir nunca %1$sNo traducir nunca este sitio
+
+ Anula todas las demás configuraciones
+
+ Anula las ofertas de traducciónAjustes de traducción
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 aef3dd0fc897..bd4b73655315 100644
--- a/fenix/app/src/main/res/values-nb-rNO/strings.xml
+++ b/fenix/app/src/main/res/values-nb-rNO/strings.xml
@@ -1769,6 +1769,8 @@
Sikre dine lagrede passordKonfigurer 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.
+
+ Konfigurer en PIN-kode, et passord eller et låsemønster for å beskytte dine lagrede passord om noen andre skulle få tak i enheten din.Senere
@@ -1790,6 +1792,9 @@
Sorter innlogginger-meny
+
+ Sorter passord-menyen
+
Autofyll
@@ -1797,10 +1802,16 @@
AdresserBetalingskort
+
+ BetalingsmåterLagre og fyll ut kort automatisk
+
+ Lagre og fyll inn betalingsmåterData er kryptert
+
+ %s krypterer alle betalingsmåter du lagrerSynkroniser kort på tvers av enheter
@@ -1808,17 +1819,26 @@
Legg til betalingskort
+
+ Legg til kortBehandle lagrede kort
+
+ Behandle kortLegg til adresseBehandle adresserLagre og autoutfyll adresser
+
+ Lagre og fyll ut adresserInkluderer informasjon som telefonnummer, e-post og leveringsadresser
+
+ Inkluderer telefonnumre og e-postadresser
+
Legg til kort
@@ -1839,6 +1859,8 @@
Slett kortEr du sikker på at du vil slette dette bankkortet?
+
+ Slett kort?Slett
@@ -1853,14 +1875,22 @@
Oppgi et gyldig betalingskortnummer
+
+ Skriv inn et gyldig kortnummerFyll ut dette feltet
+
+ Legg til et navnLås opp for å se dine lagrede betalingskortSikre dine betalingskort
+
+ Sikre dine lagrede betalingsmåterKonfigurer en PIN-kode, et passord eller et låsemønster for å beskytte de lagrede betalingskortene dine om noen andre skulle få tak i enheten din.
+
+ Konfigurer en PIN-kode, et passord eller et låsemønster for å beskytte dine lagrede betalingsmåter om noen andre skulle få tak i enheten din.Konfigurer nå
@@ -1871,6 +1901,8 @@
Lås opp for å bruke lagret betalingskortinformasjon
+
+ Lås opp for å bruke lagrede betalingsmåterLegg til adresse
@@ -1908,6 +1940,8 @@
Er du sikker på at du vil slette denne adressen?
+
+ Slette denne adressen?Slett
@@ -2008,30 +2042,52 @@
RedigerEr du sikker på at du ønsker å slette denne innloggingen?
+
+ Er du sikker på at du ønsker å slette dette passordet?SlettAvbrytInnloggingsalternativer
+
+ PassordalternativerDet redigerbare tekstfeltet for innloggingens nettadresse.
+
+ Det redigerbare tekstfeltet for nettstedsadressen.Det redigerbare tekstfeltet for innloggingens brukernavn.
+
+ Det redigerbare tekstfeltet for brukernavnet.Det redigerbare tekstfeltet for innloggingens passord.
+
+ Det redigerbare tekstfeltet for passordet.Lagre endringer for innlogging.
+
+ Lagre endringer.Rediger
+
+ Rediger passordLegg til ny innlogging
+
+ Legg til passordPassord kreves
+
+ Skriv inn et passordBrukernavn påkrevd
+
+ Skriv inn et brukernavnServernavn påkrevd
+
+ Skriv inn en nettadresseStemmesøk
@@ -2126,6 +2182,9 @@
%s-søk
+
+
+ Endre standard nettleserAngi at lenker fra nettsteder, e-postmeldinger og meldinger skal åpnes automatisk i Firefox.
@@ -2352,8 +2411,86 @@
%s, Overskrift
+
+ Lenker
+
+ Lenker tilgjengelig
+
+
+
+ Oversett denne siden?
+
+ Prøv private oversettelser i %1$s
+
+ Av hensyn til personvernet ditt forlater aldri oversettelser enheten din. Nye språk og forbedringer kommer snart! %1$s
+
+ Les mer
+
+ Oversett fra
+
+ Oversett til
+
+ Ikke nå
+
+ Ferdig
+
+ Oversett
+
+ Prøv igjen
+
+ Oversetter
+
+ Oversettelse pågår
+
+ Velg et språk
+
+ Det oppstod et problem med å oversette. Prøv på nytt.
+
+ Kunne ikke laste inn språk. Sjekk Internett-tilkoblingen din og prøv igjen.
+
+ Beklager, vi støtter ikke %1$s ennå.
+
+ Les mer
+
+
+
+ Oversettelsesinnstillinger
+
+ Tilby alltid å oversette
+
+ Oversett alltid %1$s
+
+ Oversett aldri %1$s
+
+ Oversett aldri dette nettstedet
+
+ Overstyrer alle andre innstillinger
+
+ Overstyrer tilbud om å oversette
+
+ Oversettelsesinnstillinger
+
+ Om oversettelser i %1$s
+
+
+
+ Oversettelser
+
+ Tilby å oversette når det er mulig
+
+
+ Last alltid ned språk i datasparingsmodus
+
+ Innstillinger for oversetting
+
+ Automatisk oversettelse
+
+ Oversett aldri disse nettstedene
+
+ Last ned språk
+
Automatisk oversettelse
@@ -2402,6 +2539,10 @@
Tilgjengelige språknødvendig
+
+ %1$s (%2$s)Last ned språk
@@ -2415,4 +2556,64 @@
Valgt
-
+
+ Slette %1$s (%2$s)?
+
+ Hvis du sletter dette språket, vil %1$s laste ned deler av språk til hurtigbufferen din mens du oversetter.
+
+ Slette alle språk (%1$s)?
+
+ Hvis du sletter alle språk, vil %1$s laste ned deler av språk til hurtigbufferen din mens du oversetter.
+
+ Slett
+
+ Avbryt
+
+
+ Laste ned mens du er i datasparingsmodus (%1$s)?
+
+ Vi laster ned delvise språk til hurtigbufferen din for å holde oversettelser private.
+
+ Last alltid ned i datasparingsmodus
+
+ Last ned
+
+ Last ned og oversett
+
+ Avbryt
+
+
+
+ Feilsøkingsverktøy
+
+ Naviger tilbake
+
+ Faneverktøy
+
+ Antall faner
+
+ Aktiv
+
+ Inaktiv
+
+ Privat
+
+ Totalt
+
+ Verktøy for å lage faner
+
+ Antall faner som skal opprettes
+
+ Legg til aktive faner
+
+ Legg til inaktive faner
+
+ Legg til private faner
+
diff --git a/focus-android/app/src/main/res/values-es-rAR/strings.xml b/focus-android/app/src/main/res/values-es-rAR/strings.xml
index 3a483e160b8d..02222fab8c5d 100644
--- a/focus-android/app/src/main/res/values-es-rAR/strings.xml
+++ b/focus-android/app/src/main/res/values-es-rAR/strings.xml
@@ -88,7 +88,7 @@
- Toca o desliza esta notificación para borrar de forma segura tu historial de navegación.
+ Tocá o deslizá esta notificación para eliminar de forma segura tu historial de navegación.Borrar historial de navegación
diff --git a/focus-android/app/src/main/res/values-es-rCL/strings.xml b/focus-android/app/src/main/res/values-es-rCL/strings.xml
index 654da7109e86..69b3b0c4e89f 100644
--- a/focus-android/app/src/main/res/values-es-rCL/strings.xml
+++ b/focus-android/app/src/main/res/values-es-rCL/strings.xml
@@ -84,7 +84,11 @@
Compartir vía¿Eliminar historial de navegación?
- Toca o elimina esta notificación para borrar de forma segura tu historial de navegación.
+ Toca o elimina esta notificación para borrar de forma segura tu historial de navegación.
+
+
+ Toca o desliza esta notificación para borrar de forma segura tu historial de navegación.Eliminar historial de navegación
diff --git a/focus-android/app/src/main/res/values-fur/strings.xml b/focus-android/app/src/main/res/values-fur/strings.xml
index 52363011ddad..6abc77ff228f 100644
--- a/focus-android/app/src/main/res/values-fur/strings.xml
+++ b/focus-android/app/src/main/res/values-fur/strings.xml
@@ -88,7 +88,11 @@
Condivît vieScancelâ la cronologjie di navigazion?
- Tocje o scancele cheste notifiche par eliminâ in mût sigûr la tô cronologjie di navigazion.
+ Tocje o scancele cheste notifiche par eliminâ in mût sigûr la tô cronologjie di navigazion.
+
+
+ Tocje o fâs scori cheste notifiche par eliminâ in mût sigûr la tô cronologjie di navigazion.Scancele la cronologjie di navigazion
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 e5257880a9bd..ad4b98e217e7 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
@@ -84,7 +84,11 @@
Del viaSlett nettleserhistorikk?
- Trykk eller fjern dette varselet for å slette nettleserhistorikken din på en sikker måte.
+ Trykk eller fjern dette varselet for å slette nettleserhistorikken din på en sikker måte.
+
+
+ Trykk eller sveip dette varselet for å slette nettleserhistorikken din på en sikker måte.Slett nettleserhistorikk
diff --git a/focus-android/app/src/main/res/values-sl/strings.xml b/focus-android/app/src/main/res/values-sl/strings.xml
index 05647575d723..6c3f7349e3eb 100644
--- a/focus-android/app/src/main/res/values-sl/strings.xml
+++ b/focus-android/app/src/main/res/values-sl/strings.xml
@@ -84,7 +84,11 @@
Deli prekoIzbrišem zgodovino brskanja?
- Tapnite ali odstranite to obvestilo za varen izbris zgodovine brskanja.
+ Tapnite ali odstranite to obvestilo za varen izbris zgodovine brskanja.
+
+
+ Tapnite to obvestilo ali ga podrsajte vstran za varen izbris zgodovine brskanja.Počisti zgodovino brskanja
From 3c9a7c648de6879837043695f11b445b228b555b Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Mon, 26 Feb 2024 22:21:54 +0000
Subject: [PATCH 336/586] Update GeckoView (Nightly) to 125.0.20240226165659.
---
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 785c58163864..aaaf212789d5 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 = "125.0.20240226091922"
+ const val version = "125.0.20240226165659"
/**
* GeckoView channel
From 95866778c7cfb843f1f3654faa907dcd47980636 Mon Sep 17 00:00:00 2001
From: Roger Yang
Date: Mon, 26 Feb 2024 12:35:48 -0500
Subject: [PATCH 337/586] Bug 1880284 - Show keyboard after voice input
---
.../main/java/org/mozilla/fenix/search/SearchDialogFragment.kt | 3 +++
1 file changed, 3 insertions(+)
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 c41d5ea4c2af..80f0e310af85 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
@@ -69,6 +69,7 @@ import mozilla.components.support.ktx.android.content.res.getSpanned
import mozilla.components.support.ktx.android.net.isHttpOrHttps
import mozilla.components.support.ktx.android.view.findViewInHierarchy
import mozilla.components.support.ktx.android.view.hideKeyboard
+import mozilla.components.support.ktx.android.view.showKeyboard
import mozilla.components.support.ktx.kotlin.toNormalizedUrl
import mozilla.components.ui.autocomplete.InlineAutocompleteEditText
import mozilla.components.ui.widgets.withCenterAlignedButtons
@@ -166,6 +167,8 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
val updatedUrl = toolbarView.view.edit.updateUrl(url = it, shouldHighlight = false, shouldAppend = true)
interactor.onTextChanged(updatedUrl)
toolbarView.view.edit.focus()
+ // When using voice input, show keyboard after for user convenience.
+ toolbarView.view.showKeyboard()
}
}
}
From 218d4dd3a09efa3f63da67c3bb471164974a2772 Mon Sep 17 00:00:00 2001
From: ohall-m
Date: Wed, 21 Feb 2024 14:38:40 -0500
Subject: [PATCH 338/586] Bug 1881294 - Refine `isExpectedTranslate`
This patch fixes an issue where `isExpectedTranslate` is not cleared
between navigations. It adds logic in `TranslationsStateReducer` to
check if the criteria is met and clears the state, if applicable.
---
.../state/reducer/TranslationsStateReducer.kt | 18 ++++++++
.../state/action/TranslationsActionTest.kt | 42 +++++++++++++++++++
2 files changed, 60 insertions(+)
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 8008b2af80be..1d8eeea5a380 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
@@ -37,19 +37,37 @@ internal object TranslationsStateReducer {
}
is TranslationsAction.TranslateStateChangeAction -> {
+ var isExpectedTranslate = state.findTab(action.tabId)?.translationsState?.isExpectedTranslate ?: true
+ // Checking if a translation can be anticipated or not based on
+ // the new translation engine state detected metadata.
+ if (action.translationEngineState.detectedLanguages == null ||
+ action.translationEngineState.detectedLanguages?.supportedDocumentLang == false ||
+ action.translationEngineState.detectedLanguages?.userPreferredLangTag == null
+ ) {
+ // Value can also update through [TranslateExpectedAction]
+ // via the translations engine.
+ isExpectedTranslate = false
+ }
+
+ // Checking for if the translations engine is in the fully translated state or not based
+ // on the values of the translation pair.
if (action.translationEngineState.requestedTranslationPair == null ||
action.translationEngineState.requestedTranslationPair?.fromLanguage == null ||
action.translationEngineState.requestedTranslationPair?.toLanguage == null
) {
+ // In an untranslated state
state.copyWithTranslationsState(action.tabId) {
it.copy(
+ isExpectedTranslate = isExpectedTranslate,
isTranslated = false,
translationEngineState = action.translationEngineState,
)
}
} else {
+ // In a translated state
state.copyWithTranslationsState(action.tabId) {
it.copy(
+ isExpectedTranslate = isExpectedTranslate,
isTranslated = true,
translationError = null,
translationEngineState = action.translationEngineState,
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 06e4fdf15431..9d0a2dfbf253 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
@@ -80,6 +80,7 @@ class TranslationsActionTest {
fun `WHEN a TranslateStateChangeAction is dispatched THEN the translation status updates accordingly`() {
assertNull(tabState().translationsState.translationEngineState)
assertFalse(tabState().translationsState.isTranslated)
+ assertFalse(tabState().translationsState.isExpectedTranslate)
val translatedEngineState = TranslationEngineState(
detectedLanguages = DetectedLanguages(documentLangTag = "es", supportedDocumentLang = true, userPreferredLangTag = "en"),
@@ -94,6 +95,7 @@ class TranslationsActionTest {
// Translated state
assertEquals(translatedEngineState, tabState().translationsState.translationEngineState)
assertTrue(tabState().translationsState.isTranslated)
+ assertFalse(tabState().translationsState.isExpectedTranslate)
val nonTranslatedEngineState = TranslationEngineState(
detectedLanguages = DetectedLanguages(documentLangTag = "es", supportedDocumentLang = true, userPreferredLangTag = "en"),
@@ -108,6 +110,46 @@ class TranslationsActionTest {
// Non-translated state
assertEquals(nonTranslatedEngineState, tabState().translationsState.translationEngineState)
assertFalse(tabState().translationsState.isTranslated)
+ assertFalse(tabState().translationsState.isExpectedTranslate)
+ }
+
+ @Test
+ fun `WHEN a TranslateStateChangeAction is dispatched THEN the isExpectedTranslate status updates accordingly`() {
+ // Initial State
+ assertNull(tabState().translationsState.translationEngineState)
+
+ // Sending an initial request to set state; however, the engine hasn't decided if it is an
+ // expected state
+ var 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()
+ assertFalse(tabState().translationsState.isExpectedTranslate)
+
+ // Engine is sending a translation expected action
+ store.dispatch(TranslationsAction.TranslateExpectedAction(tabId = tab.id))
+ .joinBlocking()
+
+ // Initial expected translation state
+ store.dispatch(TranslationsAction.TranslateStateChangeAction(tabId = tab.id, translationEngineState = translatedEngineState))
+ .joinBlocking()
+ assertTrue(tabState().translationsState.isExpectedTranslate)
+
+ // Not expected translation state, because it is no longer supported
+ translatedEngineState = TranslationEngineState(
+ detectedLanguages = DetectedLanguages(documentLangTag = "es", supportedDocumentLang = false, userPreferredLangTag = "en"),
+ error = null,
+ isEngineReady = true,
+ requestedTranslationPair = TranslationPair(fromLanguage = "es", toLanguage = "en"),
+ )
+
+ store.dispatch(TranslationsAction.TranslateStateChangeAction(tabId = tab.id, translationEngineState = translatedEngineState))
+ .joinBlocking()
+ assertFalse(tabState().translationsState.isExpectedTranslate)
}
@Test
From 47ba092b6307b8eb7e37cb070298196587478384 Mon Sep 17 00:00:00 2001
From: Ben Dean-Kawamura
Date: Mon, 26 Feb 2024 11:34:22 -0500
Subject: [PATCH 339/586] Bug 1882136 - Fxa state machine checker fix
This should prevent some Sentry errors from the state machine checker
code.
---
.../manager/AppServicesStateMachineChecker.kt | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
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
index e9042c099dfd..3cb58737b4e0 100644
--- 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
@@ -57,7 +57,22 @@ object AppServicesStateMachineChecker {
val pairingUrl = event.pairingUrl ?: ""
FxaEvent.BeginPairingFlow(pairingUrl, ArrayList(scopes), event.entrypoint.entryName)
}
- is Event.Account.AuthenticationError -> FxaEvent.CheckAuthorizationStatus
+ is Event.Account.AuthenticationError -> {
+ // There are basically 2 ways for this to happen:
+ //
+ // - Another component called `FxaAccountManager.encounteredAuthError()`. In this
+ // case, we should initiate the state transition by sending the state machine the
+ // `FxaEvent.CheckAuthorizationStatus`
+ // - `FxaAccountManager` sent it to itself, because there was an error when
+ // `internalStateSideEffects` called `finalizeDevice()`. In this case, we're
+ // already in the middle of a state transition and already sent the state machine
+ // the `EnsureCapabilitiesAuthError` event, so we should ignore it.
+ if (event.operation == "finalizeDevice") {
+ return
+ } else {
+ 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
From 5cbd4101e00cc6596691debed0b0153169af8539 Mon Sep 17 00:00:00 2001
From: rahulsainani
Date: Fri, 19 Jan 2024 14:01:37 +0100
Subject: [PATCH 340/586] Bug 1875465 - Part 1: Set toolbar position if tablet
---
.../fenix/browser/BaseBrowserFragment.kt | 18 +++++++++---------
.../org/mozilla/fenix/browser/TabPreview.kt | 5 +++--
.../java/org/mozilla/fenix/utils/Settings.kt | 11 ++++++++++-
3 files changed, 22 insertions(+), 12 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 ae27629bb8bd..9ba7df57d1ae 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
@@ -134,6 +134,7 @@ import org.mozilla.fenix.components.toolbar.BrowserToolbarView
import org.mozilla.fenix.components.toolbar.DefaultBrowserToolbarController
import org.mozilla.fenix.components.toolbar.DefaultBrowserToolbarMenuController
import org.mozilla.fenix.components.toolbar.ToolbarIntegration
+import org.mozilla.fenix.components.toolbar.ToolbarPosition
import org.mozilla.fenix.components.toolbar.interactor.BrowserToolbarInteractor
import org.mozilla.fenix.components.toolbar.interactor.DefaultBrowserToolbarInteractor
import org.mozilla.fenix.crashes.CrashContentIntegration
@@ -463,7 +464,7 @@ abstract class BaseBrowserFragment :
toolbarInfo = FindInPageIntegration.ToolbarInfo(
browserToolbarView.view,
!context.settings().shouldUseFixedTopToolbar && context.settings().isDynamicToolbarEnabled,
- !context.settings().shouldUseBottomToolbar,
+ context.settings().toolbarPosition == ToolbarPosition.TOP,
),
),
owner = this,
@@ -820,7 +821,7 @@ abstract class BaseBrowserFragment :
browserStore = requireComponents.core.store,
appStore = requireComponents.appStore,
toolbar = browserToolbarView.view,
- isToolbarPlacedAtTop = !context.settings().shouldUseBottomToolbar,
+ isToolbarPlacedAtTop = context.settings().toolbarPosition == ToolbarPosition.TOP,
crashReporterView = binding.crashReporterView,
components = requireComponents,
settings = context.settings(),
@@ -1155,10 +1156,9 @@ abstract class BaseBrowserFragment :
if (!context.settings().shouldUseFixedTopToolbar && context.settings().isDynamicToolbarEnabled) {
getEngineView().setDynamicToolbarMaxHeight(toolbarHeight)
- val toolbarPosition = if (context.settings().shouldUseBottomToolbar) {
- MozacToolbarPosition.BOTTOM
- } else {
- MozacToolbarPosition.TOP
+ val toolbarPosition = when (context.settings().toolbarPosition) {
+ ToolbarPosition.BOTTOM -> MozacToolbarPosition.BOTTOM
+ ToolbarPosition.TOP -> MozacToolbarPosition.TOP
}
(getSwipeRefreshLayout().layoutParams as CoordinatorLayout.LayoutParams).behavior =
EngineViewClippingBehavior(
@@ -1175,10 +1175,10 @@ abstract class BaseBrowserFragment :
// Effectively place the engineView on top/below of the toolbar if that is not dynamic.
val swipeRefreshParams =
getSwipeRefreshLayout().layoutParams as CoordinatorLayout.LayoutParams
- if (context.settings().shouldUseBottomToolbar) {
- swipeRefreshParams.bottomMargin = toolbarHeight
- } else {
+ if (context.settings().toolbarPosition == ToolbarPosition.TOP) {
swipeRefreshParams.topMargin = toolbarHeight
+ } else {
+ swipeRefreshParams.bottomMargin = toolbarHeight
}
}
}
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/browser/TabPreview.kt b/fenix/app/src/main/java/org/mozilla/fenix/browser/TabPreview.kt
index facb796e5e74..d04089dd6fdf 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/browser/TabPreview.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/browser/TabPreview.kt
@@ -18,6 +18,7 @@ import mozilla.components.browser.state.selector.selectedTab
import mozilla.components.browser.thumbnails.loader.ThumbnailLoader
import mozilla.components.concept.base.images.ImageLoadRequest
import org.mozilla.fenix.R
+import org.mozilla.fenix.components.toolbar.ToolbarPosition
import org.mozilla.fenix.databinding.TabPreviewBinding
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
@@ -34,7 +35,7 @@ class TabPreview @JvmOverloads constructor(
private val thumbnailLoader = ThumbnailLoader(context.components.core.thumbnailStorage)
init {
- if (!context.settings().shouldUseBottomToolbar) {
+ if (context.settings().toolbarPosition == ToolbarPosition.TOP) {
binding.fakeToolbar.updateLayoutParams {
gravity = Gravity.TOP
}
@@ -59,7 +60,7 @@ class TabPreview @JvmOverloads constructor(
binding.tabButton.setCount(count)
}
- binding.previewThumbnail.translationY = if (!context.settings().shouldUseBottomToolbar) {
+ binding.previewThumbnail.translationY = if (context.settings().toolbarPosition == ToolbarPosition.TOP) {
binding.fakeToolbar.height.toFloat()
} else {
0f
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 1808eb3a30d6..957741fabe3e 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
@@ -854,6 +854,9 @@ class Settings(private val appContext: Context) : PreferencesHolder {
return touchExplorationIsEnabled || switchServiceIsEnabled
}
+ private val isTablet: Boolean
+ get() = appContext.resources.getBoolean(R.bool.tablet)
+
var lastKnownMode: BrowsingMode = BrowsingMode.Normal
get() {
val lastKnownModeWasPrivate = preferences.getBoolean(
@@ -922,7 +925,13 @@ class Settings(private val appContext: Context) : PreferencesHolder {
)
val toolbarPosition: ToolbarPosition
- get() = if (shouldUseBottomToolbar) ToolbarPosition.BOTTOM else ToolbarPosition.TOP
+ get() = if (isTablet) {
+ ToolbarPosition.TOP
+ } else if (shouldUseBottomToolbar) {
+ ToolbarPosition.BOTTOM
+ } else {
+ ToolbarPosition.TOP
+ }
/**
* Check each active accessibility service to see if it can perform gestures, if any can,
From 98388d8c5289baf854179caf2246740eea71885d Mon Sep 17 00:00:00 2001
From: rahulsainani
Date: Fri, 19 Jan 2024 14:03:06 +0100
Subject: [PATCH 341/586] Bug 1875465 - Part 2: Update layout and positioning
logic
---
.../org/mozilla/fenix/home/ToolbarView.kt | 30 ++++++++++++++-----
.../fenix/search/toolbar/ToolbarView.kt | 8 +++++
.../src/main/res/layout/fragment_browser.xml | 10 ++++++-
.../app/src/main/res/layout/fragment_home.xml | 8 +++++
.../src/main/res/values-sw600dp/dimens.xml | 8 +++++
fenix/app/src/main/res/values/dimens.xml | 1 +
6 files changed, 57 insertions(+), 8 deletions(-)
create mode 100644 fenix/app/src/main/res/values-sw600dp/dimens.xml
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/home/ToolbarView.kt b/fenix/app/src/main/java/org/mozilla/fenix/home/ToolbarView.kt
index c37ae5e22a56..b364030405f7 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/home/ToolbarView.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/home/ToolbarView.kt
@@ -66,16 +66,27 @@ class ToolbarView(
gravity = Gravity.TOP
}
+ val isTabletAndTabStripEnabled = context.resources.getBoolean(R.bool.tablet)
ConstraintSet().apply {
clone(binding.toolbarLayout)
clear(binding.bottomBar.id, ConstraintSet.BOTTOM)
clear(binding.bottomBarShadow.id, ConstraintSet.BOTTOM)
- connect(
- binding.bottomBar.id,
- ConstraintSet.TOP,
- ConstraintSet.PARENT_ID,
- ConstraintSet.TOP,
- )
+
+ if (isTabletAndTabStripEnabled) {
+ connect(
+ binding.bottomBar.id,
+ ConstraintSet.TOP,
+ binding.tabStripView.id,
+ ConstraintSet.BOTTOM,
+ )
+ } else {
+ connect(
+ binding.bottomBar.id,
+ ConstraintSet.TOP,
+ ConstraintSet.PARENT_ID,
+ ConstraintSet.TOP,
+ )
+ }
connect(
binding.bottomBarShadow.id,
ConstraintSet.TOP,
@@ -98,7 +109,12 @@ class ToolbarView(
binding.homeAppBar.updateLayoutParams {
topMargin =
- context.resources.getDimensionPixelSize(R.dimen.home_fragment_top_toolbar_header_margin)
+ context.resources.getDimensionPixelSize(R.dimen.home_fragment_top_toolbar_header_margin) +
+ if (isTabletAndTabStripEnabled) {
+ context.resources.getDimensionPixelSize(R.dimen.tab_strip_height)
+ } else {
+ 0
+ }
}
}
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/search/toolbar/ToolbarView.kt b/fenix/app/src/main/java/org/mozilla/fenix/search/toolbar/ToolbarView.kt
index fc186e8da545..5c362119fd79 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/search/toolbar/ToolbarView.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/search/toolbar/ToolbarView.kt
@@ -4,9 +4,11 @@
package org.mozilla.fenix.search.toolbar
+import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
+import androidx.core.view.updateMargins
import mozilla.components.browser.toolbar.BrowserToolbar
import mozilla.components.concept.toolbar.Toolbar
import mozilla.components.feature.toolbar.ToolbarAutocompleteFeature
@@ -123,6 +125,12 @@ class ToolbarView(
}
},
)
+
+ if (settings.isTabletAndTabStripEnabled) {
+ (layoutParams as ViewGroup.MarginLayoutParams).updateMargins(
+ top = context.resources.getDimensionPixelSize(R.dimen.tab_strip_height),
+ )
+ }
}
}
diff --git a/fenix/app/src/main/res/layout/fragment_browser.xml b/fenix/app/src/main/res/layout/fragment_browser.xml
index b61d82c1b9ae..34a87920503b 100644
--- a/fenix/app/src/main/res/layout/fragment_browser.xml
+++ b/fenix/app/src/main/res/layout/fragment_browser.xml
@@ -13,6 +13,14 @@
android:id="@+id/browserWindow"
android:layout_width="match_parent"
android:layout_height="match_parent">
+
+
+
+
+
+
+
+ 48dp
+
diff --git a/fenix/app/src/main/res/values/dimens.xml b/fenix/app/src/main/res/values/dimens.xml
index c48be70a5c41..8e990dae92ee 100644
--- a/fenix/app/src/main/res/values/dimens.xml
+++ b/fenix/app/src/main/res/values/dimens.xml
@@ -70,6 +70,7 @@
56dp
+ 0dp48dp
From d37240f0b03f8b8f5907a400c4fea0a71fb45f00 Mon Sep 17 00:00:00 2001
From: rahulsainani
Date: Fri, 19 Jan 2024 14:03:33 +0100
Subject: [PATCH 342/586] Bug 1875465 - Part 3: Add tab strip ui for tablets
---
.../mozilla/fenix/browser/BrowserFragment.kt | 37 ++
.../fenix/browser/tabstrip/TabStrip.kt | 414 ++++++++++++++++++
.../fenix/browser/tabstrip/TabStripCard.kt | 71 +++
.../fenix/browser/tabstrip/TabStripState.kt | 63 +++
.../org/mozilla/fenix/home/HomeFragment.kt | 29 ++
.../browser/tabstrip/TabStripStateTest.kt | 244 +++++++++++
6 files changed, 858 insertions(+)
create mode 100644 fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStrip.kt
create mode 100644 fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStripCard.kt
create mode 100644 fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStripState.kt
create mode 100644 fenix/app/src/test/java/org/mozilla/fenix/browser/tabstrip/TabStripStateTest.kt
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
index f4faa1c12d12..15872282a2ce 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
@@ -10,7 +10,9 @@ import android.view.View
import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import androidx.appcompat.content.res.AppCompatResources
+import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.core.content.ContextCompat
+import androidx.core.view.isVisible
import androidx.fragment.app.setFragmentResultListener
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
@@ -37,7 +39,9 @@ import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import org.mozilla.fenix.GleanMetrics.ReaderMode
import org.mozilla.fenix.GleanMetrics.Shopping
import org.mozilla.fenix.HomeActivity
+import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.R
+import org.mozilla.fenix.browser.tabstrip.TabStrip
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.appstate.AppAction
@@ -48,11 +52,13 @@ import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.runIfFragmentIsAttached
import org.mozilla.fenix.ext.settings
+import org.mozilla.fenix.home.HomeFragment
import org.mozilla.fenix.nimbus.FxNimbus
import org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.getCookieBannerUIMode
import org.mozilla.fenix.shopping.DefaultShoppingExperienceFeature
import org.mozilla.fenix.shopping.ReviewQualityCheckFeature
import org.mozilla.fenix.shortcut.PwaOnboardingObserver
+import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.translations.TranslationsDialogFragment.Companion.SESSION_ID
import org.mozilla.fenix.translations.TranslationsDialogFragment.Companion.TRANSLATION_IN_PROGRESS
@@ -87,6 +93,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
val context = requireContext()
val components = context.components
+ initTabStrip()
if (context.settings().isSwipeToolbarToSwitchTabsEnabled) {
binding.gestureLayout.addGestureListener(
@@ -238,6 +245,36 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
}
}
+ private fun initTabStrip() {
+ if (!resources.getBoolean(R.bool.tablet)) {
+ return
+ }
+
+ binding.tabStripView.isVisible = true
+ binding.tabStripView.apply {
+ setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
+ setContent {
+ FirefoxTheme {
+ TabStrip(
+ onAddTabClick = {
+ findNavController().navigate(
+ NavGraphDirections.actionGlobalHome(
+ focusOnAddressBar = true,
+ ),
+ )
+ },
+ onLastTabClose = {
+ findNavController().navigate(
+ BrowserFragmentDirections.actionGlobalHome(),
+ )
+ },
+ onSelectedTabClick = {},
+ )
+ }
+ }
+ }
+ }
+
private fun initTranslationsAction(context: Context, view: View) {
if (!context.settings().enableTranslations) {
return
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStrip.kt b/fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStrip.kt
new file mode 100644
index 000000000000..b7d808fe82f7
--- /dev/null
+++ b/fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStrip.kt
@@ -0,0 +1,414 @@
+/* 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.browser.tabstrip
+
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.BoxWithConstraints
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+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.foundation.layout.width
+import androidx.compose.foundation.lazy.LazyListItemInfo
+import androidx.compose.foundation.lazy.LazyListState
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.lazy.rememberLazyListState
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.systemGestureExclusion
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Devices
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import androidx.compose.ui.tooling.preview.PreviewParameterProvider
+import androidx.compose.ui.unit.coerceIn
+import androidx.compose.ui.unit.dp
+import mozilla.components.browser.state.action.TabListAction
+import mozilla.components.browser.state.state.createTab
+import mozilla.components.browser.state.store.BrowserStore
+import mozilla.components.feature.tabs.TabsUseCases
+import mozilla.components.lib.state.ext.observeAsState
+import org.mozilla.fenix.R
+import org.mozilla.fenix.components.AppStore
+import org.mozilla.fenix.components.components
+import org.mozilla.fenix.compose.Favicon
+import org.mozilla.fenix.theme.FirefoxTheme
+import org.mozilla.fenix.theme.Theme
+
+private val minTabStripItemWidth = 160.dp
+private val maxTabStripItemWidth = 280.dp
+private val tabStripIconSize = 24.dp
+private val spaceBetweenTabs = 4.dp
+private val tabStripStartPadding = 8.dp
+private val addTabIconSize = 20.dp
+
+/**
+ * Top level composable for the tabs strip.
+ *
+ * @param onHome Whether or not the tabs strip is in the home screen.
+ * @param browserStore The [BrowserStore] instance used to observe tabs state.
+ * @param appStore The [AppStore] instance used to observe browsing mode.
+ * @param tabsUseCases The [TabsUseCases] instance to perform tab actions.
+ * @param onAddTabClick Invoked when the add tab button is clicked.
+ * @param onLastTabClose Invoked when the last remaining open tab is closed.
+ * @param onSelectedTabClick Invoked when a tab is selected.
+ */
+@Composable
+fun TabStrip(
+ onHome: Boolean = false,
+ browserStore: BrowserStore = components.core.store,
+ appStore: AppStore = components.appStore,
+ tabsUseCases: TabsUseCases = components.useCases.tabsUseCases,
+ onAddTabClick: () -> Unit,
+ onLastTabClose: () -> Unit,
+ onSelectedTabClick: () -> Unit,
+) {
+ val isPrivateMode by appStore.observeAsState(false) { it.mode.isPrivate }
+ val state by browserStore.observeAsState(TabStripState.initial) {
+ it.toTabStripState(isSelectDisabled = onHome, isPrivateMode = isPrivateMode)
+ }
+
+ TabStripContent(
+ state = state,
+ onAddTabClick = onAddTabClick,
+ onCloseTabClick = {
+ if (state.tabs.size == 1) {
+ onLastTabClose()
+ }
+ tabsUseCases.removeTab(it)
+ },
+ onSelectedTabClick = {
+ tabsUseCases.selectTab(it)
+ onSelectedTabClick()
+ },
+ )
+}
+
+@Composable
+private fun TabStripContent(
+ state: TabStripState,
+ onAddTabClick: () -> Unit,
+ onCloseTabClick: (id: String) -> Unit,
+ onSelectedTabClick: (id: String) -> Unit,
+) {
+ Row(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(FirefoxTheme.colors.layer1)
+ .systemGestureExclusion(),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ TabsList(
+ state = state,
+ modifier = Modifier.weight(1f, fill = false),
+ onCloseTabClick = onCloseTabClick,
+ onSelectedTabClick = onSelectedTabClick,
+ )
+
+ IconButton(onClick = onAddTabClick) {
+ Icon(
+ painter = painterResource(R.drawable.mozac_ic_plus_24),
+ modifier = Modifier.size(addTabIconSize),
+ tint = FirefoxTheme.colors.iconPrimary,
+ contentDescription = stringResource(R.string.add_tab),
+ )
+ }
+ }
+}
+
+@Composable
+@OptIn(ExperimentalFoundationApi::class)
+private fun TabsList(
+ state: TabStripState,
+ modifier: Modifier = Modifier,
+ onCloseTabClick: (id: String) -> Unit,
+ onSelectedTabClick: (id: String) -> Unit,
+) {
+ BoxWithConstraints(modifier = modifier) {
+ val listState = rememberLazyListState()
+ // Calculate the width of each tab item based on available width and the number of tabs and
+ // taking into account the space between tabs.
+ val availableWidth = maxWidth - tabStripStartPadding
+ val tabWidth = (availableWidth / state.tabs.size) - spaceBetweenTabs
+
+ LazyRow(
+ modifier = Modifier,
+ state = listState,
+ contentPadding = PaddingValues(start = tabStripStartPadding),
+ ) {
+ items(
+ items = state.tabs,
+ key = { it.id },
+ ) { itemState ->
+ TabItem(
+ state = itemState,
+ onCloseTabClick = onCloseTabClick,
+ onSelectedTabClick = onSelectedTabClick,
+ modifier = Modifier
+ .padding(end = spaceBetweenTabs)
+ .animateItemPlacement()
+ .width(
+ tabWidth.coerceIn(
+ minimumValue = minTabStripItemWidth,
+ maximumValue = maxTabStripItemWidth,
+ ),
+ ),
+ )
+ }
+ }
+
+ if (state.tabs.isNotEmpty()) {
+ // When a new tab is added, scroll to the end of the list. This is done here instead of
+ // in onCloseTabClick so this acts on state change which can occur from any other
+ // place e.g. tabs tray.
+ LaunchedEffect(state.tabs.last().id) {
+ listState.scrollToItem(state.tabs.size)
+ }
+
+ // When a tab is selected, scroll to the selected tab. This is done here instead of
+ // in onSelectedTabClick so this acts on state change which can occur from any other
+ // place e.g. tabs tray.
+ val selectedTab = state.tabs.firstOrNull { it.isSelected }
+ LaunchedEffect(selectedTab?.id) {
+ if (selectedTab != null) {
+ val selectedItemInfo =
+ listState.layoutInfo.visibleItemsInfo.firstOrNull { it.key == selectedTab.id }
+
+ if (listState.isItemPartiallyVisible(selectedItemInfo) || selectedItemInfo == null) {
+ listState.animateScrollToItem(state.tabs.indexOf(selectedTab))
+ }
+ }
+ }
+ }
+ }
+}
+
+private fun LazyListState.isItemPartiallyVisible(itemInfo: LazyListItemInfo?) =
+ itemInfo != null &&
+ (itemInfo.offset + itemInfo.size > layoutInfo.viewportEndOffset || itemInfo.offset < 0)
+
+@Composable
+private fun TabItem(
+ state: TabStripItem,
+ modifier: Modifier = Modifier,
+ onCloseTabClick: (id: String) -> Unit,
+ onSelectedTabClick: (id: String) -> Unit,
+) {
+ TabStripCard(
+ modifier = modifier.fillMaxSize(),
+ backgroundColor =
+ if (state.isPrivate) {
+ if (state.isSelected) {
+ FirefoxTheme.colors.layer3
+ } else {
+ FirefoxTheme.colors.layer2
+ }
+ } else {
+ if (state.isSelected) {
+ FirefoxTheme.colors.layer2
+ } else {
+ FirefoxTheme.colors.layer3
+ }
+ },
+ elevation = if (state.isSelected) {
+ selectedTabStripCardElevation
+ } else {
+ defaultTabStripCardElevation
+ },
+ ) {
+ Row(
+ modifier = Modifier
+ .fillMaxSize()
+ .clickable { onSelectedTabClick(state.id) },
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.SpaceBetween,
+ ) {
+ Row(
+ modifier = Modifier.weight(1f, fill = false),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Spacer(modifier = Modifier.size(8.dp))
+
+ TabStripIcon(state.url)
+
+ Spacer(modifier = Modifier.size(8.dp))
+
+ Text(
+ text = state.title,
+ color = FirefoxTheme.colors.textPrimary,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ style = FirefoxTheme.typography.subtitle2,
+ )
+ }
+
+ IconButton(onClick = { onCloseTabClick(state.id) }) {
+ Icon(
+ painter = painterResource(R.drawable.mozac_ic_cross_20),
+ tint = FirefoxTheme.colors.iconPrimary,
+ contentDescription = stringResource(R.string.close_tab),
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun TabStripIcon(url: String) {
+ Box(
+ modifier = Modifier
+ .size(tabStripIconSize)
+ .clip(CircleShape),
+ contentAlignment = Alignment.Center,
+ ) {
+ Favicon(
+ url = url,
+ size = tabStripIconSize,
+ )
+ }
+}
+
+private class TabUIStateParameterProvider : PreviewParameterProvider {
+ override val values: Sequence
+ get() = sequenceOf(
+ TabStripState(
+ listOf(
+ TabStripItem(
+ id = "1",
+ title = "Tab 1",
+ url = "https://www.mozilla.org",
+ isPrivate = false,
+ isSelected = false,
+ ),
+ TabStripItem(
+ id = "2",
+ title = "Tab 2 with a very long title that should be truncated",
+ url = "https://www.mozilla.org",
+ isPrivate = false,
+ isSelected = false,
+ ),
+ TabStripItem(
+ id = "3",
+ title = "Selected tab",
+ url = "https://www.mozilla.org",
+ isPrivate = false,
+ isSelected = true,
+ ),
+ TabStripItem(
+ id = "p1",
+ title = "Private tab 1",
+ url = "https://www.mozilla.org",
+ isPrivate = true,
+ isSelected = false,
+ ),
+ TabStripItem(
+ id = "p2",
+ title = "Private selected tab",
+ url = "https://www.mozilla.org",
+ isPrivate = true,
+ isSelected = true,
+ ),
+ ),
+ ),
+ )
+}
+
+@Preview(device = Devices.TABLET)
+@Composable
+private fun TabStripPreview(
+ @PreviewParameter(TabUIStateParameterProvider::class) tabStripState: TabStripState,
+) {
+ FirefoxTheme {
+ TabStripContentPreview(tabStripState.tabs.filter { !it.isPrivate })
+ }
+}
+
+@Preview(device = Devices.TABLET)
+@Composable
+private fun TabStripPreviewDarkMode(
+ @PreviewParameter(TabUIStateParameterProvider::class) tabStripState: TabStripState,
+) {
+ FirefoxTheme(theme = Theme.Dark) {
+ TabStripContentPreview(tabStripState.tabs.filter { !it.isPrivate })
+ }
+}
+
+@Preview(device = Devices.TABLET)
+@Composable
+private fun TabStripPreviewPrivateMode(
+ @PreviewParameter(TabUIStateParameterProvider::class) tabStripState: TabStripState,
+) {
+ FirefoxTheme(theme = Theme.Private) {
+ TabStripContentPreview(tabStripState.tabs.filter { it.isPrivate })
+ }
+}
+
+@Composable
+private fun TabStripContentPreview(tabs: List) {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(dimensionResource(id = R.dimen.tab_strip_height)),
+ contentAlignment = Alignment.Center,
+ ) {
+ TabStripContent(
+ state = TabStripState(
+ tabs = tabs,
+ ),
+ onAddTabClick = {},
+ onCloseTabClick = {},
+ onSelectedTabClick = {},
+ )
+ }
+}
+
+@Preview(device = Devices.TABLET)
+@Composable
+private fun TabStripPreview() {
+ val browserStore = BrowserStore()
+
+ FirefoxTheme {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(dimensionResource(id = R.dimen.tab_strip_height)),
+ contentAlignment = Alignment.Center,
+ ) {
+ TabStrip(
+ appStore = AppStore(),
+ browserStore = browserStore,
+ tabsUseCases = TabsUseCases(browserStore),
+ onAddTabClick = {
+ val tab = createTab(
+ url = "www.example.com",
+ )
+ browserStore.dispatch(TabListAction.AddTabAction(tab))
+ },
+ onLastTabClose = {},
+ onSelectedTabClick = {},
+ )
+ }
+ }
+}
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStripCard.kt b/fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStripCard.kt
new file mode 100644
index 000000000000..57f9c7b3a407
--- /dev/null
+++ b/fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStripCard.kt
@@ -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/. */
+
+package org.mozilla.fenix.browser.tabstrip
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Card
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import org.mozilla.fenix.compose.annotation.LightDarkPreview
+import org.mozilla.fenix.theme.FirefoxTheme
+
+private val cardShape = RoundedCornerShape(8.dp)
+internal val defaultTabStripCardElevation = 0.dp
+internal val selectedTabStripCardElevation = 1.dp
+
+/**
+ * Card composable used in Tab Strip items.
+ *
+ * @param modifier The modifier to be applied to the card.
+ * @param backgroundColor The background color of the card.
+ * @param elevation The elevation of the card.
+ * @param content The content of the card.
+ */
+@Composable
+fun TabStripCard(
+ modifier: Modifier = Modifier,
+ backgroundColor: Color = FirefoxTheme.colors.layer3,
+ elevation: Dp = defaultTabStripCardElevation,
+ content: @Composable () -> Unit,
+) {
+ Card(
+ shape = cardShape,
+ backgroundColor = backgroundColor,
+ elevation = elevation,
+ modifier = modifier,
+ content = content,
+ )
+}
+
+@LightDarkPreview
+@Composable
+private fun TabStripCardPreview() {
+ FirefoxTheme {
+ TabStripCard {
+ Box(
+ modifier = Modifier
+ .height(56.dp)
+ .width(200.dp)
+ .padding(8.dp),
+ contentAlignment = Alignment.Center,
+ ) {
+ Text(
+ text = "Tab Strip Card",
+ color = FirefoxTheme.colors.textPrimary,
+ style = FirefoxTheme.typography.subtitle1,
+ )
+ }
+ }
+ }
+}
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStripState.kt b/fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStripState.kt
new file mode 100644
index 000000000000..5dacf2b4a4cc
--- /dev/null
+++ b/fenix/app/src/main/java/org/mozilla/fenix/browser/tabstrip/TabStripState.kt
@@ -0,0 +1,63 @@
+/* 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.browser.tabstrip
+
+import mozilla.components.browser.state.selector.getNormalOrPrivateTabs
+import mozilla.components.browser.state.state.BrowserState
+
+/**
+ * The ui state of the tabs strip.
+ *
+ * @property tabs The list of [TabStripItem].
+ */
+data class TabStripState(
+ val tabs: List,
+) {
+ companion object {
+ val initial = TabStripState(tabs = emptyList())
+ }
+}
+
+/**
+ * The ui state of a tab.
+ *
+ * @property id The id of the tab.
+ * @property title The title of the tab.
+ * @property url The url of the tab.
+ * @property isPrivate Whether or not the tab is private.
+ * @property isSelected Whether or not the tab is selected.
+ */
+data class TabStripItem(
+ val id: String,
+ val title: String,
+ val url: String,
+ val isPrivate: Boolean,
+ val isSelected: Boolean,
+)
+
+/**
+ * Converts [BrowserState] to [TabStripState] that contains the information needed to render the
+ * tabs strip.
+ *
+ * @param isSelectDisabled When true, the tabs will show as selected.
+ * @param isPrivateMode Whether or not the browser is in private mode.
+ */
+internal fun BrowserState.toTabStripState(
+ isSelectDisabled: Boolean,
+ isPrivateMode: Boolean,
+): TabStripState {
+ return TabStripState(
+ tabs = getNormalOrPrivateTabs(isPrivateMode)
+ .map {
+ TabStripItem(
+ id = it.id,
+ title = it.content.title.ifBlank { it.content.url },
+ url = it.content.url,
+ isPrivate = it.content.private,
+ isSelected = !isSelectDisabled && it.id == selectedTabId,
+ )
+ },
+ )
+}
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 fccae3ff9973..5f61e7cd70cf 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
@@ -23,6 +23,7 @@ import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.semantics.testTagsAsResourceId
@@ -77,6 +78,7 @@ import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.service.glean.private.NoExtras
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import mozilla.components.ui.colors.PhotonColors
+import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.GleanMetrics.HomeScreen
import org.mozilla.fenix.GleanMetrics.Homepage
import org.mozilla.fenix.GleanMetrics.PrivateBrowsingShortcutCfr
@@ -84,6 +86,7 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.addons.showSnackBar
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
+import org.mozilla.fenix.browser.tabstrip.TabStrip
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.PrivateShortcutCreateManager
import org.mozilla.fenix.components.TabCollectionStorage
@@ -576,6 +579,7 @@ class HomeFragment : Fragment() {
)
toolbarView?.build()
+ initTabStrip()
PrivateBrowsingButtonView(binding.privateBrowsingButton, browsingModeManager) { newMode ->
sessionControlInteractor.onPrivateModeButtonClicked(newMode)
@@ -653,6 +657,31 @@ class HomeFragment : Fragment() {
)
}
+ private fun initTabStrip() {
+ if (!resources.getBoolean(R.bool.tablet)) {
+ return
+ }
+
+ binding.tabStripView.isVisible = true
+ binding.tabStripView.apply {
+ setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
+ setContent {
+ FirefoxTheme {
+ TabStrip(
+ onHome = true,
+ onAddTabClick = {
+ sessionControlInteractor.onNavigateSearch()
+ },
+ onSelectedTabClick = {
+ (requireActivity() as HomeActivity).openToBrowser(BrowserDirection.FromHome)
+ },
+ onLastTabClose = {},
+ )
+ }
+ }
+ }
+ }
+
/**
* Method used to listen to search engine name changes and trigger a top sites update accordingly
*/
diff --git a/fenix/app/src/test/java/org/mozilla/fenix/browser/tabstrip/TabStripStateTest.kt b/fenix/app/src/test/java/org/mozilla/fenix/browser/tabstrip/TabStripStateTest.kt
new file mode 100644
index 000000000000..e6c98b0eff22
--- /dev/null
+++ b/fenix/app/src/test/java/org/mozilla/fenix/browser/tabstrip/TabStripStateTest.kt
@@ -0,0 +1,244 @@
+package org.mozilla.fenix.browser.tabstrip
+
+import mozilla.components.browser.state.state.BrowserState
+import mozilla.components.browser.state.state.createTab
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+class TabStripStateTest {
+
+ @Test
+ fun `WHEN browser state tabs is empty THEN tabs strip state tabs is empty`() {
+ val browserState = BrowserState(tabs = emptyList())
+ val actual = browserState.toTabStripState(isSelectDisabled = false, isPrivateMode = false)
+
+ val expected = TabStripState(tabs = emptyList())
+
+ assertEquals(expected, actual)
+ }
+
+ @Test
+ fun `WHEN private mode is off THEN tabs strip state tabs should include only non private tabs`() {
+ val browserState = BrowserState(
+ tabs = listOf(
+ createTab(
+ url = "https://example.com",
+ title = "Example 1",
+ private = false,
+ id = "1",
+ ),
+ createTab(
+ url = "https://example2.com",
+ title = "Example 2",
+ private = true,
+ id = "2",
+ ),
+ createTab(
+ url = "https://example3.com",
+ title = "Example 3",
+ private = false,
+ id = "3",
+ ),
+ ),
+ )
+ val actual = browserState.toTabStripState(isSelectDisabled = false, isPrivateMode = false)
+
+ val expected = TabStripState(
+ tabs = listOf(
+ TabStripItem(
+ id = "1",
+ title = "Example 1",
+ url = "https://example.com",
+ isSelected = false,
+ isPrivate = false,
+ ),
+ TabStripItem(
+ id = "3",
+ title = "Example 3",
+ url = "https://example3.com",
+ isSelected = false,
+ isPrivate = false,
+ ),
+ ),
+ )
+
+ assertEquals(expected, actual)
+ }
+
+ @Test
+ fun `WHEN private mode is on THEN tabs strip state tabs should include only private tabs`() {
+ val browserState = BrowserState(
+ tabs = listOf(
+ createTab(
+ url = "https://example.com",
+ title = "Example",
+ private = false,
+ id = "1",
+ ),
+ createTab(
+ url = "https://example2.com",
+ title = "Private Example",
+ private = true,
+ id = "2",
+ ),
+ createTab(
+ url = "https://example3.com",
+ title = "Example 3",
+ private = true,
+ id = "3",
+ ),
+ ),
+ )
+ val actual = browserState.toTabStripState(isSelectDisabled = false, isPrivateMode = true)
+
+ val expected = TabStripState(
+ tabs = listOf(
+ TabStripItem(
+ id = "2",
+ title = "Private Example",
+ url = "https://example2.com",
+ isSelected = false,
+ isPrivate = true,
+ ),
+ TabStripItem(
+ id = "3",
+ title = "Example 3",
+ url = "https://example3.com",
+ isSelected = false,
+ isPrivate = true,
+ ),
+ ),
+ )
+
+ assertEquals(expected, actual)
+ }
+
+ @Test
+ fun `WHEN isSelectDisabled is false THEN tabs strip state tabs should have a selected tab`() {
+ val browserState = BrowserState(
+ tabs = listOf(
+ createTab(
+ url = "https://example.com",
+ title = "Example 1",
+ private = false,
+ id = "1",
+ ),
+ createTab(
+ url = "https://example2.com",
+ title = "Example 2",
+ private = false,
+ id = "2",
+ ),
+ ),
+ selectedTabId = "2",
+ )
+ val actual = browserState.toTabStripState(isSelectDisabled = false, isPrivateMode = false)
+
+ val expected = TabStripState(
+ tabs = listOf(
+ TabStripItem(
+ id = "1",
+ title = "Example 1",
+ url = "https://example.com",
+ isSelected = false,
+ isPrivate = false,
+ ),
+ TabStripItem(
+ id = "2",
+ title = "Example 2",
+ url = "https://example2.com",
+ isSelected = true,
+ isPrivate = false,
+ ),
+ ),
+ )
+
+ assertEquals(expected, actual)
+ }
+
+ @Test
+ fun `WHEN isSelectDisabled is true THEN tabs strip state tabs should not have a selected tab`() {
+ val browserState = BrowserState(
+ tabs = listOf(
+ createTab(
+ url = "https://example.com",
+ title = "Example 1",
+ private = false,
+ id = "1",
+ ),
+ createTab(
+ url = "https://example2.com",
+ title = "Example 2",
+ private = false,
+ id = "2",
+ ),
+ ),
+ selectedTabId = "2",
+ )
+ val actual = browserState.toTabStripState(isSelectDisabled = true, isPrivateMode = false)
+
+ val expected = TabStripState(
+ tabs = listOf(
+ TabStripItem(
+ id = "1",
+ title = "Example 1",
+ url = "https://example.com",
+ isSelected = false,
+ isPrivate = false,
+ ),
+ TabStripItem(
+ id = "2",
+ title = "Example 2",
+ url = "https://example2.com",
+ isSelected = false,
+ isPrivate = false,
+ ),
+ ),
+ )
+
+ assertEquals(expected, actual)
+ }
+
+ @Test
+ fun `WHEN a tab does not have a title THEN tabs strip should display the url`() {
+ val browserState = BrowserState(
+ tabs = listOf(
+ createTab(
+ url = "https://example.com",
+ title = "Example 1",
+ private = false,
+ id = "1",
+ ),
+ createTab(
+ url = "https://example2.com",
+ title = "",
+ private = false,
+ id = "2",
+ ),
+ ),
+ selectedTabId = "2",
+ )
+ val actual = browserState.toTabStripState(isSelectDisabled = false, isPrivateMode = false)
+
+ val expected = TabStripState(
+ tabs = listOf(
+ TabStripItem(
+ id = "1",
+ title = "Example 1",
+ url = "https://example.com",
+ isSelected = false,
+ isPrivate = false,
+ ),
+ TabStripItem(
+ id = "2",
+ title = "https://example2.com",
+ url = "https://example2.com",
+ isSelected = true,
+ isPrivate = false,
+ ),
+ ),
+ )
+
+ assertEquals(expected, actual)
+ }
+}
From 13ad64a6c017035ed04aa5850e77b30c3a7a0e45 Mon Sep 17 00:00:00 2001
From: rahulsainani
Date: Sat, 17 Feb 2024 00:07:47 +0100
Subject: [PATCH 343/586] Bug 1875465 - Part 4: Add secret setting and remove
toolbar customization
---
.../mozilla/fenix/browser/BrowserFragment.kt | 11 +++++-----
.../org/mozilla/fenix/home/HomeFragment.kt | 8 +++-----
.../org/mozilla/fenix/home/ToolbarView.kt | 2 +-
.../fenix/settings/CustomizationFragment.kt | 20 ++++++++++++++++---
.../fenix/settings/SecretSettingsFragment.kt | 10 ++++++++++
.../java/org/mozilla/fenix/utils/Settings.kt | 13 +++++++++++-
.../src/main/res/values/preference_keys.xml | 3 +++
.../src/main/res/values/static_strings.xml | 2 ++
.../res/xml/customization_preferences.xml | 4 +++-
.../res/xml/secret_settings_preferences.xml | 5 +++++
.../fenix/search/toolbar/ToolbarViewTest.kt | 4 ++++
11 files changed, 65 insertions(+), 17 deletions(-)
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
index 15872282a2ce..115a8a85e481 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
@@ -93,9 +93,12 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
val context = requireContext()
val components = context.components
- initTabStrip()
+ val isTabletAndTabStripEnabled = context.settings().isTabletAndTabStripEnabled
+ if (isTabletAndTabStripEnabled) {
+ initTabStrip()
+ }
- if (context.settings().isSwipeToolbarToSwitchTabsEnabled) {
+ if (!isTabletAndTabStripEnabled && context.settings().isSwipeToolbarToSwitchTabsEnabled) {
binding.gestureLayout.addGestureListener(
ToolbarGestureHandler(
activity = requireActivity(),
@@ -246,10 +249,6 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
}
private fun initTabStrip() {
- if (!resources.getBoolean(R.bool.tablet)) {
- return
- }
-
binding.tabStripView.isVisible = true
binding.tabStripView.apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
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 5f61e7cd70cf..5d9270121139 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
@@ -579,7 +579,9 @@ class HomeFragment : Fragment() {
)
toolbarView?.build()
- initTabStrip()
+ if (requireContext().settings().isTabletAndTabStripEnabled) {
+ initTabStrip()
+ }
PrivateBrowsingButtonView(binding.privateBrowsingButton, browsingModeManager) { newMode ->
sessionControlInteractor.onPrivateModeButtonClicked(newMode)
@@ -658,10 +660,6 @@ class HomeFragment : Fragment() {
}
private fun initTabStrip() {
- if (!resources.getBoolean(R.bool.tablet)) {
- return
- }
-
binding.tabStripView.isVisible = true
binding.tabStripView.apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/home/ToolbarView.kt b/fenix/app/src/main/java/org/mozilla/fenix/home/ToolbarView.kt
index b364030405f7..3c556f7b481d 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/home/ToolbarView.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/home/ToolbarView.kt
@@ -66,7 +66,7 @@ class ToolbarView(
gravity = Gravity.TOP
}
- val isTabletAndTabStripEnabled = context.resources.getBoolean(R.bool.tablet)
+ val isTabletAndTabStripEnabled = context.settings().isTabletAndTabStripEnabled
ConstraintSet().apply {
clone(binding.toolbarLayout)
clear(binding.bottomBar.id, ConstraintSet.BOTTOM)
diff --git a/fenix/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt
index fb1d26a6d2af..9f5d6b6d057c 100644
--- a/fenix/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt
+++ b/fenix/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt
@@ -10,7 +10,9 @@ import android.os.Build.VERSION.SDK_INT
import android.os.Bundle
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.Preference
+import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
+import androidx.preference.PreferenceScreen
import androidx.preference.SwitchPreference
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.GleanMetrics.AppTheme
@@ -51,8 +53,19 @@ class CustomizationFragment : PreferenceFragmentCompat() {
bindLightTheme()
bindAutoBatteryTheme()
setupRadioGroups()
- setupToolbarCategory()
- setupGesturesCategory()
+ val tabletAndTabStripEnabled = requireContext().settings().isTabletAndTabStripEnabled
+ if (tabletAndTabStripEnabled) {
+ val preferenceScreen: PreferenceScreen =
+ requirePreference(R.string.pref_key_customization_preference_screen)
+ val toolbarPrefCategory: PreferenceCategory =
+ requirePreference(R.string.pref_key_customization_category_toolbar)
+ preferenceScreen.removePreference(toolbarPrefCategory)
+ } else {
+ setupToolbarCategory()
+ }
+ // if tab strip is enabled, swipe toolbar to switch tabs should not be enabled so the
+ // preference is not shown
+ setupGesturesCategory(isSwipeToolbarToSwitchTabsVisible = !tabletAndTabStripEnabled)
}
private fun setupRadioGroups() {
@@ -140,7 +153,7 @@ class CustomizationFragment : PreferenceFragmentCompat() {
addToRadioGroup(topPreference, bottomPreference)
}
- private fun setupGesturesCategory() {
+ private fun setupGesturesCategory(isSwipeToolbarToSwitchTabsVisible: Boolean) {
requirePreference(R.string.pref_key_website_pull_to_refresh).apply {
isVisible = FeatureFlags.pullToRefreshEnabled
isChecked = context.settings().isPullToRefreshEnabledInBrowser
@@ -152,6 +165,7 @@ class CustomizationFragment : PreferenceFragmentCompat() {
}
requirePreference(R.string.pref_key_swipe_toolbar_switch_tabs).apply {
isChecked = context.settings().isSwipeToolbarToSwitchTabsEnabled
+ isVisible = isSwipeToolbarToSwitchTabsVisible
onPreferenceChangeListener = SharedPreferenceUpdater()
}
}
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 2d91285fedfb..7d7d4108c9b2 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
@@ -122,6 +122,8 @@ class SecretSettingsFragment : PreferenceFragmentCompat() {
}
}
+ setupTabStripPreference()
+
// for performance reasons, this is only available in Nightly or Debug builds
requirePreference(R.string.pref_key_custom_glean_server_url).apply {
isVisible = Config.channel.isNightlyOrDebug && BuildConfig.GLEAN_CUSTOM_URL.isNullOrEmpty()
@@ -138,6 +140,14 @@ class SecretSettingsFragment : PreferenceFragmentCompat() {
}
}
+ private fun setupTabStripPreference() {
+ requirePreference(R.string.pref_key_enable_tab_strip).apply {
+ isVisible = Config.channel.isNightlyOrDebug && context.resources.getBoolean(R.bool.tablet)
+ isChecked = context.settings().isTabStripEnabled
+ onPreferenceChangeListener = SharedPreferenceUpdater()
+ }
+ }
+
override fun onPreferenceTreeClick(preference: Preference): Boolean {
when (preference.key) {
getString(R.string.pref_key_custom_sponsored_stories_parameters) ->
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 957741fabe3e..b978ae3395ae 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
@@ -857,6 +857,17 @@ class Settings(private val appContext: Context) : PreferencesHolder {
private val isTablet: Boolean
get() = appContext.resources.getBoolean(R.bool.tablet)
+ /**
+ * Indicates if the user has enabled the tab strip feature.
+ */
+ val isTabStripEnabled by booleanPreference(
+ key = appContext.getPreferenceKey(R.string.pref_key_enable_tab_strip),
+ default = false,
+ )
+
+ val isTabletAndTabStripEnabled: Boolean
+ get() = isTablet && isTabStripEnabled
+
var lastKnownMode: BrowsingMode = BrowsingMode.Normal
get() {
val lastKnownModeWasPrivate = preferences.getBoolean(
@@ -925,7 +936,7 @@ class Settings(private val appContext: Context) : PreferencesHolder {
)
val toolbarPosition: ToolbarPosition
- get() = if (isTablet) {
+ get() = if (isTabletAndTabStripEnabled) {
ToolbarPosition.TOP
} else if (shouldUseBottomToolbar) {
ToolbarPosition.BOTTOM
diff --git a/fenix/app/src/main/res/values/preference_keys.xml b/fenix/app/src/main/res/values/preference_keys.xml
index 6c161555677b..0db2c3d738c3 100644
--- a/fenix/app/src/main/res/values/preference_keys.xml
+++ b/fenix/app/src/main/res/values/preference_keys.xml
@@ -78,6 +78,7 @@
pref_key_suggest_strong_password_enabledpref_key_enable_debug_drawerpref_key_show_first_time_translation
+ pref_key_enable_tab_strippref_key_telemetry
@@ -155,12 +156,14 @@
pref_key_follow_device_theme
+ pref_key_customization_preference_screenpref_key_website_pull_to_refreshpref_key_dynamic_toolbarpref_key_swipe_toolbar_switch_tabspref_key_swipe_toolbar_show_tabspref_key_recent_tabspref_key_recent_bookmarks
+ pref_key_customization_category_toolbarpref_key_https_only_settings
diff --git a/fenix/app/src/main/res/values/static_strings.xml b/fenix/app/src/main/res/values/static_strings.xml
index 6432c5bedda1..649bfb5ae178 100644
--- a/fenix/app/src/main/res/values/static_strings.xml
+++ b/fenix/app/src/main/res/values/static_strings.xml
@@ -78,6 +78,8 @@
Enable Felt PrivacyEnable Debug Drawer
+
+ Enable Tab StripMake inactive
diff --git a/fenix/app/src/main/res/xml/customization_preferences.xml b/fenix/app/src/main/res/xml/customization_preferences.xml
index cfd13f3aaf70..f1e1ea05e25b 100644
--- a/fenix/app/src/main/res/xml/customization_preferences.xml
+++ b/fenix/app/src/main/res/xml/customization_preferences.xml
@@ -3,7 +3,8 @@
- 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/. -->
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:key="@string/pref_key_customization_preference_screen" >
+
Date: Mon, 19 Feb 2024 11:09:39 +0100
Subject: [PATCH 344/586] Bug 1875465 - Part 5: Hide tab strip when full screen
---
.../java/org/mozilla/fenix/browser/BaseBrowserFragment.kt | 4 ++++
1 file changed, 4 insertions(+)
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 9ba7df57d1ae..e2bc0dc37a82 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
@@ -1560,6 +1560,7 @@ abstract class BaseBrowserFragment :
(view as? SwipeGestureLayout)?.isSwipeEnabled = false
browserToolbarView.collapse()
browserToolbarView.view.isVisible = false
+ binding.tabStripView.isVisible = false
val browserEngine = binding.swipeRefresh.layoutParams as CoordinatorLayout.LayoutParams
browserEngine.bottomMargin = 0
browserEngine.topMargin = 0
@@ -1585,6 +1586,9 @@ abstract class BaseBrowserFragment :
initializeEngineView(toolbarHeight)
browserToolbarView.expand()
}
+ if (requireContext().settings().isTabletAndTabStripEnabled) {
+ binding.tabStripView.isVisible = true
+ }
}
binding.swipeRefresh.isEnabled = shouldPullToRefreshBeEnabled(inFullScreen)
From 0ac771115e6fa9bc998583d27f6a557043836bd9 Mon Sep 17 00:00:00 2001
From: "oana.horvath"
Date: Mon, 26 Feb 2024 13:02:03 +0200
Subject: [PATCH 345/586] Bug 1880087 - Create TestSetup helper: Test classes
D-L
---
.../java/org/mozilla/fenix/ui/DeepLinkTest.kt | 25 +----------
.../mozilla/fenix/ui/DownloadFileTypesTest.kt | 11 +----
.../java/org/mozilla/fenix/ui/DownloadTest.kt | 38 +---------------
.../ui/EnhancedTrackingProtectionTest.kt | 22 +---------
.../mozilla/fenix/ui/FirefoxSuggestTest.kt | 3 +-
.../fenix/ui/GlobalPrivacyControlTest.kt | 20 ++-------
.../java/org/mozilla/fenix/ui/HistoryTest.kt | 43 ++-----------------
.../org/mozilla/fenix/ui/HomeScreenTest.kt | 27 +-----------
.../java/org/mozilla/fenix/ui/LoginsTest.kt | 21 ++-------
9 files changed, 24 insertions(+), 186 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DeepLinkTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DeepLinkTest.kt
index 258adb4cb2e2..1a3cf129f25b 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DeepLinkTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DeepLinkTest.kt
@@ -5,16 +5,12 @@
package org.mozilla.fenix.ui
import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.DeepLinkRobot
/**
@@ -31,29 +27,12 @@ import org.mozilla.fenix.ui.robots.DeepLinkRobot
**/
@Ignore("All tests perma-failing, see: https://github.com/mozilla-mobile/fenix/issues/13491")
-class DeepLinkTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
-
+class DeepLinkTest : TestSetup() {
private val robot = DeepLinkRobot()
@get:Rule
val activityIntentTestRule = HomeActivityIntentTestRule()
- @Before
- fun setUp() {
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- }
-
@Test
fun openHomeScreen() {
robot.openHomeScreen {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt
index ff0a744ade5b..1ff999f4280a 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt
@@ -5,14 +5,13 @@
package org.mozilla.fenix.ui
import androidx.core.net.toUri
-import org.junit.After
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.mozilla.fenix.customannotations.SmokeTest
-import org.mozilla.fenix.helpers.AppAndSystemHelper.clearDownloadsFolder
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.downloadRobot
/**
@@ -22,7 +21,7 @@ import org.mozilla.fenix.ui.robots.downloadRobot
* - Verifies downloading of varying file types and the appearance inside the Downloads listing.
**/
@RunWith(Parameterized::class)
-class DownloadFileTypesTest(fileName: String) {
+class DownloadFileTypesTest(fileName: String) : TestSetup() {
/* Remote test page managed by Mozilla Mobile QA team at https://github.com/mozilla-mobile/testapp */
private val downloadTestPage = "https://storage.googleapis.com/mobile_test_assets/test_app/downloads.html"
private var downloadFile: String = fileName
@@ -30,12 +29,6 @@ class DownloadFileTypesTest(fileName: String) {
@get:Rule
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
- @After
- fun tearDown() {
- // Check and clear the downloads folder
- clearDownloadsFolder()
- }
-
companion object {
// Creating test data. The test will take each file name as a parameter and run it individually.
@JvmStatic
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt
index 987660636b32..23c8e2ac3ca6 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt
@@ -5,16 +5,11 @@
package org.mozilla.fenix.ui
import androidx.core.net.toUri
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.AppAndSystemHelper.assertExternalAppOpens
-import org.mozilla.fenix.helpers.AppAndSystemHelper.clearDownloadsFolder
import org.mozilla.fenix.helpers.AppAndSystemHelper.deleteDownloadedFileOnStorage
import org.mozilla.fenix.helpers.AppAndSystemHelper.setNetworkEnabled
import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_APPS_PHOTOS
@@ -25,6 +20,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.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.downloadRobot
@@ -40,9 +36,7 @@ import org.mozilla.fenix.ui.robots.notificationShade
* - Verifies download notification and actions
* - Verifies managing downloads inside the Downloads listing.
**/
-class DownloadTest {
- private lateinit var mockWebServer: MockWebServer
-
+class DownloadTest : TestSetup() {
/* Remote test page managed by Mozilla Mobile QA team at https://github.com/mozilla-mobile/testapp */
private val downloadTestPage = "https://storage.googleapis.com/mobile_test_assets/test_app/downloads.html"
private var downloadFile: String = ""
@@ -50,34 +44,6 @@ class DownloadTest {
@get:Rule
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
- @Before
- fun setUp() {
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
-
- // clear all existing notifications
- notificationShade {
- mDevice.openNotification()
- clearNotifications()
- }
- }
-
- @After
- fun tearDown() {
- notificationShade {
- cancelAllShownNotifications()
- }
-
- mockWebServer.shutdown()
-
- setNetworkEnabled(enabled = true)
-
- // Check and clear the downloads folder
- clearDownloadsFolder()
- }
-
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243844
@Test
fun verifyTheDownloadPromptsTest() {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt
index eabf00b6ef39..5909ebc9c7f6 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt
@@ -6,14 +6,10 @@ package org.mozilla.fenix.ui
import androidx.core.net.toUri
import androidx.test.espresso.Espresso.pressBack
-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.ext.settings
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.TestAssetHelper.getEnhancedTrackingProtectionAsset
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
@@ -22,6 +18,7 @@ import org.mozilla.fenix.helpers.TestHelper.exitMenu
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.restartApp
import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.enhancedTrackingProtection
import org.mozilla.fenix.ui.robots.homeScreen
@@ -40,9 +37,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
* - Verifying Enhanced Tracking Protection site exceptions
*/
-class EnhancedTrackingProtectionTest {
- private lateinit var mockWebServer: MockWebServer
-
+class EnhancedTrackingProtectionTest : TestSetup() {
@get:Rule
val activityTestRule = HomeActivityIntentTestRule(
isJumpBackInCFREnabled = false,
@@ -50,19 +45,6 @@ class EnhancedTrackingProtectionTest {
isWallpaperOnboardingEnabled = false,
)
- @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/416046
@Test
fun testETPSettingsItemsAndSubMenus() {
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 ae384d0632a6..151ee41aebaf 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
@@ -14,6 +14,7 @@ import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithCondition
import org.mozilla.fenix.helpers.DataGenerationHelper.getSponsoredFxSuggestPlaceHolder
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.TestHelper
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.navigationToolbar
/**
@@ -21,7 +22,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
*
*/
-class FirefoxSuggestTest {
+class FirefoxSuggestTest : TestSetup() {
@get:Rule
val activityTestRule = AndroidComposeTestRule(
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/GlobalPrivacyControlTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/GlobalPrivacyControlTest.kt
index 25a333b5099c..02e4cc224274 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/GlobalPrivacyControlTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/GlobalPrivacyControlTest.kt
@@ -4,15 +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.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.TestAssetHelper.TestAsset
import org.mozilla.fenix.helpers.TestAssetHelper.getGPCTestAsset
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
@@ -20,8 +18,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
* Tests for Global Privacy Control setting.
*/
-class GlobalPrivacyControlTest {
- private lateinit var mockWebServer: MockWebServer
+class GlobalPrivacyControlTest : TestSetup() {
private lateinit var gpcPage: TestAsset
@get:Rule
@@ -33,20 +30,11 @@ class GlobalPrivacyControlTest {
)
@Before
- fun setUp() {
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
-
+ override fun setUp() {
+ super.setUp()
gpcPage = getGPCTestAsset(mockWebServer)
}
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- }
-
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2429327
@Test
fun testGPCinNormalBrowsing() {
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 f29372c637e8..10ca3d150bf9 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
@@ -4,24 +4,14 @@
package org.mozilla.fenix.ui
-import android.content.Context
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
-import androidx.test.uiautomator.UiDevice
-import kotlinx.coroutines.runBlocking
-import mozilla.components.browser.storage.sync.PlacesHistoryStorage
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
import org.mozilla.fenix.customannotations.SmokeTest
-import org.mozilla.fenix.ext.settings
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MockBrowserDataHelper
@@ -29,7 +19,9 @@ 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.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.historyMenu
import org.mozilla.fenix.ui.robots.homeScreen
@@ -40,40 +32,13 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
* Tests for verifying basic functionality of history
*
*/
-class HistoryTest {
- private lateinit var mockWebServer: MockWebServer
- private lateinit var mDevice: UiDevice
-
+class HistoryTest : TestSetup() {
@get:Rule
val activityTestRule =
AndroidComposeTestRule(
- HomeActivityIntentTestRule.withDefaultSettingsOverrides(),
+ HomeActivityIntentTestRule(isJumpBackInCFREnabled = false),
) { it.activity }
- @Before
- fun setUp() {
- InstrumentationRegistry.getInstrumentation().targetContext.settings()
- .shouldShowJumpBackInCFR = false
-
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- // Clearing all history data after each test to avoid overlapping data
- val applicationContext: Context = activityTestRule.activity.applicationContext
- val historyStorage = PlacesHistoryStorage(applicationContext)
-
- runBlocking {
- historyStorage.deleteEverything()
- }
- }
-
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243285
@Test
fun verifyEmptyHistoryMenuTest() {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt
index 3f3ba4d3197d..f1cff8c78110 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt
@@ -5,19 +5,14 @@
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.HomeActivityTestRule
import org.mozilla.fenix.helpers.RetryTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestHelper
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
import org.mozilla.fenix.ui.robots.searchScreen
@@ -29,10 +24,7 @@ import org.mozilla.fenix.ui.robots.searchScreen
*
*/
-class HomeScreenTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
-
+class HomeScreenTest : TestSetup() {
@get:Rule(order = 0)
val activityTestRule =
AndroidComposeTestRule(HomeActivityTestRule.withDefaultSettingsOverrides()) { it.activity }
@@ -41,21 +33,6 @@ class HomeScreenTest {
@JvmField
val retryTestRule = RetryTestRule(3)
- @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/235396
@Test
fun homeScreenItemsTest() {
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 394c449eb557..e91723e27569 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
@@ -7,14 +7,11 @@ package org.mozilla.fenix.ui
import android.os.Build
import android.view.autofill.AutofillManager
import androidx.core.net.toUri
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
@@ -29,6 +26,7 @@ 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.helpers.TestSetup
import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.clearTextFieldItem
import org.mozilla.fenix.ui.robots.clickPageObject
@@ -42,20 +40,14 @@ import org.mozilla.fenix.ui.robots.setPageObjectText
* - save login prompts.
* - saving logins based on the user's preferences.
*/
-class LoginsTest {
- private lateinit var mockWebServer: MockWebServer
-
+class LoginsTest : TestSetup() {
@get:Rule
val activityTestRule =
HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
@Before
- fun setUp() {
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
-
+ override fun setUp() {
+ super.setUp()
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
val autofillManager: AutofillManager =
TestHelper.appContext.getSystemService(AutofillManager::class.java)
@@ -63,11 +55,6 @@ class LoginsTest {
}
}
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- }
-
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2092713
// Tests the Logins and passwords menu items and default values
@Test
From 33d831ae833bed8018343c5b6998086ad8a50634 Mon Sep 17 00:00:00 2001
From: "oana.horvath"
Date: Thu, 15 Feb 2024 11:55:22 +0200
Subject: [PATCH 346/586] Bug 1880497 - Create TestSetup helper: Test classes
M-N
---
.../java/org/mozilla/fenix/ui/MainMenuTest.kt | 27 ++-------------
.../mozilla/fenix/ui/MediaNotificationTest.kt | 34 ++-----------------
.../mozilla/fenix/ui/NavigationToolbarTest.kt | 29 ++--------------
.../org/mozilla/fenix/ui/NimbusEventTest.kt | 26 ++------------
.../fenix/ui/NimbusMessagingHomescreenTest.kt | 25 +++-----------
.../fenix/ui/NimbusMessagingMessageTest.kt | 11 +++---
.../ui/NimbusMessagingNotificationTest.kt | 12 +++----
.../fenix/ui/NimbusMessagingTriggerTest.kt | 11 +++---
.../fenix/ui/NoNetworkAccessStartupTests.kt | 10 ++----
9 files changed, 30 insertions(+), 155 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 24a877737846..7302bc9b0a64 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
@@ -5,17 +5,11 @@
package org.mozilla.fenix.ui
import androidx.core.net.toUri
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
import mozilla.components.concept.engine.utils.EngineReleaseChannel
-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.ext.components
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.AppAndSystemHelper.assertNativeAppOpens
import org.mozilla.fenix.helpers.AppAndSystemHelper.assertYoutubeAppOpens
import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithCondition
@@ -25,6 +19,8 @@ import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper
import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestHelper
+import org.mozilla.fenix.helpers.TestHelper.mDevice
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.clickContextMenuItem
import org.mozilla.fenix.ui.robots.clickPageObject
@@ -32,28 +28,11 @@ import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.longClickPageObject
import org.mozilla.fenix.ui.robots.navigationToolbar
-class MainMenuTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
-
+class MainMenuTest : TestSetup() {
@get:Rule
val activityTestRule =
HomeActivityIntentTestRule.withDefaultSettingsOverrides(translationsEnabled = true)
- @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/233849
@Test
fun verifyTabMainMenuItemsTest() {
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 eba6aad2e6c6..33304899c986 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
@@ -4,23 +4,17 @@
package org.mozilla.fenix.ui
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
-import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.mediasession.MediaSession
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
-import org.mozilla.fenix.ext.components
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.RetryTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
+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.clickPageObject
import org.mozilla.fenix.ui.robots.homeScreen
@@ -33,36 +27,14 @@ import org.mozilla.fenix.ui.robots.notificationShade
* - a media notification icon is displayed on the homescreen for the tab playing media content
* Note: this test only verifies media notifications, not media itself
*/
-class MediaNotificationTest {
- private lateinit var mockWebServer: MockWebServer
- private lateinit var mDevice: UiDevice
-
+class MediaNotificationTest : TestSetup() {
@get:Rule
val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides()
- private lateinit var browserStore: BrowserStore
@Rule
@JvmField
val retryTestRule = RetryTestRule(3)
- @Before
- fun setUp() {
- // Initializing this as part of class construction, below the rule would throw a NPE
- // So we are initializing this here instead of in all tests.
- browserStore = activityTestRule.activity.components.core.store
-
- 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/1347033
@SmokeTest
@Test
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt
index 13c8812c54b3..a486a4e6764a 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt
@@ -5,19 +5,14 @@
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.customannotations.SmokeTest
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
-import org.mozilla.fenix.helpers.AppAndSystemHelper
import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithSystemLocaleChanged
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
+import org.mozilla.fenix.helpers.TestHelper.mDevice
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
import java.util.Locale
@@ -32,28 +27,10 @@ import java.util.Locale
* - Find in page
*/
-class NavigationToolbarTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
-
+class NavigationToolbarTest : TestSetup() {
@get:Rule
val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides()
- @Before
- fun setUp() {
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- AppAndSystemHelper.resetSystemLocaleToEnUS()
- }
-
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/987326
// Swipes the nav bar left/right to switch between tabs
@SmokeTest
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusEventTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusEventTest.kt
index 0d63197d9ec6..943e0624c856 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusEventTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusEventTest.kt
@@ -5,28 +5,20 @@
package org.mozilla.fenix.ui
import android.content.Intent
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
import io.mockk.mockk
import mozilla.components.concept.sync.AuthType
import mozilla.components.service.fxa.FirefoxAccount
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
import org.junit.Assert.assertTrue
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.components.TelemetryAccountObserver
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.Experimentation
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RetryTestRule
import org.mozilla.fenix.helpers.TestHelper.appContext
+import org.mozilla.fenix.helpers.TestSetup
-class NimbusEventTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
-
+class NimbusEventTest : TestSetup() {
@get:Rule
val homeActivityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
.withIntent(
@@ -39,20 +31,6 @@ class NimbusEventTest {
@JvmField
val retryTestRule = RetryTestRule(3)
- @Before
- fun setUp() {
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- }
-
@Test
fun homeScreenNimbusEventsTest() {
Experimentation.withHelper {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt
index f71784acc59c..22f4dd412829 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt
@@ -5,22 +5,18 @@
package org.mozilla.fenix.ui
import android.content.Intent
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
import mozilla.components.service.nimbus.messaging.FxNimbusMessaging
import mozilla.components.service.nimbus.messaging.MessageData
import mozilla.components.service.nimbus.messaging.Messaging
import mozilla.components.service.nimbus.messaging.StyleData
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.experiments.nimbus.Res
import org.mozilla.fenix.FenixApplication
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RetryTestRule
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.nimbus.FxNimbus
import org.mozilla.fenix.nimbus.HomeScreenSection
import org.mozilla.fenix.nimbus.Homescreen
@@ -32,10 +28,7 @@ import org.mozilla.fenix.ui.robots.homeScreen
* Verifies a message can be displayed with all of the correct components
**/
-class NimbusMessagingHomescreenTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
-
+class NimbusMessagingHomescreenTest : TestSetup() {
private var messageButtonLabel = "CLICK ME"
private var messageText = "Some Nimbus Messaging text"
private var messageTitle = "A Nimbus title"
@@ -54,7 +47,8 @@ class NimbusMessagingHomescreenTest {
val retryTestRule = RetryTestRule(3)
@Before
- fun setUp() {
+ override fun setUp() {
+ super.setUp()
// Set up nimbus message
FxNimbusMessaging.features.messaging.withInitializer { _, _ ->
// FML generated objects.
@@ -95,22 +89,11 @@ class NimbusMessagingHomescreenTest {
),
)
}
-
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
// refresh message store
val application = (homeActivityTestRule.activity.application as FenixApplication)
application.restoreMessaging()
}
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- }
-
@Test
fun testNimbusMessageIsDisplayed() {
// Checks the home screen card message is displayed correctly
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt
index 4cbd0735c75d..0ca94358e857 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt
@@ -5,8 +5,6 @@
package org.mozilla.fenix.ui
import android.content.Context
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
import kotlinx.coroutines.test.runTest
import mozilla.components.service.nimbus.messaging.FxNimbusMessaging
import mozilla.components.service.nimbus.messaging.Messaging
@@ -20,6 +18,7 @@ import org.junit.Test
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.TestHelper
+import org.mozilla.fenix.helpers.TestSetup
/**
* This test is to test the integrity of messages hardcoded in the FML.
@@ -27,10 +26,8 @@ import org.mozilla.fenix.helpers.TestHelper
* It tests if the trigger expressions are valid, all the fields are complete
* and a simple check if they are localized (don't contain `_`).
*/
-class NimbusMessagingMessageTest {
+class NimbusMessagingMessageTest : TestSetup() {
private lateinit var feature: Messaging
- private lateinit var mDevice: UiDevice
-
private lateinit var context: Context
private val messaging
@@ -41,9 +38,9 @@ class NimbusMessagingMessageTest {
HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
@Before
- fun setUp() {
+ override fun setUp() {
+ super.setUp()
context = TestHelper.appContext
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
feature = FxNimbusMessaging.features.messaging.value()
}
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingNotificationTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingNotificationTest.kt
index 9f3762a21a0b..1348ff00715d 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingNotificationTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingNotificationTest.kt
@@ -6,10 +6,8 @@ package org.mozilla.fenix.ui
import android.content.Context
import android.os.Build
-import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import androidx.test.rule.GrantPermissionRule.grant
-import androidx.test.uiautomator.UiDevice
import mozilla.components.service.nimbus.messaging.FxNimbusMessaging
import org.json.JSONObject
import org.junit.Before
@@ -18,15 +16,15 @@ import org.junit.Test
import org.mozilla.experiments.nimbus.HardcodedNimbusFeatures
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.TestHelper
+import org.mozilla.fenix.helpers.TestHelper.mDevice
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.nimbus.FxNimbus
import org.mozilla.fenix.ui.robots.notificationShade
/**
* A UI test for testing the notification surface for Nimbus Messaging.
*/
-class NimbusMessagingNotificationTest {
- private lateinit var mDevice: UiDevice
-
+class NimbusMessagingNotificationTest : TestSetup() {
private lateinit var context: Context
private lateinit var hardcodedNimbus: HardcodedNimbusFeatures
@@ -43,9 +41,9 @@ class NimbusMessagingNotificationTest {
}
@Before
- fun setUp() {
+ override fun setUp() {
+ super.setUp()
context = TestHelper.appContext
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
}
@Test
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingTriggerTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingTriggerTest.kt
index e061d6845f64..31be3ec83ff2 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingTriggerTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingTriggerTest.kt
@@ -4,8 +4,6 @@
package org.mozilla.fenix.ui
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
import mozilla.components.service.nimbus.messaging.FxNimbusMessaging
import mozilla.components.service.nimbus.messaging.Messaging
import org.junit.Assert
@@ -17,6 +15,7 @@ import org.mozilla.experiments.nimbus.internal.NimbusException
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.TestHelper
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.messaging.CustomAttributeProvider
/**
@@ -26,9 +25,7 @@ import org.mozilla.fenix.messaging.CustomAttributeProvider
* - as much of the custom targeting and trigger attributes are recorded as possible.
* - we can run the Rust JEXL evaluator.
*/
-class NimbusMessagingTriggerTest {
- private lateinit var mDevice: UiDevice
-
+class NimbusMessagingTriggerTest : TestSetup() {
private lateinit var feature: Messaging
private lateinit var nimbus: NimbusInterface
@@ -36,8 +33,8 @@ class NimbusMessagingTriggerTest {
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
@Before
- fun setUp() {
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ override fun setUp() {
+ super.setUp()
nimbus = TestHelper.appContext.components.nimbus.sdk
feature = FxNimbusMessaging.features.messaging.value()
}
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NoNetworkAccessStartupTests.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NoNetworkAccessStartupTests.kt
index fd30ae0ad629..ce59c9e561bb 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NoNetworkAccessStartupTests.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NoNetworkAccessStartupTests.kt
@@ -5,7 +5,6 @@
package org.mozilla.fenix.ui
import androidx.core.net.toUri
-import org.junit.After
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
@@ -14,6 +13,7 @@ import org.mozilla.fenix.helpers.AppAndSystemHelper.setNetworkEnabled
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.TestHelper.packageName
import org.mozilla.fenix.helpers.TestHelper.verifyUrl
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
@@ -23,17 +23,11 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
*
*/
-class NoNetworkAccessStartupTests {
+class NoNetworkAccessStartupTests : TestSetup() {
@get:Rule
val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides(launchActivity = false)
- @After
- fun tearDown() {
- // Restoring network connection
- setNetworkEnabled(true)
- }
-
// Test running on beta/release builds in CI:
// caution when making changes to it, so they don't block the builds
// Based on STR from https://github.com/mozilla-mobile/fenix/issues/16886
From b420a74b4927186f142561e46227171e137f8269 Mon Sep 17 00:00:00 2001
From: "oana.horvath"
Date: Mon, 26 Feb 2024 14:51:25 +0200
Subject: [PATCH 347/586] Bug 1880796 - Create TestSetup helper: Test classes
O-R
---
.../org/mozilla/fenix/ui/OnboardingTest.kt | 3 +-
.../org/mozilla/fenix/ui/PDFViewerTest.kt | 29 ++-----------------
.../java/org/mozilla/fenix/ui/PocketTest.kt | 11 +++----
.../java/org/mozilla/fenix/ui/PwaTest.kt | 3 +-
.../org/mozilla/fenix/ui/ReaderViewTest.kt | 26 ++---------------
.../fenix/ui/RecentlyClosedTabsTest.kt | 29 +++----------------
.../java/org/mozilla/fenix/ui/SearchTest.kt | 10 +++----
7 files changed, 22 insertions(+), 89 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/OnboardingTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/OnboardingTest.kt
index 9913b7769ac0..6b305496e468 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/OnboardingTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/OnboardingTest.kt
@@ -6,9 +6,10 @@ import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithLauncherIntent
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.homeScreen
-class OnboardingTest {
+class OnboardingTest : TestSetup() {
@get:Rule
val activityTestRule =
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 340cbd08ef4d..913d1c7d28b7 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
@@ -5,17 +5,10 @@
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.customannotations.SmokeTest
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.AppAndSystemHelper.assertExternalAppOpens
-import org.mozilla.fenix.helpers.AppAndSystemHelper.clearDownloadsFolder
import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_DOCS
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper
@@ -23,12 +16,11 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
-import org.mozilla.fenix.helpers.TestHelper.mDevice
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.navigationToolbar
-class PDFViewerTest {
- private lateinit var mockWebServer: MockWebServer
+class PDFViewerTest : TestSetup() {
private val downloadTestPage =
"https://storage.googleapis.com/mobile_test_assets/test_app/downloads.html"
private val pdfFileName = "washington.pdf"
@@ -38,23 +30,6 @@ class PDFViewerTest {
@get:Rule
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
- @Before
- fun setUp() {
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
-
- // Check and clear the downloads folder
- clearDownloadsFolder()
- }
-
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2048140
@SmokeTest
@Test
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt
index 885fa80c0e21..674924c9549f 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt
@@ -1,22 +1,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 org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.helpers.Constants
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.RetryTestRule
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.homeScreen
/**
* Tests for verifying the presence of the Pocket section and its elements
*/
-class PocketTest {
- private lateinit var mDevice: UiDevice
+class PocketTest : TestSetup() {
private lateinit var firstPocketStoryPublisher: String
@get:Rule(order = 0)
@@ -28,9 +26,8 @@ class PocketTest {
val retryTestRule = RetryTestRule(3)
@Before
- fun setUp() {
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
-
+ override fun setUp() {
+ super.setUp()
// Workaround to make sure the Pocket articles are populated before starting the tests.
homeScreen {
}.openThreeDotMenu {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt
index 4ccfa4a976f8..6ce798c2fee1 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt
@@ -11,12 +11,13 @@ import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.TestHelper.mDevice
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.customTabScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
import org.mozilla.fenix.ui.robots.pwaScreen
-class PwaTest {
+class PwaTest : TestSetup() {
/* Updated externalLinks.html to v2.0,
changed the hypertext reference to mozilla-mobile.github.io/testapp/downloads for "External link"
*/
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt
index aa2215fddb1d..8e138aa8be24 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt
@@ -5,20 +5,16 @@
package org.mozilla.fenix.ui
import android.view.View
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
import org.mozilla.fenix.customannotations.SmokeTest
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RetryTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
+import org.mozilla.fenix.helpers.TestHelper.mDevice
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource
import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
@@ -32,9 +28,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
*
*/
-class ReaderViewTest {
- private lateinit var mockWebServer: MockWebServer
- private lateinit var mDevice: UiDevice
+class ReaderViewTest : TestSetup() {
private val estimatedReadingTime = "1 - 2 minutes"
@get:Rule
@@ -44,20 +38,6 @@ class ReaderViewTest {
@JvmField
val retryTestRule = RetryTestRule(3)
- @Before
- fun setUp() {
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- }
-
/**
* Verify that Reader View capable pages
*
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/RecentlyClosedTabsTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/RecentlyClosedTabsTest.kt
index ca4084655bc4..044696b36c99 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/RecentlyClosedTabsTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/RecentlyClosedTabsTest.kt
@@ -6,21 +6,17 @@ package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
-import androidx.test.espresso.intent.Intents
-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.registerAndCleanupIdlingResources
-import org.mozilla.fenix.helpers.HomeActivityTestRule
+import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem
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.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
@@ -29,31 +25,14 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
* Tests for verifying basic functionality of recently closed tabs history
*
*/
-class RecentlyClosedTabsTest {
- private lateinit var mockWebServer: MockWebServer
-
+class RecentlyClosedTabsTest : TestSetup() {
@get:Rule
val activityTestRule = AndroidComposeTestRule(
- HomeActivityTestRule.withDefaultSettingsOverrides(
+ HomeActivityIntentTestRule.withDefaultSettingsOverrides(
tabsTrayRewriteEnabled = true,
),
) { it.activity }
- @Before
- fun setUp() {
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
-
- Intents.init()
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- }
-
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1065414
// Verifies that a recently closed item is properly opened
@SmokeTest
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 d1d0076cd16f..ede7b06b5dc5 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
@@ -21,7 +21,6 @@ import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
-import org.mozilla.fenix.helpers.AppAndSystemHelper
import org.mozilla.fenix.helpers.AppAndSystemHelper.assertNativeAppOpens
import org.mozilla.fenix.helpers.AppAndSystemHelper.denyPermission
import org.mozilla.fenix.helpers.AppAndSystemHelper.grantSystemPermission
@@ -45,6 +44,7 @@ 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.helpers.TestSetup
import org.mozilla.fenix.ui.robots.clickContextMenuItem
import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.homeScreen
@@ -64,7 +64,7 @@ import java.util.Locale
*
*/
-class SearchTest {
+class SearchTest : TestSetup() {
private lateinit var searchMockServer: MockWebServer
private var queryString = "firefox"
private val generalEnginesList = listOf("DuckDuckGo", "Google", "Bing")
@@ -84,7 +84,8 @@ class SearchTest {
) { it.activity }
@Before
- fun setUp() {
+ override fun setUp() {
+ super.setUp()
searchMockServer = MockWebServer().apply {
dispatcher = SearchDispatcher()
start()
@@ -92,9 +93,8 @@ class SearchTest {
}
@After
- fun tearDown() {
+ override fun tearDown() {
searchMockServer.shutdown()
- AppAndSystemHelper.resetSystemLocaleToEnUS()
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2154189
From 51ee7db86d94b1dd216cc948d1d01807732deeec Mon Sep 17 00:00:00 2001
From: "oana.horvath"
Date: Mon, 26 Feb 2024 16:51:30 +0200
Subject: [PATCH 348/586] Bug 1880797 - Create TestSetup helper: Settings Test
classes
---
.../org/mozilla/fenix/ui/SettingsAboutTest.kt | 26 ++---------------
.../mozilla/fenix/ui/SettingsAddonsTest.kt | 22 ++-------------
.../mozilla/fenix/ui/SettingsAdvancedTest.kt | 27 ++----------------
.../mozilla/fenix/ui/SettingsCustomizeTest.kt | 22 ++-------------
.../SettingsDeleteBrowsingDataOnQuitTest.kt | 26 ++---------------
.../ui/SettingsDeleteBrowsingDataTest.kt | 22 ++-------------
.../mozilla/fenix/ui/SettingsGeneralTest.kt | 24 ++--------------
.../fenix/ui/SettingsHTTPSOnlyModeTest.kt | 3 +-
.../mozilla/fenix/ui/SettingsHomepageTest.kt | 22 ++-------------
.../mozilla/fenix/ui/SettingsPrivacyTest.kt | 27 ++----------------
.../fenix/ui/SettingsPrivateBrowsingTest.kt | 21 ++------------
.../mozilla/fenix/ui/SettingsSearchTest.kt | 20 +++++--------
.../fenix/ui/SettingsSitePermissionsTest.kt | 28 ++-----------------
13 files changed, 33 insertions(+), 257 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt
index bd2debace0d0..3e37fb5e3b3a 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt
@@ -4,18 +4,13 @@
package org.mozilla.fenix.ui
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiSelector
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RetryTestRule
import org.mozilla.fenix.helpers.TestHelper.mDevice
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.clickRateButtonGooglePlay
import org.mozilla.fenix.ui.robots.homeScreen
@@ -24,10 +19,7 @@ import org.mozilla.fenix.ui.robots.homeScreen
*
*/
-class SettingsAboutTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
-
+class SettingsAboutTest : TestSetup() {
@get:Rule
val activityIntentTestRule = HomeActivityIntentTestRule()
@@ -35,20 +27,6 @@ class SettingsAboutTest {
@JvmField
val retryTestRule = RetryTestRule(3)
- @Before
- fun setUp() {
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- }
-
// Walks through the About settings menu to ensure all items are present
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2092700
@Test
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt
index 62923e2c0347..695d0af3c013 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt
@@ -4,15 +4,11 @@
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.R
import org.mozilla.fenix.customannotations.SmokeTest
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.RecyclerViewIdlingResource
@@ -20,6 +16,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper.getEnhancedTrackingProtectionAs
import org.mozilla.fenix.helpers.TestHelper
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
import org.mozilla.fenix.helpers.TestHelper.waitUntilSnackbarGone
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.addonsMenu
import org.mozilla.fenix.ui.robots.homeScreen
@@ -27,25 +24,10 @@ import org.mozilla.fenix.ui.robots.homeScreen
* Tests for verifying the functionality of installing or removing addons
*
*/
-class SettingsAddonsTest {
- private lateinit var mockWebServer: MockWebServer
-
+class SettingsAddonsTest : TestSetup() {
@get:Rule
val activityTestRule = 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/875780
// Walks through settings add-ons menu to ensure all items are present
@Test
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 86b0b1752314..da889b435f05 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
@@ -5,16 +5,10 @@
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.customannotations.SmokeTest
import org.mozilla.fenix.ext.settings
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.AppAndSystemHelper.assertYoutubeAppOpens
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
@@ -22,6 +16,8 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText
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.mDevice
+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
@@ -31,31 +27,14 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
*
*/
-class SettingsAdvancedTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
+class SettingsAdvancedTest : TestSetup() {
private val youTubeSchemaLink = itemContainingText("Youtube schema link")
- private val youTubeFullLink = itemContainingText("Youtube full link")
private val playStoreLink = itemContainingText("Playstore link")
private val playStoreUrl = "play.google.com"
@get:Rule
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
- @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/2092699
// Walks through settings menu and sub-menus to ensure all items are present
@Test
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt
index 78b0b4af83e2..f20ff14182e2 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt
@@ -5,39 +5,21 @@
package org.mozilla.fenix.ui
import android.content.res.Configuration
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestHelper.exitMenu
import org.mozilla.fenix.helpers.TestHelper.verifyDarkThemeApplied
import org.mozilla.fenix.helpers.TestHelper.verifyLightThemeApplied
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
-class SettingsCustomizeTest {
- private lateinit var mockWebServer: MockWebServer
-
+class SettingsCustomizeTest : TestSetup() {
@get:Rule
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
- @Before
- fun setUp() {
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- }
-
private fun getUiTheme(): Boolean {
val mode =
activityIntentTestRule.activity.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataOnQuitTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataOnQuitTest.kt
index 40a26ac53171..cae712884c4f 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataOnQuitTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataOnQuitTest.kt
@@ -8,15 +8,10 @@ import android.Manifest
import androidx.core.net.toUri
import androidx.test.espresso.Espresso.pressBack
import androidx.test.rule.GrantPermissionRule
-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
import org.mozilla.fenix.helpers.AppAndSystemHelper.setNetworkEnabled
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
@@ -26,6 +21,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper.getStorageTestAsset
import org.mozilla.fenix.helpers.TestHelper.exitMenu
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.restartApp
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.clickPageObject
import org.mozilla.fenix.ui.robots.downloadRobot
import org.mozilla.fenix.ui.robots.homeScreen
@@ -36,9 +32,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
* Delete Browsing Data on quit
*
*/
-class SettingsDeleteBrowsingDataOnQuitTest {
- private lateinit var mockWebServer: MockWebServer
-
+class SettingsDeleteBrowsingDataOnQuitTest : TestSetup() {
@get:Rule
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
@@ -48,22 +42,6 @@ class SettingsDeleteBrowsingDataOnQuitTest {
Manifest.permission.RECORD_AUDIO,
)
- @Before
- fun setUp() {
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
-
- // Check and clear the downloads folder
- AppAndSystemHelper.clearDownloadsFolder()
- }
-
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/416048
@Test
fun deleteBrowsingDataOnQuitSettingTest() {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataTest.kt
index 14fd12d11fce..a2dcf12695a9 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataTest.kt
@@ -4,15 +4,11 @@
package org.mozilla.fenix.ui
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
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.HomeActivityIntentTestRule
@@ -22,6 +18,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper.getStorageTestAsset
import org.mozilla.fenix.helpers.TestHelper.exitMenu
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.restartApp
+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.homeScreen
@@ -33,25 +30,10 @@ import org.mozilla.fenix.ui.robots.settingsScreen
* Delete Browsing Data
*/
-class SettingsDeleteBrowsingDataTest {
- private lateinit var mockWebServer: MockWebServer
-
+class SettingsDeleteBrowsingDataTest : TestSetup() {
@get:Rule
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
- @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/937561
@Test
fun deleteBrowsingDataOptionStatesTest() {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsGeneralTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsGeneralTest.kt
index d2292b31cb76..5736fa14c12a 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsGeneralTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsGeneralTest.kt
@@ -4,17 +4,12 @@
package org.mozilla.fenix.ui
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.FenixApplication
import org.mozilla.fenix.R
import org.mozilla.fenix.customannotations.SmokeTest
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
-import org.mozilla.fenix.helpers.AppAndSystemHelper
import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources
import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithSystemLocaleChanged
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
@@ -23,6 +18,7 @@ import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
import org.mozilla.fenix.helpers.TestAssetHelper.getLoremIpsumAsset
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong
import org.mozilla.fenix.helpers.TestHelper.mDevice
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.checkTextSizeOnWebsite
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.util.FRENCH_LANGUAGE_HEADER
@@ -35,26 +31,10 @@ import java.util.Locale
* Tests for verifying the General section of the Settings menu
*
*/
-class SettingsGeneralTest {
- private lateinit var mockWebServer: MockWebServer
-
+class SettingsGeneralTest : TestSetup() {
@get:Rule
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
- @Before
- fun setUp() {
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- AppAndSystemHelper.resetSystemLocaleToEnUS()
- }
-
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2092697
@Test
fun verifyGeneralSettingsItemsTest() {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHTTPSOnlyModeTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHTTPSOnlyModeTest.kt
index f8c1bccbba17..9636810e3b20 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHTTPSOnlyModeTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHTTPSOnlyModeTest.kt
@@ -11,11 +11,12 @@ import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.TestHelper.exitMenu
+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 SettingsHTTPSOnlyModeTest {
+class SettingsHTTPSOnlyModeTest : TestSetup() {
private val httpPageUrl = "http://example.com/"
private val httpsPageUrl = "https://example.com/"
private val insecureHttpPage = "http.badssl.com"
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 bc4a78a9fbea..8dc31c64e82f 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
@@ -4,14 +4,10 @@
package org.mozilla.fenix.ui
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.AppAndSystemHelper.openAppFromExternalLink
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RetryTestRule
@@ -19,6 +15,7 @@ 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.helpers.TestSetup
import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
@@ -27,9 +24,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
* Tests for verifying the Homepage settings menu
*
*/
-class SettingsHomepageTest {
- private lateinit var mockWebServer: MockWebServer
-
+class SettingsHomepageTest : TestSetup() {
@get:Rule
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
@@ -37,19 +32,6 @@ class SettingsHomepageTest {
@JvmField
val retryTestRule = RetryTestRule(3)
- @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/1564843
@Test
fun verifyHomepageSettingsTest() {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt
index bbfe7cb91968..93084fb3eaae 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt
@@ -4,16 +4,12 @@
package org.mozilla.fenix.ui
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.UiDevice
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
+import org.mozilla.fenix.helpers.TestHelper.mDevice
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
import org.mozilla.fenix.ui.robots.notificationShade
@@ -23,27 +19,10 @@ import org.mozilla.fenix.ui.robots.notificationShade
*
*/
-class SettingsPrivacyTest {
- private lateinit var mDevice: UiDevice
- private lateinit var mockWebServer: MockWebServer
-
+class SettingsPrivacyTest : TestSetup() {
@get:Rule
val activityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
- @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/2092698
@Test
fun settingsPrivacyItemsTest() {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivateBrowsingTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivateBrowsingTest.kt
index bf52c2748e1a..033addb4c69c 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivateBrowsingTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivateBrowsingTest.kt
@@ -4,43 +4,26 @@
package org.mozilla.fenix.ui
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.AppAndSystemHelper.openAppFromExternalLink
import org.mozilla.fenix.helpers.DataGenerationHelper.generateRandomString
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.restartApp
+import org.mozilla.fenix.helpers.TestSetup
import org.mozilla.fenix.ui.robots.addToHomeScreen
import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
-class SettingsPrivateBrowsingTest {
- private lateinit var mockWebServer: MockWebServer
+class SettingsPrivateBrowsingTest : TestSetup() {
private val pageShortcutName = generateRandomString(5)
@get:Rule
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
- @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/555822
@Test
fun verifyPrivateBrowsingMenuItemsTest() {
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt
index f9aab824ff9c..c6ae4df21cb1 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt
@@ -13,8 +13,6 @@ import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
-import org.mozilla.fenix.helpers.AppAndSystemHelper.resetSystemLocaleToEnUS
import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithSystemLocaleChanged
import org.mozilla.fenix.helpers.AppAndSystemHelper.setSystemLocale
import org.mozilla.fenix.helpers.DataGenerationHelper.setTextToClipBoard
@@ -28,14 +26,14 @@ import org.mozilla.fenix.helpers.TestHelper.appContext
import org.mozilla.fenix.helpers.TestHelper.exitMenu
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.EngineShortcut
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
import org.mozilla.fenix.ui.robots.searchScreen
import java.util.Locale
-class SettingsSearchTest {
- private lateinit var mockWebServer: MockWebServer
+class SettingsSearchTest : TestSetup() {
private lateinit var searchMockServer: MockWebServer
private val defaultSearchEngineList =
listOf(
@@ -50,12 +48,8 @@ class SettingsSearchTest {
) { it.activity }
@Before
- fun setUp() {
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
-
+ override fun setUp() {
+ super.setUp()
searchMockServer = MockWebServer().apply {
dispatcher = SearchDispatcher()
start()
@@ -63,9 +57,9 @@ class SettingsSearchTest {
}
@After
- fun tearDown() {
- mockWebServer.shutdown()
- resetSystemLocaleToEnUS()
+ override fun tearDown() {
+ super.tearDown()
+ searchMockServer.shutdown()
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2203333
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt
index 3f6b5792938f..4b3842fc6ac6 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt
@@ -7,17 +7,11 @@ package org.mozilla.fenix.ui
import androidx.core.net.toUri
import androidx.test.espresso.Espresso.pressBack
import androidx.test.filters.SdkSuppress
-import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.mediasession.MediaSession
-import okhttp3.mockwebserver.MockWebServer
-import org.junit.After
-import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
-import org.mozilla.fenix.ext.components
-import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.AppAndSystemHelper.grantSystemPermission
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
@@ -25,6 +19,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
import org.mozilla.fenix.helpers.TestAssetHelper.getMutedVideoPageAsset
import org.mozilla.fenix.helpers.TestAssetHelper.getVideoPageAsset
import org.mozilla.fenix.helpers.TestHelper.exitMenu
+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.homeScreen
@@ -36,13 +31,11 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
* - the settings effects on the app behavior
*
*/
-class SettingsSitePermissionsTest {
+class SettingsSitePermissionsTest : TestSetup() {
/* Test page created and handled by the Mozilla mobile test-eng team */
private val permissionsTestPage = "https://mozilla-mobile.github.io/testapp/v2.0/permissions"
private val permissionsTestPageHost = "https://mozilla-mobile.github.io"
private val testPageSubstring = "https://mozilla-mobile.github.io:443"
- private lateinit var mockWebServer: MockWebServer
- private lateinit var browserStore: BrowserStore
@get:Rule
val activityTestRule = HomeActivityTestRule(
@@ -52,23 +45,6 @@ class SettingsSitePermissionsTest {
isDeleteSitePermissionsEnabled = true,
)
- @Before
- fun setUp() {
- // Initializing this as part of class construction, below the rule would throw a NPE
- // So we are initializing this here instead of in all tests.
- browserStore = activityTestRule.activity.components.core.store
-
- mockWebServer = MockWebServer().apply {
- dispatcher = AndroidAssetDispatcher()
- start()
- }
- }
-
- @After
- fun tearDown() {
- mockWebServer.shutdown()
- }
-
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/246974
@Test
fun sitePermissionsItemsTest() {
From bc9140ac826434f40db54e414c6ce3adb93043cf Mon Sep 17 00:00:00 2001
From: Ryan VanderMeulen
Date: Fri, 23 Feb 2024 14:18:38 -0500
Subject: [PATCH 349/586] Bug 1882134 - Use jvmToolchain for setting target JVM
version
---
android-components/.config.yml | 1 +
android-components/build.gradle | 10 ++++------
.../components/tooling/detekt/build.gradle | 3 ---
.../components/tooling/lint/build.gradle | 7 -------
fenix/app/build.gradle | 5 -----
fenix/benchmark/build.gradle | 9 ---------
fenix/build.gradle | 10 ++--------
fenix/mozilla-lint-rules/build.gradle | 3 ---
focus-android/app/build.gradle | 7 -------
focus-android/build.gradle | 9 ++-------
shared-settings.gradle | 4 ++++
11 files changed, 13 insertions(+), 55 deletions(-)
diff --git a/android-components/.config.yml b/android-components/.config.yml
index c199639cbe04..045cdf97402f 100644
--- a/android-components/.config.yml
+++ b/android-components/.config.yml
@@ -2,6 +2,7 @@
componentsGroupId: "org.mozilla.components"
# Synchronized build configuration for all modules
+jvmTargetCompatibility: 17
compileSdkVersion: 34
minSdkVersion: 21
targetSdkVersion: 34
diff --git a/android-components/build.gradle b/android-components/build.gradle
index 60ddf96706de..51f45bcbaba8 100644
--- a/android-components/build.gradle
+++ b/android-components/build.gradle
@@ -202,6 +202,10 @@ subprojects {
lintChecks project(':tooling-lint')
}
+ kotlin {
+ jvmToolchain(config.jvmTargetCompatibility)
+ }
+
android {
testOptions {
unitTests {
@@ -224,13 +228,7 @@ subprojects {
ignoreAssetsPattern "manifest.template.json"
}
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_17
- targetCompatibility JavaVersion.VERSION_17
- }
-
tasks.withType(KotlinCompile).configureEach {
- kotlinOptions.jvmTarget = "17"
kotlinOptions.freeCompilerArgs += ["-opt-in=kotlin.RequiresOptIn"]
}
}
diff --git a/android-components/components/tooling/detekt/build.gradle b/android-components/components/tooling/detekt/build.gradle
index 670da1319844..ad0c3eb038d1 100644
--- a/android-components/components/tooling/detekt/build.gradle
+++ b/android-components/components/tooling/detekt/build.gradle
@@ -5,9 +5,6 @@
apply plugin: 'java-library'
apply plugin: 'kotlin'
-targetCompatibility = JavaVersion.VERSION_17
-sourceCompatibility = JavaVersion.VERSION_17
-
dependencies {
implementation ComponentsDependencies.tools_detekt_api
diff --git a/android-components/components/tooling/lint/build.gradle b/android-components/components/tooling/lint/build.gradle
index 185189c8a5c3..adee887580e4 100644
--- a/android-components/components/tooling/lint/build.gradle
+++ b/android-components/components/tooling/lint/build.gradle
@@ -7,9 +7,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
apply plugin: 'java-library'
apply plugin: 'kotlin'
-targetCompatibility = JavaVersion.VERSION_17
-sourceCompatibility = JavaVersion.VERSION_17
-
dependencies {
compileOnly ComponentsDependencies.tools_lintapi
compileOnly ComponentsDependencies.tools_lintchecks
@@ -43,7 +40,3 @@ tasks.register("assembleAndroidTest") {
// behaves like our others and we do not need to special case it in automation.
}
}
-
-tasks.withType(KotlinCompile).configureEach {
- kotlinOptions.jvmTarget = "17"
-}
diff --git a/fenix/app/build.gradle b/fenix/app/build.gradle
index 44a84cfffce6..ea48e5ac4ae9 100644
--- a/fenix/app/build.gradle
+++ b/fenix/app/build.gradle
@@ -219,11 +219,6 @@ android {
}
}
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_17
- targetCompatibility JavaVersion.VERSION_17
- }
-
bundle {
// Profiler issues require us to temporarily package native code compressed to
// match the previous APK packaging.
diff --git a/fenix/benchmark/build.gradle b/fenix/benchmark/build.gradle
index 20825ec4ea25..8f13686ff459 100644
--- a/fenix/benchmark/build.gradle
+++ b/fenix/benchmark/build.gradle
@@ -13,15 +13,6 @@ android {
namespace 'org.mozilla.fenix.benchmark'
compileSdk config.compileSdkVersion
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_17
- targetCompatibility = JavaVersion.VERSION_17
- }
-
- kotlinOptions {
- jvmTarget = "17"
- }
-
defaultConfig {
minSdk 23
targetSdk config.targetSdkVersion
diff --git a/fenix/build.gradle b/fenix/build.gradle
index bd002d017909..53718ef05a7a 100644
--- a/fenix/build.gradle
+++ b/fenix/build.gradle
@@ -170,7 +170,6 @@ allprojects {
}
tasks.withType(KotlinCompile).configureEach {
- kotlinOptions.jvmTarget = "17"
kotlinOptions.allWarningsAsErrors = true
kotlinOptions.freeCompilerArgs += [
"-opt-in=kotlin.RequiresOptIn", "-Xjvm-default=all-compatibility"
@@ -180,13 +179,8 @@ allprojects {
subprojects {
afterEvaluate {
- if (it.hasProperty('android')) {
- android {
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_17
- targetCompatibility JavaVersion.VERSION_17
- }
- }
+ kotlin {
+ jvmToolchain(config.jvmTargetCompatibility)
}
}
}
diff --git a/fenix/mozilla-lint-rules/build.gradle b/fenix/mozilla-lint-rules/build.gradle
index 00fcdb7d3a86..70c330727d24 100644
--- a/fenix/mozilla-lint-rules/build.gradle
+++ b/fenix/mozilla-lint-rules/build.gradle
@@ -5,9 +5,6 @@
apply plugin: 'java-library'
apply plugin: 'kotlin'
-targetCompatibility = JavaVersion.VERSION_17
-sourceCompatibility = JavaVersion.VERSION_17
-
repositories {
if (project.hasProperty("centralRepo")) {
maven {
diff --git a/focus-android/app/build.gradle b/focus-android/app/build.gradle
index 5c6909f12b55..9e9fec6fbfe4 100644
--- a/focus-android/app/build.gradle
+++ b/focus-android/app/build.gradle
@@ -37,11 +37,6 @@ android {
vectorDrawables.useSupportLibrary = true
}
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_17
- targetCompatibility JavaVersion.VERSION_17
- }
-
lint {
lintConfig file("lint.xml")
}
@@ -167,7 +162,6 @@ android {
}
}
-
namespace 'org.mozilla.focus'
}
@@ -178,7 +172,6 @@ tasks.withType(KotlinCompile).configureEach {
"-opt-in=kotlin.RequiresOptIn",
"-Xjvm-default=all"
]
- kotlinOptions.jvmTarget = '17'
}
// -------------------------------------------------------------------------------------------------
diff --git a/focus-android/build.gradle b/focus-android/build.gradle
index ee4d63d40b67..88013a477f7b 100644
--- a/focus-android/build.gradle
+++ b/focus-android/build.gradle
@@ -108,13 +108,8 @@ allprojects {
subprojects {
afterEvaluate {
- if (it.hasProperty('android')) {
- android {
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_17
- targetCompatibility JavaVersion.VERSION_17
- }
- }
+ kotlin {
+ jvmToolchain(config.jvmTargetCompatibility)
}
}
}
diff --git a/shared-settings.gradle b/shared-settings.gradle
index 268b208e375f..9aa8d460b944 100644
--- a/shared-settings.gradle
+++ b/shared-settings.gradle
@@ -21,6 +21,7 @@ class Config {
public final String componentsVersion
public final String componentsGroupId
+ public final Integer jvmTargetCompatibility
public final Integer compileSdkVersion
public final Integer minSdkVersion
public final Integer targetSdkVersion
@@ -28,12 +29,14 @@ class Config {
Config(
String componentsVersion,
String componentsGroupId,
+ Integer jvmTargetCompatibility,
Integer compileSdkVersion,
Integer minSdkVersion,
Integer targetSdkVersion
) {
this.componentsVersion = componentsVersion
this.componentsGroupId = componentsGroupId
+ this.jvmTargetCompatibility = jvmTargetCompatibility
this.compileSdkVersion = compileSdkVersion
this.minSdkVersion = minSdkVersion
this.targetSdkVersion = targetSdkVersion
@@ -102,6 +105,7 @@ gradle.projectsLoaded { ->
gradle.rootProject.ext.config = new Config(
version,
configData.componentsGroupId,
+ configData.jvmTargetCompatibility,
configData.compileSdkVersion,
configData.minSdkVersion,
configData.targetSdkVersion
From f71fffe35300fec48f93e74c084f94ff20bf182e Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Tue, 27 Feb 2024 12:59:23 +0200
Subject: [PATCH 350/586] Bug 1882264 - Convert private variables to functions
so they don't get initialised
---
.../SettingsSubMenuOpenLinksInAppsRobot.kt | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuOpenLinksInAppsRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuOpenLinksInAppsRobot.kt
index e1ce8d7a453d..f10d5db946a1 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuOpenLinksInAppsRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuOpenLinksInAppsRobot.kt
@@ -25,7 +25,7 @@ class SettingsSubMenuOpenLinksInAppsRobot {
fun verifyOpenLinksInAppsView(selectedOpenLinkInAppsOption: String) {
assertUIObjectExists(
- goBackButton,
+ goBackButton(),
itemContainingText(getStringResource(R.string.preferences_open_links_in_apps)),
itemContainingText(getStringResource(R.string.preferences_open_links_in_apps_always)),
itemContainingText(getStringResource(R.string.preferences_open_links_in_apps_ask)),
@@ -36,7 +36,7 @@ class SettingsSubMenuOpenLinksInAppsRobot {
fun verifyPrivateOpenLinksInAppsView(selectedOpenLinkInAppsOption: String) {
assertUIObjectExists(
- goBackButton,
+ goBackButton(),
itemContainingText(getStringResource(R.string.preferences_open_links_in_apps)),
itemContainingText(getStringResource(R.string.preferences_open_links_in_apps_ask)),
itemContainingText(getStringResource(R.string.preferences_open_links_in_apps_never)),
@@ -54,26 +54,26 @@ class SettingsSubMenuOpenLinksInAppsRobot {
fun clickOpenLinkInAppOption(openLinkInAppsOption: String) {
when (openLinkInAppsOption) {
- "Always" -> alwaysOption.click()
- "Ask before opening" -> askBeforeOpeningOption.click()
- "Never" -> neverOption.click()
+ "Always" -> alwaysOption().click()
+ "Ask before opening" -> askBeforeOpeningOption().click()
+ "Never" -> neverOption().click()
}
}
class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
mDevice.waitForIdle()
- goBackButton.click()
+ goBackButton().click()
SettingsRobot().interact()
return SettingsRobot.Transition()
}
}
}
-private val goBackButton = itemWithDescription("Navigate up")
-private val alwaysOption =
+private fun goBackButton() = itemWithDescription("Navigate up")
+private fun alwaysOption() =
itemContainingText(getStringResource(R.string.preferences_open_links_in_apps_always))
-private val askBeforeOpeningOption =
+private fun askBeforeOpeningOption() =
itemContainingText(getStringResource(R.string.preferences_open_links_in_apps_ask))
-private val neverOption =
+private fun neverOption() =
itemContainingText(getStringResource(R.string.preferences_open_links_in_apps_never))
From 1c1eb3400bbe2f13ba8daf739d3c0c651c887bba Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Tue, 27 Feb 2024 13:09:43 +0200
Subject: [PATCH 351/586] Bug 1882264 - Add logs to
SettingsSubMenuOpenLinksInAppsRobot
---
.../robots/SettingsSubMenuOpenLinksInAppsRobot.kt | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuOpenLinksInAppsRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuOpenLinksInAppsRobot.kt
index f10d5db946a1..1ee72b2cd741 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuOpenLinksInAppsRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuOpenLinksInAppsRobot.kt
@@ -4,6 +4,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.ViewMatchers.hasSibling
@@ -11,6 +12,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import org.hamcrest.CoreMatchers.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
@@ -44,26 +46,35 @@ class SettingsSubMenuOpenLinksInAppsRobot {
verifySelectedOpenLinksInAppOption(selectedOpenLinkInAppsOption)
}
- fun verifySelectedOpenLinksInAppOption(openLinkInAppsOption: String) =
+ fun verifySelectedOpenLinksInAppOption(openLinkInAppsOption: String) {
+ Log.i(TAG, "verifySelectedOpenLinksInAppOption: Trying to verify that the $openLinkInAppsOption option is checked")
onView(
allOf(
withId(R.id.radio_button),
hasSibling(withText(openLinkInAppsOption)),
),
).check(matches(isChecked(true)))
+ Log.i(TAG, "verifySelectedOpenLinksInAppOption: Verified that the $openLinkInAppsOption option is checked")
+ }
fun clickOpenLinkInAppOption(openLinkInAppsOption: String) {
+ Log.i(TAG, "clickOpenLinkInAppOption: Trying to click the $openLinkInAppsOption option")
when (openLinkInAppsOption) {
"Always" -> alwaysOption().click()
"Ask before opening" -> askBeforeOpeningOption().click()
"Never" -> neverOption().click()
}
+ Log.i(TAG, "clickOpenLinkInAppOption: Clicked the $openLinkInAppsOption option")
}
class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
+ Log.i(TAG, "goBack: Waiting for device to be idle")
mDevice.waitForIdle()
+ Log.i(TAG, "goBack: Waited for device to be idle")
+ Log.i(TAG, "goBack: Trying to click the navigate up button")
goBackButton().click()
+ Log.i(TAG, "goBack: Clicked the navigate up button")
SettingsRobot().interact()
return SettingsRobot.Transition()
From 52f1ecfb22b6b678f4b79d76d7df346462732064 Mon Sep 17 00:00:00 2001
From: MickeyMoz
Date: Tue, 27 Feb 2024 13:52:39 +0000
Subject: [PATCH 352/586] Update GeckoView (Nightly) to 125.0.20240227095754.
---
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 aaaf212789d5..9ed2103c6c1e 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 = "125.0.20240226165659"
+ const val version = "125.0.20240227095754"
/**
* GeckoView channel
From 18f4757cb750c09a22c57b0068e8834de8d3b65a Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Tue, 27 Feb 2024 13:32:01 +0200
Subject: [PATCH 353/586] Bug 1882272 - Remove redundant assertion functions
from SettingsSubMenuPrivateBrowsingRobot
---
.../SettingsSubMenuPrivateBrowsingRobot.kt | 79 +++++++------------
1 file changed, 27 insertions(+), 52 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt
index 2ce205706f99..d2347f2982b9 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt
@@ -9,18 +9,14 @@ import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.Visibility
-import androidx.test.espresso.matcher.ViewMatchers.withChild
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
-import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.uiautomator.By
import androidx.test.uiautomator.By.text
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
-import org.hamcrest.CoreMatchers
import org.junit.Assert.assertTrue
-import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
import org.mozilla.fenix.helpers.MatcherHelper.checkedItemWithResId
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
@@ -35,17 +31,37 @@ import org.mozilla.fenix.helpers.isEnabled
class SettingsSubMenuPrivateBrowsingRobot {
- fun verifyNavigationToolBarHeader() = assertNavigationToolBarHeader()
-
- fun verifyOpenLinksInPrivateTab() = assertOpenLinksInPrivateTab()
+ fun verifyOpenLinksInPrivateTab() {
+ openLinksInPrivateTabSwitch()
+ .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ }
- fun verifyAddPrivateBrowsingShortcutButton() = assertAddPrivateBrowsingShortcutButton()
+ fun verifyAddPrivateBrowsingShortcutButton() {
+ mDevice.wait(
+ Until.findObject(text("Add private browsing shortcut")),
+ waitingTime,
+ )
+ addPrivateBrowsingShortcutButton()
+ .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ }
- fun verifyOpenLinksInPrivateTabEnabled() = assertOpenLinksInPrivateTabEnabled()
+ fun verifyOpenLinksInPrivateTabEnabled() {
+ openLinksInPrivateTabSwitch().check(matches(isEnabled(true)))
+ }
- fun verifyOpenLinksInPrivateTabOff() = assertOpenLinksInPrivateTabOff()
+ fun verifyOpenLinksInPrivateTabOff() {
+ assertUIObjectExists(
+ checkedItemWithResId("android:id/switch_widget", isChecked = true),
+ exists = false,
+ )
+ openLinksInPrivateTabSwitch()
+ .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ }
- fun verifyPrivateBrowsingShortcutIcon() = assertPrivateBrowsingShortcutIcon()
+ fun verifyPrivateBrowsingShortcutIcon() {
+ mDevice.wait(Until.findObject(text("Private $appName")), waitingTime)
+ assertTrue(mDevice.hasObject(text("Private $appName")))
+ }
fun clickPrivateModeScreenshotsSwitch() = screenshotsInPrivateModeSwitch().click()
@@ -92,16 +108,6 @@ class SettingsSubMenuPrivateBrowsingRobot {
}
}
-private fun assertNavigationToolBarHeader() {
- onView(
- CoreMatchers.allOf(
- withId(R.id.navigationToolbar),
- withChild(withText(R.string.preferences_private_browsing_options)),
- ),
- )
- .check((matches(withEffectiveVisibility(Visibility.VISIBLE))))
-}
-
private fun openLinksInPrivateTabSwitch() =
onView(withText("Open links in a private tab"))
@@ -119,34 +125,3 @@ private fun cancelShortcutAdditionButton() =
mDevice.findObject(UiSelector().textContains("CANCEL"))
private fun privateBrowsingShortcutIcon() = mDevice.findObject(text("Private $appName"))
-
-private fun assertAddPrivateBrowsingShortcutButton() {
- mDevice.wait(
- Until.findObject(text("Add private browsing shortcut")),
- waitingTime,
- )
- addPrivateBrowsingShortcutButton()
- .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-}
-
-private fun assertOpenLinksInPrivateTab() {
- openLinksInPrivateTabSwitch()
- .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-}
-
-private fun assertOpenLinksInPrivateTabEnabled() =
- openLinksInPrivateTabSwitch().check(matches(isEnabled(true)))
-
-private fun assertOpenLinksInPrivateTabOff() {
- assertUIObjectExists(
- checkedItemWithResId("android:id/switch_widget", isChecked = true),
- exists = false,
- )
- openLinksInPrivateTabSwitch()
- .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
-}
-
-private fun assertPrivateBrowsingShortcutIcon() {
- mDevice.wait(Until.findObject(text("Private $appName")), waitingTime)
- assertTrue(mDevice.hasObject(text("Private $appName")))
-}
From 6f2f4b3843d81b2b1dd8b0794d03d658cf771301 Mon Sep 17 00:00:00 2001
From: AndiAJ
Date: Tue, 27 Feb 2024 13:57:36 +0200
Subject: [PATCH 354/586] Bug 1882272 - Add logs to
SettingsSubMenuPrivateBrowsingRobot
---
.../SettingsSubMenuPrivateBrowsingRobot.kt | 50 +++++++++++++++++--
1 file changed, 47 insertions(+), 3 deletions(-)
diff --git a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt
index d2347f2982b9..62bde104e72a 100644
--- a/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt
+++ b/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt
@@ -5,6 +5,7 @@
package org.mozilla.fenix.ui.robots
import android.os.Build
+import android.util.Log
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions.matches
@@ -17,6 +18,7 @@ import androidx.test.uiautomator.By.text
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
import org.junit.Assert.assertTrue
+import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
import org.mozilla.fenix.helpers.MatcherHelper.checkedItemWithResId
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
@@ -32,21 +34,29 @@ import org.mozilla.fenix.helpers.isEnabled
class SettingsSubMenuPrivateBrowsingRobot {
fun verifyOpenLinksInPrivateTab() {
+ Log.i(TAG, "verifyOpenLinksInPrivateTab: Trying to verify that the \"Open links in a private tab\" option is visible")
openLinksInPrivateTabSwitch()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ Log.i(TAG, "verifyOpenLinksInPrivateTab: Verified that the \"Open links in a private tab\" option is visible")
}
fun verifyAddPrivateBrowsingShortcutButton() {
+ Log.i(TAG, "verifyAddPrivateBrowsingShortcutButton: Waiting for $waitingTime ms until finding the \"Add private browsing shortcut\" button")
mDevice.wait(
Until.findObject(text("Add private browsing shortcut")),
waitingTime,
)
+ Log.i(TAG, "verifyAddPrivateBrowsingShortcutButton: Waited for $waitingTime ms until the \"Add private browsing shortcut\" button was found")
+ Log.i(TAG, "verifyAddPrivateBrowsingShortcutButton: Trying to verify that the \"Add private browsing shortcut\" button is visible")
addPrivateBrowsingShortcutButton()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ Log.i(TAG, "verifyAddPrivateBrowsingShortcutButton: Verified that the \"Add private browsing shortcut\" button is visible")
}
fun verifyOpenLinksInPrivateTabEnabled() {
+ Log.i(TAG, "verifyOpenLinksInPrivateTabEnabled: Trying to verify that the \"Open links in a private tab\" toggle is enabled")
openLinksInPrivateTabSwitch().check(matches(isEnabled(true)))
+ Log.i(TAG, "verifyOpenLinksInPrivateTabEnabled: Verified that the \"Open links in a private tab\" toggle is enabled")
}
fun verifyOpenLinksInPrivateTabOff() {
@@ -54,53 +64,87 @@ class SettingsSubMenuPrivateBrowsingRobot {
checkedItemWithResId("android:id/switch_widget", isChecked = true),
exists = false,
)
+ Log.i(TAG, "verifyOpenLinksInPrivateTabOff: Trying to verify that the \"Open links in a private tab\" toggle is visible")
openLinksInPrivateTabSwitch()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
+ Log.i(TAG, "verifyOpenLinksInPrivateTabOff: Verified that the \"Open links in a private tab\" toggle is visible")
}
fun verifyPrivateBrowsingShortcutIcon() {
+ Log.i(TAG, "verifyPrivateBrowsingShortcutIcon: Waiting for $waitingTime ms until finding the \"Private $appName\" shortcut icon")
mDevice.wait(Until.findObject(text("Private $appName")), waitingTime)
- assertTrue(mDevice.hasObject(text("Private $appName")))
+ Log.i(TAG, "verifyPrivateBrowsingShortcutIcon: Waited for $waitingTime ms until the \"Private $appName\" shortcut icon was found")
+ Log.i(TAG, "verifyPrivateBrowsingShortcutIcon: Trying to verify the \"Private $appName\" shortcut icon")
+ assertTrue("\"Private $appName\" shortcut icon wasn't verified", mDevice.hasObject(text("Private $appName")))
+ Log.i(TAG, "verifyPrivateBrowsingShortcutIcon: Verified the \"Private $appName\" shortcut icon")
}
- fun clickPrivateModeScreenshotsSwitch() = screenshotsInPrivateModeSwitch().click()
+ fun clickPrivateModeScreenshotsSwitch() {
+ Log.i(TAG, "clickPrivateModeScreenshotsSwitch: Trying to click the \"Allow screenshots in private browsing\" toggle")
+ screenshotsInPrivateModeSwitch().click()
+ Log.i(TAG, "clickPrivateModeScreenshotsSwitch: Clicked the \"Allow screenshots in private browsing\" toggle")
+ }
- fun clickOpenLinksInPrivateTabSwitch() = openLinksInPrivateTabSwitch().click()
+ fun clickOpenLinksInPrivateTabSwitch() {
+ Log.i(TAG, "clickOpenLinksInPrivateTabSwitch: Trying to click the \"Open links in a private tab\" toggle")
+ openLinksInPrivateTabSwitch().click()
+ Log.i(TAG, "clickOpenLinksInPrivateTabSwitch: Clicked the \"Open links in a private tab\" toggle")
+ }
fun cancelPrivateShortcutAddition() {
+ Log.i(TAG, "cancelPrivateShortcutAddition: Waiting for $waitingTime ms until finding the \"Add private browsing shortcut\" button")
mDevice.wait(
Until.findObject(text("Add private browsing shortcut")),
waitingTime,
)
+ Log.i(TAG, "cancelPrivateShortcutAddition: Waited for $waitingTime ms until the \"Add private browsing shortcut\" button was found")
+ Log.i(TAG, "cancelPrivateShortcutAddition: Trying to click the \"Add private browsing shortcut\" button")
addPrivateBrowsingShortcutButton().click()
+ Log.i(TAG, "cancelPrivateShortcutAddition: Clicked the \"Add private browsing shortcut\" button")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ Log.i(TAG, "cancelPrivateShortcutAddition: Waiting for $waitingTime ms until finding the \"Cancel\" button")
mDevice.wait(Until.findObject(By.textContains("CANCEL")), waitingTime)
+ Log.i(TAG, "cancelPrivateShortcutAddition: Waited for $waitingTime ms until the \"Cancel\" button was found")
+ Log.i(TAG, "cancelPrivateShortcutAddition: Trying to click the \"Cancel\" button")
cancelShortcutAdditionButton().click()
+ Log.i(TAG, "cancelPrivateShortcutAddition: Clicked the \"Cancel\" button")
}
}
fun addPrivateShortcutToHomescreen() {
+ Log.i(TAG, "addPrivateShortcutToHomescreen: Waiting for $waitingTime ms until finding the \"Add private browsing shortcut\" button")
mDevice.wait(
Until.findObject(text("Add private browsing shortcut")),
waitingTime,
)
+ Log.i(TAG, "addPrivateShortcutToHomescreen: Waited for $waitingTime ms until the \"Add private browsing shortcut\" button was found")
+ Log.i(TAG, "addPrivateShortcutToHomescreen: Trying to click the \"Add private browsing shortcut\" button")
addPrivateBrowsingShortcutButton().click()
+ Log.i(TAG, "addPrivateShortcutToHomescreen: Clicked the \"Add private browsing shortcut\" button")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ Log.i(TAG, "addPrivateShortcutToHomescreen: Waiting for $waitingTime ms until finding the \"Add automatically\" button")
mDevice.wait(Until.findObject(By.textContains("add automatically")), waitingTime)
+ Log.i(TAG, "addPrivateShortcutToHomescreen: Waited for $waitingTime ms until the \"Add automatically\" button was found")
+ Log.i(TAG, "addPrivateShortcutToHomescreen: Trying to click the \"Add automatically\" button")
addAutomaticallyButton().click()
+ Log.i(TAG, "addPrivateShortcutToHomescreen: Clicked the \"Add automatically\" button")
}
}
class Transition {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
+ Log.i(TAG, "goBack: Trying to click the navigate up button")
goBackButton().perform(ViewActions.click())
+ Log.i(TAG, "goBack: Clicked the navigate up button")
SettingsRobot().interact()
return SettingsRobot.Transition()
}
fun openPrivateBrowsingShortcut(interact: SearchRobot.() -> Unit): SearchRobot.Transition {
+ Log.i(TAG, "openPrivateBrowsingShortcut: Trying to click the \"Private $appName\" shortcut icon")
privateBrowsingShortcutIcon().click()
+ Log.i(TAG, "openPrivateBrowsingShortcut: Clicked the \"Private $appName\" shortcut icon")
SearchRobot().interact()
return SearchRobot.Transition()
From 87f1f74d26dd5a96e9d664aca04b7deb2f2e6dfd Mon Sep 17 00:00:00 2001
From: t-p-white
Date: Mon, 26 Feb 2024 10:18:44 +0000
Subject: [PATCH 355/586] Bug 1879512 - Added experimental onboarding images
for Nimbus
---
fenix/app/lint-baseline.xml | 10 +
.../drawable/ic_onboarding_key_features.xml | 423 ++++++++++++++++++
.../ic_onboarding_key_features_icons_only.xml | 307 +++++++++++++
fenix/app/src/main/res/raw/keep.xml | 2 +-
4 files changed, 741 insertions(+), 1 deletion(-)
create mode 100644 fenix/app/src/main/res/drawable/ic_onboarding_key_features.xml
create mode 100644 fenix/app/src/main/res/drawable/ic_onboarding_key_features_icons_only.xml
diff --git a/fenix/app/lint-baseline.xml b/fenix/app/lint-baseline.xml
index b4ce2b38e20e..c9eb994da118 100644
--- a/fenix/app/lint-baseline.xml
+++ b/fenix/app/lint-baseline.xml
@@ -1101,6 +1101,16 @@
column="1"/>
+
+
+
+
+
+
+
+
diff --git a/fenix/app/src/main/res/drawable/ic_onboarding_key_features.xml b/fenix/app/src/main/res/drawable/ic_onboarding_key_features.xml
new file mode 100644
index 000000000000..c5eeaffcf10f
--- /dev/null
+++ b/fenix/app/src/main/res/drawable/ic_onboarding_key_features.xml
@@ -0,0 +1,423 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fenix/app/src/main/res/drawable/ic_onboarding_key_features_icons_only.xml b/fenix/app/src/main/res/drawable/ic_onboarding_key_features_icons_only.xml
new file mode 100644
index 000000000000..820fd340e360
--- /dev/null
+++ b/fenix/app/src/main/res/drawable/ic_onboarding_key_features_icons_only.xml
@@ -0,0 +1,307 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fenix/app/src/main/res/raw/keep.xml b/fenix/app/src/main/res/raw/keep.xml
index c19db331d7c9..9a17666f9717 100644
--- a/fenix/app/src/main/res/raw/keep.xml
+++ b/fenix/app/src/main/res/raw/keep.xml
@@ -1,3 +1,3 @@
+ tools:keep="@drawable/onboarding_ctd_default_browser,@drawable-night/onboarding_ctd_default_browser,@drawable/onboarding_ctd_sync,@drawable/onboarding_ctd_notification,@drawable/ic_onboarding_key_features.xml,@drawable/ic_onboarding_key_features_icons_only.xml" />
From 6959b5ef2c7aaf2fa0e61a25852b1e90ca2b20fa Mon Sep 17 00:00:00 2001
From: Aaron Train
Date: Mon, 26 Feb 2024 15:51:38 -0500
Subject: [PATCH 356/586] Bug 1882162 - remove JQuery slim test asset
---
fenix/app/src/androidTest/assets/pages/jquery-3.4.1.slim.min.js | 2 --
fenix/app/src/androidTest/assets/pages/refresh.html | 1 -
2 files changed, 3 deletions(-)
delete mode 100644 fenix/app/src/androidTest/assets/pages/jquery-3.4.1.slim.min.js
diff --git a/fenix/app/src/androidTest/assets/pages/jquery-3.4.1.slim.min.js b/fenix/app/src/androidTest/assets/pages/jquery-3.4.1.slim.min.js
deleted file mode 100644
index af151cfe3fea..000000000000
--- a/fenix/app/src/androidTest/assets/pages/jquery-3.4.1.slim.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/*! jQuery v3.4.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector | (c) JS Foundation and other contributors | jquery.org/license */
-!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(g,e){"use strict";var t=[],v=g.document,r=Object.getPrototypeOf,s=t.slice,y=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,m=n.hasOwnProperty,a=m.toString,l=a.call(Object),b={},x=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},w=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function C(e,t,n){var r,i,o=(n=n||v).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function T(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector",E=function(e,t){return new E.fn.init(e,t)},d=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function p(e){var t=!!e&&"length"in e&&e.length,n=T(e);return!x(e)&&!w(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+R+")"+R+"*"),U=new RegExp(R+"|>"),V=new RegExp(W),X=new RegExp("^"+B+"$"),Q={ID:new RegExp("^#("+B+")"),CLASS:new RegExp("^\\.("+B+")"),TAG:new RegExp("^("+B+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+I+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,G=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,J=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+R+"?|("+R+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){C()},ae=xe(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{O.apply(t=P.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){O={apply:t.length?function(e,t){q.apply(e,P.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,d=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==d&&9!==d&&11!==d)return n;if(!r&&((e?e.ownerDocument||e:m)!==T&&C(e),e=e||T,E)){if(11!==d&&(u=Z.exec(t)))if(i=u[1]){if(9===d){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return O.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&p.getElementsByClassName&&e.getElementsByClassName)return O.apply(n,e.getElementsByClassName(i)),n}if(p.qsa&&!S[t+" "]&&(!v||!v.test(t))&&(1!==d||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===d&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=N),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+be(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return O.apply(n,f.querySelectorAll(c)),n}catch(e){S(t,!0)}finally{s===N&&e.removeAttribute("id")}}}return g(t.replace(F,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>x.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[N]=!0,e}function ce(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)x.attrHandle[n[r]]=t}function de(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in p=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},C=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==T&&9===r.nodeType&&r.documentElement&&(a=(T=r).documentElement,E=!i(T),m!==T&&(n=T.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),p.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),p.getElementsByTagName=ce(function(e){return e.appendChild(T.createComment("")),!e.getElementsByTagName("*").length}),p.getElementsByClassName=J.test(T.getElementsByClassName),p.getById=ce(function(e){return a.appendChild(e).id=N,!T.getElementsByName||!T.getElementsByName(N).length}),p.getById?(x.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(x.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),x.find.TAG=p.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):p.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},x.find.CLASS=p.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(p.qsa=J.test(T.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+R+"*(?:value|"+I+")"),e.querySelectorAll("[id~="+N+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+N+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=T.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(p.matchesSelector=J.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){p.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",W)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=J.test(a.compareDocumentPosition),y=t||J.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!p.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument===m&&y(m,e)?-1:t===T||t.ownerDocument===m&&y(m,t)?1:u?H(u,e)-H(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===T?-1:t===T?1:i?-1:o?1:u?H(u,e)-H(u,t):0;if(i===o)return de(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?de(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),T},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==T&&C(e),p.matchesSelector&&E&&!S[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||p.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){S(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&V.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=d[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&d(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function L(e,n,r){return x(n)?E.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?E.grep(e,function(e){return e===n!==r}):"string"!=typeof n?E.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(E.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof E?t[0]:t,E.merge(this,E.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:v,!0)),D.test(r[1])&&E.isPlainObject(t))for(r in t)x(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=v.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):x(e)?void 0!==n.ready?n.ready(e):e(E):E.makeArray(e,this)}).prototype=E.fn,j=E(v);var O=/^(?:parents|prev(?:Until|All))/,P={children:!0,contents:!0,next:!0,prev:!0};function H(e,t){while((e=e[t])&&1!==e.nodeType);return e}E.fn.extend({has:function(e){var t=E(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,he={option:[1,""],thead:[1,"