[Zope3-dev] mechtest-based README.txt

Stephan Richter srichter at cosmos.phy.tufts.edu
Tue Jul 26 09:01:10 EDT 2005


Hi all,

FYI, Benji and I are discussing putting mechanize and mechtest into the Zope 3 
trunk (we can do this, since it is not in the release). Attached you can find 
a README.txt based on mechtest I wrote for some SchoolTool development I am 
doing.

I hope you are getting as excited about this as I am by looking at the 
demo. :-)

mechtest URL: svn+ssh://svnzope/repos/main/Sandbox/zc/mechtest

Regards,
Stephan
-- 
Stephan Richter
CBU Physics & Chemistry (B.S.) / Tufts Physics (Ph.D. student)
Web2k - Web Software Design, Development and Training
-------------- next part --------------
=====================================================
Level Management and Academic Workflow via the Web UI
=====================================================

This document presents the management of levels and the academic career of a
student via a promotion workflow from the perspective of the Web UI.

  >>> from zc.mechtest.testing import Browser
  >>> browser = Browser()
  >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')

  >>> browser.open(
  ...     'http://localhost/contents.html?'
  ...     'type_name=BrowserAdd__schooltool.app.SchoolToolApplication&'
  ...     'new_value=test')

  >>> "test" in browser.contents
  True
  >>> browser.click('test')


Level Management
----------------

First we create a couple of levels.

  >>> browser.click('Levels')

  >>> browser.click('New Level')
  >>> browser.controls['field.title'] = u'1st Grade'
  >>> browser.controls['field.isInitial'] = True
  >>> browser.controls['add_input_name'] = u'level1'
  >>> browser.click('Add')

  >>> '1st Grade' in browser.contents
  True

  >>> browser.click('New Level')
  >>> browser.controls['field.title'] = u'2nd Grade'
  >>> browser.controls['field.isInitial'] = False
  >>> browser.controls['add_input_name'] = u'level2'
  >>> browser.click('Add')

  >>> '2nd Grade' in browser.contents
  True

Since we did not connect the two levels, validation should fail:

  >>> browser.click('Validate Levels')
  >>> browser.click('Validate')

  >>> "One or more disconnected levels detected." in browser.contents
  True
  >>> "2nd Grade" in browser.contents
  True

If we connect `level1` to `level2` and also `level2` to `level1`, we get a
loop validation error:

  >>> browser.click('Levels')
  >>> browser.click('1st Grade')
  >>> browser.click('Edit Info')
  >>> browser.controls['field.nextLevel'] = ['level2']
  >>> browser.click('Apply')

  >>> browser.click('Levels')
  >>> browser.click('2nd Grade')
  >>> browser.click('Edit Info')
  >>> browser.controls['field.nextLevel'] = ['level1']
  >>> browser.click('Apply')
  
  >>> browser.click('Levels')
  >>> browser.click('Validate Levels')
  >>> browser.click('Validate')

  >>> "A Level Loop Error was detected." in browser.contents
  True
  >>> print browser.contents
  <BLANKLINE>
  ...
  Simply do not specify level
  <em>1st Grade</em>
  ...

Okay, so let's do what the error tells us and remove the link in `level2` to
`level1`:

  >>> browser.click('Levels')
  >>> browser.click('2nd Grade')
  >>> browser.click('Edit Info')
  >>> browser.controls['field.nextLevel'] = []
  >>> browser.click('Apply')

  >>> browser.click('Levels')
  >>> browser.click('Validate Levels')
  >>> browser.click('Validate')

  >>> print browser.contents
  <BLANKLINE>
  ...
  No errors were detected.
  ...


The Academic Career of a Student
--------------------------------

Before we can do anything, we have to create a student:

  >>> import StringIO

  >>> browser.click('Persons')
  >>> browser.click('New Person')

  >>> browser.controls['field.title'] = 'Stephan Richter'
  >>> browser.controls['field.username'] = 'srichter'
  >>> browser.controls['field.password'] = 'foobar'
  >>> browser.controls['field.verify_password'] = 'foobar'
  >>> browser.controls['field.photo'] = StringIO.StringIO()
  >>> browser.click('Add')

  >>> 'Stephan Richter' in browser.contents
  True

Now we go to the manager group, and walk the student through the academic
career:

  >>> browser.click('Groups')
  >>> browser.click('Manager')
  >>> browser.click('Student Management')

We now select the student which we want to enroll in the school.

  >>> form = browser.forms['enroll']
  >>> ctrl = browser.getControl('ids:list', form=form.mech_form) 
  >>> ctrl.mech_control.value = ['srichter']
  >>> browser.click('Enroll')

  >>> print browser.contents
  <BLANKLINE>
  ...
  <div id="message">Students successfully enrolled.</div>
  ...
  <option value="level1">1st Grade</option>
  <option value="level2">2nd Grade</option>
  ...

