[11949] | 1 | Browsing Ikoba |
---|
[7321] | 2 | ************* |
---|
[6607] | 3 | |
---|
[11949] | 4 | Here we visit all parts of a Ikoba portal using a browser. |
---|
[6607] | 5 | |
---|
[11954] | 6 | Company |
---|
[12993] | 7 | ======= |
---|
[6607] | 8 | |
---|
| 9 | We can watch universities in the browser. |
---|
| 10 | |
---|
[11954] | 11 | We create an company object and put into the ZODB root:: |
---|
[6607] | 12 | |
---|
| 13 | >>> root = getRootFolder() |
---|
| 14 | >>> list(root) |
---|
| 15 | [] |
---|
| 16 | |
---|
[11954] | 17 | >>> from waeup.ikoba.app import Company |
---|
| 18 | >>> u = Company() |
---|
| 19 | >>> root['mycompany'] = u |
---|
[6607] | 20 | >>> list(root) |
---|
[11954] | 21 | [u'mycompany'] |
---|
[6607] | 22 | |
---|
| 23 | >>> from zope.component.hooks import setSite |
---|
[11954] | 24 | >>> setSite(root['mycompany']) |
---|
[6607] | 25 | |
---|
[6609] | 26 | To make sure, we can 'watch' pages, we first have to initialize out |
---|
| 27 | test browser:: |
---|
| 28 | |
---|
| 29 | >>> from zope.testbrowser.testing import Browser |
---|
| 30 | >>> browser = Browser() |
---|
| 31 | |
---|
[11954] | 32 | Let's get the default view of a company:: |
---|
[6607] | 33 | |
---|
[11954] | 34 | >>> browser.open('http://localhost/mycompany') |
---|
[6607] | 35 | >>> print browser.contents |
---|
| 36 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
[11949] | 37 | ...Welcome to WAeUP.Ikoba... |
---|
[6607] | 38 | ... |
---|
| 39 | |
---|
[7674] | 40 | We can change to German:: |
---|
| 41 | >>> browser.getLink('de').click() |
---|
| 42 | >>> print browser.contents |
---|
| 43 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
| 44 | ...Anfragen... |
---|
| 45 | ... |
---|
| 46 | |
---|
| 47 | And then change back to English by clicking on the third link containing 'en' |
---|
| 48 | behind 'Anfragen' and 'Einloggen':: |
---|
[12764] | 49 | >>> browser.getLink('en', index=2).click() |
---|
[7674] | 50 | >>> print browser.contents |
---|
| 51 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
| 52 | ...Enquiries... |
---|
| 53 | ... |
---|
| 54 | |
---|
[6609] | 55 | The contact form for anonymous users is called 'Enquiries':: |
---|
[6607] | 56 | |
---|
[11954] | 57 | >>> browser.open('http://localhost/mycompany') |
---|
[6609] | 58 | >>> browser.getLink('Enquiries').click() |
---|
[7225] | 59 | >>> browser.getControl('Send').click() |
---|
[6609] | 60 | >>> print browser.contents |
---|
| 61 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
[7234] | 62 | ...Required input is missing... |
---|
[6609] | 63 | ... |
---|
| 64 | |
---|
[7225] | 65 | >>> browser.getControl(name='form.fullname').value = "Bob Tester" |
---|
| 66 | >>> browser.getControl(name='form.email_from').value = "xx@yy.zz" |
---|
[7401] | 67 | >>> browser.getControl(name='form.body').value = u'test message' |
---|
[7225] | 68 | >>> browser.getControl('Send').click() |
---|
[6611] | 69 | >>> print browser.contents |
---|
| 70 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
[7459] | 71 | ...Your message has been sent... |
---|
[6611] | 72 | ... |
---|
| 73 | |
---|
[8364] | 74 | Registered users with an email address can request a password change: |
---|
| 75 | |
---|
[11954] | 76 | >>> root['mycompany']['users'].addUser('forgetful', 'secret',title='Bob Forgetful', |
---|
[8364] | 77 | ... description='A forgetful user', email='aa@aa.ng') |
---|
[11954] | 78 | >>> browser.open('http://localhost/mycompany/changepw') |
---|
[8364] | 79 | >>> browser.getControl(name="form.email").value = 'aa@aa.ng' |
---|
[9178] | 80 | >>> browser.getControl("Send login credentials").click() |
---|
[8364] | 81 | >>> print browser.contents |
---|
| 82 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
| 83 | ...An email with your user name and password has been sent to aa@aa.ng... |
---|
| 84 | |
---|
[6609] | 85 | Now we login as manager:: |
---|
| 86 | |
---|
| 87 | >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw') |
---|
| 88 | >>> browser.handleErrors = False |
---|
| 89 | |
---|
[6907] | 90 | We can then get an edit view of the configuration container:: |
---|
[6609] | 91 | |
---|
[11954] | 92 | >>> browser.open('http://localhost/mycompany/configuration') |
---|
[6607] | 93 | >>> print browser.contents |
---|
| 94 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
[11954] | 95 | ...<form action="http://localhost/mycompany/configuration/@@index" |
---|
[6607] | 96 | ... |
---|
| 97 | |
---|
[11954] | 98 | The edit form contains the default value for the company name:: |
---|
[6607] | 99 | |
---|
[11954] | 100 | >>> 'Sample Company' in browser.contents |
---|
[6607] | 101 | True |
---|
[7208] | 102 | |
---|
[6607] | 103 | We can perform several actions on the edit form:: |
---|
| 104 | |
---|
| 105 | >>> browser.getControl("Save", index=0).click() |
---|
| 106 | >>> print browser.contents |
---|
| 107 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
[8739] | 108 | ...Form has been saved... |
---|
[6607] | 109 | ... |
---|
| 110 | |
---|
[11954] | 111 | >>> browser.open('http://localhost/mycompany/configuration') |
---|
[6607] | 112 | >>> browser.getControl("Update plugins").click() |
---|
| 113 | >>> print browser.contents |
---|
| 114 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
[7459] | 115 | ...Plugins were updated. See log file for details... |
---|
[6607] | 116 | ... |
---|
| 117 | |
---|
[8364] | 118 | The default frontpage HTML has been saved in a dictionary |
---|
[7704] | 119 | and is properly rendered on the frontpage of the portal: |
---|
| 120 | |
---|
[11954] | 121 | >>> browser.open('http://localhost/mycompany') |
---|
[7704] | 122 | >>> print browser.contents |
---|
| 123 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
[11949] | 124 | ...<h1>Welcome to WAeUP.Ikoba...</h1> |
---|
[7704] | 125 | ... |
---|
| 126 | |
---|
| 127 | The German part is really not being rendered: |
---|
| 128 | |
---|
| 129 | >>> 'Willkommen' in browser.contents |
---|
| 130 | False |
---|
| 131 | |
---|
| 132 | |
---|
| 133 | If we change to German so that the German part of frontpage.rst is rendered: |
---|
| 134 | |
---|
[11954] | 135 | >>> browser.open('http://localhost/mycompany//@@change_language?lang=de') |
---|
[7704] | 136 | >>> print browser.contents |
---|
| 137 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
[11949] | 138 | ...<h1>Willkommen auf WAeUP.Ikoba...</h1> |
---|
[7704] | 139 | ... |
---|
| 140 | |
---|
| 141 | The English part is really not being rendered: |
---|
| 142 | |
---|
| 143 | >>> 'Welcome' in browser.contents |
---|
| 144 | False |
---|
| 145 | |
---|
| 146 | Switch back to English: |
---|
| 147 | |
---|
[11954] | 148 | >>> browser.open('http://localhost/mycompany//@@change_language?lang=en') |
---|
[7704] | 149 | |
---|
[6607] | 150 | |
---|
[12525] | 151 | Officers |
---|
| 152 | ======== |
---|
[6607] | 153 | |
---|
[11954] | 154 | >>> browser.open('http://localhost/mycompany') |
---|
[12525] | 155 | >>> browser.getLink('Officers').click() |
---|
[6607] | 156 | >>> print browser.contents |
---|
| 157 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
[12525] | 158 | ...Officers... |
---|
[6607] | 159 | ... |
---|
| 160 | |
---|
| 161 | We can add users: |
---|
| 162 | |
---|
| 163 | >>> browser.getLink("Add user").click() |
---|
| 164 | >>> browser.getControl(name="form.name").value = 'bob' |
---|
[8759] | 165 | >>> browser.getControl(name="form.title").value = 'Bob The User' |
---|
[7149] | 166 | >>> browser.getControl(name="password").value = 'secret' |
---|
| 167 | >>> browser.getControl(name="control_password").value = 'secret' |
---|
[7222] | 168 | >>> browser.getControl(name="form.email").value = 'xx@yy.zz' |
---|
[7869] | 169 | >>> browser.getControl(name="form.phone.country").value = ['+234'] |
---|
| 170 | >>> browser.getControl(name="form.phone.area").value = '123' |
---|
| 171 | >>> browser.getControl(name="form.phone.ext").value = '45678' |
---|
[6607] | 172 | >>> browser.getControl("Add user").click() |
---|
| 173 | >>> print browser.contents |
---|
| 174 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
| 175 | ...<td>bob</td> |
---|
| 176 | ... |
---|
| 177 | |
---|
| 178 | We can edit user bob: |
---|
| 179 | |
---|
[7707] | 180 | >>> browser.getControl("Manage", index=0).click() |
---|
[6607] | 181 | >>> browser.getControl("Save", index=0).click() |
---|
| 182 | >>> browser.getControl("Cancel", index=0).click() |
---|
| 183 | |
---|
[7178] | 184 | We can add site roles which are then displayed on the user container page. |
---|
| 185 | Since the test browser does not use javascript, we have to add site roles |
---|
[6607] | 186 | manually by setting the roles attribute: |
---|
| 187 | |
---|
[12328] | 188 | Since JS is not supported by the test browser, the default role has been removed |
---|
| 189 | when clicking the Save button. |
---|
| 190 | |
---|
[11954] | 191 | >>> print root['mycompany']['users']['bob'].roles |
---|
[6607] | 192 | [] |
---|
[11954] | 193 | >>> root['mycompany']['users']['bob'].roles = ['waeup.UsersManager'] |
---|
| 194 | >>> print root['mycompany']['users']['bob'].roles |
---|
[11947] | 195 | ['waeup.UsersManager'] |
---|
[11954] | 196 | >>> browser.open('http://localhost/mycompany/users') |
---|
[6607] | 197 | >>> print browser.contents |
---|
| 198 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
[11947] | 199 | ...<td nowrap>Users Manager <br /></td> |
---|
[6607] | 200 | ... |
---|
| 201 | |
---|
[6608] | 202 | Users can't be added twice: |
---|
[6607] | 203 | |
---|
[11954] | 204 | >>> browser.open('http://localhost/mycompany/users/add') |
---|
[6608] | 205 | >>> browser.getControl(name="form.name").value = 'bob' |
---|
[8759] | 206 | >>> browser.getControl(name="form.title").value = 'Bob The User' |
---|
[7149] | 207 | >>> browser.getControl(name="password").value = 'secret' |
---|
| 208 | >>> browser.getControl(name="control_password").value = 'secret' |
---|
[7222] | 209 | >>> browser.getControl(name="form.email").value = 'xx@yy.zz' |
---|
[7869] | 210 | >>> browser.getControl(name="form.phone.country").value = ['+234'] |
---|
| 211 | >>> browser.getControl(name="form.phone.area").value = '123' |
---|
| 212 | >>> browser.getControl(name="form.phone.ext").value = '45678' |
---|
[6608] | 213 | >>> browser.getControl("Add user").click() |
---|
| 214 | >>> 'The userid chosen already exists' in browser.contents |
---|
| 215 | True |
---|
| 216 | |
---|
| 217 | Users can be deleted: |
---|
| 218 | |
---|
[11954] | 219 | >>> browser.open('http://localhost/mycompany/users') |
---|
[8364] | 220 | >>> browser.getControl("Remove", index=0).click() |
---|
[7657] | 221 | >>> 'User account bob successfully deleted' in browser.contents |
---|
[6608] | 222 | True |
---|
| 223 | |
---|
| 224 | |
---|
[8364] | 225 | |
---|
[6607] | 226 | Contact Form |
---|
| 227 | ============ |
---|
| 228 | |
---|
| 229 | Let's enter the contact form:: |
---|
| 230 | |
---|
[11954] | 231 | >>> browser.open('http://localhost/mycompany/contactadmin') |
---|
[6607] | 232 | >>> print browser.contents |
---|
| 233 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
[6647] | 234 | ...Contact |
---|
[6607] | 235 | ... |
---|
| 236 | |
---|
[7234] | 237 | We fill the form (this will send a real message to |
---|
| 238 | contact@waeup.org):: |
---|
[6607] | 239 | |
---|
[11954] | 240 | >>> browser.open('http://localhost/mycompany/contactadmin') |
---|
[7225] | 241 | >>> browser.getControl(name='form.body').value = "test message" |
---|
| 242 | >>> browser.getControl('Send').click() |
---|
[7208] | 243 | >>> print browser.contents |
---|
[6607] | 244 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... |
---|
[7459] | 245 | ...Your message has been sent... |
---|
[6607] | 246 | ... |
---|
| 247 | |
---|
[7234] | 248 | If this test fails, chances are, that the local machine has no SMTP |
---|
| 249 | server installed. |
---|
[6607] | 250 | |
---|
| 251 | |
---|
| 252 | Data Center |
---|
| 253 | =========== |
---|
| 254 | |
---|
| 255 | The data center helps us uploading files for later import or similar. |
---|
| 256 | |
---|
[11954] | 257 | >>> browser.open('http://localhost/mycompany') |
---|
[6607] | 258 | >>> browser.getLink('Data Center').click() |
---|
| 259 | |
---|
| 260 | Setting the file path |
---|
| 261 | --------------------- |
---|
| 262 | |
---|
| 263 | A datacenter stores files in a path in filesystem. By default this is |
---|
| 264 | a directory in the sources: |
---|
| 265 | |
---|
| 266 | >>> print browser.contents |
---|
| 267 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
---|
| 268 | ... |
---|
[7584] | 269 | <b>Storage path:</b> <span>.../parts/test/datacenter</span> |
---|
[6607] | 270 | ... |
---|
| 271 | |
---|
| 272 | Going to 'Settings` we can change the path: |
---|
| 273 | |
---|
| 274 | >>> browser.getLink('Edit settings').click() |
---|
| 275 | >>> pathsetting = browser.getControl(name='newpath') |
---|
| 276 | |
---|
| 277 | We create a directory and set it as our upload path: |
---|
| 278 | |
---|
| 279 | >>> import os |
---|
| 280 | >>> cwd = os.getcwd() |
---|
| 281 | >>> uploadpath = os.path.join(cwd, 'testfiles') |
---|
| 282 | >>> os.mkdir(uploadpath) |
---|
| 283 | >>> pathsetting.value = uploadpath |
---|
| 284 | |
---|
| 285 | And submit the form: |
---|
| 286 | |
---|
| 287 | >>> browser.getControl(name='save').click() |
---|
| 288 | |
---|
| 289 | We clean up the set directory path, as there might be some files be |
---|
| 290 | copied some files from installation: |
---|
| 291 | |
---|
| 292 | >>> files = os.listdir(uploadpath) |
---|
| 293 | >>> for filename in files: |
---|
| 294 | ... if os.path.isdir(os.path.join(uploadpath, filename)): |
---|
| 295 | ... continue |
---|
| 296 | ... os.unlink(os.path.join(uploadpath, filename)) |
---|
| 297 | |
---|
| 298 | We also remove any existing 'accesscodes' subdir: |
---|
| 299 | |
---|
| 300 | >>> import shutil |
---|
| 301 | >>> for filename in files: |
---|
| 302 | ... if not os.path.isdir(os.path.join(uploadpath, filename)): |
---|
| 303 | ... continue |
---|
| 304 | ... if filename != 'accesscodes': |
---|
| 305 | ... continue |
---|
| 306 | ... shutil.rmtree(os.path.join(uploadpath, filename)) |
---|
| 307 | |
---|
| 308 | The new upload directory is now empty, except from the logs and other |
---|
| 309 | standard dirs, which are created automatically: |
---|
| 310 | |
---|
| 311 | >>> sorted(os.listdir(uploadpath)) |
---|
[8372] | 312 | ['deleted', 'finished', 'logs', 'unfinished'] |
---|
[6607] | 313 | |
---|
| 314 | |
---|
| 315 | Uploading files |
---|
| 316 | --------------- |
---|
| 317 | |
---|
| 318 | Now we can upload files. Most interesting files might be CSV files, |
---|
| 319 | that can be imported lateron. We create a CSV file containing faculty |
---|
| 320 | descriptions: |
---|
| 321 | |
---|
| 322 | >>> open('faculties.csv', 'wb').write( |
---|
| 323 | ... """code,title,title_prefix |
---|
| 324 | ... FA,Arts,faculty |
---|
| 325 | ... FS,Sciences,faculty |
---|
| 326 | ... """) |
---|
| 327 | |
---|
| 328 | Now we can upload this file. To do this, we first go to the upload |
---|
| 329 | page: |
---|
| 330 | |
---|
[9024] | 331 | >>> browser.getLink('Upload data').click() |
---|
[6607] | 332 | |
---|
| 333 | and enter the appropriate data in the form: |
---|
| 334 | |
---|
| 335 | >>> filewidget = browser.getControl(name='uploadfile:file') |
---|
| 336 | >>> filewidget |
---|
| 337 | <Control name='uploadfile:file' type='file'> |
---|
[7208] | 338 | |
---|
[6607] | 339 | A sidenote for developers: by marking the filewidget with the |
---|
| 340 | ``:file`` extension, we tell Zope to handle this field as a file |
---|
| 341 | widget. |
---|
| 342 | |
---|
| 343 | >>> import cStringIO |
---|
| 344 | >>> filecontents = cStringIO.StringIO( |
---|
| 345 | ... open('faculties.csv', 'rb').read()) |
---|
| 346 | >>> filewidget.add_file(filecontents, 'text/plain', 'myfaculties.csv') |
---|
[7208] | 347 | |
---|
[6607] | 348 | >>> browser.getControl(name='SUBMIT').click() |
---|
| 349 | |
---|
| 350 | The file was indeed uploaded, with the current userid inserted: |
---|
| 351 | |
---|
| 352 | >>> sorted(os.listdir(uploadpath)) |
---|
[8372] | 353 | ['deleted', 'finished', 'logs', 'myfaculties_zope.mgr.csv', 'unfinished'] |
---|
[6607] | 354 | |
---|
| 355 | |
---|
| 356 | |
---|
| 357 | Importing a CSV file |
---|
| 358 | -------------------- |
---|
| 359 | |
---|
| 360 | The import of CSV files is described in batchprocessing.txt. |
---|
| 361 | |
---|
| 362 | |
---|
| 363 | Clean up: |
---|
| 364 | |
---|
| 365 | >>> import os |
---|
| 366 | >>> import shutil |
---|
| 367 | >>> shutil.rmtree(uploadpath) |
---|
| 368 | |
---|