Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(855)

Side by Side Diff: components/test/data/password_manager/websitetest.py

Issue 743013004: Move password manager automated tests to its own subdirectory (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/test/data/password_manager/tests.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2014 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 """WebsiteTest testing class."""
6
7 import logging
8 import sys
9 import time
10
11 sys.path.insert(0, '../../../../third_party/webdriver/pylib/')
12
13 from selenium.webdriver.common.action_chains import ActionChains
14 from selenium.webdriver.common.keys import Keys
15
16 import environment
17
18
19 def _IsOneSubstringOfAnother(s1, s2):
20 """Checks if one of the string arguements is substring of the other.
21
22 Args:
23 s1: The first string.
24 s2: The second string.
25 Returns:
26
27 True if one of the string arguements is substring of the other.
28 False otherwise.
29 """
30 return s1 in s2 or s2 in s1
31
32
33 class WebsiteTest:
34 """Handles a tested WebsiteTest."""
35
36 class Mode:
37 """Test mode."""
38 # Password and username are expected to be autofilled.
39 AUTOFILLED = 1
40 # Password and username are not expected to be autofilled.
41 NOT_AUTOFILLED = 2
42
43 def __init__(self):
44 pass
45
46 def __init__(self, name, username_not_auto=False):
47 """Creates a new WebsiteTest.
48
49 Args:
50 name: The website name.
51 username_not_auto: Username inputs in some websites (like wikipedia) are
52 sometimes filled with some messages and thus, the usernames are not
53 automatically autofilled. This flag handles that and disables us from
54 checking if the state of the DOM is the same as the username of
55 website.
56 """
57 # Name of the website
58 self.name = name
59 # Username of the website.
60 self.username = None
61 # Password of the website.
62 self.password = None
63 # Username is not automatically filled.
64 self.username_not_auto = username_not_auto
65 # Autofilling mode.
66 self.mode = self.Mode.NOT_AUTOFILLED
67 # The |remaining_time_to_wait| limits the total time in seconds spent in
68 # potentially infinite loops.
69 self.remaining_time_to_wait = 200
70 # The testing Environment.
71 self.environment = None
72 # The webdriver.
73 self.driver = None
74 # Whether or not the test was run.
75 self.was_run = False
76
77 # Mouse/Keyboard actions.
78
79 def Click(self, selector):
80 """Clicks on an element.
81
82 Args:
83 selector: The element CSS selector.
84 """
85 logging.info("action: Click %s" % selector)
86 self.WaitUntilDisplayed(selector)
87 element = self.driver.find_element_by_css_selector(selector)
88 element.click()
89
90 def ClickIfClickable(self, selector):
91 """Clicks on an element if it's clickable: If it doesn't exist in the DOM,
92 it's covered by another element or it's out viewing area, nothing is
93 done and False is returned. Otherwise, even if the element is 100%
94 transparent, the element is going to receive a click and a True is
95 returned.
96
97 Args:
98 selector: The element CSS selector.
99
100 Returns:
101 True if the click happens.
102 False otherwise.
103 """
104 logging.info("action: ClickIfVisible %s" % selector)
105 self.WaitUntilDisplayed(selector)
106 try:
107 element = self.driver.find_element_by_css_selector(selector)
108 element.click()
109 return True
110 except Exception:
111 return False
112
113 def GoTo(self, url):
114 """Navigates the main frame to the |url|.
115
116 Args:
117 url: The URL.
118 """
119 logging.info("action: GoTo %s" % self.name)
120 if self.environment.first_go_to:
121 self.environment.OpenTabAndGoToInternals(url)
122 self.environment.first_go_to = False
123 else:
124 self.driver.get(url)
125
126 def HoverOver(self, selector):
127 """Hovers over an element.
128
129 Args:
130 selector: The element CSS selector.
131 """
132 logging.info("action: Hover %s" % selector)
133 self.WaitUntilDisplayed(selector)
134 element = self.driver.find_element_by_css_selector(selector)
135 hover = ActionChains(self.driver).move_to_element(element)
136 hover.perform()
137
138 def SendEnterTo(self, selector):
139 """Sends an enter key to an element.
140
141 Args:
142 selector: The element CSS selector.
143 """
144 logging.info("action: SendEnterTo %s" % selector)
145 body = self.driver.find_element_by_tag_name("body")
146 body.send_keys(Keys.ENTER)
147
148 # Waiting/Displaying actions.
149
150 def IsDisplayed(self, selector):
151 """Returns False if an element doesn't exist in the DOM or is 100%
152 transparent. Otherwise, returns True even if it's covered by another
153 element or it's out viewing area.
154
155 Args:
156 selector: The element CSS selector.
157 """
158 logging.info("action: IsDisplayed %s" % selector)
159 try:
160 element = self.driver.find_element_by_css_selector(selector)
161 return element.is_displayed()
162 except Exception:
163 return False
164
165 def Wait(self, duration):
166 """Wait for a duration in seconds. This needs to be used in potentially
167 infinite loops, to limit their running time.
168
169 Args:
170 duration: The time to wait in seconds.
171 """
172 logging.info("action: Wait %s" % duration)
173 time.sleep(duration)
174 self.remaining_time_to_wait -= 1
175 if self.remaining_time_to_wait < 0:
176 raise Exception("Tests took more time than expected for the following "
177 "website : %s \n" % self.name)
178
179 def WaitUntilDisplayed(self, selector, timeout=10):
180 """Waits until an element is displayed.
181
182 Args:
183 selector: The element CSS selector.
184 timeout: The maximum waiting time in seconds before failing.
185 """
186 if not self.IsDisplayed(selector):
187 self.Wait(1)
188 timeout = timeout - 1
189 if (timeout <= 0):
190 raise Exception("Error: Element %s not shown before timeout is "
191 "finished for the following website: %s"
192 % (selector, self.name))
193 else:
194 self.WaitUntilDisplayed(selector, timeout)
195
196 # Form actions.
197
198 def FillPasswordInto(self, selector):
199 """If the testing mode is the Autofilled mode, compares the website
200 password to the DOM state.
201 If the testing mode is the NotAutofilled mode, checks that the DOM state
202 is empty.
203 Then, fills the input with the Website password.
204
205 Args:
206 selector: The password input CSS selector.
207
208 Raises:
209 Exception: An exception is raised if the DOM value of the password is
210 different than the one we expected.
211 """
212 logging.info("action: FillPasswordInto %s" % selector)
213 self.WaitUntilDisplayed(selector)
214 password_element = self.driver.find_element_by_css_selector(selector)
215 # Chrome protects the password inputs and doesn't fill them until
216 # the user interacts with the page. To be sure that such thing has
217 # happened we perform |Keys.CONTROL| keypress.
218 action_chains = ActionChains(self.driver)
219 action_chains.key_down(Keys.CONTROL).key_up(Keys.CONTROL).perform()
220 if self.mode == self.Mode.AUTOFILLED:
221 autofilled_password = password_element.get_attribute("value")
222 if autofilled_password != self.password:
223 raise Exception("Error: autofilled password is different from the one "
224 "we just saved for the following website : %s p1: %s "
225 "p2:%s \n" % (self.name,
226 password_element.get_attribute("value"),
227 self.password))
228
229 elif self.mode == self.Mode.NOT_AUTOFILLED:
230 autofilled_password = password_element.get_attribute("value")
231 if autofilled_password:
232 raise Exception("Error: password is autofilled when it shouldn't be "
233 "for the following website : %s \n"
234 % self.name)
235
236 password_element.send_keys(self.password)
237
238 def FillUsernameInto(self, selector):
239 """If the testing mode is the Autofilled mode, compares the website
240 username to the input value. Then, fills the input with the website
241 username.
242
243 Args:
244 selector: The username input CSS selector.
245
246 Raises:
247 Exception: An exception is raised if the DOM value of the username is
248 different that the one we expected.
249 """
250 logging.info("action: FillUsernameInto %s" % selector)
251 self.WaitUntilDisplayed(selector)
252 username_element = self.driver.find_element_by_css_selector(selector)
253
254 if (self.mode == self.Mode.AUTOFILLED and not self.username_not_auto):
255 if not (username_element.get_attribute("value") == self.username):
256 raise Exception("Error: autofilled username is different form the one "
257 "we just saved for the following website : %s \n" %
258 self.name)
259 else:
260 username_element.clear()
261 username_element.send_keys(self.username)
262
263 def Submit(self, selector):
264 """Finds an element using CSS Selector and calls its submit() handler.
265
266 Args:
267 selector: The input CSS selector.
268 """
269 logging.info("action: Submit %s" % selector)
270 self.WaitUntilDisplayed(selector)
271 element = self.driver.find_element_by_css_selector(selector)
272 element.submit()
273
274 # Login/Logout Methods
275
276 def Login(self):
277 """Login Method. Has to be overloaded by the WebsiteTest test."""
278 raise NotImplementedError("Login is not implemented.")
279
280 def LoginWhenAutofilled(self):
281 """Logs in and checks that the password is autofilled."""
282 self.mode = self.Mode.AUTOFILLED
283 self.Login()
284
285 def LoginWhenNotAutofilled(self):
286 """Logs in and checks that the password is not autofilled."""
287 self.mode = self.Mode.NOT_AUTOFILLED
288 self.Login()
289
290 def Logout(self):
291 """Logout Method."""
292
293 # Tests
294
295 def WrongLoginTest(self):
296 """Does the wrong login test: Tries to login with a wrong password and
297 checks that the password is not saved.
298
299 Raises:
300 Exception: An exception is raised if the test fails: If there is a
301 problem when performing the login (ex: the login button is not
302 available ...), if the state of the username and password fields is
303 not like we expected or if the password is saved.
304 """
305 logging.info("\nWrong Login Test for %s \n" % self.name)
306 try:
307 correct_password = self.password
308 self.password = self.password + "1"
309 self.LoginWhenNotAutofilled()
310 self.password = correct_password
311 self.Wait(2)
312 self.environment.SwitchToInternals()
313 self.environment.CheckForNewMessage(
314 environment.MESSAGE_SAVE,
315 False,
316 "Error: password manager thinks that a login with wrong password was "
317 "successful for the following website : %s \n" % self.name)
318 finally:
319 self.environment.SwitchFromInternals()
320
321 def SuccessfulLoginTest(self):
322 """Does the successful login when the password is not expected to be
323 autofilled test: Checks that the password is not autofilled, tries to login
324 with a right password and checks if the password is saved. Then logs out.
325
326 Raises:
327 Exception: An exception is raised if the test fails: If there is a
328 problem when performing the login and the logout (ex: the login
329 button is not available ...), if the state of the username and
330 password fields is not like we expected or if the password is not
331 saved.
332 """
333 logging.info("\nSuccessful Login Test for %s \n" % self.name)
334 try:
335 self.LoginWhenNotAutofilled()
336 self.Wait(2)
337 self.environment.SwitchToInternals()
338 self.environment.CheckForNewMessage(
339 environment.MESSAGE_SAVE,
340 True,
341 "Error: password manager hasn't detected a successful login for the "
342 "following website : %s \n"
343 % self.name)
344 finally:
345 self.environment.SwitchFromInternals()
346 self.Logout()
347
348 def SuccessfulLoginWithAutofilledPasswordTest(self):
349 """Does the successful login when the password is expected to be autofilled
350 test: Checks that the password is autofilled, tries to login with the
351 autofilled password and checks if the password is saved. Then logs out.
352
353 Raises:
354 Exception: An exception is raised if the test fails: If there is a
355 problem when performing the login and the logout (ex: the login
356 button is not available ...), if the state of the username and
357 password fields is not like we expected or if the password is not
358 saved.
359 """
360 logging.info("\nSuccessful Login With Autofilled Password"
361 " Test %s \n" % self.name)
362 try:
363 self.LoginWhenAutofilled()
364 self.Wait(2)
365 self.environment.SwitchToInternals()
366 self.environment.CheckForNewMessage(
367 environment.MESSAGE_SAVE,
368 True,
369 "Error: password manager hasn't detected a successful login for the "
370 "following website : %s \n"
371 % self.name)
372 finally:
373 self.environment.SwitchFromInternals()
374 self.Logout()
375
376 def PromptTest(self):
377 """Does the prompt test: Tries to login with a wrong password and
378 checks that the prompt is not shown. Then tries to login with a right
379 password and checks that the prompt is not shown.
380
381 Raises:
382 Exception: An exception is raised if the test fails: If there is a
383 problem when performing the login (ex: the login button is not
384 available ...), if the state of the username and password fields is
385 not like we expected or if the prompt is not shown for the right
386 password or is shown for a wrong one.
387 """
388 logging.info("\nPrompt Test for %s \n" % self.name)
389 try:
390 correct_password = self.password
391 self.password = self.password + "1"
392 self.LoginWhenNotAutofilled()
393 self.password = correct_password
394 self.Wait(2)
395 self.environment.SwitchToInternals()
396 self.environment.CheckForNewMessage(
397 environment.MESSAGE_ASK,
398 False,
399 "Error: password manager thinks that a login with wrong password was "
400 "successful for the following website : %s \n" % self.name)
401 self.environment.SwitchFromInternals()
402
403 self.LoginWhenNotAutofilled()
404 self.Wait(2)
405 self.environment.SwitchToInternals()
406 self.environment.CheckForNewMessage(
407 environment.MESSAGE_ASK,
408 True,
409 "Error: password manager hasn't detected a successful login for the "
410 "following website : %s \n" % self.name)
411 finally:
412 self.environment.SwitchFromInternals()
OLDNEW
« no previous file with comments | « components/test/data/password_manager/tests.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698