|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 package org.mozilla.gecko.tests.components; |
|
6 |
|
7 import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertEquals; |
|
8 import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertFalse; |
|
9 import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertNotNull; |
|
10 import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertTrue; |
|
11 |
|
12 import org.mozilla.gecko.R; |
|
13 import org.mozilla.gecko.tests.UITestContext; |
|
14 import org.mozilla.gecko.tests.helpers.DeviceHelper; |
|
15 import org.mozilla.gecko.tests.helpers.WaitHelper; |
|
16 |
|
17 import android.view.View; |
|
18 import android.widget.EditText; |
|
19 import android.widget.ImageButton; |
|
20 import android.widget.TextView; |
|
21 |
|
22 import com.jayway.android.robotium.solo.Condition; |
|
23 import com.jayway.android.robotium.solo.Solo; |
|
24 |
|
25 /** |
|
26 * A class representing any interactions that take place on the Toolbar. |
|
27 */ |
|
28 public class ToolbarComponent extends BaseComponent { |
|
29 public ToolbarComponent(final UITestContext testContext) { |
|
30 super(testContext); |
|
31 } |
|
32 |
|
33 public ToolbarComponent assertIsEditing() { |
|
34 fAssertTrue("The toolbar is in the editing state", isEditing()); |
|
35 return this; |
|
36 } |
|
37 |
|
38 public ToolbarComponent assertIsNotEditing() { |
|
39 fAssertFalse("The toolbar is not in the editing state", isEditing()); |
|
40 return this; |
|
41 } |
|
42 |
|
43 public ToolbarComponent assertTitle(final String expected) { |
|
44 fAssertEquals("The Toolbar title is " + expected, expected, getTitle()); |
|
45 return this; |
|
46 } |
|
47 |
|
48 public ToolbarComponent assertUrl(final String expected) { |
|
49 assertIsEditing(); |
|
50 fAssertEquals("The Toolbar url is " + expected, expected, getUrlEditText().getText()); |
|
51 return this; |
|
52 } |
|
53 |
|
54 /** |
|
55 * Returns the root View for the browser toolbar. |
|
56 */ |
|
57 private View getToolbarView() { |
|
58 return mSolo.getView(R.id.browser_toolbar); |
|
59 } |
|
60 |
|
61 private EditText getUrlEditText() { |
|
62 return (EditText) getToolbarView().findViewById(R.id.url_edit_text); |
|
63 } |
|
64 |
|
65 private View getUrlDisplayLayout() { |
|
66 return getToolbarView().findViewById(R.id.display_layout); |
|
67 } |
|
68 |
|
69 private TextView getUrlTitleText() { |
|
70 return (TextView) getToolbarView().findViewById(R.id.url_bar_title); |
|
71 } |
|
72 |
|
73 private ImageButton getBackButton() { |
|
74 DeviceHelper.assertIsTablet(); |
|
75 return (ImageButton) getToolbarView().findViewById(R.id.back); |
|
76 } |
|
77 |
|
78 private ImageButton getForwardButton() { |
|
79 DeviceHelper.assertIsTablet(); |
|
80 return (ImageButton) getToolbarView().findViewById(R.id.forward); |
|
81 } |
|
82 |
|
83 /** |
|
84 * Returns the View for the edit cancel button in the browser toolbar. |
|
85 */ |
|
86 private ImageButton getEditCancelButton() { |
|
87 return (ImageButton) getToolbarView().findViewById(R.id.edit_cancel); |
|
88 } |
|
89 |
|
90 private CharSequence getTitle() { |
|
91 return getTitleHelper(true); |
|
92 } |
|
93 |
|
94 /** |
|
95 * Returns the title of the page. Note that this makes no assertions to Toolbar state and |
|
96 * may return a value that may never be visible to the user. Callers likely want to use |
|
97 * {@link assertTitle} instead. |
|
98 */ |
|
99 public CharSequence getPotentiallyInconsistentTitle() { |
|
100 return getTitleHelper(false); |
|
101 } |
|
102 |
|
103 private CharSequence getTitleHelper(final boolean shouldAssertNotEditing) { |
|
104 if (shouldAssertNotEditing) { |
|
105 assertIsNotEditing(); |
|
106 } |
|
107 |
|
108 return getUrlTitleText().getText(); |
|
109 } |
|
110 |
|
111 private boolean isEditing() { |
|
112 return getUrlDisplayLayout().getVisibility() != View.VISIBLE && |
|
113 getUrlEditText().getVisibility() == View.VISIBLE; |
|
114 } |
|
115 |
|
116 public ToolbarComponent enterEditingMode() { |
|
117 assertIsNotEditing(); |
|
118 |
|
119 mSolo.clickOnView(getUrlTitleText(), true); |
|
120 |
|
121 waitForEditing(); |
|
122 WaitHelper.waitFor("UrlEditText to be input method target", new Condition() { |
|
123 @Override |
|
124 public boolean isSatisfied() { |
|
125 return getUrlEditText().isInputMethodTarget(); |
|
126 } |
|
127 }); |
|
128 |
|
129 return this; |
|
130 } |
|
131 |
|
132 public ToolbarComponent commitEditingMode() { |
|
133 assertIsEditing(); |
|
134 |
|
135 WaitHelper.waitForPageLoad(new Runnable() { |
|
136 @Override |
|
137 public void run() { |
|
138 mSolo.sendKey(Solo.ENTER); |
|
139 } |
|
140 }); |
|
141 waitForNotEditing(); |
|
142 |
|
143 return this; |
|
144 } |
|
145 |
|
146 public ToolbarComponent dismissEditingMode() { |
|
147 assertIsEditing(); |
|
148 |
|
149 // Cancel Button not implemeneted in tablet. |
|
150 if (DeviceHelper.isTablet()) { |
|
151 if (getUrlEditText().isInputMethodTarget()) { |
|
152 // Drop the soft keyboard. |
|
153 // TODO: Solo.hideSoftKeyboard() does not clear focus, causing unexpected |
|
154 // behavior, but we may want to use it over goBack(). |
|
155 mSolo.goBack(); |
|
156 } |
|
157 |
|
158 mSolo.goBack(); |
|
159 } else { |
|
160 mSolo.clickOnView(getEditCancelButton()); |
|
161 } |
|
162 |
|
163 waitForNotEditing(); |
|
164 |
|
165 return this; |
|
166 } |
|
167 |
|
168 public ToolbarComponent enterUrl(final String url) { |
|
169 fAssertNotNull("url is not null", url); |
|
170 |
|
171 assertIsEditing(); |
|
172 |
|
173 final EditText urlEditText = getUrlEditText(); |
|
174 fAssertTrue("The UrlEditText is the input method target", |
|
175 urlEditText.isInputMethodTarget()); |
|
176 |
|
177 mSolo.clearEditText(urlEditText); |
|
178 mSolo.enterText(urlEditText, url); |
|
179 |
|
180 return this; |
|
181 } |
|
182 |
|
183 public ToolbarComponent pressBackButton() { |
|
184 final ImageButton backButton = getBackButton(); |
|
185 return pressButton(backButton, "back"); |
|
186 } |
|
187 |
|
188 public ToolbarComponent pressForwardButton() { |
|
189 final ImageButton forwardButton = getForwardButton(); |
|
190 return pressButton(forwardButton, "forward"); |
|
191 } |
|
192 |
|
193 private ToolbarComponent pressButton(final View view, final String buttonName) { |
|
194 fAssertNotNull("The " + buttonName + " button View is not null", view); |
|
195 fAssertTrue("The " + buttonName + " button is enabled", view.isEnabled()); |
|
196 fAssertEquals("The " + buttonName + " button is visible", |
|
197 View.VISIBLE, view.getVisibility()); |
|
198 assertIsNotEditing(); |
|
199 |
|
200 WaitHelper.waitForPageLoad(new Runnable() { |
|
201 @Override |
|
202 public void run() { |
|
203 mSolo.clickOnView(view); |
|
204 } |
|
205 }); |
|
206 |
|
207 return this; |
|
208 } |
|
209 |
|
210 private void waitForEditing() { |
|
211 WaitHelper.waitFor("Toolbar to enter editing mode", new Condition() { |
|
212 @Override |
|
213 public boolean isSatisfied() { |
|
214 return isEditing(); |
|
215 } |
|
216 }); |
|
217 } |
|
218 |
|
219 private void waitForNotEditing() { |
|
220 WaitHelper.waitFor("Toolbar to exit editing mode", new Condition() { |
|
221 @Override |
|
222 public boolean isSatisfied() { |
|
223 return !isEditing(); |
|
224 } |
|
225 }); |
|
226 } |
|
227 } |