mirror of
https://github.com/bitwarden/android.git
synced 2024-12-25 18:38:27 +03:00
[PM-2691] Adding AutomationIDs for Vault Page sections (#2580)
* Adding IDs for Vault Page sections * Removing extra spaces * Adding Matt's comments * Fixing Filters Id bug * Adding Fede's suggestions * Fixing Settings Ids issues * Fixing AutomationIds issues with RecyclerViews + implementing AutomationId helper class * Adding Fede's suggestion * Adding latest Fede's suggestions
This commit is contained in:
parent
216c6abcf6
commit
72e67bd6f2
14 changed files with 178 additions and 30 deletions
|
@ -159,6 +159,7 @@
|
|||
<Compile Include="Constants.cs" />
|
||||
<Compile Include="Effects\RemoveFontPaddingEffect.cs" />
|
||||
<Compile Include="Services\WatchDeviceService.cs" />
|
||||
<Compile Include="Renderers\CustomLabelRenderer.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidAsset Include="Assets\bwi-font.ttf" />
|
||||
|
|
31
src/Android/Renderers/CustomLabelRenderer.cs
Normal file
31
src/Android/Renderers/CustomLabelRenderer.cs
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -145,6 +145,7 @@
|
|||
<Folder Include="Controls\DateTime\" />
|
||||
<Folder Include="Controls\IconLabelButton\" />
|
||||
<Folder Include="Controls\PasswordStrengthProgressBar\" />
|
||||
<Folder Include="Utilities\Automation\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -440,5 +441,6 @@
|
|||
<None Remove="MessagePack" />
|
||||
<None Remove="MessagePack.MSBuild.Tasks" />
|
||||
<None Remove="Controls\PasswordStrengthProgressBar\" />
|
||||
<None Remove="Utilities\Automation\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
13
src/App/Controls/CustomLabel.cs
Normal file
13
src/App/Controls/CustomLabel.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class CustomLabel : Label
|
||||
{
|
||||
public CustomLabel()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,8 +20,7 @@
|
|||
x:Key="regularTemplate"
|
||||
x:DataType="pages:SettingsPageListItem">
|
||||
<controls:ExtendedStackLayout Orientation="Horizontal"
|
||||
StyleClass="list-row, list-row-platform"
|
||||
AutomationId="{Binding AutomationId}">
|
||||
StyleClass="list-row, list-row-platform">
|
||||
<Frame
|
||||
IsVisible="{Binding UseFrame}"
|
||||
Padding="10"
|
||||
|
@ -33,21 +32,21 @@
|
|||
StyleClass="text-muted, text-sm, text-bold"
|
||||
HorizontalTextAlignment="Center" />
|
||||
</Frame>
|
||||
<Label IsVisible="{Binding UseFrame, Converter={StaticResource inverseBool}}"
|
||||
<controls:CustomLabel IsVisible="{Binding UseFrame, Converter={StaticResource inverseBool}}"
|
||||
Text="{Binding Name, Mode=OneWay}"
|
||||
LineBreakMode="{Binding LineBreakMode}"
|
||||
HorizontalOptions="StartAndExpand"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
StyleClass="list-title"
|
||||
AutomationId="SettingTitleLabel" />
|
||||
<Label Text="{Binding SubLabel, Mode=OneWay}"
|
||||
AutomationId="{Binding AutomationIdSettingName}" />
|
||||
<controls:CustomLabel Text="{Binding SubLabel, Mode=OneWay}"
|
||||
IsVisible="{Binding ShowSubLabel}"
|
||||
HorizontalOptions="End"
|
||||
HorizontalTextAlignment="End"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
TextColor="{Binding SubLabelColor}"
|
||||
StyleClass="list-sub"
|
||||
AutomationId="SettingStatusLabel" />
|
||||
AutomationId="{Binding AutomationIdSettingStatus}" />
|
||||
</controls:ExtendedStackLayout>
|
||||
</DataTemplate>
|
||||
<DataTemplate
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Globalization;
|
|||
using System.Threading.Tasks;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.App.Utilities.Automation;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
|
@ -23,23 +24,28 @@ namespace Bit.App.Pages
|
|||
public Color SubLabelColor => SubLabelTextEnabled ?
|
||||
ThemeManager.GetResourceColor("SuccessColor") :
|
||||
ThemeManager.GetResourceColor("MutedColor");
|
||||
public string AutomationId
|
||||
|
||||
public string AutomationIdSettingName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!UseFrame)
|
||||
return AutomationIdsHelper.AddSuffixFor(
|
||||
UseFrame ? "EnabledPolicy"
|
||||
: AutomationIdsHelper.ToEnglishTitleCase(Name)
|
||||
, SuffixType.Cell);
|
||||
}
|
||||
}
|
||||
|
||||
public string AutomationIdSettingStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
if (UseFrame)
|
||||
{
|
||||
var idText = new CultureInfo("en-US", false)
|
||||
.TextInfo
|
||||
.ToTitleCase(Name)
|
||||
.Replace(" ", String.Empty)
|
||||
.Replace("-", String.Empty);
|
||||
return $"{idText}Cell";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "EnabledPolicyCell";
|
||||
return null;
|
||||
}
|
||||
|
||||
return AutomationIdsHelper.AddSuffixFor(AutomationIdsHelper.ToEnglishTitleCase(Name), SuffixType.SettingValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,8 +72,7 @@
|
|||
<StackLayout StyleClass="box" AutomationId="ItemInformationSection">
|
||||
<StackLayout StyleClass="box-row-header">
|
||||
<Label Text="{u:I18n ItemInformation, Header=True}"
|
||||
StyleClass="box-header, box-header-platform"
|
||||
AutomationId="" />
|
||||
StyleClass="box-header, box-header-platform" />
|
||||
</StackLayout>
|
||||
<StackLayout StyleClass="box-row" AutomationId="ItemRow">
|
||||
<Label
|
||||
|
@ -196,7 +195,9 @@
|
|||
</Grid>
|
||||
<BoxView StyleClass="box-row-separator"
|
||||
IsVisible="{Binding Cipher.Login.Password, Converter={StaticResource stringHasValue}}" />
|
||||
<Grid StyleClass="box-row" IsVisible="{Binding ShowTotp}" AutomationId="ItemRow">
|
||||
<Grid StyleClass="box-row"
|
||||
IsVisible="{Binding ShowTotp}"
|
||||
AutomationId="ItemRow">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
|
|
|
@ -60,13 +60,14 @@
|
|||
<controls:AuthenticatorViewCell
|
||||
Cipher="{Binding Cipher}"
|
||||
WebsiteIconsEnabled="{Binding BindingContext.WebsiteIconsEnabled, Source={x:Reference _page}}"
|
||||
TotpSec="{Binding TotpSec}"/>
|
||||
TotpSec="{Binding TotpSec}" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="groupTemplate"
|
||||
x:DataType="pages:GroupingsPageListItem">
|
||||
<controls:ExtendedStackLayout Orientation="Horizontal"
|
||||
StyleClass="list-row, list-row-platform">
|
||||
StyleClass="list-row, list-row-platform"
|
||||
AutomationId="{Binding AutomationId}">
|
||||
<controls:IconLabel Text="{Binding Icon, Mode=OneWay}"
|
||||
HorizontalOptions="Start"
|
||||
VerticalOptions="Center"
|
||||
|
@ -80,12 +81,14 @@
|
|||
LineBreakMode="TailTruncation"
|
||||
HorizontalOptions="FillAndExpand"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
StyleClass="list-title"/>
|
||||
StyleClass="list-title"
|
||||
AutomationId="ItemNameLabel" />
|
||||
<Label Text="{Binding ItemCount, Mode=OneWay}"
|
||||
HorizontalOptions="End"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalTextAlignment="End"
|
||||
StyleClass="list-sub"/>
|
||||
StyleClass="list-sub"
|
||||
AutomationId="ItemCountLabel" />
|
||||
</controls:ExtendedStackLayout>
|
||||
</DataTemplate>
|
||||
|
||||
|
@ -96,7 +99,8 @@
|
|||
Spacing="0"
|
||||
Padding="0"
|
||||
VerticalOptions="FillAndExpand"
|
||||
StyleClass="list-row-header-container, list-row-header-container-platform">
|
||||
StyleClass="list-row-header-container, list-row-header-container-platform"
|
||||
AutomationId="{Binding AutomationId}">
|
||||
<BoxView
|
||||
StyleClass="list-section-separator-top, list-section-separator-top-platform" />
|
||||
<StackLayout StyleClass="list-row-header, list-row-header-platform">
|
||||
|
@ -105,7 +109,8 @@
|
|||
StyleClass="list-header, list-header-platform" />
|
||||
<Label
|
||||
Text="{Binding ItemCount}"
|
||||
StyleClass="list-header-sub" />
|
||||
StyleClass="list-header-sub"
|
||||
AutomationId="SectionItemCount" />
|
||||
</StackLayout>
|
||||
<BoxView StyleClass="list-section-separator-bottom, list-section-separator-bottom-platform" />
|
||||
</StackLayout>
|
||||
|
@ -148,7 +153,8 @@
|
|||
IsVisible="{Binding ShowNoData}">
|
||||
<Label
|
||||
Text="{Binding NoDataText}"
|
||||
HorizontalTextAlignment="Center"></Label>
|
||||
HorizontalTextAlignment="Center"
|
||||
AutomationId="NoDataDisplayed"></Label>
|
||||
<Button
|
||||
Text="{u:I18n AddAnItem}"
|
||||
Clicked="AddButton_Clicked"
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace Bit.App.Pages
|
||||
using Bit.App.Utilities.Automation;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class GroupingsPageHeaderListItem : IGroupingsPageListItem
|
||||
{
|
||||
|
@ -10,5 +12,12 @@
|
|||
|
||||
public string Title { get; }
|
||||
public string ItemCount { get; set; }
|
||||
public string AutomationId
|
||||
{
|
||||
get
|
||||
{
|
||||
return AutomationIdsHelper.AddSuffixFor(AutomationIdsHelper.ToEnglishTitleCase(Title), SuffixType.Header);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using Bit.App.Utilities.Automation;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -32,5 +33,6 @@ namespace Bit.App.Pages
|
|||
public string Name { get; set; }
|
||||
public string NameShort => string.IsNullOrWhiteSpace(Name) || Name.Length == 0 ? "-" : Name[0].ToString();
|
||||
public string ItemCount { get; set; }
|
||||
public string AutomationId => AutomationIdsHelper.AddSuffixFor(NameShort, SuffixType.ListGroup);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities.Automation;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.View;
|
||||
|
@ -115,5 +116,38 @@ namespace Bit.App.Pages
|
|||
return _icon;
|
||||
}
|
||||
}
|
||||
|
||||
public string AutomationId
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Type != null)
|
||||
{
|
||||
return AutomationIdsHelper.AddSuffixFor(System.Enum.GetName(typeof(CipherType), Type.Value), SuffixType.Filter);
|
||||
}
|
||||
|
||||
if (IsTrash)
|
||||
{
|
||||
return AutomationIdsHelper.AddSuffixFor("Trash", SuffixType.Filter);
|
||||
}
|
||||
|
||||
if (Folder != null)
|
||||
{
|
||||
return AutomationIdsHelper.AddSuffixFor("Folder", SuffixType.Filter);
|
||||
}
|
||||
|
||||
if (Collection != null)
|
||||
{
|
||||
return AutomationIdsHelper.AddSuffixFor("Collection", SuffixType.Filter);
|
||||
}
|
||||
|
||||
if (IsTotpCode)
|
||||
{
|
||||
return AutomationIdsHelper.AddSuffixFor("TOTP", SuffixType.ListItem);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
23
src/App/Utilities/Automation/AutomationIdsHelper.cs
Normal file
23
src/App/Utilities/Automation/AutomationIdsHelper.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Bit.App.Utilities.Automation
|
||||
{
|
||||
public static class AutomationIdsHelper
|
||||
{
|
||||
public static string ToEnglishTitleCase(string name)
|
||||
{
|
||||
return new CultureInfo("en-US", false)
|
||||
.TextInfo
|
||||
.ToTitleCase(name)
|
||||
.Replace(" ", String.Empty)
|
||||
.Replace("-", String.Empty);
|
||||
}
|
||||
|
||||
public static string AddSuffixFor(string text, SuffixType type)
|
||||
{
|
||||
return $"{text}{Enum.GetName(typeof(SuffixType), type)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
src/App/Utilities/Automation/SuffixType.cs
Normal file
13
src/App/Utilities/Automation/SuffixType.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace Bit.App.Utilities.Automation
|
||||
{
|
||||
public enum SuffixType
|
||||
{
|
||||
Cell,
|
||||
SettingValue,
|
||||
Header,
|
||||
ListGroup,
|
||||
ListItem,
|
||||
Filter
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,15 @@ namespace Bit.iOS.Core.Renderers
|
|||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
var label = sender as CustomLabel;
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case nameof(CustomLabel.AutomationId):
|
||||
Control.AccessibilityIdentifier = label.AutomationId;
|
||||
break;
|
||||
}
|
||||
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
|
||||
if (e.PropertyName == Label.FontProperty.PropertyName ||
|
||||
e.PropertyName == Label.TextProperty.PropertyName ||
|
||||
|
|
Loading…
Reference in a new issue