[Checkins] SVN: z3c.formdemo/trunk/src/z3c/formdemo/ Okay,
all demo packages have tests now. Next task: check the coverage.
Stephan Richter
srichter at cosmos.phy.tufts.edu
Mon Jul 2 14:14:46 EDT 2007
Log message for revision 77310:
Okay, all demo packages have tests now. Next task: check the coverage.
Changed:
A z3c.formdemo/trunk/src/z3c/formdemo/addressbook/README.txt
U z3c.formdemo/trunk/src/z3c/formdemo/addressbook/form-macros.pt
A z3c.formdemo/trunk/src/z3c/formdemo/calculator/README.txt
U z3c.formdemo/trunk/src/z3c/formdemo/message/README.txt
A z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/README.txt
A z3c.formdemo/trunk/src/z3c/formdemo/sqlmessage/README.txt
U z3c.formdemo/trunk/src/z3c/formdemo/sqlmessage/overview.pt
U z3c.formdemo/trunk/src/z3c/formdemo/testing.py
U z3c.formdemo/trunk/src/z3c/formdemo/tests.py
A z3c.formdemo/trunk/src/z3c/formdemo/wizard/README.txt
-=-
Added: z3c.formdemo/trunk/src/z3c/formdemo/addressbook/README.txt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/addressbook/README.txt (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/addressbook/README.txt 2007-07-02 18:14:46 UTC (rev 77310)
@@ -0,0 +1,193 @@
+================
+Addressbook Demo
+================
+
+The purpose of the addressbook demo is to demonstrate a complex, form-driven
+UI with several sub-forms and table-integration.
+
+To start, we need to open a browser and go to the demo applications overview
+screen:
+
+ >>> from z3c.formdemo import testing
+ >>> from z3c.etestbrowser.testing import ExtendedTestBrowser
+ >>> user = ExtendedTestBrowser()
+ >>> user.addHeader('Accept-Language', 'en')
+ >>> user.open('http://localhost:8080')
+
+Since all demos are purely public, there is no need to log in. Let's now click
+on the "Address Book" link:
+
+ >>> user.getLink('Address Book').click()
+
+There is only one screen for this demo. In it you see the table of all
+contacts on the left side and on the right side is the contact
+form. Initially, this is an add form.
+
+ >>> testing.printElement(user, "//h1")
+ <h1><span>Address Book Demo</span></h1>
+
+So let's start by filling out the add form. The first portion contains basic
+personal information:
+
+ >>> user.getControl('First Name').value = 'Stephan'
+ >>> user.getControl('Last Name').value = 'Richter'
+
+ >>> user.getControl(name='contact.add.widgets.birthday.day:list')\
+ ... .getControl('25').click()
+ >>> user.getControl(name='contact.add.widgets.birthday.year:list')\
+ ... .getControl('1980').click()
+
+In the second portion we can add any number of addresses. Let's just add a
+home address:
+
+ >>> user.getControl('Add', index=0).click()
+
+ >>> user.getControl('Street').value = '110 Main Street'
+ >>> user.getControl('City').value = 'Maynard'
+ >>> user.getControl('State').value = 'MA'
+ >>> user.getControl('ZIP').value = '01754'
+
+When accidently adding another address, ...
+
+ >>> user.getControl(name='contact.add.addresses.widgets.addressName:list')\
+ ... .getControl('Work').click()
+ >>> user.getControl('Add', index=0).click()
+
+you can delete it any time:
+
+ >>> user.getControl('Delete', index=1).click()
+
+Let's now add the home phone number, because it is a required field:
+
+ >>> user.getControl(name='contact.add.phones.homePhone.widgets.countryCode')\
+ ... .value = '+1'
+ >>> user.getControl(name='contact.add.phones.homePhone.widgets.areaCode')\
+ ... .value = '555'
+ >>> user.getControl(name='contact.add.phones.homePhone.widgets.number')\
+ ... .value = '127-1284'
+
+Finally, the user is requested to enter the E-mail addresses of the contact;
+we have two in this case:
+
+ >>> user.getControl(name='contact.add.emails.widgets.fullAddress')\
+ ... .value = 'srichter at gmail.com'
+ >>> user.getControl('Add', index=1).click()
+
+ >>> user.getControl(name='contact.add.emails.widgets.fullAddress')\
+ ... .value = 'srichter at tufts.edu'
+ >>> user.getControl('Add', index=1).click()
+
+Once all the information has been provided, we can add the contact:
+
+ >>> user.getControl('Add Contact').click()
+
+The new contact appears now in the contact list:
+
+ >>> testing.printElement(user, "//table/tbody/tr[1]")
+ <tr class="odd"><td class="sorted-on">
+ <a href="...?selectContact=contact-0">Richter</a>
+ </td>
+ <td class="">
+ <a href="...?selectContact=contact-0">Stephan</a>
+ </td>
+ </tr>
+
+By clicking on the name, the edit form for Stephan is shown:
+
+ >>> user.getLink('Richter').click()
+
+Note that the row is highlighted now:
+
+ >>> testing.printElement(user, "//table/tbody/tr[1]")
+ <tr class="selected"><td class="sorted-on">
+ <a href="...?selectContact=contact-0">Richter</a>
+ </td>
+ <td class="">
+ <a href="...?selectContact=contact-0">Stephan</a>
+ </td>
+ </tr>
+
+After adding a work phone number and deleting one of the two E-mail addresses,
+
+ >>> user.getControl(name='contact.edit.phones.workPhone.widgets.countryCode')\
+ ... .value = '+1'
+ >>> user.getControl(name='contact.edit.phones.workPhone.widgets.areaCode')\
+ ... .value = '555'
+ >>> user.getControl(name='contact.edit.phones.workPhone.widgets.number')\
+ ... .value = '346-3573'
+
+ >>> user.getControl('Delete', index=1).click()
+
+we now save the contact changes:
+
+ >>> user.getControl('Apply').click()
+
+This submission saves all the data but stays in the edit form of the
+contact. Only by pressing the "Done" button, the add form will return.
+
+ >>> user.getControl('Done').click()
+ >>> user.getControl('Add Contact')
+ <SubmitControl name='contact.add.buttons.add' type='submit'>
+
+You will also notice that the contact is not highlighted in the table
+anymore. Let's nwo add a second contact:
+
+ >>> user.getControl('First Name').value = 'Roger'
+ >>> user.getControl('Last Name').value = 'Ineichen'
+
+ >>> user.getControl(name='contact.add.phones.homePhone.widgets.countryCode')\
+ ... .value = '+41'
+ >>> user.getControl(name='contact.add.phones.homePhone.widgets.areaCode')\
+ ... .value = '43'
+ >>> user.getControl(name='contact.add.phones.homePhone.widgets.number')\
+ ... .value = '12 23 23'
+
+ >>> user.getControl('Add Contact').click()
+
+You can now sort the contacts by last and first name now, of course. Clicking
+on the "Last Name" table header cell, will leave the order, since the ordering
+must be initialized. The second time the order is reversed:
+
+ >>> user.getLink('Last Name').click()
+ >>> user.getLink('Last Name').click()
+
+ >>> testing.printElement(user, "//table/tbody/tr/td[1]/a/text()",
+ ... multiple=True, serialize=False)
+ Richter
+ Ineichen
+
+Selecting another header will sort on it. Let's choose the first name;
+clicking on it once sorts it in ascending order:
+
+ >>> user.getLink('First Name').click()
+ >>> testing.printElement(user, "//table/tbody/tr/td[2]/a/text()",
+ ... multiple=True, serialize=False)
+ Roger
+ Stephan
+
+Clicking it again, reverses the order:
+
+ >>> user.getLink('First Name').click()
+ >>> testing.printElement(user, "//table/tbody/tr/td[2]/a/text()",
+ ... multiple=True, serialize=False)
+ Stephan
+ Roger
+
+To delete a contact, you must first select it:
+
+ >>> user.getLink('Roger').click()
+
+At the bototm of the contact form is a delete button that will delete the
+entire contact:
+
+ >>> user.getControl('Delete').click()
+
+The user is now gone from the table and we are returned to the add form:
+
+ >>> user.getLink('Roger')
+ Traceback (most recent call last):
+ ...
+ LinkNotFoundError
+
+ >>> user.getControl('Add Contact')
+ <SubmitControl name='contact.add.buttons.add' type='submit'>
Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/addressbook/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: z3c.formdemo/trunk/src/z3c/formdemo/addressbook/form-macros.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/addressbook/form-macros.pt 2007-07-02 16:27:27 UTC (rev 77309)
+++ z3c.formdemo/trunk/src/z3c/formdemo/addressbook/form-macros.pt 2007-07-02 18:14:46 UTC (rev 77310)
@@ -1,7 +1,7 @@
<metal:block define-macro="widget-noerror-row">
<div class="noerror">
<div class="label">
- <label tal:attributes="for widget/name">
+ <label tal:attributes="for widget/id">
<span i18n:translate=""
tal:content="widget/label">label</span
><span class="required" tal:condition="widget/required">*</span>
Added: z3c.formdemo/trunk/src/z3c/formdemo/calculator/README.txt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/calculator/README.txt (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/calculator/README.txt 2007-07-02 18:14:46 UTC (rev 77310)
@@ -0,0 +1,68 @@
+===============
+Calculator Demo
+===============
+
+The purpose of the calculator demo is demonstrate the concept of buttons and
+their actions and how the framework allows high degrees of customization.
+
+To start, we need to open a browser and go to the demo applications overview
+screen:
+
+ >>> from z3c.formdemo import testing
+ >>> from z3c.etestbrowser.testing import ExtendedTestBrowser
+ >>> user = ExtendedTestBrowser()
+ >>> user.addHeader('Accept-Language', 'en')
+ >>> user.open('http://localhost:8080')
+
+Since all demos are purely public, there is no need to log in. Let's now click
+on the "Calculator" link:
+
+ >>> user.getLink('Calculator').click()
+
+You are now seeing the calculator:
+
+ >>> testing.printElement(user, "//h1")
+ <h1>
+ <span class="name">A simple calculator</span>
+ <span class="version">v1.0</span>
+ </h1>
+
+Let's start by doing a simple addition (``35 + 4.3 = ``:
+
+ >>> user.getControl('3').click()
+ >>> user.getControl('5').click()
+
+ >>> user.getControl('+').click()
+
+ >>> user.getControl('4').click()
+ >>> user.getControl('.').click()
+ >>> user.getControl('3').click()
+
+ >>> user.getControl('=').click()
+
+The result is shown within the display structure:
+
+ >>> testing.printElement(
+ ... user, "//div[@id='current']/span[@class='value']/text()",
+ ... serialize=False)
+ 39.3
+
+When an illegal operation occurs, an error message is shown:
+
+ >>> user.getControl('/').click()
+ >>> user.getControl('0').click()
+ >>> user.getControl('=').click()
+
+ >>> testing.printElement(
+ ... user, "//div[@id='current']/span[@class='value']/text()",
+ ... serialize=False)
+ -E-
+
+The entire calculator state can be reset at any time using the clear button:
+
+ >>> user.getControl('C').click()
+
+ >>> testing.printElement(
+ ... user, "//div[@id='current']/span[@class='value']/text()",
+ ... serialize=False)
+ 0
Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/calculator/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: z3c.formdemo/trunk/src/z3c/formdemo/message/README.txt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/message/README.txt 2007-07-02 16:27:27 UTC (rev 77309)
+++ z3c.formdemo/trunk/src/z3c/formdemo/message/README.txt 2007-07-02 18:14:46 UTC (rev 77310)
@@ -71,7 +71,7 @@
>>> user.getControl('Who').value = u'Roger'
>>> user.getControl('Apply', index=0).click()
-The now informs us that the data has been updated:
+The page now informs us that the data has been updated:
>>> testing.printElement(user, "//div[@class='summary']")
<div class="summary">Data successfully updated.</div>
Added: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/README.txt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/README.txt (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/README.txt 2007-07-02 18:14:46 UTC (rev 77310)
@@ -0,0 +1,160 @@
+================
+Spreadsheet Demo
+================
+
+The purpose of the spreadsheet demo is to demonstrate how the form framework
+can be combined with another framework, in our case the Zope Corp.'s tables.
+
+To start, we need to open a browser and go to the demo applications overview
+screen:
+
+ >>> from z3c.formdemo import testing
+ >>> from z3c.etestbrowser.testing import ExtendedTestBrowser
+ >>> user = ExtendedTestBrowser()
+ >>> user.addHeader('Accept-Language', 'en')
+ >>> user.open('http://localhost:8080')
+
+Since all demos are purely public, there is no need to log in. Let's now click
+on the "Spreadsheet" link:
+
+ >>> user.getLink('Spreadsheet').click()
+
+There is only one screen for this demo. In it you see the candidate
+evaluations table:
+
+ >>> testing.printElement(user, "//h1")
+ <h1>Spreadsheet Demo â Candidate Evaluations</h1>
+
+Initially there are no evaluations, so the screen contains little
+information. Let's first fill out a few evaluations by clicking on the button
+below the table.
+
+ >>> user.getControl('Add').click()
+
+Once clicked, the button below the table disappears, and a new row is shown in
+the table allowing us to add another evaluation. So let's fill out information
+and add the evaluation:
+
+ >>> user.getControl(name='add.widgets.lastName').value = u'Richter'
+ >>> user.getControl(name='add.widgets.firstName').value = u'Stephan'
+ >>> user.getControl(name='add.widgets.rating:list').getControl('good').click()
+
+ >>> user.getControl('Add').click()
+
+When the page returns, we see a row with the entry of Stephan Richter, ...
+
+ >>> testing.printElement(user, "//table/tbody/tr[2]")
+ <tr class="even"><td class="sorted-on">
+ Richter
+ </td>
+ <td class="">
+ Stephan
+ </td>
+ <td class="">
+ good
+ </td>
+ <td class="">
+ <input type="submit" ... value="Edit" /></td>
+ </tr>
+
+... but also another add evaluation row. This is by design, so that the user
+can quickly record new entries. So let's add another:
+
+ >>> user.getControl(name='add.widgets.lastName').value = u'Ineichen'
+ >>> user.getControl(name='add.widgets.firstName').value = u'Roger'
+ >>> user.getControl(name='add.widgets.rating:list')\
+ ... .getControl('excellent').click()
+
+ >>> user.getControl('Add').click()
+
+We are done now with adding new evaluations. Clicking on the "Cancel" button,
+removes the add line.
+
+ >>> user.getControl('Cancel').click()
+ >>> user.getControl(name='add.widgets.lastName')
+ Traceback (most recent call last):
+ ...
+ LookupError: name 'add.widgets.lastName'
+
+We can now edit an evaluation by clicking on the row's edit button:
+
+ >>> user.getControl('Edit', index=1).click()
+
+An edit form for this row appears now for Stephan. Let's change his rating to
+"average":
+
+ >>> user.getControl(name='candidate-0.widgets.rating:list')\
+ ... .getControl('average').click()
+
+But hitting the "Cancel" button wil ignore the changes and simply return to
+diaplay the row:
+
+ >>> user.getControl('Cancel').click()
+ >>> testing.printElement(user, "//table/tbody/tr[2]/td[3]/text()",
+ ... serialize=False)
+ good
+
+Let's now edit the rating for real:
+
+ >>> user.getControl('Edit', index=1).click()
+ >>> user.getControl(name='candidate-0.widgets.rating:list')\
+ ... .getControl('average').click()
+ >>> user.getControl('Save').click()
+
+Saving the changes also collapses the edit form back into a display form,
+saving the user from accessive button clicking. Of course, the data is
+properly stored.
+
+ >>> testing.printElement(user, "//table/tbody/tr[2]/td[3]/text()",
+ ... serialize=False)
+ average
+
+The real power of integrating the forms into ``zc.table`` is the automtic
+column sorting feature that comes with the table framework. By default they
+are sorted by last name:
+
+ >>> testing.printElement(user, "//table/tbody/tr/td[1]/text()",
+ ... multiple=True, serialize=False)
+ Ineichen
+ Richter
+
+Clicking on the "Last Name" table header cell, will leave the order, since the
+ordering must be initialized. The second time the order is reversed:
+
+ >>> user.getLink('Last Name').click()
+ >>> user.getLink('Last Name').click()
+
+ >>> testing.printElement(user, "//table/tbody/tr/td[1]/text()",
+ ... multiple=True, serialize=False)
+ Richter
+ Ineichen
+
+Selecting another header will sort on it. Let's choose the first name;
+clicking on it once sorts it in ascending order:
+
+ >>> user.getLink('First Name').click()
+ >>> testing.printElement(user, "//table/tbody/tr/td[2]/text()",
+ ... multiple=True, serialize=False)
+ Roger
+ Stephan
+
+Clicking it again, reverses the order:
+
+ >>> user.getLink('First Name').click()
+ >>> testing.printElement(user, "//table/tbody/tr/td[2]/text()",
+ ... multiple=True, serialize=False)
+ Stephan
+ Roger
+
+Except for the "Actions" column, all headers can be sorted on:
+
+ >>> user.getLink('Last Name')
+ <Link text='Last Name' url='...lastName'>
+ >>> user.getLink('First Name')
+ <Link text='First Name' url='...firstName'>
+ >>> user.getLink('Rating')
+ <Link text='Rating' url='...rating'>
+ >>> user.getLink('Actions')
+ Traceback (most recent call last):
+ ...
+ LinkNotFoundError
Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.formdemo/trunk/src/z3c/formdemo/sqlmessage/README.txt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/sqlmessage/README.txt (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/sqlmessage/README.txt 2007-07-02 18:14:46 UTC (rev 77310)
@@ -0,0 +1,193 @@
+============================
+SQL Hello World Message Demo
+============================
+
+The purpose of the SQL Hello World Message demo is to demonstrate how
+non-bject data can be manipulated and displayed using the form framework.
+
+To start, we need to open a browser and go to the demo applications overview
+screen:
+
+ >>> from z3c.formdemo import testing
+ >>> from z3c.etestbrowser.testing import ExtendedTestBrowser
+ >>> user = ExtendedTestBrowser()
+ >>> user.addHeader('Accept-Language', 'en')
+ >>> user.open('http://localhost:8080')
+
+Since all demos are purely public, there is no need to log in. Let's now click
+on the "SQL Hello World" link:
+
+ >>> user.getLink('SQL Hello World').click()
+
+The initial page of the demo is the list of all messages. This screen exists,
+because the ZMI management screens are not helpful for unmapped relational data.
+
+ >>> testing.printElement(user, "//h1")
+ <h1>SQL Hello World Message Demo</h1>
+
+Let's make sure the database is truly empty:
+
+ >>> testing.printElement(user, "//table/tbody", multiple=True)
+
+We can now initialize the database using one of the action links below the
+table:
+
+ >>> user.getLink('[Initialize the database]').click()
+ >>> testing.printElement(user, "//div[@class='summary']", multiple=True)
+
+The page returns with no notable messages. Clicking the link again results in
+an error, because the database is already initialized:
+
+ >>> user.getLink('[Initialize the database]').click()
+ >>> testing.printElement(user, "//div[@class='summary']")
+ <div class="summary">Database Message: cannot create MSG, exists</div>
+
+Let's now add a new message:
+
+ >>> user.getLink('[Add message]').click()
+
+You are now represented with the message add form.
+
+ >>> user.url
+ 'http://localhost:8080/addSQLHelloWorld.html'
+
+If we submit the form by clicking on add, ...
+
+ >>> user.getControl('Add').click()
+
+... the same page returns telling us we have some errors:
+
+ >>> testing.printElement(user, "//div[@class='summary']")
+ <div class="summary">There were some errors.</div>
+
+This is because we forgot to enter the "Who" field, which is required:
+
+ >>> testing.printElement(user, "//ul[@class='errors']/li")
+ <li>
+ Who: <div class="error">Required input is missing.</div>
+ </li>
+
+Let's now fill out all the required fields and try to add the message again:
+
+ >>> user.getControl('Who').value = u'Stephan'
+ >>> user.getControl('When').value = u'7/1/07'
+ >>> user.getControl('Add').click()
+
+Once submitted, the message is now added to the database and we are returned
+back to the overview:
+
+ >>> testing.printElement(user, "//table/tbody/tr[1]")
+ <tr class="odd"><td class="sorted-on">
+ <a href="showSQLHelloWorld.html?id=0">0</a>
+ </td>
+ <td class="">
+ <a href="showSQLHelloWorld.html?id=0">Stephan</a>
+ </td>
+ <td class="">
+ <a href="showSQLHelloWorld.html?id=0">2007-07-01</a>
+ </td>
+ <td class="">
+ <a href="showSQLHelloWorld.html?id=0">cool</a>
+ </td>
+ <td class="">
+ <a href="?delete=0">[Delete]</a>
+ </td>
+ </tr>
+
+Clicking on any data item, brings us to the message display screen:
+
+ >>> user.getLink('Stephan').click()
+ >>> testing.printElement(user, "//h1")
+ <h1>
+ A cool Hello World from Stephan on 7/1/07 !
+ </h1>
+
+The message's edit form can be accessed by clicking on the "Edit Message"
+link:
+
+ >>> user.getLink('Edit Message').click()
+
+When immediately pressing "Apply", a message appears telling us that no data
+has been changed:
+
+ >>> user.getControl('Apply', index=0).click()
+ >>> testing.printElement(user, "//div[@class='summary']")
+ <div class="summary">No changes were applied.</div>
+
+Let's now change the name and submit the form:
+
+ >>> user.getControl('Who').value = u'Roger'
+ >>> user.getControl('Apply', index=0).click()
+
+The page now informs us that the data has been updated:
+
+ >>> testing.printElement(user, "//div[@class='summary']")
+ <div class="summary">Data successfully updated.</div>
+
+When pressing the "Apply and View" button, the changed data is stored and the
+user is also forwarded to the view page again:
+
+ >>> user.getControl('What').getControl('best').click()
+ >>> user.getControl('Apply and View').click()
+
+Of course, the view shows the latest data:
+
+ >>> testing.printElement(user, "//h1")
+ <h1>
+ A best Hello World from Roger on 7/1/07 !
+ </h1>
+
+From the display screen you can also return to the overview:
+
+ >>> user.getLink('[Show All Messages]').click()
+ >>> user.url
+ 'http://localhost:8080/showAllSQLHelloWorld.html'
+
+Let's now add a new message:
+
+ >>> user.getLink('[Add message]').click()
+
+ >>> user.getControl('Who').value = u'Stephan'
+ >>> user.getControl('When').value = u'7/2/07'
+ >>> user.getControl('Add').click()
+
+As you probably already guessed, the table headers can be used to sort
+items. Clicking on the "Id" table header cell, will leave the order,
+since the ordering must be initialized. The second time the order is reversed:
+
+ >>> user.getLink('Id').click()
+ >>> user.getLink('Id').click()
+
+ >>> testing.printElement(user, "//table/tbody/tr/td[1]/a/text()",
+ ... multiple=True, serialize=False)
+ 1
+ 0
+
+Selecting another header will sort on it. Let's choose the "Who" column;
+clicking on it once sorts it in ascending order:
+
+ >>> user.getLink('Who').click()
+ >>> testing.printElement(user, "//table/tbody/tr/td[2]/a/text()",
+ ... multiple=True, serialize=False)
+ Roger
+ Stephan
+
+Clicking it again, reverses the order:
+
+ >>> user.getLink('Who').click()
+ >>> testing.printElement(user, "//table/tbody/tr/td[2]/a/text()",
+ ... multiple=True, serialize=False)
+ Stephan
+ Roger
+
+To delete a contact, you Simply click on the "Delete" link of the
+corresponding row:
+
+ >>> user.getLink('[Delete]').click()
+
+The message is now gone from the table:
+
+ >>> user.getLink('Roger')
+ Traceback (most recent call last):
+ ...
+ LinkNotFoundError
Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/sqlmessage/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: z3c.formdemo/trunk/src/z3c/formdemo/sqlmessage/overview.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/sqlmessage/overview.pt 2007-07-02 16:27:27 UTC (rev 77309)
+++ z3c.formdemo/trunk/src/z3c/formdemo/sqlmessage/overview.pt 2007-07-02 18:14:46 UTC (rev 77310)
@@ -14,6 +14,8 @@
<div class="actions">
<a href="addSQLHelloWorld.html">[Add message]</a>
- <a href="?initialize=1">[Initialize the database]</a>
+ <a href="showAllSQLHelloWorld.html?initialize=1">
+ [Initialize the database]
+ </a>
</div>
</div>
Modified: z3c.formdemo/trunk/src/z3c/formdemo/testing.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/testing.py 2007-07-02 16:27:27 UTC (rev 77309)
+++ z3c.formdemo/trunk/src/z3c/formdemo/testing.py 2007-07-02 18:14:46 UTC (rev 77310)
@@ -15,10 +15,17 @@
$Id$
"""
__docformat__ = "reStructuredText"
+import tempfile
import lxml.etree
import os
+from zope.rdb import gadflyda
from zope.app.testing.functional import ZCMLLayer
+def setUp(test):
+ gadfly_dir = tempfile.mkdtemp()
+ os.mkdir(os.path.join(gadfly_dir, 'msg'))
+ gadflyda.setGadflyRoot(gadfly_dir)
+
def printElement(browser, xpath, multiple=False, serialize=True):
result = [serialize and lxml.etree.tounicode(elem) or elem
for elem in browser.etree.xpath(xpath)]
Modified: z3c.formdemo/trunk/src/z3c/formdemo/tests.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/tests.py 2007-07-02 16:27:27 UTC (rev 77309)
+++ z3c.formdemo/trunk/src/z3c/formdemo/tests.py 2007-07-02 18:14:46 UTC (rev 77310)
@@ -28,9 +28,16 @@
for docpath in (('message', 'README.txt'),
('widgets', 'README.txt'),
('questionnaire', 'README.txt'),
+ ('calculator', 'README.txt'),
+ ('wizard', 'README.txt'),
+ ('spreadsheet', 'README.txt'),
+ ('addressbook', 'README.txt'),
+ ('sqlmessage', 'README.txt'),
):
suite = functional.FunctionalDocFileSuite(
- os.path.join(*docpath), globs={'getRootFolder': getRootFolder})
+ os.path.join(*docpath),
+ setUp=testing.setUp,
+ globs={'getRootFolder': getRootFolder})
suite.layer = testing.FormDemoLayer
suites.append(suite)
return unittest.TestSuite(suites)
Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/README.txt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/wizard/README.txt (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/wizard/README.txt 2007-07-02 18:14:46 UTC (rev 77310)
@@ -0,0 +1,166 @@
+===========
+Wizard Demo
+===========
+
+The purpose of the wizard demo is demonstrate the construction of a typical UI
+wizard, effectively splitting one form into multiple pages. None of the data
+is permanently stored until the wizard is submitted.
+
+To start, we need to open a browser and go to the demo applications overview
+screen:
+
+ >>> from z3c.formdemo import testing
+ >>> from z3c.etestbrowser.testing import ExtendedTestBrowser
+ >>> user = ExtendedTestBrowser()
+ >>> user.addHeader('Accept-Language', 'en')
+ >>> user.open('http://localhost:8080')
+
+Since all demos are purely public, there is no need to log in. Let's now click
+on the "Wizard" link:
+
+ >>> user.getLink('Wizard').click()
+
+You are now seeing the first step of the wizard, which asks for personal
+information:
+
+ >>> testing.printElement(user, "//h1")
+ <h1>Wizard Demo - Person Demographics</h1>
+
+ >>> testing.printElement(user, "//legend")
+ <legend>Personal Information</legend>
+
+Let's fill out the form and save the data:
+
+ >>> user.getControl('First Name').value = 'Stephan'
+ >>> user.getControl('Last Name').value = 'Richter'
+
+ >>> user.getControl('Phone').value = '+1 555 276-3761'
+ >>> user.getControl('Email').value = 'stephan.richter_(at)_gmail.com'
+
+ >>> user.getControl('Save').click()
+
+Rhe "Save" button causes the form to be submitted, but not to proceed to the
+next step. A message that the data has been successfully saved in shown:
+
+ >>> testing.printElement(user, "//div[@class='summary']")
+ <div class="summary">Data successfully updated.</div>
+
+Pressing the "Clear" button (which only appears on the first step) will clear
+out the data of all steps:
+
+ >>> user.getControl('Clear').click()
+
+ >>> user.getControl('First Name').value
+ ''
+ >>> user.getControl('Last Name').value
+ ''
+ >>> user.getControl('Phone').value
+ ''
+ >>> user.getControl('Email').value
+ ''
+
+So let's now fill out the form and click the next button this time.
+
+ >>> user.getControl('First Name').value = 'Stephan'
+ >>> user.getControl('Last Name').value = 'Richter'
+
+ >>> user.getControl('Phone').value = '+1 555 276-3761'
+ >>> user.getControl('Email').value = 'stephan.richter_(at)_gmail.com'
+
+ >>> user.getControl('Next').click()
+
+You are now forwarded to the second step:
+
+ >>> testing.printElement(user, "//legend")
+ <legend>Address</legend>
+
+The "Next" button does not only forward the user to the second step, but also
+stores the data. Clicking on "Previous" will bring us back to the first
+screen. But let's first fill out step 2, since the "Previous" button also
+stores the data of the current step:
+
+ >>> user.getControl('Street').value = '110 Main Street'
+ >>> user.getControl('Zip').value = '01754'
+ >>> user.getControl('City').value = 'Maynard'
+
+ >>> user.getControl('Previous').click()
+
+So back at step 1, we can see that all the personal information is there.
+
+ >>> user.getControl('First Name').value
+ 'Stephan'
+ >>> user.getControl('Last Name').value
+ 'Richter'
+ >>> user.getControl('Phone').value
+ '+1 555 276-3761'
+ >>> user.getControl('Email').value
+ 'stephan.richter_(at)_gmail.com'
+
+You can also navigate through the wizard by clicking on the step number on the
+top, so let's go to step 2 by clicking on that link:
+
+ >>> user.getLink('2').click()
+ >>> testing.printElement(user, "//legend")
+ <legend>Address</legend>
+
+Note that no data is saved, when using this link. We also notice that all the
+data fields are filled out:
+
+ >>> user.getControl('Street').value
+ '110 Main Street'
+ >>> user.getControl('Zip').value
+ '01754'
+ >>> user.getControl('City').value
+ 'Maynard'
+
+Let's now go to the third and forth step, filling them out.
+
+ >>> user.getControl('Next').click()
+
+ >>> user.getControl('First Name').value = 'Wolfgang'
+ >>> user.getControl('Last Name').value = 'Richter'
+ >>> user.getControl('Phone').value = '+49 33 1271568'
+ >>> user.getControl('Email').value = 'wrichter at telekom.de'
+ >>> user.getControl('Street').value = u'DorfstraÃe 12'.encode('utf-8')
+ >>> user.getControl('Zip').value = '01945'
+ >>> user.getControl('City').value = 'Tetta'
+
+ >>> user.getControl('Next').click()
+
+ >>> user.getControl('First Name').value = 'Marion'
+ >>> user.getControl('Last Name').value = 'Richter'
+ >>> user.getControl('Phone').value = '+49 33 1271568'
+ >>> user.getControl('Street').value = u'DorfstraÃe 12'.encode('utf-8')
+ >>> user.getControl('Zip').value = '01945'
+ >>> user.getControl('City').value = 'Tettau'
+
+ >>> user.getControl('Next').click()
+
+We are now at the final screen. As you will notice, initially there is no
+button that allows submitting the wizard:
+
+ >>> user.getControl('Finish')
+ Traceback (most recent call last):
+ ...
+ LookupError: label 'Finish'
+
+This is because not all required fields have been filled out. Filling out the
+last step and saving it, ...
+
+ >>> user.getControl('Name').value = 'Myself'
+ >>> user.getControl('Street').value = '110 Main Street'
+ >>> user.getControl('Zip').value = '01754'
+ >>> user.getControl('City').value = 'Maynard'
+
+ >>> user.getControl('Save').click()
+
+... will allow the "Finish" button to show:
+
+ >>> user.getControl('Finish')
+ <SubmitControl name='form.buttons.finish' type='submit'>
+
+Clicking it, brings us to the final summary screen:
+
+ >>> user.getControl('Finish').click()
+ >>> user.url
+ 'http://localhost:8080/summary.html'
Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the Checkins
mailing list