~launchpad-pqm/launchpad/devel

9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
1
=====================
9209.8.12 by Michael Nelson
Added initial pagetest for new +packages page.
2
The PPA packages page
3
=====================
4
5
The PPA packages page is accessible from the PPA page.
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
6
7
    >>> anon_browser.open('http://launchpad.dev/~cprov/+archive/ppa')
9209.8.39 by Michael Nelson
Fixed xx-ppa-packages.txt
8
    >>> anon_browser.getLink('View package details').click()
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
9
    >>> print anon_browser.url
10
    http://launchpad.dev/~cprov/+archive/ppa/+packages
9209.8.12 by Michael Nelson
Added initial pagetest for new +packages page.
11
12
    >>> print anon_browser.title
9322.10.18 by Guilherme Salgado
Fix a few tests
13
    Packages in...
9209.8.12 by Michael Nelson
Added initial pagetest for new +packages page.
14
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
15
16
Page structure
17
==============
18
19
The PPA packages page uses the 'Overview' application button and displays
20
a descriptive main heading.
9209.8.12 by Michael Nelson
Added initial pagetest for new +packages page.
21
22
    >>> print_location(anon_browser.contents)
9322.10.18 by Guilherme Salgado
Fix a few tests
23
    Hierarchy: Celso Providelo > PPA for Celso Providelo > Packages in...
9209.8.12 by Michael Nelson
Added initial pagetest for new +packages page.
24
    Tabs:
25
    * Overview (selected) - http://launchpad.dev/~cprov
10842.1.3 by Paul Hummer
Fixed tests
26
    * Code - http://code.launchpad.dev/~cprov
9209.8.12 by Michael Nelson
Added initial pagetest for new +packages page.
27
    * Bugs - http://bugs.launchpad.dev/~cprov
28
    * Blueprints - http://blueprints.launchpad.dev/~cprov
29
    * Translations - http://translations.launchpad.dev/~cprov
30
    * Answers - http://answers.launchpad.dev/~cprov
31
    Main heading: Packages in ...PPA for Celso Providelo...
32
33
You can see the build details of the packages in the archive by using
34
the 'View all builds' link.
35
36
    >>> anon_browser.getLink('View all builds').click()
9209.8.14 by Michael Nelson
Initial (failing) pagetests for portals.
37
    >>> print anon_browser.title
9855.4.1 by William Grant
Add a BuildBreadcrumb.
38
    Builds : PPA for Celso Providelo : Celso Providelo
9209.8.12 by Michael Nelson
Added initial pagetest for new +packages page.
39
9209.8.14 by Michael Nelson
Initial (failing) pagetests for portals.
40
    >>> print anon_browser.url
9209.8.15 by Michael Nelson
Updated pagetest for packages with portlets.
41
    http://launchpad.dev/~cprov/+archive/ppa/+builds
