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

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

Issue 273523004: Password Manager testing automation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: log Created 6 years, 7 months 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
OLDNEW
(Empty)
1 """The testing Environment class."""
2
3 import shutil
4 import time
5
6 from selenium import webdriver
7 from selenium.webdriver.chrome.options import Options
8 from xml.etree import ElementTree
9
10
11 class Environment:
12 """Sets up the testing Environment. """
13
14 def __init__(self, chrome_path, chromedriver_path,
15 profile_path, passwords_path,
16 log_to_screen, log_file):
17 """Creates a new testing Environment.
18
19 Args:
20 chrome_path: The chrome binary file.
21 chromedriver_path: The chromedriver binary file.
22 profile_path: The testing profile folder.
23 passwords_path: The usernames and passwords file.
24 log_to_screen: If set, the tests log is going to be shown on the screen.
25 log_file: The file where to store the log.
26 """
27 # Cleaning the profile folder.
28 try:
29 shutil.rmtree(profile_path)
30 except Exception, e:
31 self.Log(e)
vabr (Chromium) 2014/05/16 09:36:00 This deservers a comment on why is it OK to procee
rchtara 2014/05/20 08:24:47 Done.
32 options = Options()
33 options.add_argument("enable-automatic-password-saving")
34 options.add_argument("enable-password-manager-internals-ui")
vabr (Chromium) 2014/05/16 09:36:00 nit: Since yesterday, this is no more needed. :)
rchtara 2014/05/22 08:44:38 Yes, i have an old version of code, so i need it.
35 # Chrome path.
36 options.binary_location = chrome_path
37 # Testing profile path.
38 options.add_argument("user-data-dir=%s" % profile_path)
39
40 # The webdriver. It's possible to choose the port the service is going to
41 # run on. If it's left to 0, a free port will be found.
42 self.driver = webdriver.Chrome(chromedriver_path, 0, options)
43 # The password internals window.
44 self.internals_window = self.driver.current_window_handle
45 # Password internals page.
46 self.internals_page = "chrome://password-manager-internals/"
47 # The Website window.
48 self.websitewindow = None
49 # The Websites list.
50 self.websites = []
51 # An xml tree filled with logins and passwords.
52 self.passwords_tree = None
53 if passwords_path:
54 self.passwords_tree = ElementTree.parse(passwords_path).getroot()
55 # The Websites list for which we expect the test to be working.
56 self.working_tests = []
57 # The number of the save operations done through all the tests.
vabr (Chromium) 2014/05/16 09:36:00 nit: "through all" contains 2 spaces instead of 1
rchtara 2014/05/20 08:24:47 Done.
58 self.save_count = 0
59
60 self.log_to_screen = log_to_screen
61 self.log_file = None
62 if log_file:
63 self.log_file = open(log_file,'w')
64
65 def AddWebsite(self,
66 website,
67 disabled=False):
68 """Adds a Website to the testing Environment.
vabr (Chromium) 2014/05/16 09:36:00 Actually, what do you think of renaming Website to
rchtara 2014/05/20 08:24:47 Done.
69
70 Args:
71 website: The Website instance that's going to be added to the testing
72 Environment.
73 disabled: Test is disabled.
74 """
75 website.environment = self
76 website.driver = self.driver
77 if self.passwords_tree is not None:
vabr (Chromium) 2014/05/16 09:36:00 nit: Just use if self.passwords_tree:
rchtara 2014/05/20 08:24:47 I got this warning when I tied to replace this Non
vabr (Chromium) 2014/05/20 14:47:25 Fair enough. Your test for "is not None" is actual
rchtara 2014/05/22 08:44:38 No problem
78 if not website.username:
79 username_tag = (
80 self.passwords_tree.find(
81 ".//*[@name='%s']/username" % website.name))
82 if username_tag.text:
83 website.username = username_tag.text
84 if not website.password:
85 password_tag = (
86 self.passwords_tree.find(
87 ".//*[@name='%s']/password" % website.name))
88 if password_tag.text:
89 website.password = password_tag.text
90 self.websites.append(website)
91 if disabled == False:
vabr (Chromium) 2014/05/16 09:36:00 nit: Just use: if not disabled:
rchtara 2014/05/20 08:24:47 Done.
92 self.working_tests.append(website.name)
93
94 def RemoveAllPasswords(self, websites):
95 """Removes the stored passwords for all Websites.
vabr (Chromium) 2014/05/16 09:36:00 Why don't you just flush all the stored passwords,
rchtara 2014/05/20 08:24:47 Done.
96
97 Args:
98 websites: The Websites which the passwords are going to be removed.
99 """
100 self.Log("\nRemoveAllPasswords\n")
101 self.driver.get("chrome://settings/passwords")
102 self.driver.switch_to_frame("settings")
103 for website in websites:
104 urls = self.GetURLs()
105 website.RemoveAllPasswords(urls)
106
107 def GetURLs(self):
108 """Gets all URLs of the saved passwords in the chrome://settings/passwords.
109
110 Returns:
111 A list of the URLs.
112 """
113 deletable_passwords = self.driver.find_elements_by_css_selector(
114 "#saved-passwords-list .deletable-item")
115 urls = []
116 for entry in deletable_passwords:
117 urls.append(entry.find_element_by_class_name("url").text)
118 return urls
119
120 def OpenTabAndGoInternal(self):
vabr (Chromium) 2014/05/16 09:36:00 nit: Please rename to OpenTabAndGoToInternals ("go
rchtara 2014/05/20 08:24:47 Done.
121 """Opens a new tab and navigates to passwords internals page in the first
vabr (Chromium) 2014/05/16 09:36:00 The comment does not seem to match the code exactl
rchtara 2014/05/20 08:24:47 Done.
122 tab."""
123 if not self.websitewindow:
124 self.driver.get("https://google.com")
vabr (Chromium) 2014/05/16 09:36:00 Would chrome://newtab work instead of google.com?
rchtara 2014/05/20 08:24:47 I updated the test to go to the url of the first w
vabr (Chromium) 2014/05/20 14:47:25 Great, thanks for fixing this!
rchtara 2014/05/22 08:44:38 Thanks :)
125 # There is no straightforward way to open a new tab with chromedriver.
126 # One work-around is to go to a website, insert a link that is going
127 # to be opened in a new tab, click on it. To avoid that the chrome popup
128 # blocker blocks the new tab, we need to choose a trusted website which
129 # is google.com.
130 a = self.driver.execute_script(
131 "var a = document.createElement('a');"
132 "a.target = '_blank';"
133 "a.href = arguments[0];"
134 "a.innerHTML = '.';"
135 "document.body.appendChild(a);"
136 "return a;",
137 "https://google.com")
138
139 a.click()
140 time.sleep(1)
vabr (Chromium) 2014/05/16 09:36:00 It's a bit unfortunate that this sleep() does not
rchtara 2014/05/20 08:24:47 I don't think it's make sense to do that.max_durat
vabr (Chromium) 2014/05/20 14:47:25 OK, makes sense, I misunderstood the function of m
rchtara 2014/05/22 08:44:38 Done.
141
142 self.websitewindow = self.driver.window_handles[-1]
143 self.driver.get(self.internals_page)
144 self.driver.switch_to_window(self.websitewindow)
145
146 def SwitchToInternals(self):
147 """Switches from the Website window to internals tab."""
148 self.driver.switch_to_window(self.internals_window)
149
150 def SwitchFromInternals(self):
151 """Switches from internals tab to the Website window."""
152 self.driver.switch_to_window(self.websitewindow)
153
154 def CheckPromptIsNotShown(self, expected, msg, timeout=10):
155 """Checks if the prompt was shown: If the prompt is shown when it shouldn't
vabr (Chromium) 2014/05/16 09:36:00 nit: CheckPromptIsNotShown ... Checks if the promp
rchtara 2014/05/20 08:24:47 Done.
156 be or is not shown when it should be, raise an exception.
157
158 Args:
159 expected: Whether or not the prompt is expected to be shown.
160 msg: Error message for the exception.
161 timeout: There is some delay between the login and the password
162 internals update. In case nothing is detected, the method is going to
163 wait and execute itself recursively until the time will end.
vabr (Chromium) 2014/05/16 09:36:00 This is not clear (and also does not mention the t
rchtara 2014/05/20 08:24:47 Done.
164
165 Raises:
166 Exception: An exception is raised in case there a problem.
167 """
168 if expected:
169 self.save_count += 1
170 log = self.driver.find_element_by_css_selector("#log-entries")
171 count = log.text.count("Message: Decision: SAVE the password")
vabr (Chromium) 2014/05/16 09:36:00 This is not correct. The message actually says tha
rchtara 2014/05/20 08:24:47 Done.
172
173 if count < self.save_count and timeout > 0:
174 time.sleep(1)
175 self.CheckPromptIsNotShown(False, msg, timeout - 1)
176
177 elif not self.save_count == count:
178 raise Exception(msg)
179
180 def Log(self, text):
vabr (Chromium) 2014/05/16 09:36:00 Please use the standard Python logging support ins
rchtara 2014/05/20 08:24:47 Done.
181 """Writes to the log.
182 Args:
183 text: Text to be written.
184 """
185 if self.log_to_screen:
186 print text
187 if self.log_file:
188 self.log_file.write("%s \n" % text)
189
190 def TestList(self, websites):
191 """Runs the tests on many Websites.
vabr (Chromium) 2014/05/16 09:36:00 nit: "many Websites" is unnecessarily vague. Just
rchtara 2014/05/20 08:24:47 Done.
vabr (Chromium) 2014/05/20 14:47:25 That's not what I meant: you still kept "many". I
rchtara 2014/05/22 08:44:38 sorry :)
192 Args:
193 websites: A list of Websites that are going to be tested.
194 Raises:
195 Exception: An exception is raised if the tests fail.
196 """
197 self.RemoveAllPasswords(websites)
198
199 self.OpenTabAndGoInternal()
200 for website in websites:
201 website.WrongLoginTest()
202 website.SuccessfulLoginTest()
203 website.SuccessfulLoginWithAutofilledPasswordTest()
204
205 self.RemoveAllPasswords(websites)
206 for website in websites:
207 website.SuccessfulLoginAfterDeletionTest()
208
209 def AllTests(self):
210 """Runs the tests on all the websites.
211 Raises:
212 Exception: An exception is raised if the tests fail.
213 """
214 self.TestList(self.websites)
215
216 def WorkingTests(self):
217 """Runs the tests on all the working websites.
218 Raises:
219 Exception: An exception is raised if the tests fail.
220 """
221 self.Test(self.working_tests)
222
223 def Test(self, tests):
224 """Runs the tests on many websites.
225 Args:
226 tests: A list of the names of the websites that are going to be tested.
227 Raises:
228 Exception: An exception is raised if the tests fail.
229 """
230 websites = []
231 for website in self.websites:
232 if website.name in tests:
233 websites.append(website)
234 self.TestList(websites)
235
236 def Quit(self):
237 """Closes the tests."""
238 # Close the log file if it's open.
239 if self.log_file:
240 self.log_file.close()
241 # Close the webdriver.
242 self.driver.quit()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698