diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 452fe72b8..57812aa82 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -793,7 +793,7 @@ jobs: done - name: Upload Sources - uses: crowdin/github-action@ecd7eb0ef6f3cfa16293c79e9cbc4bc5b5fd9c49 # v1.4.9 + uses: crowdin/github-action@965d501f160af7b1f88aed4c29154b0caf1e94b9 # v1.9.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }} diff --git a/.github/workflows/crowdin-pull.yml b/.github/workflows/crowdin-pull.yml index 36aaaa9ab..a2a297a19 100644 --- a/.github/workflows/crowdin-pull.yml +++ b/.github/workflows/crowdin-pull.yml @@ -30,7 +30,7 @@ jobs: secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase" - name: Download translations - uses: crowdin/github-action@ecd7eb0ef6f3cfa16293c79e9cbc4bc5b5fd9c49 # v1.4.9 + uses: crowdin/github-action@965d501f160af7b1f88aed4c29154b0caf1e94b9 # v1.9.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }} diff --git a/.github/workflows/enforce-labels.yml b/.github/workflows/enforce-labels.yml index 417e34e9b..4e3127761 100644 --- a/.github/workflows/enforce-labels.yml +++ b/.github/workflows/enforce-labels.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Enforce Label - uses: yogevbd/enforce-label-action@a3c219da6b8fa73f6ba62b68ff09c469b3a1c024 # v2.2.2 + uses: yogevbd/enforce-label-action@a3c219da6b8fa73f6ba62b68ff09c469b3a1c024 # 2.2.2 with: BANNED_LABELS: "hold,needs-qa" BANNED_LABELS_DESCRIPTION: "PRs with the hold or needs-qa labels cannot be merged" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f1e57bbe9..50f4128e9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -68,7 +68,7 @@ jobs: - name: Download all artifacts if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10 + uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0 with: workflow: build.yml workflow_conclusion: success @@ -76,7 +76,7 @@ jobs: - name: Dry Run - Download all artifacts if: ${{ github.event.inputs.release_type == 'Dry Run' }} - uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10 + uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0 with: workflow: build.yml workflow_conclusion: success @@ -130,7 +130,7 @@ jobs: - name: Download F-Droid .apk artifact if: ${{ github.event.inputs.release_type != 'Dry Run' }} - uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10 + uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0 with: workflow: build.yml workflow_conclusion: success @@ -139,7 +139,7 @@ jobs: - name: Dry Run - Download F-Droid .apk artifact if: ${{ github.event.inputs.release_type == 'Dry Run' }} - uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10 + uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0 with: workflow: build.yml workflow_conclusion: success diff --git a/src/Android/Android.csproj b/src/Android/Android.csproj index 4b42db250..c5f838ff8 100644 --- a/src/Android/Android.csproj +++ b/src/Android/Android.csproj @@ -159,6 +159,7 @@ + diff --git a/src/Android/Autofill/FieldCollection.cs b/src/Android/Autofill/FieldCollection.cs index a01aaad70..63d2e512b 100644 --- a/src/Android/Autofill/FieldCollection.cs +++ b/src/Android/Autofill/FieldCollection.cs @@ -12,7 +12,7 @@ namespace Bit.Droid.Autofill private List _passwordFields = null; private List _usernameFields = null; private HashSet _ignoreSearchTerms = new HashSet { "search", "find", "recipient", "edit" }; - private HashSet _usernameTerms = new HashSet { "email", "phone", "username"}; + private HashSet _usernameTerms = new HashSet { "email", "phone", "username" }; private HashSet _passwordTerms = new HashSet { "password", "pswd" }; public List AutofillIds { get; private set; } = new List(); @@ -54,15 +54,14 @@ namespace Bit.Droid.Autofill if (HintToFieldsMap.ContainsKey(View.AutofillHintPassword)) { _passwordFields.AddRange(HintToFieldsMap[View.AutofillHintPassword]); + return _passwordFields; } } - else + + _passwordFields = Fields.Where(f => FieldIsPassword(f)).ToList(); + if (!_passwordFields.Any()) { - _passwordFields = Fields.Where(f => FieldIsPassword(f)).ToList(); - if (!_passwordFields.Any()) - { - _passwordFields = Fields.Where(f => FieldHasPasswordTerms(f)).ToList(); - } + _passwordFields = Fields.Where(f => FieldHasPasswordTerms(f)).ToList(); } return _passwordFields; } @@ -87,24 +86,26 @@ namespace Bit.Droid.Autofill { _usernameFields.AddRange(HintToFieldsMap[View.AutofillHintUsername]); } + if (_usernameFields.Any()) + { + return _usernameFields; + } } - else - { - foreach (var passwordField in PasswordFields) - { - var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId) - .LastOrDefault(); - if (usernameField != null) - { - _usernameFields.Add(usernameField); - } - } - if (!_usernameFields.Any()) + foreach (var passwordField in PasswordFields) + { + var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId) + .LastOrDefault(); + if (usernameField != null) { - _usernameFields = Fields.Where(f => FieldIsUsername(f)).ToList(); + _usernameFields.Add(usernameField); } } + + if (!_usernameFields.Any()) + { + _usernameFields = Fields.Where(f => FieldIsUsername(f)).ToList(); + } return _usernameFields; } } diff --git a/src/Android/Renderers/CustomLabelRenderer.cs b/src/Android/Renderers/CustomLabelRenderer.cs new file mode 100644 index 000000000..62287087d --- /dev/null +++ b/src/Android/Renderers/CustomLabelRenderer.cs @@ -0,0 +1,31 @@ +using System; +using Bit.App.Controls; +using System.ComponentModel; +using Xamarin.Forms.Platform.Android; +using Android.Content; +using Xamarin.Forms; +using Bit.Droid.Renderers; + +[assembly: ExportRenderer(typeof(CustomLabel), typeof(CustomLabelRenderer))] +namespace Bit.Droid.Renderers +{ + public class CustomLabelRenderer : LabelRenderer + { + public CustomLabelRenderer(Context context) + : base(context) + { } + + protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) + { + var label = sender as CustomLabel; + switch (e.PropertyName) + { + case nameof(CustomLabel.AutomationId): + Control.ContentDescription = label.AutomationId; + break; + } + base.OnElementPropertyChanged(sender, e); + } + } +} + diff --git a/src/App/App.csproj b/src/App/App.csproj index 83e1ee879..54d589ef7 100644 --- a/src/App/App.csproj +++ b/src/App/App.csproj @@ -145,6 +145,7 @@ + @@ -440,5 +441,6 @@ + diff --git a/src/App/Controls/AccountSwitchingOverlay/AccountSwitchingOverlayView.xaml b/src/App/Controls/AccountSwitchingOverlay/AccountSwitchingOverlayView.xaml index f0c52d0d4..4dba94dd1 100644 --- a/src/App/Controls/AccountSwitchingOverlay/AccountSwitchingOverlayView.xaml +++ b/src/App/Controls/AccountSwitchingOverlay/AccountSwitchingOverlayView.xaml @@ -30,13 +30,15 @@ BackgroundColor="{DynamicResource BackgroundColor}" VerticalOptions="Start" RowHeight="{Binding AccountListRowHeight, Source={x:Reference _mainOverlay}}" - effects:ScrollViewContentInsetAdjustmentBehaviorEffect.ContentInsetAdjustmentBehavior="Never"> + effects:ScrollViewContentInsetAdjustmentBehaviorEffect.ContentInsetAdjustmentBehavior="Never" + AutomationId="AccountListView"> diff --git a/src/App/Controls/AccountViewCell/AccountViewCell.xaml b/src/App/Controls/AccountViewCell/AccountViewCell.xaml index 3d45cf929..9a9f53831 100644 --- a/src/App/Controls/AccountViewCell/AccountViewCell.xaml +++ b/src/App/Controls/AccountViewCell/AccountViewCell.xaml @@ -1,4 +1,4 @@ - + + LineBreakMode="TailTruncation" + AutomationId="AccountEmailLabel" /> \ No newline at end of file diff --git a/src/App/Controls/CipherViewCell/CipherViewCell.xaml b/src/App/Controls/CipherViewCell/CipherViewCell.xaml index 5024ad537..e2ecba08e 100644 --- a/src/App/Controls/CipherViewCell/CipherViewCell.xaml +++ b/src/App/Controls/CipherViewCell/CipherViewCell.xaml @@ -9,7 +9,8 @@ StyleClass="list-row, list-row-platform" RowSpacing="0" ColumnSpacing="0" - x:DataType="controls:CipherViewCellViewModel"> + x:DataType="controls:CipherViewCellViewModel" + AutomationId="CipherCell"> @@ -36,7 +37,8 @@ IsVisible="{Binding ShowIconImage, Converter={StaticResource inverseBool}}" Text="{Binding Cipher, Converter={StaticResource iconGlyphConverter}}" ShouldUpdateFontSizeDynamicallyForAccesibility="True" - AutomationProperties.IsInAccessibleTree="False" /> + AutomationProperties.IsInAccessibleTree="False" + AutomationId="CipherTypeIcon" /> + AutomationProperties.IsInAccessibleTree="False" + AutomationId="CipherWebsiteIcon" /> @@ -71,7 +74,8 @@ Grid.Column="0" Grid.Row="0" StyleClass="list-title, list-title-platform" - Text="{Binding Cipher.Name}" /> + Text="{Binding Cipher.Name}" + AutomationId="CipherNameLabel" /> + AutomationProperties.Name="{u:I18n Options}" + AutomationId="CipherOptionsButton" /> \ No newline at end of file diff --git a/src/App/Controls/CustomLabel.cs b/src/App/Controls/CustomLabel.cs new file mode 100644 index 000000000..e822d3304 --- /dev/null +++ b/src/App/Controls/CustomLabel.cs @@ -0,0 +1,13 @@ +using System; +using Xamarin.Forms; + +namespace Bit.App.Controls +{ + public class CustomLabel : Label + { + public CustomLabel() + { + } + } +} + diff --git a/src/App/Controls/SendViewCell/SendViewCell.xaml b/src/App/Controls/SendViewCell/SendViewCell.xaml index 8a9d0e2a6..30d7b8ca3 100644 --- a/src/App/Controls/SendViewCell/SendViewCell.xaml +++ b/src/App/Controls/SendViewCell/SendViewCell.xaml @@ -1,4 +1,4 @@ - + + Text="{Binding Send.Name}" + AutomationId="SendNameLabel" /> diff --git a/src/App/Lists/ItemLayouts/CustomFields/BooleanCustomFieldItemLayout.xaml b/src/App/Lists/ItemLayouts/CustomFields/BooleanCustomFieldItemLayout.xaml index c50cf53eb..6c7d22ed7 100644 --- a/src/App/Lists/ItemLayouts/CustomFields/BooleanCustomFieldItemLayout.xaml +++ b/src/App/Lists/ItemLayouts/CustomFields/BooleanCustomFieldItemLayout.xaml @@ -33,7 +33,8 @@ StyleClass="box-label" Grid.Row="0" Grid.Column="0" - IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" /> + IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" + AutomationId="BooleanCustomFieldNameLabel" />