{
 "metadata": {
  "name": "",
  "signature": "sha256:1848ceaccc070baee397b0e7033b8d773e76fd7f5aacdedf442309a9cb5e6cba"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "robotframework-tools"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import robottools\n",
      "print(robottools.__version__)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "0.1a111\n"
       ]
      }
     ],
     "prompt_number": 1
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "print(robottools.__description__)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Python Tools for Robot Framework and Test Libraries.\n"
       ]
      }
     ],
     "prompt_number": 2
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "* `testlibrary()` [creates Dynamic Test Libraries][1]\n",
      "* A [`ContextHandler`][1.1] framework for `testlibrary`\n",
      "  to create switchable sets of different Keyword implementations.\n",
      "* A [`SessionHandler`][1.2] framework for `testlibrary`\n",
      "  to auto-generate Keywords for session management.\n",
      "* A [`TestLibraryInspector`][2].\n",
      "* A [`RemoteRobot`][4], combining `TestRobot`\n",
      "  with external [`RobotRemoteServer`](\n",
      "    https://pypi.python.org/pypi/robotremoteserver)\n",
      "* A [`ToolsLibrary`][5],\n",
      "  accompanying Robot Framework's standard Test Libraries.\n",
      "* A [`robotshell`][6] extension for [IPython](http://ipython.org).\n",
      "\n",
      "[1]: #1.-Creating-Dynamic-Test-Libraries"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "<https://bitbucket.org/userzimmermann/robotframework-tools>\n",
      "\n",
      "<https://github.com/userzimmermann/robotframework-tools>"
     ]
    },
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "0. Setup"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "__Supported Python versions__:\n",
      "[2.7](http://docs.python.org/2.7),\n",
      "[3.3](http://docs.python.org/3.3),\n",
      "[3.4](http://docs.python.org/3.4)\n",
      "\n",
      "Just install the latest release\n",
      "from [PyPI](https://pypi.python.org/pypi/robotframework-tools)\n",
      "with [pip](http://www.pip-installer.org):"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# !pip install robotframework-tools"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 3
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "or from [Binstar](https://binstar.org/userzimmermann/robotframework-tools)\n",
      "with [conda](http://conda.pydata.org):"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# !conda install -c userzimmermann robotframework-tools"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 4
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Both automatically install requirements:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "robottools.__requires__"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 5,
       "text": [
        "six\n",
        "path.py\n",
        "moretools>=0.1a38"
       ]
      }
     ],
     "prompt_number": 5
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "* __Python 2.7__: `robotframework>=2.8`\n",
      "\n",
      "* __Python 3.x__: `robotframework-python3>=2.8.4`"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "`RemoteRobot` and `robotshell` have extra requirements:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "robottools.__extras__"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 6,
       "text": [
        "[remote]\n",
        "robotremoteserver\n",
        "\n",
        "[robotshell]\n",
        "ipython"
       ]
      }
     ],
     "prompt_number": 6
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Pip doesn't install them by default.\n",
      "Just append any comma separated extra tags in `[]` brackets to the package name.\n",
      "To install with all extra requirements:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# !pip install robotframework-tools[all]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 7
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "This `README.ipynb` will also be installed. Just copy it:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# robottools.__notebook__.copy('path/name.ipynb')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 8
    },
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "1. Creating Dynamic Test Libraries"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from robottools import testlibrary"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 9
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "TestLibrary = testlibrary()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 10
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "This generated Dynamic `TestLibrary` class\n",
      "could now directly be imported in Robot Framework.\n",
      "It features all the Dynamic API methods:\n",
      "\n",
      "* `get_keyword_names`\n",
      "* `get_keyword_arguments`\n",
      "* `get_keyword_documentation`\n",
      "* `run_keyword`"
     ]
    },
    {
     "cell_type": "heading",
     "level": 3,
     "metadata": {},
     "source": [
      "Keywords"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "The `TestLibrary` has no Keywords so far...\n",
      "To add some just use the `TestLibrary.keyword` decorator:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "@TestLibrary.keyword\n",
      "def some_keyword(self, arg, *rest):\n",
      "    pass"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 11
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "A keyword function can be defined anywhere in any scope.\n",
      "The `TestLibrary.keyword` decorator\n",
      "always links it to the `TestLibrary`\n",
      "(but always returns the original function object).\n",
      "And when called as a Keyword from Robot Framework\n",
      "the `self` parameter will always get the `TestLibrary` instance."
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "You may want to define your keyword methods\n",
      "at your Test Library class scope.\n",
      "Just derive your actual Dynamic Test Library class from `TestLibrary`:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "class SomeLibrary(TestLibrary):\n",
      "    def no_keyword(self, *args):\n",
      "        pass\n",
      "\n",
      "    @TestLibrary.keyword\n",
      "    def some_other_keyword(self, *args):\n",
      "        pass"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 12
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "To get a simple interactive `SomeLibrary` overview just instantiate it:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "lib = SomeLibrary()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 13
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "You can inspect all Keywords in Robot CamelCase style\n",
      "(and call them for testing):"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "lib.SomeKeyword"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 14,
       "text": [
        "SomeLibrary.Some Keyword [ arg | *rest ]"
       ]
      }
     ],
     "prompt_number": 14
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "By default the Keyword names and argument lists are auto-generated\n",
      "from the function definition.\n",
      "You can override that:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "@TestLibrary.keyword(name='KEYword N@me', args=['f|r$t', 'se[ond'])\n",
      "def function(self, *args):\n",
      "    pass"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 15
    },
    {
     "cell_type": "heading",
     "level": 3,
     "metadata": {},
     "source": [
      "Keyword Options"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "When you apply custom decorators to your Keyword functions\n",
      "which don't return the original function objects,\n",
      "you would have to take care of preserving the original argspec for Robot.\n",
      "`testlibrary` can handle this for you:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def some_decorator(func):\n",
      "    def wrapper(self, *args):\n",
      "        return func(self, *args)\n",
      "\n",
      "    # You still have to take care of the function(-->Keyword) name:\n",
      "    wrapper.__name__ = func.__name__\n",
      "    return wrapper\n",
      "\n",
      "TestLibrary = testlibrary(\n",
      "  register_keyword_options=[\n",
      "    # Either just:\n",
      "    some_decorator,\n",
      "    # Or with some other name:\n",
      "    ('some_option', some_decorator),\n",
      "    ],\n",
      "  )\n",
      "\n",
      "@TestLibrary.keyword.some_option\n",
      "def some_keyword_with_options(self, arg, *rest):\n",
      "    pass"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 16
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "There are predefined options. Currently:\n",
      "\n",
      "* `unicode_to_str` - Convert all `unicode` values (pybot's default) to `str`."
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "You can specify `default_keyword_options` that will always be applied:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "TestLibrary = testlibrary(\n",
      "  register_keyword_options=[\n",
      "    ('some_option', some_decorator),\n",
      "    ],\n",
      "  default_keyword_options=[\n",
      "    'unicode_to_str',\n",
      "    'some_option',\n",
      "    ],\n",
      "  )"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 17
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "To bypass the `default_keyword_options` for single Keywords:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "@TestLibrary.keyword.no_options\n",
      "def some_keyword_without_options(self, arg, *rest):\n",
      "    pass\n",
      "\n",
      "@TestLibrary.keyword.reset_options.some_option\n",
      "def some_keyword_without_default_options(self, arg, *rest):\n",
      "    pass"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 18
    }
   ],
   "metadata": {}
  }
 ]
}