========================
twill language reference
========================

The following commands are built into twill.  Note that all text after
a '#' is ignored as a comment, unless it's in a quoted string.

Browsing
========

**go** *<url>* -- visit the given URL.  The Python function returns the
final URL visited, after all redirects.

**back** -- return to the previous URL.  The Python function returns that
URL, if any.

**reload** -- reload the current URL.  The Python function returns that URL,
if any.

**follow** *<link name>* -- follow the given link.  The Python function
returns the final URL visited, after all redirects.


Assertions
==========

**code** *<code>* -- assert that the last page loaded had this HTTP status,
e.g. ``code 200`` asserts that the page loaded fine.

**find** *<regexp>* -- assert that the page contains this regular expression. The variable ``__match__`` is set to the first matching subgroup (or the entire matching string, if no subgroups are specified).  When called from Python,
the matching string is returned.

**notfind** *<regexp>* -- assert that the page *does not* contain this
regular expression.

**url** *<regexp>* -- assert that the current URL matches the given regexp.  The variable ``__match__`` is set to the first matching subgroup (or the entire matching string, if no subgroups are specified).  When called from Python, the matching string is returned.

**title** *<regexp>* -- assert that the title of this page matches this regular expression.  The variable ``__match__`` is set to the first matching subgroup (or the entire matching string, if no subgroups are specified).  When called from Python, the matching string is returned.

Display
=======

**echo** *<string>* -- echo the string to the screen.

**info** -- display information about the current page.

**redirect_output** *<filename>* -- append all twill output to the given file.

**reset_output** -- display all output to the screen.

**save_html** *[<filename>]* -- save the current page's HTML into a file.  If
no filename is given, derive the filename from the URL.

**show** -- show the current page's HTML.  When called from Python, this function will also return a string containing the HTML.

**showlinks** -- show all of the links on the current page.  When called from Python, this function returns a list of the link objects.

**showforms** -- show all of the forms on the current page.  When called from Python, this function returns a list of the forms.

**showhistory** -- show the browser history.  When called from Python, this function returns the history.

Forms
=====

**submit** *[<n>]* -- click the n'th submit button, if given;
otherwise submit via the last submission button clicked; if nothing
clicked, use the first submit button on the form.  See `details on
form handling`_ for more information.

**formvalue** *<formnum> <fieldname> <value>* --- set the given field in the
given form to the given value.  For read-only form widgets/controls, the
click may be recorded for use by **submit**, but the value is not changed
unless the 'config' command has changed the default behavior.
See 'config' and `details on form handling`_ for more information on
the 'formvalue' command.

For list widgets, you can use 'formvalue <formnum> <fieldname> +value' or
'formvalue <formnum> <fieldname> -value' to select or deselect a particular
value.

**fv** -- abbreviation for 'formvalue'.

**formaction** *<formnum> <action>* -- change the form action URL to the given URL.

**fa** -- abbreviation for 'fa'.

**formclear** -- clear all values in the form.

**formfile** *<formspec> <fieldspec> <filename> [ <content_type> ]* -- attach a file to a file upload button by filename.

Cookies
=======

**save_cookies** *<filename>* -- save current cookie jar into a file.

**load_cookies** *<filename>* -- replace current cookie jar with file contents.

**clear_cookies** -- clear all of the current cookies.

**show_cookies** -- show all of the current cookies.

Debugging
=========

**debug** *<what>* *<level>* -- turn on or off debugging/tracing for
  various functions.  The first argument is either 'http' to show HTTP
  headers, 'equiv-refresh' to test HTTP EQUIV-REFRESH headers, or
  'commands' to show twill commands.  The second argument is '0' for off,
  '1' for on.

Variable handling
=================

**setglobal** *<name> <value>* -- set variable <name> to value <value> in
global dictionary.  The value can be retrieved with '$value'.

**setlocal** *<name> <value>* -- set variable <name> to value <value> in
local dictionary.  The value can be retrieved with '$value'.

The local dictionary is file-specific, while the global module is general
to all the commands.  Local variables will override global variables if
they exist.

Note that you can do variable interpolation in strings with ${var}, e.g. ::

   setglobal a 1
   setglobal b 2

   fv thisform thatfield "${a}${b}"

Other commands
==============

**tidy_ok** -- check to see if 'tidy' runs on this page without any errors or warnings.  (`tidy` is very stringent -- you've been warned!)

**exit** *[<code>]* -- exit with the given integer code, if specified.  'code' defaults to 0.

**run** *<command>* -- execute the given Python command.

**runfile** *<file1> [ <file2> ... ]* -- execute the given files.

**agent** -- set the browser's "User-agent" string.

**sleep** *[<seconds>]* -- sleep the given number of seconds.  Defaults to 1 second.

**reset_browser** -- reset the browser.

**extend_with** *<module>* -- import commands from Python module.  This acts
like ``from <module> import *`` does in Python, so e.g. a function
``fn`` in ``extmodule`` would be available as ``fn``.  See *examples/extend_example.py* for an example.

**getinput** *<prompt>* -- get keyboard input and store it in ``__input__``.  When called from Python, this function returns the input value.

**getpassword** *<prompt>* -- get *silent* keyboard input and store
it in ``__password__``.  When called from Python, this function returns the input value.

**add_auth** *<realm> <uri> <user> <password>* -- add HTTP Basic Authentication information for the given realm/URI combination.  For example, ::

   add_auth IdyllStuff http://www.idyll.org/ titus test

tells twill that a request from the authentication realm
"IdyllStuff" under http://www.idyll.org/ should be answered with
username 'titus', password 'test'.  If the 'with_default_realm' option
is set to True, ignore 'realm'.

**config** [*<key>* [*<value>*]] -- show/set configuration options.

**add_extra_headers** *<name>* *<value>* -- add an extra HTTP header to
each HTTP request.

**show_extra_headers** -- show the headers being added to each HTTP request.

**clear_extra_headers** -- clear the headers being added to each HTTP request.

Special variables
=================

**__input__** -- result of last **getinput**.

**__match__** -- matched text from last **find**, **title**, or **url**.

**__password__** -- result of last **getpassword**.

**__url__** -- current URL.

Details on form handling
========================

.. _details on form handling:

Both the `formvalue` (or `fv`) and `submit` commands rely on a certain
amount of implicit cleverness to do their work.  In odd situations, it
can be annoying to determine exactly what form field `formvalue` is
going to pick based on your field name, or what form & field `submit`
is going to "click" on.

Here is the pseudocode for how `formvalue` and `submit` figure out
what form to use (function `twill.commands.browser.get_form`)::

   for each form on page:
       if supplied regexp pattern matches the form name, select
   
   if no form name, try converting to an integer N & using N-1 as
   an index into the list or forms on the page (i.e. form 1 is the
   first form on the page).

Here is the pseudocode for how `formvalue` and `submit` figure out
what form field to use (function `twill.commands.browser.get_form_field`)::

   search current form for control name with exact match to fieldname;
   if single (unique) match, select.

   if no match, convert fieldname into a number and use as an index, if
   possible.

   if no match, search current form for control name with regexp match to fieldname;
   if single (unique) match, select.

   if *still* no match, look for exact matches to submit-button values.
   if single (unique) match, select.

Here is the pseudocode for `submit`::

   if a form was _not_ previously selected by formvalue:
      if there's only one form on the page, select it.
      otherwise, fail.

   if a field is not explicitly named:
      if a submit button was "clicked" with formvalue, use it.
      otherwise, use the first submit button on the form, if any.
   otherwise:
      find the field using the same rules as formvalue

   finally, if a button has been picked, submit using it;
   otherwise, submit without using a button