42
9209.8.12 by Michael Nelson
Added initial pagetest for new +packages page.
43
44
The rest of the builds page functionality is tested generically at
45
in xx-builds-pages.txt.
9209.8.14 by Michael Nelson
Initial (failing) pagetests for portals.
46
47
48
Package totals
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
49
==============
9209.8.14 by Michael Nelson
Initial (failing) pagetests for portals.
50
9209.8.15 by Michael Nelson
Updated pagetest for packages with portlets.
51
A summary of the package totals is presented in a portlet (although the
52
actual values are loaded in asynchronously.
9209.8.14 by Michael Nelson
Initial (failing) pagetests for portals.
53
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
54
    >>> anon_browser.open(
55
    ...     'http://launchpad.dev/~cprov/+archive/ppa/+packages')
9209.8.14 by Michael Nelson
Initial (failing) pagetests for portals.
56
    >>> package_totals = find_portlet(
57
    ...     anon_browser.contents, "Package totals")
58
    >>> print extract_text(package_totals)
9209.8.15 by Michael Nelson
Updated pagetest for packages with portlets.
59
    Package totals
60
    ...
61
    Package counters and estimated archive size temporarily
62
    unavailable.
63
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
64
65
Package build summary
66
=====================
67
9209.8.15 by Michael Nelson
Updated pagetest for packages with portlets.
68
A summary of the builds for the PPA is also presented.
69
70
    >>> build_summary = find_portlet(
71
    ...     anon_browser.contents, "View all builds Package build summary")
72
    >>> print extract_text(build_summary)
73
    View...
74
    A total of 4 builds have been dispatched for this PPA.
75
    Completed builds
76
    3 successful
77
    1 failed
78
79
Successful builds link directly to the builds filter.
80
81
    >>> successful_builds_link = anon_browser.getLink('3 successful')
82
    >>> print successful_builds_link.url
83
    http://launchpad.dev/~cprov/+archive/ppa/+builds?build_state=built
84
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
85
86
The detailed Packages list
87
==========================
88
89
    >>> def print_archive_package_rows(contents):
90
    ...     package_table = find_tag_by_id(
91
    ...         contents, 'packages_list')
92
    ...     for ppa_row in package_table.findChildren('tr'):
93
    ...         print extract_text(ppa_row)
94
95
    >>> print_archive_package_rows(anon_browser.contents)
96
    Source              Published   Status     Series      Section  Build
97
        Status
98
    cdrkit - 1.0        2007-07-09  Published  Breezy-a... Editors  i386
10180.2.6 by Jamal Fanaian
Merged from trunk. Changed sources.changes to changes file.
99
    ice...(changes file) 2007-07-09  Published  Warty       Editors  i386
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
100
    pmount - 0.1-1      2007-07-09  Published  Warty       Editors
101
102
Each data row is expandable to contain some sections containing:
103
104
 * Publishing details
105
 * The source package's changelog
106
 * Any built packages and their description
107
 * The list of files for this package
108
109
    >>> expander_url = anon_browser.getLink(id='pub29-expander').url
110
    >>> anon_browser.open(expander_url)
111
    >>> print extract_text(anon_browser.contents)
112
    Publishing details
113
      Published on 2007-07-09
114
      Copied from ubuntu hoary in Primary Archive for Ubuntu Linux
115
    Changelog
116
      pmount (0.1-1) hoary; urgency=low
117
      * Fix description (Malone #1)
118
      * Fix debian (Debian #2000)
119
      * Fix warty (Warty Ubuntu #1)
120
      -- Sample Person...
121
    Builds
122
      i386
123
    Built packages
124
      pmount
125
      pmount shortdesc
126
    Package files
127
      No files published for this package.
128
129
If a the binaries for a package are fully built, but have not yet been
130
published, this will be indicated to the viewer:
131
9881.5.11 by Michael Nelson
Fixed a few more affected tests.
132
    # First, we'll update the binary publishing history for the i386
133
    # record so that it is pending publication.
134
    >>> login('foo.bar@canonical.com')
135
    >>> from zope.component import getUtility
136
    >>> from lp.registry.interfaces.person import IPersonSet
10316.1.40 by Michael Nelson
Fixed xx-ppa-packages.txt
137
    >>> cprov = getUtility(IPersonSet).getByName('cprov')
138
    >>> cprov_ppa = cprov.archive
9881.5.11 by Michael Nelson
Fixed a few more affected tests.
139
    >>> pmount_i386_pub = cprov_ppa.getAllPublishedBinaries(
140
    ...     name='pmount', version='0.1-1')[1]
141
    >>> print pmount_i386_pub.displayname
142
    pmount 0.1-1 in warty i386
11411.6.12 by Julian Edwards
Move PackagePublishingStatus/Priority
143
    >>> from lp.soyuz.enums import PackagePublishingStatus
7659.7.5 by Julian Edwards
Fix lots of broken stuff
144
    >>> pmount_i386_pub.status = PackagePublishingStatus.PENDING
145
    >>> pmount_i386_pub.datepublished = None
9881.5.11 by Michael Nelson
Fixed a few more affected tests.
146
    >>> transaction.commit()
147
    >>> logout()
148
149
    # Now, to re-display the pmount expanded section:
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
150
    >>> anon_browser.open(expander_url)
151
    >>> print extract_text(anon_browser.contents)
152
    Note: Some binary packages for this source are not yet published in the
153
    repository.
154
    Publishing details
155
      Published on 2007-07-09
9881.5.11 by Michael Nelson
Fixed a few more affected tests.
156
      Copied from ubuntu hoary in Primary Archive for Ubuntu Linux
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
157
    Changelog
9881.5.11 by Michael Nelson
Fixed a few more affected tests.
158
      pmount (0.1-1) hoary; urgency=low
159
      * Fix description (Malone #1)
160
      * Fix debian (Debian #2000)
161
      * Fix warty (Warty Ubuntu #1)
162
      -- Sample Person...
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
163
    Builds
164
      i386 - Pending publication
165
    Built packages
9881.5.11 by Michael Nelson
Fixed a few more affected tests.
166
      pmount
167
      pmount shortdesc
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
168
    Package files
9881.5.11 by Michael Nelson
Fixed a few more affected tests.
169
      No files published for this package.
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
170
9881.5.11 by Michael Nelson
Fixed a few more affected tests.
171
When the package is copied from a PPA, the archive title will link
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
172
back to the source PPA.
173
9881.5.11 by Michael Nelson
Fixed a few more affected tests.
174
    >>> anon_browser.open(
175
    ...     "http://launchpad.dev/~cprov/+archive/ppa/+packages")
176
    >>> expander_url = anon_browser.getLink(id='pub28-expander').url
177
    >>> anon_browser.open(expander_url)
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
178
    >>> anon_browser.getLink("PPA for Mark Shuttleworth").url
179
    'http://launchpad.dev/~mark/+archive/ppa'
180
181
This link is not present if the user does not have permission to view
10316.1.40 by Michael Nelson
Fixed xx-ppa-packages.txt
182
the PPA.  We create a private PPA with a published source and then copy
183
the source into a public PPA to demonstrate this.
184
185
    >>> login('foo.bar@canonical.com')
186
    >>> from lp.registry.interfaces.distribution import IDistributionSet
187
    >>> ubuntu = getUtility(IDistributionSet).getByName(
188
    ...     'ubuntu')
189
    >>> warty = ubuntu.getSeries('warty')
190
    >>> private_ppa = factory.makeArchive(
191
    ...     name='p3a', private=True, owner=cprov,
192
    ...     distribution=ubuntu)
193
    >>> joe = factory.makePerson(name="joe")
194
    >>> public_ppa = factory.makeArchive(
10747.1.20 by Aaron Bentley
Fix failing tests.
195
    ...     owner=joe, distribution=ubuntu, name='ppa')
10316.1.40 by Michael Nelson
Fixed xx-ppa-packages.txt
196
    >>> from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
197
    >>> test_publisher = SoyuzTestPublisher()
198
    >>> test_publisher.prepareBreezyAutotest()
199
    >>> source = test_publisher.getPubSource(
200
    ...     sourcename='foo', archive=private_ppa, distroseries=warty)
10316.1.47 by Michael Nelson
Simplified the package copy in xx-ppa-packages.txt
201
    >>> copied_source = source.copyTo(
202
    ...     source.distroseries, source.pocket, public_ppa)
10316.1.40 by Michael Nelson
Fixed xx-ppa-packages.txt
203
    >>> expander_link_id = "pub%s-expander" % copied_source.id
10316.1.42 by Michael Nelson
Replaced endInteraction() with a simple logout in xx-ppa-packages.txt
204
    >>> logout()
10316.1.40 by Michael Nelson
Fixed xx-ppa-packages.txt
205
206
10316.1.47 by Michael Nelson
Simplified the package copy in xx-ppa-packages.txt
207
We can view the link on the public PPA to Celso's private PPA when logged
10316.1.40 by Michael Nelson
Fixed xx-ppa-packages.txt
208
in as Celso.
209
210
    >>> cprov_browser = setupBrowser(
211
    ...     auth="Basic celso.providelo@canonical.com:cprov")
212
    >>> cprov_browser.open(
213
    ...     "http://launchpad.dev/~joe/+archive/ppa/+packages")
214
    >>> expander_url = cprov_browser.getLink(id=expander_link_id).url
215
    >>> cprov_browser.open(expander_url)
216
    >>> print cprov_browser.getLink("PPA named p3a for Celso Providelo").url
217
    http://launchpad.dev/~cprov/+archive/p3a
218
219
But Joe himself will not see the link.
220
221
    >>> joe_browser = setupBrowser(
222
    ...     auth="Basic joe@example.com:test")
223
    >>> joe_browser.open(expander_url)
224
    >>> joe_browser.getLink("PPA named p3a for Celso Providelo")
225
    Traceback (most recent call last):
226
    ...
227
    LinkNotFoundError
228
229
And neither can an anonymous user.
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
230
9881.5.11 by Michael Nelson
Fixed a few more affected tests.
231
    >>> anon_browser.open(expander_url)
10316.1.40 by Michael Nelson
Fixed xx-ppa-packages.txt
232
    >>> anon_browser.getLink("PPA named p3a for Celso Providelo")
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
233
    Traceback (most recent call last):
234
    ...
235
    LinkNotFoundError
236
10316.1.40 by Michael Nelson
Fixed xx-ppa-packages.txt
237
While we are there, we can also see that the private PPA's 'repository-size'
238
pagelet isn't publicly available.
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
239
240
    >>> anon_browser.open(
10316.1.40 by Michael Nelson
Fixed xx-ppa-packages.txt
241
    ...     "http://launchpad.dev/~cprov/+archive/p3a/+repository-size")
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
242
    Traceback (most recent call last):
243
    ...
244
    Unauthorized: (..., 'launchpad.View')
245
246
247
Searching the packages list
248
===========================
249
250
We can search a PPA for a particular package.  A non-existent package shows
251
no results.
252
10316.1.40 by Michael Nelson
Fixed xx-ppa-packages.txt
253
    >>> anon_browser.open(
254
    ...     "http://launchpad.dev/~cprov/+archive/ppa/+packages")
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
255
    >>> field = anon_browser.getControl(name='field.name_filter')
256
    >>> field.value = 'nonexistentpackage'
257
    >>> anon_browser.getControl('Filter', index=0).click()
258
    >>> len(find_tags_by_class(anon_browser.contents, 'archive_package_row'))
259
    0
260
261
Searching for the package iceweasel shows that Celso is providing this.
262
263
    >>> field = anon_browser.getControl(name='field.name_filter')
264
    >>> field.value = 'iceweasel'
265
    >>> anon_browser.getControl('Filter', index=0).click()
266
    >>> len(find_tags_by_class(anon_browser.contents, 'archive_package_row'))
267
    2
268
269
In order to have a wider coverage in search status filter we will
270
modify some publication in Celso's PPA to SUPERSEDED and DELETED
271
states. Note, for consistency we have to create the binary publishing records
272
for iceweasel before marking it as superseded.
273
11716.1.12 by Curtis Hovey
Sorted imports in doctests.
274
    >>> from zope.component import getUtility
11716.1.6 by Curtis Hovey
Converted glob imports in doctests to import for the true module.
275
    >>> from lp.registry.interfaces.person import IPersonSet
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
276
    >>> login('foo.bar@canonical.com')
277
    >>> cprov = getUtility(IPersonSet).getByName('cprov')
278
    >>> iceweasel_pub = cprov.archive.getPublishedSources(
12505.4.1 by Robert Collins
Hopefully fix bug 727560 by permitting a much better query plan for folk querying the primary archive.
279
    ...     name='iceweasel').first()
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
280
    >>> bpr = test_publisher.uploadBinaryForBuild(
281
    ...     iceweasel_pub.getBuilds()[0], 'bar-bin')
282
    >>> pub_bins = test_publisher.publishBinaryInArchive(
283
    ...     bpr, cprov.archive, status=PackagePublishingStatus.PUBLISHED)
7659.7.5 by Julian Edwards
Fix lots of broken stuff
284
    >>> iceweasel_pub.status = (
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
285
    ...     PackagePublishingStatus.SUPERSEDED)
12505.4.1 by Robert Collins
Hopefully fix bug 727560 by permitting a much better query plan for folk querying the primary archive.
286
    >>> pmount_pub = cprov.archive.getPublishedSources(name='pmount').first()
7659.7.5 by Julian Edwards
Fix lots of broken stuff
287
    >>> pmount_pub.status = PackagePublishingStatus.DELETED
288
    >>> pmount_pub.removed_by = cprov
289
    >>> pmount_pub.removal_comment = 'nhack !'
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
290
    >>> logout()
291
    >>> transaction.commit()
292
    >>> from canonical.database.sqlbase import flush_database_updates
293
    >>> flush_database_updates()
294
295
The default status filter is 'published', which means that, by
296
default, PPA pages will only present PUBLISHED or PENDING packages.
297
298
    >>> field = anon_browser.getControl(name='field.name_filter')
299
    >>> field.value = ''
300
    >>> anon_browser.getControl('Filter', index=0).click()
301
    >>> print_archive_package_rows(anon_browser.contents)
302
    Source          Published   Status     Series           Section  Build
303
        Status
304
    cdrkit - 1.0    2007-07-09  Published  Breezy-autotest  Editors  i386
305
306
Use can explicitly select 'published' filter and will get the same result.
307
308
    >>> anon_browser.getControl(name='field.status_filter').value = ['published']
309
    >>> anon_browser.getControl('Filter', index=0).click()
310
    >>> print_archive_package_rows(anon_browser.contents)
311
    Source          Published   Status     Series           Section  Build
312
        Status
313
    cdrkit - 1.0    2007-07-09  Published  Breezy-autotest  Editors  i386
314
315
When needed the users can select the 'superseded' filter and the
316
result will only contain packages SUPERSEDED or DELETED.
317
318
    >>> anon_browser.getControl(name='field.status_filter').value = ['superseded']
319
    >>> anon_browser.getControl('Filter', index=0).click()
320
    >>> print_archive_package_rows(anon_browser.contents)
321
    Source            Published    Status        Series   Section  Build
322
        Status
10180.2.6 by Jamal Fanaian
Merged from trunk. Changed sources.changes to changes file.
323
    i...(changes file) 2007-07-09   Superseded    Warty    Editors
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
324
    pmount - 0.1-1    2007-07-09   Deleted       Warty    Editors
325
326
The 'Any Status' filter is also available, so the user can search over
327
any package ever published in the context PPA.
328
9426.5.5 by Michael Nelson
Updated other affected stories to new '' value for any status/series.
329
    >>> anon_browser.getControl(name='field.status_filter').value = ['']
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
330
    >>> anon_browser.getControl('Filter', index=0).click()
331
    >>> print_archive_package_rows(anon_browser.contents)
332
    Source             Published    Status     Series      Section  Build
333
        Status
334
    cdrkit - 1.0       2007-07-09   Published  Breezy-a... Editors  i386
10180.2.6 by Jamal Fanaian
Merged from trunk. Changed sources.changes to changes file.
335
    ic...(changes file) 2007-07-09   Superseded Warty       Editors
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
336
    pmount - 0.1-1     2007-07-09   Deleted    Warty       Editors
337
338
339
Team PPA package pages
340
======================
341
342
Team PPA package pages contain an extra column showing which team member
343
uploaded the package. First we need to set up a team PPA and publish
344
something to it.
345
346
    >>> foo_browser = setupBrowser(auth="Basic foo.bar@canonical.com:test")
347
    >>> foo_browser.open("http://launchpad.dev/~ubuntu-team/+activate-ppa")
348
    >>> foo_browser.getControl(name="field.displayname").value = (
349
    ...     'PPA for Ubuntu team')
350
    >>> foo_browser.getControl(name="field.accepted").value = True
351
    >>> foo_browser.getControl('Activate').click()
352
    >>> ubuntu_ppa_url = foo_browser.url
353
354
Publish mozilla-firefox to ubuntu-team's PPA and ensure that it is signed
355
by name16 (Foo Bar) who is a member - the signer is presented as the uploader
356
in the list.
357
358
    >>> from lp.soyuz.tests.ppa import publishToTeamPPA
359
    >>> login(ANONYMOUS)
360
    >>> publishToTeamPPA(team_name="ubuntu-team")
361
    >>> logout()
362
    >>> transaction.commit()
363
    >>> flush_database_updates()
364
365
Access ubuntu-team's PPA page:
366
367
    >>> foo_browser.open(ubuntu_ppa_url)
9209.8.39 by Michael Nelson
Fixed xx-ppa-packages.txt
368
    >>> foo_browser.getLink('View package details').click()
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
369
370
The package row data shows the uploader:
371
372
    >>> print_archive_package_rows(foo_browser.contents)
373
    Source              Uploader ... Status   Series  Section  Build Status
374
    mozilla-firefox...  name16       Pending  Hoary   Base
375
376
Links from files go to their on-archive locations:
377
378
    >>> expander_id = find_tags_by_class(
379
    ...     foo_browser.contents, 'expander')[0]['id']
380
    >>> expander_url = foo_browser.getLink(id=expander_id).url
381
    >>> anon_browser.open(expander_url)
382
    >>> print anon_browser.getLink("orig").url
7675.424.31 by William Grant
Fix broken sample data (NULL dsc_formats, and an orig.tar.gz with - instead of _).
383
    http://.../firefox_0.9.2.orig.tar.gz
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
384
385
The uploader name is linkified to that user's home page:
386
387
    >>> foo_browser.getLink(url="~name16").click()
388
    >>> foo_browser.url
389
    'http://launchpad.dev/~name16'
390
391
392
PPA Build Status column
393
=======================
394
395
Each row in the PPA package list contains a special column that
396
summarises its 'build status'. It contains the following information
397
for each published source:
398
399
 * Completely built: green 'yes' icon only;
400
401
 * Build in progress: 'processing' icon, followed by the
402
   architecture tags being built linking to the corresponding build
403
   page
404
405
 * Build failures: red 'no' icon, followed by the architecture tags
406
   which have failed to build linking to the corresponding build page.
407
408
Anyone can see the build status for package in Celso's PPA.
409
410
    >>> anon_browser.open(
411
    ...     "http://launchpad.dev/~cprov/+archive/ppa/+packages")
412
413
    >>> def print_build_status(contents):
414
    ...     rows = find_tags_by_class(contents, 'archive_package_row')
415
    ...     headers = rows[0].findAll('th')
416
    ...     print extract_text(headers[0]), extract_text(headers[-1])
417
    ...     for row in rows[1:]:
418
    ...         columns = row.findAll('td')
419
    ...         name = extract_text(columns[0])
420
    ...         built_icon = columns[-1].img['src']
421
    ...         built_text = columns[-1].a
422
    ...         if built_text is not None:
423
    ...             built_text = built_text.renderContents()
424
    ...         print name, built_icon, built_text
425
426
    >>> print_build_status(anon_browser.contents)
427
    Source                    Build Status
428
    cdrkit - 1.0              /@@/no i386
429
430
As mentioned before anyone can visualise 'at a glance' that there was
431
a failure while building 'cdrkit' source in Celso's PPA. They can also
432
easily see that the failure was in the i386 build, and optionally
433
click in the link to visit the build-record page (to check the dates
434
of downloading the buildlog).
435
436
    >>> anon_browser.getLink('i386').click()
437
438
    >>> print anon_browser.title
9855.4.3 by William Grant
Fix tests.
439
    i386 build of cdrkit 1.0 : PPA for Celso Providelo : Celso Providelo
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
440
441
This feature is also useful from the PPA owner perspective. When Celso
442
sees that there was a failure while building 'cdrkit' on i386 he can
443
quickly 'retry' the failure.
444
445
    >>> cprov_browser = setupBrowser(
446
    ...     auth='Basic celso.providelo@canonical.com:cprov')
447
    >>> cprov_browser.open(
448
    ...     "http://launchpad.dev/~cprov/+archive/ppa/+packages")
449
450
    >>> cprov_browser.getLink('i386').click()
9430.1.2 by Celso Providelo
Fixing #416365 (clearer 'Retry this build' action link).
451
    >>> cprov_browser.getLink("Retry this build").click()
9209.8.26 by Michael Nelson
Updated pagetests after simplifying package table on ppa-index page.
452
    >>> cprov_browser.getControl("Retry Build").click()
453
454
At this point anyone can also visualise that 'cdrkit' source is being
455
built in Celso's PPA.
456
457
    >>> anon_browser.open(
458
    ...     "http://launchpad.dev/~cprov/+archive/ppa/+packages")
459
    >>> print_build_status(anon_browser.contents)
460
    Source                    Build Status
461
    cdrkit - 1.0              /@@/build-needed i386
462
463
Again the architecture tags listed on the 'built' column link to the
464
corresponding build page.
465
466
    >>> anon_browser.getLink('i386').click()
467
    >>> print anon_browser.title
9855.4.3 by William Grant
Fix tests.
468
    i386 build of cdrkit 1.0 : PPA for Celso Providelo : Celso Providelo