| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #import <Cocoa/Cocoa.h> |
| 6 |
| 7 #import "base/mac/scoped_nsobject.h" |
| 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "ui/gfx/geometry/point.h" |
| 10 #import "ui/gfx/mac/coordinate_conversion.h" |
| 11 #include "ui/views/controls/tabbed_pane/tabbed_pane.h" |
| 12 #include "ui/views/test/widget_test.h" |
| 13 #include "ui/views/widget/widget.h" |
| 14 #import "testing/gtest_mac.h" |
| 15 |
| 16 namespace views { |
| 17 namespace test { |
| 18 |
| 19 class TabbedPaneAccessibilityMacTest : public WidgetTest { |
| 20 public: |
| 21 TabbedPaneAccessibilityMacTest() {} |
| 22 |
| 23 // WidgetTest: |
| 24 void SetUp() override { |
| 25 WidgetTest::SetUp(); |
| 26 widget_ = CreateTopLevelPlatformWidget(); |
| 27 widget_->SetBounds(gfx::Rect(50, 50, 100, 100)); |
| 28 tabbed_pane_ = new TabbedPane(); |
| 29 tabbed_pane_->SetSize(gfx::Size(100, 100)); |
| 30 |
| 31 // Create two tabs and position/size them. |
| 32 tabbed_pane_->AddTab(base::ASCIIToUTF16("Tab 1"), new View()); |
| 33 tabbed_pane_->AddTab(base::ASCIIToUTF16("Tab 2"), new View()); |
| 34 tabbed_pane_->Layout(); |
| 35 |
| 36 widget_->GetContentsView()->AddChildView(tabbed_pane_); |
| 37 widget_->Show(); |
| 38 } |
| 39 |
| 40 void TearDown() override { |
| 41 widget_->CloseNow(); |
| 42 WidgetTest::TearDown(); |
| 43 } |
| 44 |
| 45 Tab* GetTabAt(int index) { |
| 46 return static_cast<Tab*>(tabbed_pane_->tab_strip_->child_at(index)); |
| 47 } |
| 48 |
| 49 id AttributeValueAtPoint(NSString* attribute, const gfx::Point& point) { |
| 50 id value = |
| 51 [A11yElementAtPoint(point) accessibilityAttributeValue:attribute]; |
| 52 EXPECT_NE(nil, value); |
| 53 return value; |
| 54 } |
| 55 |
| 56 id A11yElementAtPoint(const gfx::Point& point) { |
| 57 // Accessibility hit tests come in Cocoa screen coordinates. |
| 58 NSPoint ns_point = gfx::ScreenPointToNSPoint(point); |
| 59 return [widget_->GetNativeWindow() accessibilityHitTest:ns_point]; |
| 60 } |
| 61 |
| 62 gfx::Point TabCenterPoint(int index) { |
| 63 return GetTabAt(index)->GetBoundsInScreen().CenterPoint(); |
| 64 } |
| 65 |
| 66 protected: |
| 67 Widget* widget_ = nullptr; |
| 68 TabbedPane* tabbed_pane_ = nullptr; |
| 69 |
| 70 private: |
| 71 DISALLOW_COPY_AND_ASSIGN(TabbedPaneAccessibilityMacTest); |
| 72 }; |
| 73 |
| 74 // Test the Tab's a11y information compared to a Cocoa NSTabViewItem. |
| 75 TEST_F(TabbedPaneAccessibilityMacTest, AttributesMatchAppKit) { |
| 76 // Create a Cocoa NSTabView to test against and select the first tab. |
| 77 base::scoped_nsobject<NSTabView> cocoa_tab_group( |
| 78 [[NSTabView alloc] initWithFrame:NSMakeRect(50, 50, 100, 100)]); |
| 79 NSArray* cocoa_tabs = @[ |
| 80 [[[NSTabViewItem alloc] init] autorelease], |
| 81 [[[NSTabViewItem alloc] init] autorelease], |
| 82 ]; |
| 83 for (size_t i = 0; i < [cocoa_tabs count]; ++i) { |
| 84 [cocoa_tabs[i] setLabel:[NSString stringWithFormat:@"Tab %zu", i + 1]]; |
| 85 [cocoa_tab_group addTabViewItem:cocoa_tabs[i]]; |
| 86 } |
| 87 |
| 88 // General a11y information. |
| 89 EXPECT_NSEQ( |
| 90 [cocoa_tabs[0] accessibilityAttributeValue:NSAccessibilityRoleAttribute], |
| 91 AttributeValueAtPoint(NSAccessibilityRoleAttribute, TabCenterPoint(0))); |
| 92 EXPECT_NSEQ( |
| 93 [cocoa_tabs[0] |
| 94 accessibilityAttributeValue:NSAccessibilityRoleDescriptionAttribute], |
| 95 AttributeValueAtPoint(NSAccessibilityRoleDescriptionAttribute, |
| 96 TabCenterPoint(0))); |
| 97 EXPECT_NSEQ( |
| 98 [cocoa_tabs[0] accessibilityAttributeValue:NSAccessibilityTitleAttribute], |
| 99 AttributeValueAtPoint(NSAccessibilityTitleAttribute, TabCenterPoint(0))); |
| 100 |
| 101 // Compare the value attribute against native Cocoa and check it matches up |
| 102 // with whether tabs are actually selected. |
| 103 for (int i : {0, 1}) { |
| 104 NSNumber* cocoa_value = [cocoa_tabs[i] |
| 105 accessibilityAttributeValue:NSAccessibilityValueAttribute]; |
| 106 // Verify that only the second tab is selected. |
| 107 EXPECT_EQ(i ? 0 : 1, [cocoa_value intValue]); |
| 108 EXPECT_NSEQ(cocoa_value, |
| 109 AttributeValueAtPoint(NSAccessibilityValueAttribute, |
| 110 TabCenterPoint(i))); |
| 111 } |
| 112 |
| 113 // NSTabViewItem doesn't support NSAccessibilitySelectedAttribute, so don't |
| 114 // compare against Cocoa here. |
| 115 EXPECT_TRUE([AttributeValueAtPoint(NSAccessibilitySelectedAttribute, |
| 116 TabCenterPoint(0)) boolValue]); |
| 117 EXPECT_FALSE([AttributeValueAtPoint(NSAccessibilitySelectedAttribute, |
| 118 TabCenterPoint(1)) boolValue]); |
| 119 } |
| 120 |
| 121 // Make sure tabs can be selected by writing the value attribute. |
| 122 TEST_F(TabbedPaneAccessibilityMacTest, WritableValue) { |
| 123 id tab1_a11y = A11yElementAtPoint(TabCenterPoint(0)); |
| 124 id tab2_a11y = A11yElementAtPoint(TabCenterPoint(1)); |
| 125 |
| 126 // Only unselected tabs should be writable. |
| 127 EXPECT_FALSE([tab1_a11y |
| 128 accessibilityIsAttributeSettable:NSAccessibilityValueAttribute]); |
| 129 EXPECT_TRUE([tab2_a11y |
| 130 accessibilityIsAttributeSettable:NSAccessibilityValueAttribute]); |
| 131 |
| 132 // Select the second tab. AXValue actually accepts any type, but for tabs, |
| 133 // Cocoa uses an integer. Despite this, the Accessibility Inspector provides a |
| 134 // textfield to set the value for a control, so test this with an NSString. |
| 135 [tab2_a11y accessibilitySetValue:@"string" |
| 136 forAttribute:NSAccessibilityValueAttribute]; |
| 137 EXPECT_EQ(0, [AttributeValueAtPoint(NSAccessibilityValueAttribute, |
| 138 TabCenterPoint(0)) intValue]); |
| 139 EXPECT_EQ(1, [AttributeValueAtPoint(NSAccessibilityValueAttribute, |
| 140 TabCenterPoint(1)) intValue]); |
| 141 EXPECT_FALSE([AttributeValueAtPoint(NSAccessibilitySelectedAttribute, |
| 142 TabCenterPoint(0)) boolValue]); |
| 143 EXPECT_TRUE([AttributeValueAtPoint(NSAccessibilitySelectedAttribute, |
| 144 TabCenterPoint(1)) boolValue]); |
| 145 EXPECT_TRUE(GetTabAt(1)->selected()); |
| 146 |
| 147 // It doesn't make sense to 'deselect' a tab (i.e., without specifying another |
| 148 // to select). So any value passed to -accessibilitySetValue: should select |
| 149 // that tab. Try an empty string. |
| 150 [tab1_a11y accessibilitySetValue:@"" |
| 151 forAttribute:NSAccessibilityValueAttribute]; |
| 152 EXPECT_EQ(1, [AttributeValueAtPoint(NSAccessibilityValueAttribute, |
| 153 TabCenterPoint(0)) intValue]); |
| 154 EXPECT_EQ(0, [AttributeValueAtPoint(NSAccessibilityValueAttribute, |
| 155 TabCenterPoint(1)) intValue]); |
| 156 EXPECT_TRUE([AttributeValueAtPoint(NSAccessibilitySelectedAttribute, |
| 157 TabCenterPoint(0)) boolValue]); |
| 158 EXPECT_FALSE([AttributeValueAtPoint(NSAccessibilitySelectedAttribute, |
| 159 TabCenterPoint(1)) boolValue]); |
| 160 EXPECT_TRUE(GetTabAt(0)->selected()); |
| 161 } |
| 162 |
| 163 } // namespace test |
| 164 } // namespace views |
| OLD | NEW |