.. _commands:

========================
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** *<regex>* [*<flags>*] -- 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. It also accepts
some flags: **i**, for case-insensitive matching, **m** for multi-line mode
and **s** for dotall matching. The flag **x** uses XPath expressions instead
of regular expressions (see below).

**find** *<xpath>* **x** -- assert that the page contains the element
matched by the XPath expression. The variable ``__match__`` is set to
the first matching element's string representation.

**notfind** *<regex>* [*<flags>*] -- assert that the page *does not* contain
this regular expression. It accepts the same flags as **find**.

**notfind** *<xpath>* **x** -- assert that the page *does not* contain this
element pointed by the XPath expression.

**url** *<regex>* -- assert that the current URL matches the given regex.
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** *<regex>* -- 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 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 controls, 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 'formaction'.

**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 show "meta refresh" redirects, 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 HTML Tidy runs on this page without any
errors or warnings. This check is very stringent, but you can relax the
default configuration by setting ``tidy_*`` configuration options.

**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 file(s).

**rf** -- abbreviation for 'runfile'.

**add_cleanup** *<file1> [ <file2> ... ]* -- add the given cleanup file(s).
These will be run after the current file has executed (successfully or not).

**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 *extras/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.

Configuration options starting with ``tidy_`` will be used when checking
documents with HTML Tidy. For example, ::

    config tidy_drop_empty_elements no

**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.browser.form`)::

   for each form on page:
       if supplied regex 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.browser.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 regex 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