Now that the student is enrolled, we can initialize him at a particular
level. Our student will enter the first grade:

  >>> form = browser.forms['initialize']
  >>> ctrl = browser.getControl('ids:list', form=form.mech_form) 
  >>> id = ctrl.options[0]
  >>> ctrl.mech_control.value = [id]
  >>> browser.controls[id+'.level'] = ['level1']
  >>> browser.click('Apply')

  >>> print browser.contents
  <BLANKLINE>
  ...
  <div id="message">Student processes successfully updated.</div>
  ...
  <div class="value">
  <select name="...outcome" size="1" >
  <option selected="selected" value="pass">pass</option>
  <option value="fail">fail</option>
  <option value="withdraw">withdraw</option>
  </select>
  </div>
  ...

The student passes the first grade

  >>> form = browser.forms['outcome']
  >>> ctrl = browser.getControl('ids:list', form=form.mech_form) 
  >>> id = ctrl.options[0]
  >>> ctrl.mech_control.value = [id]
  >>> browser.controls[id+'.outcome'] = ['pass']
  >>> form.submit('Apply')

  >>> print browser.contents
  <BLANKLINE>
  ...
  <div id="message">Student processes successfully updated.</div>
  ...
  <span>2nd Grade</span>
  ...
  
but fails the second grade the first time around:

  >>> form = browser.forms['outcome']
  >>> ctrl = browser.getControl('ids:list', form=form.mech_form) 
  >>> id = ctrl.options[0]
  >>> ctrl.mech_control.value = [id]
  >>> browser.controls[id+'.outcome'] = ['fail']
  >>> form.submit('Apply')

  >>> print browser.contents
  <BLANKLINE>
  ...
  <div id="message">Student processes successfully updated.</div>
  ...
  <span>2nd Grade</span>
  ...

If you forget to select the student, you get a nice notice:

  >>> form = browser.forms['outcome']
  >>> ctrl = browser.getControl('ids:list', form=form.mech_form) 
  >>> id = ctrl.options[0]
  >>> browser.controls[id+'.outcome'] = ['fail']
  >>> form.submit('Apply')

  >>> print browser.contents
  <BLANKLINE>
  ...
  <div id="message">No students were selected.</div>
  ...

Now we finally pass the student, so he will graduate; that means he will
appear at the top of the list again:

  >>> form = browser.forms['outcome']
  >>> ctrl = browser.getControl('ids:list', form=form.mech_form) 
  >>> id = ctrl.options[0]
  >>> ctrl.mech_control.value = [id]
  >>> browser.controls[id+'.outcome'] = ['pass']
  >>> form.submit('Apply')

  >>> print browser.contents
  <BLANKLINE>
  ...
  <div id="message">Student processes successfully updated.</div>
  ...
  <tr>
    <td>
      <input type="checkbox" name="ids:list"
             value="srichter" />
    </td>
    <td>
      <span>Stephan Richter</span>
      (<span>srichter</span>)
    </td>
  </tr>
  ...

That's it. We have successfully moved through a student's academic career.


And a second time ...
---------------------

Let's now do this again in a student-specific UI. To make the walkthrough
cleaner, we create a new student first:

  >>> browser.click('Persons')
  >>> browser.click('New Person')

  >>> browser.controls['field.title'] = 'Tom Hoffman'
  >>> browser.controls['field.username'] = 'tom'
  >>> browser.controls['field.password'] = 'foobar'
  >>> browser.controls['field.verify_password'] = 'foobar'
  >>> browser.controls['field.photo'] = StringIO.StringIO()
  >>> browser.click('Add')

  >>> print browser.contents
  <BLANKLINE>
  ...
  <a href="http://localhost/test/persons/tom">Tom Hoffman</a>
  ...

Now we enter the new student and look at his academic career:

  >>> browser.click('Tom Hoffman')
  >>> browser.click('Academic Record')

In the academic record you see the status of the student, the workflow and the
academic history:

  >>> print browser.contents
  <BLANKLINE>
  ...
  <h1>
    Academic Record for <em>Tom Hoffman</em> 
  </h1>
  ...
  <h3>Status</h3>
  ...
  <h3>Workflow</h3>
  ...
  value="Initialize"
  ...
  <h3>History</h3>
  <ul style="list-style: disc">
  </ul>
  ...

We can see that there is currently no workflow and the history is empty. Let's
now create ...


More information about the Zope3-dev mailing list