OLD | NEW |
(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 # -*- coding: utf-8 -*- |
| 6 """Automated tests for many websites""" |
| 7 |
| 8 import argparse |
| 9 import logging |
| 10 |
| 11 from environment import Environment |
| 12 from websitetest import WebsiteTest |
| 13 |
| 14 |
| 15 class Facebook(WebsiteTest): |
| 16 |
| 17 def Login(self): |
| 18 self.GoTo("https://www.facebook.com") |
| 19 self.FillUsernameInto("[name='email']") |
| 20 self.FillPasswordInto("[name='pass']") |
| 21 self.Submit("[name='pass']") |
| 22 |
| 23 def Logout(self): |
| 24 self.WaitUntilDisplayed("#userNavigationLabel") |
| 25 self.Click("#userNavigationLabel") |
| 26 self.WaitUntilDisplayed("#logout_form [type='submit']") |
| 27 self.Click("#logout_form [type='submit']") |
| 28 |
| 29 |
| 30 class Google(WebsiteTest): |
| 31 |
| 32 def Login(self): |
| 33 self.GoTo("https://accounts.google.com/ServiceLogin?sacu=1&continue=") |
| 34 self.FillUsernameInto("#Email") |
| 35 self.FillPasswordInto("#Passwd") |
| 36 self.Submit("#Passwd") |
| 37 |
| 38 def Logout(self): |
| 39 self.GoTo("https://accounts.google.com/Logout") |
| 40 |
| 41 |
| 42 class Linkedin(WebsiteTest): |
| 43 |
| 44 def Login(self): |
| 45 self.GoTo("https://www.linkedin.com") |
| 46 self.FillUsernameInto("#session_key-login") |
| 47 self.FillPasswordInto("#session_password-login") |
| 48 self.Submit("#session_password-login") |
| 49 |
| 50 def Logout(self): |
| 51 self.WaitUntilDisplayed(".account-toggle") |
| 52 self.HoverOver(".account-toggle") |
| 53 self.WaitUntilDisplayed(".account-settings .act-set-action") |
| 54 self.Click(".account-settings .act-set-action") |
| 55 |
| 56 |
| 57 class Mailru(WebsiteTest): |
| 58 |
| 59 def Login(self): |
| 60 self.GoTo("https://mail.ru") |
| 61 self.FillUsernameInto("#mailbox__login") |
| 62 self.FillPasswordInto("#mailbox__password") |
| 63 self.Submit("#mailbox__password") |
| 64 |
| 65 def Logout(self): |
| 66 self.Click("#PH_logoutLink") |
| 67 |
| 68 |
| 69 class Nytimes(WebsiteTest): |
| 70 |
| 71 def Login(self): |
| 72 self.GoTo("https://myaccount.nytimes.com/auth/login") |
| 73 self.FillUsernameInto("#userid") |
| 74 self.FillPasswordInto("#password") |
| 75 self.Submit("#password") |
| 76 |
| 77 def Logout(self): |
| 78 self.GoTo("https://myaccount.nytimes.com/gst/signout") |
| 79 |
| 80 |
| 81 class Pinterest(WebsiteTest): |
| 82 |
| 83 def Login(self): |
| 84 self.GoTo("https://www.pinterest.com/login/") |
| 85 self.FillUsernameInto("[name='username_or_email']") |
| 86 self.FillPasswordInto("[name='password']") |
| 87 self.Submit("[name='password']") |
| 88 |
| 89 def Logout(self): |
| 90 self.GoTo("https://www.pinterest.com/logout/") |
| 91 |
| 92 |
| 93 class Reddit(WebsiteTest): |
| 94 |
| 95 def Login(self): |
| 96 self.GoTo("http://www.reddit.com") |
| 97 self.Click(".user .login-required") |
| 98 self.FillUsernameInto("#user_login") |
| 99 self.FillPasswordInto("#passwd_login") |
| 100 self.Wait(2) |
| 101 self.Submit("#passwd_login") |
| 102 |
| 103 def Logout(self): |
| 104 self.Click("form[action='http://www.reddit.com/logout'] a") |
| 105 |
| 106 |
| 107 class Tumblr(WebsiteTest): |
| 108 |
| 109 def Login(self): |
| 110 self.GoTo("https://www.tumblr.com/login") |
| 111 self.FillUsernameInto("#signup_email") |
| 112 self.FillPasswordInto("#signup_password") |
| 113 self.Submit("#signup_password") |
| 114 |
| 115 def Logout(self): |
| 116 self.GoTo("https://www.tumblr.com/logout") |
| 117 |
| 118 |
| 119 class Wikipedia(WebsiteTest): |
| 120 |
| 121 def Login(self): |
| 122 self.GoTo("https://en.wikipedia.org/w/index.php?title=Special:UserLogin") |
| 123 self.FillUsernameInto("#wpName1") |
| 124 self.FillPasswordInto("#wpPassword1") |
| 125 self.Submit("#wpPassword1") |
| 126 |
| 127 def Logout(self): |
| 128 self.GoTo("https://en.wikipedia.org/w/index.php?title=Special:UserLogout") |
| 129 |
| 130 |
| 131 class Yandex(WebsiteTest): |
| 132 |
| 133 def Login(self): |
| 134 self.GoTo("https://mail.yandex.com") |
| 135 self.FillUsernameInto("#b-mail-domik-username11") |
| 136 self.FillPasswordInto("#b-mail-domik-password11") |
| 137 self.Click(".b-mail-button__button") |
| 138 |
| 139 def Logout(self): |
| 140 while not self.IsDisplayed(".b-mail-dropdown__item__content" |
| 141 u".Выход.daria-action"): |
| 142 self.ClickIfClickable(".header-user-pic.b-mail-dropdown__handle") |
| 143 self.Wait(1) |
| 144 self.Click(u".b-mail-dropdown__item__content.Выход.daria-action") |
| 145 |
| 146 |
| 147 # Disabled tests. |
| 148 |
| 149 |
| 150 # Bug not reproducible without test. |
| 151 class Amazon(WebsiteTest): |
| 152 |
| 153 def Login(self): |
| 154 self.GoTo( |
| 155 "https://www.amazon.com/ap/signin?openid.assoc_handle=usflex" |
| 156 "&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net" |
| 157 "%2Fauth%2F2.0") |
| 158 self.FillUsernameInto("[name='email']") |
| 159 self.FillPasswordInto("[name='password']") |
| 160 self.Submit("[name='password']") |
| 161 |
| 162 def Logout(self): |
| 163 while not self.IsDisplayed("#nav-item-signout"): |
| 164 self.Wait(1) |
| 165 self.HoverOver("#nav-signin-title") |
| 166 self.Click("#nav-item-signout") |
| 167 |
| 168 |
| 169 # Password not saved. |
| 170 class Ask(WebsiteTest): |
| 171 |
| 172 def Login(self): |
| 173 self.GoTo("http://www.ask.com/answers/browse?qsrc=321&q=&o=0&l=dir#") |
| 174 while not self.IsDisplayed("[name='username']"): |
| 175 self.Click("#a16CnbSignInText") |
| 176 self.Wait(1) |
| 177 self.FillUsernameInto("[name='username']") |
| 178 self.FillPasswordInto("[name='password']") |
| 179 self.Click(".signin_show.signin_submit") |
| 180 |
| 181 def Logout(self): |
| 182 self.WaitUntilDisplayed("#a16CnbSignInText") |
| 183 self.Click("#a16CnbSignInText") |
| 184 |
| 185 |
| 186 # Password not saved. |
| 187 class Baidu(WebsiteTest): |
| 188 |
| 189 def Login(self): |
| 190 self.GoTo("http://www.baidu.com/") |
| 191 self.Click("[name='tj_login']") |
| 192 self.WaitUntilDisplayed("[name='userName']") |
| 193 self.FillUsernameInto("[name='userName']") |
| 194 self.FillPasswordInto("[name='password']") |
| 195 self.Submit("[name='password']") |
| 196 |
| 197 def Logout(self): |
| 198 self.Wait(1) |
| 199 self.GoTo("https://passport.baidu.com/?logout&u=http://www.baidu.com") |
| 200 |
| 201 |
| 202 # http://crbug.com/368690 |
| 203 class Cnn(WebsiteTest): |
| 204 |
| 205 def Login(self): |
| 206 self.GoTo("http://www.cnn.com") |
| 207 self.Wait(5) |
| 208 while not self.IsDisplayed(".cnnOvrlyBtn.cnnBtnLogIn"): |
| 209 self.ClickIfClickable("#hdr-auth .no-border.no-pad-right a") |
| 210 self.Wait(1) |
| 211 |
| 212 self.Click(".cnnOvrlyBtn.cnnBtnLogIn") |
| 213 self.FillUsernameInto("#cnnOverlayEmail1l") |
| 214 self.FillPasswordInto("#cnnOverlayPwd") |
| 215 self.Click(".cnnOvrlyBtn.cnnBtnLogIn") |
| 216 self.Click(".cnnOvrlyBtn.cnnBtnLogIn") |
| 217 self.Wait(5) |
| 218 |
| 219 def Logout(self): |
| 220 self.Wait(4) |
| 221 self.Click("#hdr-auth .no-border.no-pad-right") |
| 222 |
| 223 |
| 224 # http://crbug.com/368690 |
| 225 class Ebay(WebsiteTest): |
| 226 |
| 227 def Login(self): |
| 228 self.GoTo("https://signin.ebay.com/") |
| 229 self.FillUsernameInto("[name='userid']") |
| 230 self.FillPasswordInto("[name='pass']") |
| 231 self.Submit("[name='pass']") |
| 232 |
| 233 def Logout(self): |
| 234 self.WaitUntilDisplayed("#gh-ug") |
| 235 self.Click("#gh-ug") |
| 236 self.WaitUntilDisplayed("#gh-uo") |
| 237 self.Click("#gh-uo") |
| 238 |
| 239 |
| 240 # Iframe, password saved but not autofileld. |
| 241 class Espn(WebsiteTest): |
| 242 |
| 243 def Login(self): |
| 244 self.GoTo("http://espn.go.com/") |
| 245 while not self.IsDisplayed("#cboxLoadedContent iframe"): |
| 246 self.Click("#signin .cbOverlay") |
| 247 self.Wait(1) |
| 248 frame = self.driver.find_element_by_css_selector("#cboxLoadedContent " |
| 249 "iframe") |
| 250 self.driver.switch_to_frame(frame) |
| 251 self.WaitUntilDisplayed("#username") |
| 252 self.FillUsernameInto("#username") |
| 253 self.FillPasswordInto("#password") |
| 254 while self.IsDisplayed("#password"): |
| 255 self.ClickIfClickable("#submitBtn") |
| 256 self.Wait(1) |
| 257 |
| 258 def Logout(self): |
| 259 self.WaitUntilDisplayed("#signin .small") |
| 260 self.Click("#signin .small") |
| 261 |
| 262 |
| 263 # http://crbug.com/367768 |
| 264 class Live(WebsiteTest): |
| 265 |
| 266 def Login(self): |
| 267 self.GoTo("https://www.live.com") |
| 268 self.FillUsernameInto("[name='login']") |
| 269 self.FillPasswordInto("[name='passwd']") |
| 270 self.Submit("[name='passwd']") |
| 271 |
| 272 def Logout(self): |
| 273 self.WaitUntilDisplayed("#c_meun") |
| 274 self.Click("#c_meun") |
| 275 self.WaitUntilDisplayed("#c_signout") |
| 276 self.Click("#c_signout") |
| 277 |
| 278 |
| 279 # http://crbug.com/368690 |
| 280 class One63(WebsiteTest): |
| 281 |
| 282 def Login(self): |
| 283 self.GoTo("http://www.163.com") |
| 284 self.HoverOver("#js_N_navHighlight") |
| 285 self.WaitUntilDisplayed("#js_loginframe_username") |
| 286 self.FillUsernameInto("#js_loginframe_username") |
| 287 self.FillPasswordInto(".ntes-loginframe-label-ipt[type='password']") |
| 288 self.Click(".ntes-loginframe-btn") |
| 289 |
| 290 def Logout(self): |
| 291 self.WaitUntilDisplayed("#js_N_navLogout") |
| 292 self.Click("#js_N_navLogout") |
| 293 |
| 294 |
| 295 # http://crbug.com/368690 |
| 296 class Vube(WebsiteTest): |
| 297 |
| 298 def Login(self): |
| 299 self.GoTo("https://vube.com") |
| 300 self.Click("[vube-login='']") |
| 301 self.WaitUntilDisplayed("[ng-model='login.user']") |
| 302 self.FillUsernameInto("[ng-model='login.user']") |
| 303 self.FillPasswordInto("[ng-model='login.pass']") |
| 304 while (self.IsDisplayed("[ng-model='login.pass']") |
| 305 and not self.IsDisplayed(".prompt.alert")): |
| 306 self.ClickIfClickable("[ng-click='login()']") |
| 307 self.Wait(1) |
| 308 |
| 309 def Logout(self): |
| 310 self.WaitUntilDisplayed("[ng-click='user.logout()']") |
| 311 self.Click("[ng-click='user.logout()']") |
| 312 |
| 313 |
| 314 # Tests that can cause a crash. |
| 315 |
| 316 |
| 317 class Yahoo(WebsiteTest): |
| 318 |
| 319 def Login(self): |
| 320 self.GoTo("https://login.yahoo.com") |
| 321 self.FillUsernameInto("#username") |
| 322 self.FillPasswordInto("#passwd") |
| 323 self.Submit("#passwd") |
| 324 |
| 325 def Logout(self): |
| 326 self.WaitUntilDisplayed(".tab.tab-user>.mod.view_default") |
| 327 self.HoverOver(".tab.tab-user>.mod.view_default") |
| 328 self.WaitUntilDisplayed("[data-pos='4'] .lbl.y-link-1") |
| 329 self.Click("[data-pos='4'] .lbl.y-link-1") |
| 330 |
| 331 |
| 332 def Tests(environment): |
| 333 |
| 334 |
| 335 # Working tests. |
| 336 |
| 337 |
| 338 environment.AddWebsiteTest(Facebook("facebook")) |
| 339 |
| 340 environment.AddWebsiteTest(Google("google")) |
| 341 |
| 342 environment.AddWebsiteTest(Linkedin("linkedin")) |
| 343 |
| 344 environment.AddWebsiteTest(Mailru("mailru")) |
| 345 |
| 346 environment.AddWebsiteTest(Nytimes("nytimes")) |
| 347 |
| 348 environment.AddWebsiteTest(Pinterest("pinterest")) |
| 349 |
| 350 environment.AddWebsiteTest(Reddit("reddit", username_not_auto=True)) |
| 351 |
| 352 environment.AddWebsiteTest(Tumblr("tumblr", username_not_auto=True)) |
| 353 |
| 354 environment.AddWebsiteTest(Wikipedia("wikipedia", username_not_auto=True)) |
| 355 |
| 356 environment.AddWebsiteTest(Yandex("yandex")) |
| 357 |
| 358 |
| 359 # Disabled tests. |
| 360 |
| 361 |
| 362 # Bug not reproducible without test. |
| 363 environment.AddWebsiteTest(Amazon("amazon"), disabled=True) |
| 364 |
| 365 # Password not saved. |
| 366 environment.AddWebsiteTest(Ask("ask"), disabled=True) |
| 367 |
| 368 # Password not saved. |
| 369 environment.AddWebsiteTest(Baidu("baidu"), disabled=True) |
| 370 |
| 371 # http://crbug.com/368690 |
| 372 environment.AddWebsiteTest(Cnn("cnn"), disabled=True) |
| 373 |
| 374 # http://crbug.com/368690 |
| 375 environment.AddWebsiteTest(Ebay("ebay"), disabled=True) |
| 376 |
| 377 # Iframe, password saved but not autofileld. |
| 378 environment.AddWebsiteTest(Espn("espn"), disabled=True) |
| 379 |
| 380 # http://crbug.com/367768 |
| 381 environment.AddWebsiteTest(Live("live", username_not_auto=True), |
| 382 disabled=True) |
| 383 |
| 384 # http://crbug.com/368690 |
| 385 environment.AddWebsiteTest(One63("163"), disabled=True) |
| 386 |
| 387 # http://crbug.com/368690 |
| 388 environment.AddWebsiteTest(Vube("vube"), disabled=True) |
| 389 |
| 390 # Tests that can cause a crash (the cause of the crash is not related to the |
| 391 # password manager). |
| 392 environment.AddWebsiteTest(Yahoo("yahoo", username_not_auto=True), |
| 393 disabled=True) |
| 394 |
| 395 |
| 396 def RunTests(chrome_path, chromedriver_path, profile_path, |
| 397 environment_passwords_path, enable_automatic_password_saving, |
| 398 environment_numeric_level, log_to_console, environment_log_file, |
| 399 all_tests, tests): |
| 400 |
| 401 """Runs the the tests |
| 402 |
| 403 Args: |
| 404 chrome_path: The chrome binary file. |
| 405 chromedriver_path: The chromedriver binary file. |
| 406 profile_path: The chrome testing profile folder. |
| 407 environment_passwords_path: The usernames and passwords file. |
| 408 enable_automatic_password_saving: If True, the passwords are going to be |
| 409 saved without showing the prompt. |
| 410 environment_numeric_level: The log verbosity. |
| 411 log_to_console: If True, the debug logs will be shown on the console. |
| 412 environment_log_file: The file where to store the log. If it's empty, the |
| 413 log is not stored. |
| 414 all_tests: If True, all the tests are going to be ran. |
| 415 tests: A list of the names of the WebsiteTests that are going to be tested. |
| 416 |
| 417 Raises: |
| 418 Exception: An exception is raised if the one of the tests fails. |
| 419 """ |
| 420 |
| 421 environment = Environment(chrome_path, chromedriver_path, profile_path, |
| 422 environment_passwords_path, |
| 423 enable_automatic_password_saving, |
| 424 environment_numeric_level, |
| 425 log_to_console, |
| 426 environment_log_file) |
| 427 |
| 428 # Test which care about the save-password prompt need the prompt |
| 429 # to be shown. Automatic password saving results in no prompt. |
| 430 run_prompt_tests = not enable_automatic_password_saving |
| 431 |
| 432 Tests(environment) |
| 433 |
| 434 if all_tests: |
| 435 environment.AllTests(run_prompt_tests) |
| 436 elif tests: |
| 437 environment.Test(tests, run_prompt_tests) |
| 438 else: |
| 439 environment.WorkingTests(run_prompt_tests) |
| 440 |
| 441 environment.Quit() |
| 442 |
| 443 |
| 444 # Tests setup. |
| 445 if __name__ == "__main__": |
| 446 parser = argparse.ArgumentParser( |
| 447 description="Password Manager automated tests help.") |
| 448 |
| 449 parser.add_argument( |
| 450 "--chrome-path", action="store", dest="chrome_path", |
| 451 help="Set the chrome path (required).", nargs=1, required=True) |
| 452 parser.add_argument( |
| 453 "--chromedriver-path", action="store", dest="chromedriver_path", |
| 454 help="Set the chromedriver path (required).", nargs=1, required=True) |
| 455 parser.add_argument( |
| 456 "--profile-path", action="store", dest="profile_path", |
| 457 help="Set the profile path (required). You just need to choose a " |
| 458 "temporary empty folder. If the folder is not empty all its content " |
| 459 "is going to be removed.", |
| 460 nargs=1, required=True) |
| 461 |
| 462 parser.add_argument( |
| 463 "--passwords-path", action="store", dest="passwords_path", |
| 464 help="Set the usernames/passwords path (required).", nargs=1, |
| 465 required=True) |
| 466 parser.add_argument("--all", action="store_true", dest="all", |
| 467 help="Run all tests.") |
| 468 parser.add_argument("--log", action="store", nargs=1, dest="log_level", |
| 469 help="Set log level.") |
| 470 |
| 471 parser.add_argument("--log-screen", action="store_true", dest="log_screen", |
| 472 help="Show log on the screen.") |
| 473 parser.add_argument("--log-file", action="store", dest="log_file", |
| 474 help="Write the log in a file.", nargs=1) |
| 475 parser.add_argument("tests", help="Tests to be run.", nargs="*") |
| 476 |
| 477 args = parser.parse_args() |
| 478 |
| 479 passwords_path = args.passwords_path[0] |
| 480 |
| 481 numeric_level = None |
| 482 if args.log_level: |
| 483 numeric_level = getattr(logging, args.log_level[0].upper(), None) |
| 484 if not isinstance(numeric_level, int): |
| 485 raise ValueError("Invalid log level: %s" % args.log_level[0]) |
| 486 |
| 487 log_file = None |
| 488 if args.log_file: |
| 489 log_file = args.log_file[0] |
| 490 |
| 491 # Run the test without enable-automatic-password-saving to check whether or |
| 492 # not the prompt is shown in the way we expected. |
| 493 RunTests(args.chrome_path[0], |
| 494 args.chromedriver_path[0], |
| 495 args.profile_path[0], |
| 496 passwords_path, |
| 497 False, |
| 498 numeric_level, |
| 499 args.log_screen, |
| 500 log_file, |
| 501 args.all, |
| 502 args.tests) |
| 503 |
| 504 # Run the test with enable-automatic-password-saving to check whether or not |
| 505 # the passwords is stored in the the way we expected. |
| 506 RunTests(args.chrome_path[0], |
| 507 args.chromedriver_path[0], |
| 508 args.profile_path[0], |
| 509 passwords_path, |
| 510 True, |
| 511 numeric_level, |
| 512 args.log_screen, |
| 513 log_file, |
| 514 args.all, |
| 515 args.tests) |
OLD | NEW |