├── .projectignore
├── robotlab
├── setup.py
├── src
│ └── robotlab
│ │ ├── _version.py
│ │ ├── icons
│ │ ├── lab.icns
│ │ ├── lab.ico
│ │ ├── shell.ico
│ │ ├── shell.icns
│ │ ├── build_icons.sh
│ │ ├── starter.svg
│ │ ├── lab.svg
│ │ ├── shell.svg
│ │ └── master.svg
│ │ ├── labapp.py
│ │ ├── labextensionapp.py
│ │ ├── __init__.py
│ │ ├── tutorial.py
│ │ ├── examples.py
│ │ ├── shortcuts.py
│ │ ├── launch.py
│ │ └── paths.py
├── MANIFEST.in
├── README.md
├── setup.cfg
└── LICENSE
├── recipes
├── robotframework
│ ├── run_test.sh
│ ├── run_test.bat
│ ├── meta.yaml
│ └── 70af9e3bab0217b0450d78c69e6c2ccb8f9c342d.patch
├── restinstance
│ ├── 0001-setup-entry-point.patch
│ ├── meta.yaml
│ └── apache-2.0.txt
├── robotframework-whitelibrary
│ ├── bld.bat
│ ├── meta.yaml
│ └── apache-2.0.txt
├── robotframework-jupyterlibrary
│ ├── 001-lab-114-icons.patch
│ └── meta.yaml
├── jupyter-starters
│ └── meta.yaml
├── robotframework-seleniumscreenshots
│ └── meta.yaml
├── pyshortcuts
│ └── meta.yaml
├── robotkernel
│ └── meta.yaml
├── robotframework-seleniumtestability
│ └── meta.yaml
└── robotlab
│ ├── meta.yaml
│ └── builder.py
├── constructor
├── ci
├── env-combine.yml
├── env-lab.yml
├── env-noarch.yml
├── env-main.yml
├── steps.restore.yml
├── steps.conda.yml
├── job.win.yml
├── job.lab.yml
├── job.noarch.yml
├── job.noarch-test.yml
├── job.min.yml
├── job.combine.yml
├── job.release.yml
├── job.main.yml
└── job.selftest.yml
├── tests
├── library
│ └── decolorize.py
├── acceptance
│ ├── ExoRobot
│ │ ├── __init__.robot
│ │ └── 0_Install
│ │ │ └── 0_Installer.robot
│ ├── MiniRobot
│ │ ├── __init__.robot
│ │ └── 0_Install
│ │ │ └── 0_Installer.robot
│ └── RobotLab
│ │ ├── 0_Install
│ │ ├── 0_Installer.robot
│ │ └── 1_Shortcuts.robot
│ │ ├── 1_CLI
│ │ ├── 20_tutorial.robot
│ │ ├── 00_nbrobot.robot
│ │ ├── __init__.robot
│ │ ├── 30_extensions.robot
│ │ └── 10_examples.robot
│ │ ├── 2_Lab
│ │ ├── __init__.robot
│ │ ├── 00_Smoke_Test.robot
│ │ ├── 10_IPython_Notebook.robot
│ │ ├── 20_Robot_Notebook.robot
│ │ ├── 30_Tutorial.robot
│ │ └── 40_Examples.robot
│ │ └── __init__.robot
└── resources
│ ├── Launch.robot
│ ├── Lab.robot
│ ├── Selectors.robot
│ ├── CLI.robot
│ ├── Cleanup.robot
│ ├── Browser.robot
│ └── Install.robot
├── .gitignore
├── scripts
├── combine.py
├── lint.py
├── integrity.py
├── __init__.py
├── build.py
└── test.py
├── environment.yml
├── azure-pipelines.yml
├── attic
└── robotframework-ride
│ └── meta.yaml
├── LICENSE
├── anaconda-project.yml
└── README.md
/.projectignore:
--------------------------------------------------------------------------------
1 | *.ipynb
2 |
--------------------------------------------------------------------------------
/robotlab/setup.py:
--------------------------------------------------------------------------------
1 | __import__("setuptools").setup()
2 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/_version.py:
--------------------------------------------------------------------------------
1 | __version__ = "2020.01.0"
2 |
--------------------------------------------------------------------------------
/recipes/robotframework/run_test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bi/env bash
2 | set -eux
3 | cd src/utest
4 | python run.py
5 |
--------------------------------------------------------------------------------
/robotlab/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include README.md LICENSE
2 | recursive-include src/robotlab/icons *.ico *.icns
3 |
--------------------------------------------------------------------------------
/constructor/RobotLab/post_install.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | . "${PREFIX}/bin/activate"
3 | robotlab-shortcuts
4 |
--------------------------------------------------------------------------------
/constructor/RobotLab/post_install.bat:
--------------------------------------------------------------------------------
1 | @echo on
2 | call "%PREFIX%\Scripts\activate.bat" "%PREFIX%"
3 | robotlab-shortcuts
4 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/icons/lab.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robots-from-jupyter/robotlab/HEAD/robotlab/src/robotlab/icons/lab.icns
--------------------------------------------------------------------------------
/robotlab/src/robotlab/icons/lab.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robots-from-jupyter/robotlab/HEAD/robotlab/src/robotlab/icons/lab.ico
--------------------------------------------------------------------------------
/robotlab/src/robotlab/icons/shell.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robots-from-jupyter/robotlab/HEAD/robotlab/src/robotlab/icons/shell.ico
--------------------------------------------------------------------------------
/robotlab/src/robotlab/icons/shell.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/robots-from-jupyter/robotlab/HEAD/robotlab/src/robotlab/icons/shell.icns
--------------------------------------------------------------------------------
/recipes/robotframework/run_test.bat:
--------------------------------------------------------------------------------
1 | @ECHO ON
2 | cd src\utest
3 |
4 | CALL python run.py || EXIT /B 1
5 | IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
6 |
--------------------------------------------------------------------------------
/ci/env-combine.yml:
--------------------------------------------------------------------------------
1 | name: robotlab-combine
2 |
3 | channels:
4 | - https://conda.anaconda.org/conda-forge
5 | - https://conda.anaconda.org/anaconda
6 |
7 | dependencies:
8 | - robotframework
9 |
--------------------------------------------------------------------------------
/tests/library/decolorize.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | ANSI_ESCAPE = re.compile(r'(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]')
4 |
5 |
6 | def decolorize(line):
7 | return ANSI_ESCAPE.sub('', line)
8 |
--------------------------------------------------------------------------------
/tests/acceptance/ExoRobot/__init__.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Suite Teardown Clean up the installation
3 | Force Tags os:${OS} in-product:${IN_PRODUCT} product:ExoRobot
4 | Resource ../../resources/Install.robot
5 |
--------------------------------------------------------------------------------
/tests/acceptance/MiniRobot/__init__.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Suite Teardown Clean up the installation
3 | Force Tags os:${OS} in-product:${IN_PRODUCT} product:MiniRobot
4 | Resource ../../resources/Install.robot
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__/
2 | _artifacts/
3 | _cache/
4 | .vscode/
5 | *.egg-info/
6 | *.ipynb_checkpoints/
7 | *.pyc
8 | **/construct.yaml
9 | **/icons/*.png
10 | build/
11 | constructor/.*
12 | dist/
13 | envs/
14 | robotkernel-*/
15 |
--------------------------------------------------------------------------------
/recipes/restinstance/0001-setup-entry-point.patch:
--------------------------------------------------------------------------------
1 | --- a/setup.py
2 | +++ b/setup.py
3 | @@ -58,5 +58,4 @@
4 | package_dir={"": "src"},
5 | packages=find_packages("src"),
6 | zip_safe=False,
7 | - entry_points={"console_scripts": ["robot = robot.run:run_cli"]},
8 | )
9 |
--------------------------------------------------------------------------------
/ci/env-lab.yml:
--------------------------------------------------------------------------------
1 | name: robotlab-lab
2 |
3 | channels:
4 | - https://conda.anaconda.org/conda-forge
5 | - https://conda.anaconda.org/anaconda
6 |
7 | dependencies:
8 | - black
9 | - flake8
10 | - jupyterlab ==1.2.4
11 | - nodejs >=11,<12
12 | - python >=3.6,<3.7.0a0
13 | - robotframework-lint
14 |
--------------------------------------------------------------------------------
/tests/acceptance/ExoRobot/0_Install/0_Installer.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation Is the ExoRobot installer viable?
3 | Resource ../../../resources/Install.robot
4 |
5 | *** Test Cases ***
6 | Does the installer run?
7 | [Documentation] Will it run?
8 | Run the installer ExoRobot
9 |
--------------------------------------------------------------------------------
/tests/acceptance/MiniRobot/0_Install/0_Installer.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation Is the MiniRobot installer viable?
3 | Resource ../../../resources/Install.robot
4 |
5 | *** Test Cases ***
6 | Does the installer run?
7 | [Documentation] Will it run?
8 | Run the installer MiniRobot
9 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/labapp.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from jupyterlab import labapp
3 |
4 | from . import patch_app_dir, patch_build_dir
5 |
6 |
7 | def main():
8 | patch_app_dir(labapp.LabApp)
9 | patch_build_dir(labapp.LabBuildApp)
10 | return labapp.main()
11 |
12 |
13 | if __name__ == "__main__":
14 | sys.exit(main())
15 |
--------------------------------------------------------------------------------
/ci/env-noarch.yml:
--------------------------------------------------------------------------------
1 | name: robotlab-noarch
2 |
3 | channels:
4 | - https://conda.anaconda.org/anaconda
5 | - https://conda.anaconda.org/conda-forge
6 |
7 | dependencies:
8 | - conda >=4.8,<4.9.0a0
9 | - conda-build >=3.18.11,<3.19.0a0
10 | - conda-verify
11 | - python >=3.6,<3.7.0a0
12 | - python-libarchive-c
13 | - ripgrep
14 |
--------------------------------------------------------------------------------
/robotlab/README.md:
--------------------------------------------------------------------------------
1 | # robotlab
2 |
3 | A pre-configured JupyterLab for productive Robot Framework authoring with
4 | robotkernel.
5 |
6 | ## Credits
7 | - Borrows heavily from [jupyterlab_delux][].
8 |
9 | [jupyterlab_delux]: https://github.com/jonmmease/jupyterlab_delux
10 | [robotkernel]: https://github.com/robots-from-jupyter/robotkernel
11 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/0_Install/0_Installer.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation Is the RobotLab installer viable?
3 | Force Tags installer
4 | Resource ../../../resources/Install.robot
5 |
6 | *** Test Cases ***
7 | Does the installer run?
8 | [Documentation] Will it run?
9 | Run the installer RobotLab
10 |
--------------------------------------------------------------------------------
/ci/env-main.yml:
--------------------------------------------------------------------------------
1 | name: robotlab-main
2 |
3 | channels:
4 | - https://conda.anaconda.org/anaconda
5 | - https://conda.anaconda.org/conda-forge
6 |
7 | dependencies:
8 | - conda >=4.8,<4.9.0a0
9 | - conda-build >=3.18.11,<3.19.0a0
10 | - conda-verify
11 | - constructor >=3,<3.1
12 | - pillow
13 | - python >=3.6,<3.7.0a0
14 | - python-libarchive-c
15 | - ripgrep
16 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/labextensionapp.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from jupyterlab import labextensions, labapp
3 |
4 | from . import patch_app_dir, patch_build_dir
5 |
6 |
7 | def main():
8 | patch_app_dir(labextensions.BaseExtensionApp)
9 | patch_build_dir(labapp.LabBuildApp)
10 | return labextensions.main()
11 |
12 |
13 | if __name__ == "__main__":
14 | sys.exit(main())
15 |
--------------------------------------------------------------------------------
/constructor/MiniRobot/construct.yaml.in:
--------------------------------------------------------------------------------
1 | name: MiniRobot
2 | version: {{ version }}
3 | company: Robots from Jupyter
4 | license_file: LICENSE.txt
5 |
6 | channels:
7 | - https://conda.anaconda.org/conda-forge
8 | - https://conda.anaconda.org/anaconda
9 |
10 | specs:
11 | - python >={{ py_min }},<{{ py_max }}
12 | - robotframework =={{ rf_version }}
13 | - conda =={{ conda_version }}
14 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/icons/build_icons.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | for icon in lab shell; do
3 | for size in 16 32 48 128 256 512; do
4 | inkscape -z $icon.svg -e $icon-$size.png -w $size
5 | done
6 |
7 | convert $icon-512.png -define icon:auto-resize=256,128,64,48,32,16 $icon.ico
8 | png2icns $icon.icns $icon-16.png $icon-32.png $icon-48.png $icon-128.png $icon-256.png $icon-512.png
9 | done
10 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/1_CLI/20_tutorial.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation robotlab-tutorial
3 | Force Tags app:robotlab-tutorial
4 | Resource ../../../resources/CLI.robot
5 |
6 | *** Test Cases ***
7 | Can I install the tutorial?
8 | [Documentation] Does robotlab-tutorial work?
9 | Check a RobotLab CLI command robotlab-tutorial check_dir=robotkernel-tutorial
10 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/2_Lab/__init__.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Suite Setup Start New RobotLab Server
3 | Suite Teardown Clean Up After Lab Suite
4 | Test Teardown Clean Up After Lab Test
5 | Force Tags ui:lab
6 | Library JupyterLibrary
7 | Library Process
8 | Resource ../../../resources/Launch.robot
9 | Resource ../../../resources/Cleanup.robot
10 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/1_CLI/00_nbrobot.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation nbrobot
3 | Force Tags app:nbrobot
4 | Resource ../../../resources/CLI.robot
5 |
6 | *** Test Cases ***
7 | Can I get help on nbrobot?
8 | [Documentation] Verify the nbrobot command returns help
9 | ${output} = Run nbrobot CLI --help ${251}
10 | Should Contain ${output} Robot Framework
11 |
--------------------------------------------------------------------------------
/recipes/robotframework-whitelibrary/bld.bat:
--------------------------------------------------------------------------------
1 | @echo on
2 | set RFWL_URL=https://files.pythonhosted.org/packages/ff/e9/0e460d1d6609a6cda95dbd76192f0c828089e91fd52eac93dc22df7eda08/robotframework_whitelibrary-%PKG_VERSION%-py2.py3-none-any.whl
3 | set RFWL_SHA256=8e44bcf3db2a60858230129596e93b30b692f3657977b62c7174dacb890a7339
4 |
5 | call python -m pip install --disable-pip-version-check --no-deps %RFWL_URL% -vv
6 | if errorlevel 1 exit 1
7 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from ._version import __version__ # noqa
4 |
5 | from .paths import ROBOTLAB_PATH
6 |
7 |
8 | def patch_app_dir(app_klass):
9 | path = str(ROBOTLAB_PATH)
10 | os.environ["JUPYTERLAB_DIR"] = path
11 | app_klass.app_dir.default_value = path
12 | return path
13 |
14 |
15 | def patch_build_dir(build_klass):
16 | build_klass.name.default_value = "RobotLab"
17 |
--------------------------------------------------------------------------------
/scripts/combine.py:
--------------------------------------------------------------------------------
1 | from . import TEST_OUT, run
2 |
3 |
4 | def combine():
5 | args = [
6 | "python",
7 | "-m",
8 | "robot.rebot",
9 | "--name",
10 | "All",
11 | "--outputdir",
12 | str(TEST_OUT),
13 | "--output",
14 | "output.xml",
15 | ] + list(map(str, TEST_OUT.glob("*.robot.xml")))
16 |
17 | return run(args)
18 |
19 |
20 | if __name__ == "__main__":
21 | combine()
22 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/1_CLI/__init__.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation CLI features
3 | Suite Teardown Clean Up After CLI
4 | Force Tags ui:cli
5 | Library Process
6 | Resource ../../../resources/Cleanup.robot
7 |
8 | *** Keywords ***
9 | Clean Up After CLI
10 | [Documentation] Ensure any dangling processes or files are cleaned
11 | Run Keyword If All Tests Passed Clean Up Examples and Tutorials
12 | Terminate All Processes
13 |
--------------------------------------------------------------------------------
/environment.yml:
--------------------------------------------------------------------------------
1 | name: _robots_from_jupyter
2 |
3 | channels:
4 | - https://conda.anaconda.org/anaconda
5 | - https://conda.anaconda.org/conda-forge
6 |
7 | dependencies:
8 | - conda >=4.8,<4.9.0a0
9 | - conda-build >=3.18.11,<3.19.0a0
10 | - conda-verify
11 | - constructor >=3,<3.1
12 | - firefox >=68.0.2,<69
13 | - geckodriver
14 | - pillow
15 | - python >=3.6,<3.7.0a0
16 | - python-libarchive-c
17 | - ripgrep
18 | - robotframework
19 | - robotframework-seleniumlibrary >=4.1.0,<5
20 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/2_Lab/00_Smoke_Test.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation Check the basics of Robot Lab
3 | Library JupyterLibrary
4 | Resource ../../../resources/Browser.robot
5 |
6 | *** Test Cases ***
7 | Does RobotLab Load?
8 | [Documentation] Does the Lab launcher show up with a Robot Framework entry?
9 | Wait until keyword succeeds 3 x 1 s Open RobotLab
10 | Page Should Contain Robot Framework
11 | Capture Page Screenshot smoke__00_smoke_test.png
12 |
--------------------------------------------------------------------------------
/ci/steps.restore.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | name: Linux
3 |
4 | steps:
5 | - task: DownloadPipelineArtifact@0
6 | inputs:
7 | artifactName: noarch conda packages $(Build.BuildId)
8 | targetPath: _artifacts/conda-bld/noarch
9 | displayName: restore noarch packages
10 |
11 | - ${{ if eq(parameters.name, 'Windows') }}:
12 | - task: DownloadPipelineArtifact@0
13 | inputs:
14 | artifactName: windows conda packages $(Build.BuildId)
15 | targetPath: _artifacts/conda-bld/win-64
16 | displayName: restore windows packages
17 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/0_Install/1_Shortcuts.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation Do Desktop shortcuts get installed?
3 | Resource ../../../resources/Install.robot
4 |
5 | *** Test Cases ***
6 | Are the shortcuts created?
7 | [Documentation] Does it cut short?
8 | Variable Should Exist ${ROBOTLAB SHORTCUT} msg=Should have defined shortcut during install
9 | # TODO: dump the create shortcuts in the env and check them
10 | # ${home} = Set Variable If ${IN_PRODUCT} %{HOME} ${FAKE HOME}
11 | # Wait Until Created ${home}${/}Desktop${/}${ROBOTLAB SHORTCUT}
12 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/tutorial.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | import shutil
3 | import sys
4 |
5 | from .paths import TUTORIAL_NAME, TUTORIAL
6 |
7 |
8 | def copy_robotkernel_tutorial(dest=None):
9 | dest = (Path(dest) if dest else Path(".")).resolve()
10 | shutil.copytree(TUTORIAL, dest / TUTORIAL_NAME)
11 | if not dest.exists():
12 | dest.mkdir(parents=True)
13 | print("\n".join(sorted(map(str, (dest / TUTORIAL_NAME).glob("*")))))
14 | return 0
15 |
16 |
17 | if __name__ == "__main__":
18 | dest = Path(sys.argv(1)) if len(sys.argv) > 1 else None
19 | sys.exit(copy_robotkernel_tutorial(dest))
20 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/examples.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | import shutil
3 | import sys
4 |
5 | from .paths import EXAMPLES, EXAMPLES_NAME
6 |
7 |
8 | def copy_robotkernel_examples(dest=None):
9 | dest = (Path(dest) if dest else Path(".")).resolve()
10 | shutil.copytree(EXAMPLES, dest / EXAMPLES_NAME)
11 | if not dest.exists():
12 | dest.mkdir(parents=True)
13 |
14 | print("\n".join(sorted(map(str, (dest / EXAMPLES_NAME).glob("*")))))
15 | return 0
16 |
17 |
18 | if __name__ == "__main__":
19 | dest = Path(sys.argv(1)) if len(sys.argv) > 1 else None
20 | sys.exit(copy_robotkernel_examples(dest))
21 |
--------------------------------------------------------------------------------
/constructor/RobotLab/construct.yaml.in:
--------------------------------------------------------------------------------
1 | name: RobotLab
2 | version: {{ version }}
3 | company: Robots from Jupyter
4 | post_install: post_install.bat [win]
5 | post_install: post_install.sh [unix]
6 | ignore_duplicate_files: True
7 | license_file: ../../LICENSE
8 |
9 | channels_remap:
10 | - src: {{ build_channel }}
11 | dest: https://conda.anaconda.org/conda-forge
12 |
13 | channels:
14 | - {{ build_channel }}
15 | - https://conda.anaconda.org/anaconda
16 | - https://conda.anaconda.org/conda-forge
17 | - https://conda.anaconda.org/msys2 [win]
18 |
19 | specs:
20 | - python >={{ py_min }},<{{ py_max }}
21 | - robotlab =={{ version }}
22 | - python.app [osx]
23 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/__init__.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Suite Setup Set Screenshot Directory ${OUTPUT DIR}${/}screenshots
3 | Suite Teardown Clean up the RobotLab installation
4 | Force Tags os:${OS} in-product:${IN_PRODUCT} product:RobotLab
5 | Variables ../../../scripts/__init__.py
6 | Resource ../../resources/Install.robot
7 | Library JupyterLibrary
8 |
9 | *** Keywords ***
10 | Clean up the RobotLab installation
11 | [Documentation] Clean up browser and Jupyter stuff, then the installation
12 | Terminate All Jupyter Servers
13 | Clean up the installation
14 | Run Keyword If All Tests Passed Clean Up Examples and Tutorials
15 |
--------------------------------------------------------------------------------
/tests/resources/Launch.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation Work with the RobotLab server
3 | Library OperatingSystem
4 | Library JupyterLibrary
5 | Library String
6 | Library Process
7 |
8 | *** Keywords ***
9 | Start New RobotLab Server
10 | [Documentation] Try to start the RobotLab server
11 | Should Not Be Empty ${OS} msg=Needs an OS
12 | Should Not Be Empty ${PRODUCT DIR} msg=Needs a RobotLab installation
13 | Should Not Be Empty ${PRODUCT PATH ENV} msg=Needs a RobotLab environment
14 | ${proc} = Start New Jupyter Server ${ROBOTLAB CMD} env:PATH=${PRODUCT PATH ENV} stdout=${OUTPUT DIR}${/}nbserver.log
15 |
--------------------------------------------------------------------------------
/ci/steps.conda.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | name: Linux
3 | envPath: ci/env-noarch.yml
4 |
5 | steps:
6 | - ${{ if eq(parameters.name, 'Linux') }}:
7 | - bash: echo "##vso[task.prependpath]$CONDA/bin"
8 | displayName: conda $PATH
9 |
10 | - ${{ if eq(parameters.name, 'MacOSX') }}:
11 | - bash: echo "##vso[task.prependpath]$CONDA/bin"
12 | displayName: conda $PATH
13 |
14 | - bash: sudo chown -R $USER $CONDA
15 | displayName: own conda
16 |
17 | - ${{ if eq(parameters.name, 'Windows') }}:
18 | - powershell: Write-Host "##vso[task.prependpath]$env:CONDA\Scripts"
19 | displayName: conda %PATH%
20 |
21 | - script: conda env update -n base --file ${{ parameters.envPath }} --quiet
22 | displayName: install conda environment
23 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/shortcuts.py:
--------------------------------------------------------------------------------
1 | from pprint import pprint
2 | import sys
3 |
4 | import pyshortcuts.utils
5 |
6 | from .paths import HERE, ICON_PATH
7 |
8 |
9 | def make_shortcuts():
10 | script = str(HERE / "launch.py")
11 | name = "RobotLab"
12 | print("Making RobotLab shortcut in $HOME...")
13 | print("", pyshortcuts.utils.get_homedir())
14 | scut = pyshortcuts.make_shortcut(
15 | script=script,
16 | name=name,
17 | terminal=True,
18 | description="Launch RobotLab in Firefox in your $HOME",
19 | icon=ICON_PATH,
20 | )
21 | ""
22 | print("Shortcut created...")
23 | pprint(scut.__dict__)
24 | return 0
25 |
26 |
27 | if __name__ == "__main__":
28 | sys.exit(make_shortcuts())
29 |
--------------------------------------------------------------------------------
/recipes/robotframework-jupyterlibrary/001-lab-114-icons.patch:
--------------------------------------------------------------------------------
1 | --- src/JupyterLibrary/clients/jupyterlab/Selectors.robot 2018-12-17 23:29:45.000000000 -0500
2 | +++ src/JupyterLibrary/clients/jupyterlab/Selectors.robot 2019-09-18 23:05:13.135509964 -0400
3 | @@ -12,8 +12,8 @@
4 | ${JLAB CSS BUSY KERNEL} .jp-Toolbar-kernelStatus.jp-FilledCircleIcon
5 | ${JLAB CSS CMD INPUT} .p-CommandPalette-input
6 | ${JLAB CSS CMD ITEM} .p-CommandPalette-item
7 | -${JLAB CSS ICON ADD} .jp-AddIcon
8 | -${JLAB CSS ICON RUN} .jp-RunIcon
9 | +${JLAB CSS ICON ADD} [data-icon="add"]
10 | +${JLAB CSS ICON RUN} [data-icon="run"]
11 | ${JLAB CSS NB TOOLBAR} .jp-NotebookPanel-toolbar
12 | ${JLAB CSS SIDEBAR TAB} .jp-SideBar .p-TabBar-tab
13 | ${JLAB CSS SPINNER} .jp-Spinner
14 |
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | trigger:
2 | batch: true
3 | branches:
4 | include:
5 | - master
6 | - refs/tags/v*
7 |
8 | pr: [master]
9 |
10 | variables:
11 | ROBOTLAB_VERSION: 2020.01.0
12 | PYTHONUNBUFFERED: 1
13 |
14 | jobs:
15 | # group one: simple conda/webpack builds, validation
16 | - template: ci/job.noarch.yml
17 | - template: ci/job.win.yml
18 | - template: ci/job.lab.yml
19 | # - template: ci/job.min.yml
20 |
21 | # group two: build installers, verify conda builds
22 | - template: ci/job.noarch-test.yml
23 | - template: ci/job.main.yml
24 |
25 | # group three: acceptance testing
26 | - template: ci/job.selftest.yml
27 |
28 | # group four: reporting, etc
29 | - template: ci/job.combine.yml
30 | - template: ci/job.release.yml
31 |
--------------------------------------------------------------------------------
/ci/job.win.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | vmImage: vs2017-win2016
3 | activate: call activate &&
4 |
5 | jobs:
6 | - job: CondaWindows
7 | condition: succeeded()
8 | pool:
9 | vmImage: ${{ parameters.vmImage }}
10 |
11 | steps:
12 | - template: steps.conda.yml
13 | parameters:
14 | name: Windows
15 |
16 | - script: ${{ parameters.activate }} python -m scripts.build conda --no-test pyshortcuts robotframework-whitelibrary
17 | displayName: build win packages
18 |
19 | - task: PublishPipelineArtifact@0
20 | displayName: publish windows packages
21 | inputs:
22 | targetPath: _artifacts/conda-bld/win-64
23 | artifactName: Windows Conda Packages $(Build.BuildId)
24 | condition: succeeded()
25 |
--------------------------------------------------------------------------------
/ci/job.lab.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - job: Lab
3 | pool:
4 | vmImage: ubuntu-16.04
5 |
6 | steps:
7 | - template: steps.conda.yml
8 | parameters:
9 | envPath: ci/env-lab.yml
10 |
11 | - script: python -m scripts.integrity
12 | displayName: check integrity
13 |
14 | - script: python -m scripts.lint
15 | displayName: lint
16 |
17 | - script: python -m scripts.build lab
18 | displayName: build lab
19 |
20 | - script: rm -rf _artifacts/app_dir/staging
21 | displayName: clean lab cruft
22 |
23 | - task: PublishPipelineArtifact@0
24 | displayName: publish jupyterlab package
25 | inputs:
26 | targetPath: _artifacts/app_dir
27 | artifactName: robotlab app_dir $(Build.BuildId)
28 | condition: succeeded()
29 |
--------------------------------------------------------------------------------
/constructor/ExoRobot/construct.yaml.in:
--------------------------------------------------------------------------------
1 | name: ExoRobot
2 | version: {{ version }}
3 | company: Robots from Jupyter
4 | license_file: LICENSE.txt
5 |
6 | channels_remap:
7 | - src: {{ build_channel }}
8 | dest: https://conda.anaconda.org/conda-forge
9 |
10 | channels:
11 | - {{ build_channel }}
12 | - https://conda.anaconda.org/anaconda
13 | - https://conda.anaconda.org/conda-forge
14 |
15 | channels:
16 | - https://conda.anaconda.org/conda-forge
17 | - https://conda.anaconda.org/anaconda
18 |
19 | specs:
20 | - python >={{ py_min }},<{{ py_max }}
21 | - robotframework =={{ rf_version }}
22 | - conda =={{ conda_version }}
23 | # other first-party
24 | - robotframework-ride
25 | # extra library/doc dependencies
26 | - docutils
27 | - lxml
28 | - pyte
29 | - pyyaml
30 | - wxpython
31 | - pillow
32 |
--------------------------------------------------------------------------------
/ci/job.noarch.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - job: CondaNoarch
3 | pool:
4 | vmImage: ubuntu-16.04
5 |
6 | steps:
7 | - template: steps.conda.yml
8 |
9 | - script: |-
10 | python -m scripts.build conda \
11 | --no-test \
12 | jupyter-starters \
13 | robotframework \
14 | restinstance \
15 | robotframework-jupyterlibrary \
16 | robotframework-seleniumscreenshots \
17 | robotframework-seleniumtestability \
18 | robotkernel
19 | displayName: build noarch packages
20 |
21 | - task: PublishPipelineArtifact@0
22 | displayName: publish noarch packages
23 | inputs:
24 | targetPath: _artifacts/conda-bld/noarch
25 | artifactName: noarch conda packages $(Build.BuildId)
26 | condition: succeeded()
27 |
--------------------------------------------------------------------------------
/tests/resources/Lab.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Library JupyterLibrary
3 |
4 | *** Keywords ***
5 | Start a new Notebook
6 | [Arguments] ${kernel}
7 | [Documentation] Convenience method around
8 | [Tags] robot:no-dry-run
9 | Execute JupyterLab Command Close All
10 | Launch a new JupyterLab Document ${kernel} Notebook
11 | Wait Until JupyterLab Kernel Is Idle
12 |
13 | The Robot Popup Should Contain
14 | [Arguments] ${prefix} ${document} ${msg}
15 | [Documentation] With an open Robot Notebook, take a look at the log or report
16 | Click Link ${document}
17 | Sleep 1s
18 | Select Window Jupyter ${document}
19 | Page Should Contain ${msg}
20 | Capture Page Screenshot ${prefix}_10_${document.lower()}.png
21 | Close Window
22 | Select Window RobotLab
23 |
--------------------------------------------------------------------------------
/recipes/jupyter-starters/meta.yaml:
--------------------------------------------------------------------------------
1 | {% set name = "jupyter_starters" %}
2 | {% set version = "0.2.2a0" %}
3 |
4 | package:
5 | name: {{ name | replace("_", "-") }}
6 | version: {{ version }}
7 |
8 | source:
9 | url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
10 | sha256: 8773e03f8e05532197aa16f4a634bb3d1f8fe858658a7f20bf64879fd78e367f
11 |
12 | build:
13 | noarch: python
14 | number: 0
15 | script: "{{ PYTHON }} -m pip install . -vv"
16 |
17 | requirements:
18 | host:
19 | - python >=3.6
20 | - pip
21 | run:
22 | - python >=3.6
23 | - notebook >=5.3
24 |
25 | test:
26 | imports:
27 | - jupyter_starters
28 |
29 | about:
30 | home: https://github.com/deathbeds/jupyterlab-starters
31 | license: BSD-3-Clause
32 | license_family: BSD
33 | license_file: LICENSE
34 | summary: 'Parameterized file and directory starters for JupyterLab.'
35 |
--------------------------------------------------------------------------------
/recipes/robotframework-whitelibrary/meta.yaml:
--------------------------------------------------------------------------------
1 | package:
2 | name: '{% set name = "robotframework-whitelibrary" %}{{ name }}'
3 | version: '{% set version = "1.6.0" %}{{ version }}'
4 |
5 | build:
6 | number: 0
7 | skip: true # [not win]
8 |
9 | requirements:
10 | host:
11 | - pip
12 | - python
13 | - pythonnet
14 | run:
15 | - robotframework
16 | - pythonnet
17 | - python
18 | test:
19 | imports:
20 | - WhiteLibrary
21 |
22 | about:
23 | home: https://github.com/Omenia/robotframework-whitelibrary
24 | license: Apache-2.0
25 | license_family: Apache
26 | license_file: apache-2.0.txt
27 | summary: WhiteLibrary is a Robot Framework library for automating Windows GUI.
28 | doc_url: http://omenia.github.io/robotframework-whitelibrary/keywords.html
29 | description: >
30 | It is a wrapper for TestStack.White automation framework, which is based on
31 | Microsoft UI Automation API (UIA).
32 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/2_Lab/10_IPython_Notebook.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation Try out IPython Notebooks
3 | Library JupyterLibrary
4 | Resource ../../../resources/Browser.robot
5 | Resource ../../../resources/Lab.robot
6 |
7 | *** Test Cases ***
8 | Can RobotLab make an IPython Notebook?
9 | [Documentation] Try a basic IPython Notebook
10 | ${prefix} = Set Variable ipython_
11 | Open RobotLab
12 | Start a new Notebook Python 3
13 | Capture Page Screenshot ${prefix}_01_notebook.png
14 | Add and Run JupyterLab Code Cell print("Hello" + " World")
15 | Capture Page Screenshot ${prefix}_02_execute.png
16 | Wait Until Page Contains Hello World timeout=10s
17 | Capture Page Screenshot ${prefix}_03_execute_result.png
18 | Execute JupyterLab Command Save Notebook
19 | Sleep 2s
20 | Capture Page Screenshot ${prefix}_09_save.png
21 |
--------------------------------------------------------------------------------
/ci/job.noarch-test.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | platforms:
3 | - name: Linux
4 | vmImage: ubuntu-16.04
5 | activate: ""
6 | - name: MacOSX
7 | vmImage: macos-10.13
8 | activate: ""
9 | - name: Windows
10 | vmImage: vs2017-win2016
11 | activate: call activate &&
12 |
13 | jobs:
14 | - ${{ each platform in parameters.platforms }}:
15 | - job: CondaNoarchTest${{ platform.name }}
16 | pool:
17 | vmImage: ${{ platform.vmImage }}
18 | condition: succeeded()
19 | dependsOn:
20 | - CondaNoarch
21 | - CondaWindows
22 |
23 | steps:
24 | - template: steps.restore.yml
25 | parameters:
26 | name: ${{ platform.name }}
27 |
28 | - template: steps.conda.yml
29 | parameters:
30 | name: ${{ platform.name }}
31 |
32 | - script: ${{ platform.activate }} python -m scripts.test conda
33 | displayName: test prebuilt packages
34 |
--------------------------------------------------------------------------------
/tests/resources/Selectors.robot:
--------------------------------------------------------------------------------
1 | *** Variables ***
2 | ${XP LAUNCH SECTION} xpath://h2[contains(@class, 'jp-Launcher-sectionTitle')][text() = 'Starters']
3 | ${CSS LAUNCH CARD} css:[data-category\="Starters"]
4 | ${CSS LAUNCH CARD TUTORIAL} ${CSS LAUNCH CARD}\[title\="Tutorial for Robot Framework on Jupyter"]
5 | ${CSS LAUNCH CARD EXAMPLES} ${CSS LAUNCH CARD}\[title\="Miscellanous examples of using RobotKernel"]
6 | ${XP FILE TREE ITEM} xpath://span[contains(@class, 'jp-DirListing-itemText')]
7 | ${XP FILE TREE TUTORIAL} ${XP FILE TREE ITEM}\[text() = 'tutorial']
8 | ${XP FILE TREE TUTORIAL 00} ${XP FILE TREE ITEM}\[text() = '00 Keyboard Shortcuts.ipynb']
9 | ${XP FILE TREE EXAMPLE} ${XP FILE TREE ITEM}\[text() = 'robotkernel-examples']
10 | ${XP FILE TREE EXAMPLE OPENCV} ${XP FILE TREE ITEM}\[text() = 'OpenCV.ipynb']
11 | ${CSS NOTEBOOK SAVE} css:[data-icon="save"]
12 | ${JP STATUS BAR} id:jp-bottom-panel
13 | ${CRUMBS HOME} css:.jp-BreadCrumbs-home
14 |
--------------------------------------------------------------------------------
/attic/robotframework-ride/meta.yaml:
--------------------------------------------------------------------------------
1 | package:
2 | name: '{% set name = "robotframework-ride" %}{{ name }}'
3 | version: '{% set version = "1.7.4b2" %}{{ version }}'
4 |
5 | source:
6 | url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
7 | sha256: 40b67134573883b34de186bd9d4d2ee582a5d7451b5ccae4d2f84a876c44cd80
8 |
9 | build:
10 | noarch: python
11 | number: 0
12 | script: {{ PYTHON }} -m pip install --no-deps -vv .
13 | entry_points:
14 | - ride = robotide:main
15 |
16 | requirements:
17 | host:
18 | - pip
19 | - python
20 | run:
21 | - pygments
22 | - pypubsub
23 | - python
24 | - wxpython
25 | - docutils >=0.9
26 | - robotframework
27 |
28 | test:
29 | imports:
30 | - robotide
31 | - robotide.robotapi
32 |
33 | about:
34 | home: https://github.com/robotframework/RIDE
35 | license: Apache-2.0
36 | license_family: Apache
37 | license_file: LICENSE.txt
38 | summary: Test data editor for Robot Framework
39 |
--------------------------------------------------------------------------------
/scripts/lint.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from . import ROOT, run
3 |
4 |
5 | PY_SRC = [str(ROOT / "robotlab"), str(ROOT / "scripts")]
6 | RF_SRC = list(map(str, (ROOT / "tests").rglob("*.robot")))
7 |
8 |
9 | def black():
10 | return run(["black", "-l79"] + PY_SRC)
11 |
12 |
13 | def tidy():
14 | return run([sys.executable, "-m", "robot.tidy", "--inplace"] + RF_SRC)
15 |
16 |
17 | def flake8():
18 | return run(["flake8", "--ignore", "E203,W503"] + PY_SRC)
19 |
20 |
21 | def rflint():
22 | return run(
23 | [
24 | "rflint",
25 | "--configure",
26 | "TooManyTestSteps:20",
27 | "--configure",
28 | "TooFewTestSteps:0",
29 | "--configure",
30 | "TooFewKeywordSteps:0",
31 | "--configure",
32 | "LineTooLong:200",
33 | ]
34 | + RF_SRC
35 | )
36 |
37 |
38 | if __name__ == "__main__":
39 | assert not black() and not tidy() and not flake8() and not rflint()
40 | sys.exit(0)
41 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/1_CLI/30_extensions.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation robotlab-extension
3 | Force Tags app:robotlab-extension
4 | Resource ../../../resources/CLI.robot
5 | Variables ../../../../scripts/__init__.py
6 | Library ../../../library/decolorize.py
7 |
8 | *** Test Cases ***
9 | Can I list extensions?
10 | [Documentation] Does robotlab-extension list work?
11 | ${output} = Check a RobotLab CLI command robotlab-extension list
12 | Extensions Should Be Installed ${output} ${LABEXTENSIONS}
13 |
14 | *** Keywords ***
15 | Extensions Should Be Installed
16 | [Arguments] ${output} ${extensions}
17 | [Documentation] Check that some JupyterLab extensions are installed
18 | ${cleaned} = Decolorize ${output.replace(" ", "").lower()}
19 | FOR ${spec} IN @{extensions}
20 | ${ext} = Set Variable ${spec.rsplit('@', 1)}
21 | Should Contain ${cleaned.lower()} ${ext[0]}v${ext[1]}enabledok
22 | END
23 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/launch.py:
--------------------------------------------------------------------------------
1 | """
2 | Perform a proper conda activate and launch robotlab
3 | """
4 |
5 | import subprocess
6 | import os
7 | import sys
8 | import signal
9 | from pathlib import Path
10 | from tempfile import TemporaryDirectory
11 |
12 | from robotlab.paths import ACTIVATE, LAUNCH_CMD, LAUNCH_SCRIPT
13 |
14 |
15 | def launch_robotlab(lab_args=None):
16 | lab_cmd = " ".join([LAUNCH_CMD] + (lab_args or []))
17 |
18 | with TemporaryDirectory() as td:
19 | tdp = Path(td)
20 | script = tdp / LAUNCH_SCRIPT
21 | lines = ACTIVATE + [lab_cmd]
22 | script.write_text(os.linesep.join(lines))
23 | script.chmod(0o755)
24 | print("Launching RobotLab")
25 | print(script.read_text(), "\n")
26 | proc = subprocess.Popen([str(script)], cwd=os.path.expanduser("~"))
27 | try:
28 | proc.wait()
29 | except KeyboardInterrupt:
30 | os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
31 |
32 |
33 | if __name__ == "__main__":
34 | launch_robotlab(sys.argv[1:])
35 |
--------------------------------------------------------------------------------
/scripts/integrity.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | from . import ROOT, RECIPE_DIR, ROBOTLAB_DIR, SCRIPTS_DIR, TEST_DIR
4 |
5 |
6 | META_PATTERN = r""" set version = "([\d\.rc]+)" """
7 |
8 | VERSIONS = {
9 | ROOT / "azure-pipelines.yml": r"ROBOTLAB_VERSION: ([\d\.rc]+)",
10 | RECIPE_DIR / "robotlab" / "meta.yaml": META_PATTERN,
11 | ROBOTLAB_DIR / "setup.cfg": r"version = ([\d\.rc]+)",
12 | ROBOTLAB_DIR
13 | / "src"
14 | / "robotlab"
15 | / "_version.py": r"""__version__ = "([\d\.rc]+)""",
16 | SCRIPTS_DIR / "__init__.py": r"""ROBOTLAB_VERSION", "([\d\.rc]+)""",
17 | TEST_DIR
18 | / "resources"
19 | / "Install.robot": r"\$\{INSTALLER VERSION\}\s+([\d\.rc]+)",
20 | }
21 |
22 |
23 | def ensure_integrity():
24 | versions = {}
25 | for path, pattern in VERSIONS.items():
26 | print(path.relative_to(ROOT))
27 | versions[path] = re.findall(pattern, path.read_text())[0]
28 | print("\t", versions[path])
29 |
30 | assert len(set(versions.values())) == 1, versions
31 |
32 |
33 | if __name__ == "__main__":
34 | ensure_integrity()
35 |
--------------------------------------------------------------------------------
/recipes/robotframework-seleniumscreenshots/meta.yaml:
--------------------------------------------------------------------------------
1 | package:
2 | name: '{% set name = "robotframework-seleniumscreenshots" %}{{ name }}'
3 | version: '{% set version = "0.9.5" %}{{ version }}'
4 |
5 | source:
6 | url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
7 | sha256: 400f3c2213578d1e249216170cd1dd1e86999492d9e731a030beca0d87181b17
8 |
9 | build:
10 | noarch: python
11 | number: 0
12 | script: {{ PYTHON }} -m pip install --no-deps -vvv .
13 |
14 | requirements:
15 | host:
16 | - pip
17 | - python
18 | run:
19 | - python
20 | - robotframework >=3.0.2
21 | - robotframework-SeleniumLibrary>=3.2.0
22 |
23 | test:
24 | imports:
25 | - SeleniumScreenshots
26 |
27 | about:
28 | home: https://github.com/datakurre/robotframework-seleniumscreenshots
29 | license: BSD-3-Clause
30 | license_family: BSD
31 | license_file: LICENSE
32 | summary: Robot Framework keyword library for capturing annotated screenshots with SeleniumLibrary
33 | doc_url: https://datakurre.github.io/robotframework-seleniumscreenshots
34 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/2_Lab/20_Robot_Notebook.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation Try out Robot Notebooks
3 | Library JupyterLibrary
4 | Resource ../../../resources/Browser.robot
5 | Resource ../../../resources/Lab.robot
6 |
7 | *** Test Cases ***
8 | Can RobotLab make a Robot Notebook?
9 | [Documentation] Try a basic Robot Notebook
10 | ${prefix} = Set Variable robot_
11 | Open RobotLab
12 | Start a new Notebook Robot Framework
13 | Capture Page Screenshot ${prefix}_01_notebook.png
14 | Add and Run JupyterLab Code Cell | *Test Case* |${\n}| Hello |${\n}| | Log | Hello World
15 | Capture Page Screenshot ${prefix}_02_execute.png
16 | Sleep 3s
17 | Wait Until JupyterLab Kernel Is Idle
18 | Capture Page Screenshot ${prefix}_03_execute_result.png
19 | The Robot Popup Should Contain ${prefix} Log 1 passed, 0 failed
20 | The Robot Popup Should Contain ${prefix} Report All tests passed
21 | Execute JupyterLab Command Save Notebook
22 | Sleep 2s
23 | Capture Page Screenshot ${prefix}_09_save.png
24 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/1_CLI/10_examples.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation robotlab-examples
3 | Force Tags app:robotlab-examples
4 | Resource ../../../resources/CLI.robot
5 | Library Process
6 |
7 | *** Variables ***
8 | ${NBCONVERT} jupyter nbconvert --execute --ExecutePreprocessor.timeout=600
9 |
10 | *** Test Cases ***
11 | Can I install the examples?
12 | [Documentation] Does robotlab-examples work?
13 | [Tags] example:opencv
14 | Check a RobotLab CLI command robotlab-examples check_dir=robotkernel-examples
15 |
16 | Can I run the examples?
17 | [Documentation] Will they nbconvert?
18 | [Tags] example:opencv
19 | ${log} = Set Variable ${OUTPUT DIR}${/}robotlab-example-nbconvert-opencv.log
20 | ${proc} = Run Process ${ACTIVATE} && ${NBCONVERT} OpenCV.ipynb shell=True cwd=${OUTPUT DIR}${/}robotkernel-examples stdout=${log} stderr=STDOUT
21 | ... env:PS1=[:|]
22 | Should Be Equal As Numbers ${proc.rc} 0
23 | Copy File ${OUTPUT DIR}${/}robotkernel-examples${/}OpenCV.html ${OUTPUT DIR}${/}nbconvert-OpenCV.html
24 |
--------------------------------------------------------------------------------
/recipes/robotframework-jupyterlibrary/meta.yaml:
--------------------------------------------------------------------------------
1 | package:
2 | name: '{% set name = "robotframework-jupyterlibrary" %}{{ name }}'
3 | version: '{% set version = "0.2.0" %}{{ version }}'
4 |
5 | source:
6 | url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
7 | sha256: 63bb7bd94bb21fbd6f88a640b605d51728bc48a1a9aebbe27ee033c218a5aa03
8 | patches:
9 | - 001-lab-114-icons.patch
10 |
11 | build:
12 | noarch: python
13 | number: 0
14 | script: {{ PYTHON }} -m pip install -vv .
15 |
16 | requirements:
17 | host:
18 | - pip
19 | - python
20 | run:
21 | - pillow
22 | - python
23 | - robotframework >=3.1
24 | - robotframework-seleniumlibrary >=4.1.0,<5
25 | - six
26 |
27 | test:
28 | imports:
29 | - JupyterLibrary
30 |
31 | about:
32 | home: https://robotframework-jupyterlibrary.rtfd.io
33 | license: BSD-3-Clause
34 | license_family: BSD
35 | license_file: LICENSE
36 | summary: A Robot Framework library for automating (testing of) Jupyter end-user applications and extensions
37 | dev_url: https://github.com/robots-from-jupyter/robotframework-jupyterlibrary
38 |
--------------------------------------------------------------------------------
/recipes/pyshortcuts/meta.yaml:
--------------------------------------------------------------------------------
1 | package:
2 | name: '{% set name = "pyshortcuts" %}{{ name }}'
3 | version: '{% set version = "1.4" %}{{ version }}'
4 |
5 | source:
6 | url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
7 | sha256: 503820fce779cf42e9b52e4674f5ef0b1672930d662401af53a6a73d07360a8d
8 |
9 | build:
10 | number: 0
11 | script: {{ PYTHON }} -m pip install . --no-deps -vv
12 | entry_points:
13 | - pyshortcut = pyshortcuts:shortcut_cli
14 |
15 | requirements:
16 | host:
17 | - pip
18 | - python
19 | run:
20 | - six
21 | - python
22 | - pywin32 # [win]
23 |
24 | test:
25 | # TODO: some issues currently with wx.__version__
26 | # requires:
27 | # - wxpython
28 | imports:
29 | - pyshortcuts
30 | - pyshortcuts.darwin
31 | - pyshortcuts.linux
32 | - pyshortcuts.windows
33 | # - pyshortcuts.wxgui
34 |
35 | commands:
36 | - pyshortcut --help
37 |
38 | about:
39 | home: https://github.com/newville/pyshortcuts
40 | license: MIT
41 | license_file: LICENSE
42 | summary: create desktop shortcuts to python scripts on Windows, Mac, or Linux
43 |
--------------------------------------------------------------------------------
/recipes/robotkernel/meta.yaml:
--------------------------------------------------------------------------------
1 | package:
2 | name: '{% set name = "robotkernel" %}{{ name }}'
3 | version: '{% set version = "1.3.0" %}{{ version }}'
4 |
5 | source:
6 | url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
7 | sha256: 8401e9bee8df473e586a1607c2b50c628dd01493ac258569f56720e345360019
8 |
9 | build:
10 | noarch: python
11 | number: 0
12 | script: {{ PYTHON }} -m pip install --no-deps -vv .
13 | entry_points:
14 | - nbrobot = robotkernel.nbreader:robot
15 | - nblibdoc = robotkernel.nbreader:libdoc
16 |
17 | requirements:
18 | host:
19 | - pip
20 | - python
21 | run:
22 | - docutils
23 | - ipykernel
24 | - lunr
25 | - nbformat
26 | - pillow
27 | - pygments
28 | - python
29 | - robotframework >=3.1
30 |
31 | test:
32 | imports:
33 | - robotkernel
34 | commands:
35 | - jupyter kernelspec list
36 |
37 | about:
38 | home: https://github.com/robots-from-jupyter/robotkernel
39 | license: BSD-3-Clause
40 | license_family: BSD
41 | license_file: LICENSE
42 | summary: Robot Framework IPython kernel for Jupyter Notebook and JupyterLab
43 |
--------------------------------------------------------------------------------
/recipes/robotframework-seleniumtestability/meta.yaml:
--------------------------------------------------------------------------------
1 | {% set name = "robotframework-seleniumtestability" %}
2 | {% set version = "0.0.15" %}
3 |
4 | package:
5 | name: {{ name }}
6 | version: {{ version }}
7 |
8 | source:
9 | url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
10 | sha256: a49df9eb970f95794ab6af12b8a51312340d8349e7b92bf2b59021898b40e1c0
11 |
12 | build:
13 | number: 0
14 | noarch: python
15 | script:
16 | - {{ PYTHON }} -m pip install . --no-deps --ignore-installed -vvv
17 |
18 | requirements:
19 | host:
20 | - pip
21 | - python
22 | run:
23 | - furl
24 | - python
25 | - robotframework-seleniumlibrary >=4.0.0
26 | - wrapt
27 |
28 | test:
29 | imports:
30 | - SeleniumTestability
31 | - SeleniumTestability.javascript
32 | - SeleniumTestability.listener
33 | - SeleniumTestability.logger
34 | - SeleniumTestability.plugin
35 | - SeleniumTestability.types
36 |
37 | about:
38 | home: https://github.com/rasjani/robotframework-seleniumtestability
39 | license: Apache-2.0
40 | license_file: LICENSE
41 | license_family: Apache
42 | summary: Extension for SeleniumLibrary that provides manual and automatic waiting for asyncronous events like fetch, xhr, etc.
43 |
--------------------------------------------------------------------------------
/recipes/restinstance/meta.yaml:
--------------------------------------------------------------------------------
1 | package:
2 | name: '{% set name = "RESTinstance" %}{{ name|lower }}'
3 | version: '{% set version = "1.0.2" %}{{ version }}'
4 |
5 | source:
6 | url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
7 | sha256: c241e44e51c7a793c7c5ca0476caac2b703cc78da8041ab05ded965ce49bc187
8 | patches:
9 | - 0001-setup-entry-point.patch
10 |
11 | build:
12 | noarch: python
13 | number: 0
14 | script: {{ PYTHON }} -m pip install --no-deps -vv .
15 |
16 | requirements:
17 | build:
18 | - patch
19 | host:
20 | - pip
21 | - python
22 | run:
23 | - python
24 | - flex-swagger >=6.13.2
25 | - genson >=1.0.1
26 | - jsonpath-ng >=1.4.3
27 | - jsonschema >=3.0.0a3
28 | - pygments >=2.2.0
29 | - pytz >=2018.5
30 | - requests >=2.20.0
31 | - rfc3987 >=1.3.8
32 | - robotframework >=2.9
33 | - strict-rfc3339 >=0.7
34 | - tzlocal >=1.5.1
35 |
36 | test:
37 | imports:
38 | - REST
39 |
40 | about:
41 | home: https://asyrjasalo.github.io/RESTinstance
42 | license: Apache-2.0
43 | license_family: Apache
44 | license_file: apache-2.0.txt
45 | summary: Robot Framework test library for (RESTful) JSON APIs
46 | dev_url: https://github.com/asyrjasalo/RESTinstance
47 |
--------------------------------------------------------------------------------
/tests/resources/CLI.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation Keywords for CLIs we ship
3 | Library Process
4 | Library OperatingSystem
5 |
6 | *** Variables ***
7 | ${NEXT CLI LOG} ${0}
8 |
9 | *** Keywords ***
10 | Check a RobotLab CLI Command
11 | [Arguments] ${cmd} ${check_dir}=${EMPTY} ${rc}=${0}
12 | [Documentation] Run a command in the robotlab environment
13 | ${logs} = Set Variable ${OUTPUT DIR}${/}cli
14 | Create Directory ${logs}
15 | ${log} = Set Variable ${logs}${/}${NEXT CLI LOG}-${cmd.split()[0]}.log
16 | Set Global Variable ${NEXT CLI LOG} ${NEXT CLI LOG.__add__(1)}
17 | ${proc} = Run Process ${ACTIVATE} && ${cmd} shell=True cwd=${OUTPUT DIR} stdout=${log} stderr=STDOUT
18 | ... env:PS1=[:|]
19 | Should Be Equal As Numbers ${proc.rc} ${rc}
20 | Run Keyword If "${check_dir}" Directory Should Not Be Empty ${OUTPUT DIR}${/}${check_dir}
21 | ${output} = Get File ${log}
22 | [Return] ${output}
23 |
24 | Run nbrobot CLI
25 | [Arguments] ${args} ${rc}=${0}
26 | [Documentation] Run nbrobot and write the output to a log file
27 | ${output} = Check a RobotLab CLI Command nbrobot ${args} rc=${rc}
28 | [Return] ${output}
29 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/paths.py:
--------------------------------------------------------------------------------
1 | """ Paths
2 |
3 | These will probably only work with the like-versioned RobotLab distribution
4 | """
5 | from pathlib import Path
6 | import sys
7 |
8 | import platform
9 |
10 | HERE = Path(__file__).parent
11 |
12 | PREFIX = Path(sys.prefix).resolve()
13 | PYTHON_EXE = Path(sys.executable)
14 |
15 | ROBOTLAB_PATH = PREFIX / "share" / "jupyter" / "robotlab"
16 |
17 | PLATFORM = platform.system().lower()
18 | WIN = PLATFORM == "windows"
19 | OSX = PLATFORM == "darwin"
20 | SCRIPT_EXT = "bat" if WIN else "sh"
21 |
22 | ICON_EXT = "icns" if OSX else "ico"
23 | ICON_PATH = str(HERE / "icons" / f"lab.{ICON_EXT}")
24 |
25 | BIN_DIR = Path(sys.prefix, *(["Scripts"] if WIN else ["bin"]))
26 |
27 | BAT_ACTIVATE = [
28 | f'call "{BIN_DIR}\\activate.bat" "{PREFIX}" || call activate "{PREFIX}"'
29 | ]
30 |
31 | SH_ACTIVATE = [
32 | "#!" + "/usr/bin/env bash",
33 | f'. "{BIN_DIR}/activate" "{PREFIX}" || . activate "{PREFIX}"',
34 | ]
35 |
36 | ACTIVATE = BAT_ACTIVATE if WIN else SH_ACTIVATE
37 | BROWSER = f"--browser=firefox"
38 |
39 | LAUNCH_CMD = f"python -m robotlab.labapp {BROWSER}"
40 | LAUNCH_SCRIPT = f"launch_robotlab.{SCRIPT_EXT}"
41 |
42 | TUTORIAL_NAME = "robotkernel-tutorial"
43 | TUTORIAL = PREFIX / "var" / "www" / TUTORIAL_NAME
44 |
45 | EXAMPLES_NAME = "robotkernel-examples"
46 | EXAMPLES = PREFIX / "var" / "www" / EXAMPLES_NAME
47 |
--------------------------------------------------------------------------------
/ci/job.min.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | products:
3 | - MiniRobot
4 | platforms:
5 | - name: Linux
6 | vmImage: ubuntu-16.04
7 | activate: ""
8 | - name: MacOSX
9 | vmImage: macos-10.13
10 | activate: ""
11 | - name: Windows
12 | vmImage: vs2017-win2016
13 | activate: call activate &&
14 |
15 | jobs:
16 | - ${{ each product in parameters.products }}:
17 | - ${{ each platform in parameters.platforms }}:
18 | - job: ${{ product }}${{ platform.name }}Build
19 | condition: succeeded()
20 | pool:
21 | vmImage: ${{ platform.vmImage }}
22 |
23 | steps:
24 | - template: steps.conda.yml
25 | parameters:
26 | name: ${{ platform.name }}
27 | envPath: ci/env-main.yml
28 |
29 | - script: ${{ platform.activate }} python -m scripts.build constructor ${{ product }}
30 | displayName: build installer
31 |
32 | - ${{ if eq(parameters.name, 'MacOSX') }}:
33 | - script: chmod -R 777 _artifacts
34 | displayName: fix artifact permissions
35 |
36 | - task: PublishPipelineArtifact@1
37 | displayName: publish installer
38 | inputs:
39 | targetPath: _artifacts/constructor
40 | artifactName: ${{ product }} for ${{ platform.name }} $(Build.BuildId)
41 | condition: succeeded()
42 |
--------------------------------------------------------------------------------
/robotlab/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | name = robotlab
3 | version = 2020.01.0
4 | description = A pre-configured JupyterLab for demonstrating robotkernel
5 | long_description = file: README.md
6 | url = https://github.com/robots-from-jupyter/robotlab
7 | author = Nick Bollweg
8 | author_email = nick.bollweg@gmail.com
9 | license = BSD-3-Clause
10 | keywords =
11 | Interactive
12 | Interpreter
13 | Shell
14 | Testing
15 | Web
16 | Jupyter
17 | JupyterLab
18 | classifiers =
19 | Framework :: Jupyter
20 | Intended Audience :: Developers
21 | Intended Audience :: Information Technology
22 | License :: OSI Approved :: BSD License
23 | Programming Language :: Python
24 | Programming Language :: Python :: 3.6
25 | Programming Language :: Python :: 3 :: Only
26 | Topic :: Software Development :: Quality Assurance
27 | Topic :: Software Development :: Testing
28 |
29 | [options.entry_points]
30 | console_scripts =
31 | robotlab = robotlab.labapp:main
32 | robotlab-extension = robotlab.labextensionapp:main
33 | robotlab-shortcuts = robotlab.shortcuts:make_shortcuts
34 | robotlab-examples = robotlab.examples:copy_robotkernel_examples
35 | robotlab-tutorial = robotlab.tutorial:copy_robotkernel_tutorial
36 |
37 | [options]
38 | install_requires =
39 | jupyterlab
40 | package_dir =
41 | = src
42 | packages = find:
43 | include_package_data = True
44 | zip_safe = False
45 |
46 | [options.packages.find]
47 | where =
48 | src
49 |
--------------------------------------------------------------------------------
/ci/job.combine.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | name: Linux
3 | vmImage: ubuntu-16.04
4 | githubConnection: release-robots-from-jupyter
5 | repositoryName: robots-from-jupyter/robotlab
6 | platforms:
7 | - Linux
8 | - MacOSX
9 | - Windows
10 | products:
11 | - RobotLab
12 | # - MiniRobot
13 | # - ExoRobot
14 | constructors: _artifacts/constructor
15 |
16 | jobs:
17 | - job: Combine
18 | dependsOn:
19 | - ${{ each platform in parameters.platforms }}:
20 | - ${{ each product in parameters.products }}:
21 | - ${{ product }}${{ platform }}Test
22 | condition: always()
23 | pool:
24 | vmImage: ubuntu-16.04
25 | steps:
26 | - template: steps.conda.yml
27 | parameters:
28 | envPath: ci/env-combine.yml
29 |
30 | - ${{ each platform in parameters.platforms }}:
31 | - ${{ each product in parameters.products }}:
32 | - task: DownloadPipelineArtifact@0
33 | condition: always()
34 | inputs:
35 | artifactName: ${{ product }} ${{ platform }} Output $(Build.BuildId)
36 | targetPath: _artifacts/test_output
37 | displayName: restore ${{ product }} ${{ platform }} output
38 |
39 | - script: python -m scripts.combine
40 | condition: always()
41 | displayName: combine outputs
42 |
43 | - task: PublishPipelineArtifact@1
44 | condition: always()
45 | displayName: publish combined output
46 | inputs:
47 | targetPath: _artifacts/test_output
48 | artifactName: All Robot Output $(Build.BuildId)
49 |
--------------------------------------------------------------------------------
/ci/job.release.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | githubConnection: release-robots-from-jupyter
3 | repositoryName: robots-from-jupyter/robotlab
4 | platforms:
5 | - Linux
6 | - MacOSX
7 | - Windows
8 | products:
9 | - RobotLab
10 | # - MiniRobot
11 | # - ExoRobot
12 | constructors: _artifacts/constructor
13 |
14 | jobs:
15 | - job: Deploy
16 | pool:
17 | vmImage: ubuntu-16.04
18 | dependsOn:
19 | - ${{ each platform in parameters.platforms }}:
20 | - CondaNoarchTest${{ platform }}
21 | - ${{ each product in parameters.products }}:
22 | - ${{ product }}${{ platform }}Test
23 | condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/v'))
24 | steps:
25 | - ${{ each product in parameters.products }}:
26 | - ${{ each platform in parameters.platforms }}:
27 | - task: DownloadPipelineArtifact@0
28 | displayName: fetch ${{ product }} ${{ platform }} Installer
29 | inputs:
30 | artifactName: ${{ product }} For ${{ platform }} $(Build.BuildId)
31 | targetPath: ${{ parameters.constructors }}
32 | - script: find .
33 | displayName: list files before release
34 | - script: cd ${{ parameters.constructors }} && sha256sum * >> SHA256SUMS
35 | displayName: build hashes
36 | - task: GithubRelease@0
37 | inputs:
38 | githubConnection: ${{ parameters.githubConnection }}
39 | repositoryName: ${{ parameters.repositoryName }}
40 | assets: ${{ parameters.constructors }}/*
41 | isDraft: true
42 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2020, Robots from Jupyter
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/tests/resources/Cleanup.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Library OperatingSystem
3 | Library Process
4 | Resource ./Browser.robot
5 |
6 | *** Keywords ***
7 | Clean up the installation
8 | [Documentation] Clean out the installed product
9 | Sleep 5s
10 | Terminate All Processes
11 | Sleep 5s
12 | Terminate All Processes kill=True
13 | Sleep 5s
14 | Run Keyword If not ${IN_PRODUCT} Remove Directory ${PRODUCT DIR} recursive=True
15 | Sleep 5s
16 | Run Keyword If not ${IN_PRODUCT} Remove Directory ${PRODUCT DIR} recursive=True
17 |
18 | Clean Up Examples and Tutorials
19 | [Documentation] These are large, and don't prove much if they work
20 | Remove Directory ${OUTPUT DIR}${/}robotkernel-examples recursive=${True}
21 | Remove Directory ${OUTPUT DIR}${/}robotkernel-tutorials recursive=${True}
22 |
23 | Clean Up After Lab Suite
24 | [Documentation] Really try to make sure Lab is cleaned up
25 | Open RobotLab
26 | Clean Up After Lab Test
27 | Really Close All Browsers
28 | Terminate All Jupyter Servers
29 | Sleep 5s
30 | Run Keyword and Ignore Error Terminate All Processes
31 | Sleep 7s
32 | Run Keyword and Ignore Error Terminate All Processes kill=${True}
33 |
34 | Clean Up After Lab Test
35 | [Documentation] Try to make sure Lab is cleaned up
36 | Wait Until Keyword Succeeds 2x 1s Execute JupyterLab Command Shutdown All Kernels
37 | Wait Until Keyword Succeeds 2x 1s Execute JupyterLab Command Reset Application State
38 |
--------------------------------------------------------------------------------
/robotlab/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2019, Robots from Jupyter
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/icons/starter.svg:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/tests/resources/Browser.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Library JupyterLibrary
3 | Library OperatingSystem
4 | Resource Install.robot
5 |
6 | *** Variables ***
7 | ${NEXT GECKO LOG} ${0}
8 | ${GECKO LOGS} ${OUTPUT DIR}${/}geckodriver
9 |
10 | *** Keywords ***
11 | Open RobotLab
12 | [Arguments] ${nbserver}=${None} ${url}=${EMPTY} &{configuration}
13 | [Documentation] Open RobotLab with the bundled Firefox, served from the
14 | ... given (or most-recently-started) ``nbserver`` or ``url``, then wait
15 | ... for the splash screen.
16 | ... Extra ``configuration`` is passed on to SeleniumLibrary's *Create WebDriver*.
17 | ${geckodriver} = Get RobotLab GeckoDriver
18 | ${firefox} = Get RobotLab Firefox
19 | Create Directory ${GECKO LOGS}
20 | Create WebDriver Firefox executable_path=${geckodriver} firefox_binary=${firefox} service_log_path=${GECKO LOGS}${/}${NEXT GECKO LOG}.log &{configuration}
21 | Set Global Variable ${NEXT GECKO LOG} ${NEXT GECKO LOG.__add__(1)}
22 | ${nbserver_url} = Run Keyword If not "${url}" Get Jupyter Server URL ${nbserver}
23 | ${token} = Run Keyword If not "${url}" Get Jupyter Server Token ${nbserver}
24 | Set Global Variable ${TOKEN} ${token}
25 | ${final_url} = Set Variable If "${url}" ${url} ${nbserver_url}lab?token=${token}
26 | Go To about:blank
27 | Set Window Size 1920 1080
28 | Go To ${final_url}
29 | Wait Until Keyword Succeeds 5x 5s Wait for JupyterLab Splash Screen
30 |
31 | Really Close All Browsers
32 | [Documentation] We might open lots of browsers... this might help
33 | Run keyword And Ignore Error Handle Alert timeout=1s
34 | Run Keyword and Ignore Error Close All Browsers
35 | Run keyword And Ignore Error Handle Alert timeout=1s
36 |
--------------------------------------------------------------------------------
/ci/job.main.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | products:
3 | - RobotLab
4 | # - ExoRobot
5 | platforms:
6 | - name: Linux
7 | vmImage: ubuntu-16.04
8 | activate: ""
9 | - name: MacOSX
10 | vmImage: macos-10.13
11 | activate: ""
12 | - name: Windows
13 | vmImage: vs2017-win2016
14 | activate: call activate &&
15 | jobs:
16 | - ${{ each product in parameters.products }}:
17 | - ${{ each platform in parameters.platforms }}:
18 | - job: ${{ product }}${{ platform.name }}Build
19 | pool:
20 | vmImage: ${{ platform.vmImage }}
21 | condition: succeeded()
22 | dependsOn:
23 | - CondaNoarch
24 | - ${{ if eq(product, 'RobotLab') }}:
25 | - Lab
26 | - ${{ if eq(platform.name, 'Windows') }}:
27 | - CondaWindows
28 |
29 | steps:
30 | - template: steps.restore.yml
31 | parameters:
32 | name: ${{ platform.name }}
33 |
34 | - ${{ if eq(product, 'RobotLab') }}:
35 | - task: DownloadPipelineArtifact@0
36 | inputs:
37 | artifactName: robotlab app_dir $(Build.BuildId)
38 | targetPath: _artifacts/app_dir
39 | displayName: restore jupyterlab
40 |
41 | - template: steps.conda.yml
42 | parameters:
43 | name: ${{ platform.name }}
44 | envPath: ci/env-main.yml
45 |
46 | - ${{ if eq(product, 'RobotLab') }}:
47 | - script: ${{ platform.activate }} python -m scripts.build conda
48 | displayName: build/test remaining packages
49 |
50 | - script: ${{ platform.activate }} python -m scripts.build constructor ${{ product }}
51 | displayName: build installer
52 |
53 | - ${{ if eq(platform.name, 'MacOSX') }}:
54 | - script: chmod -R 777 _artifacts
55 | displayName: fix artifact permissions
56 |
57 | - task: PublishPipelineArtifact@1
58 | displayName: publish installer
59 | inputs:
60 | targetPath: _artifacts/constructor
61 | artifactName: ${{ product }} for ${{ platform.name }} $(Build.BuildId)
62 | condition: succeeded()
63 |
--------------------------------------------------------------------------------
/scripts/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 | import subprocess
3 | from pathlib import Path
4 | import platform
5 |
6 |
7 | PLATFORM = platform.system().lower()
8 |
9 | SCRIPTS_DIR = Path(__file__).parent
10 | SCRIPT_EXT = "bat" if platform == "windows" else "sh"
11 | ROOT = SCRIPTS_DIR.parent
12 |
13 | ARTIFACTS = ROOT / "_artifacts"
14 | CACHE = ROOT / "_cache"
15 |
16 | CONSTRUCT_DIR = ROOT / "constructor"
17 |
18 | RECIPE_DIR = ROOT / "recipes"
19 | CONDA_CACHE = CACHE / "conda-bld"
20 |
21 | CONSTRUCT_CACHE = CACHE / "constructor"
22 |
23 | TEST_DIR = ROOT / "tests"
24 |
25 | CONDA_OUT = ARTIFACTS / "conda-bld"
26 | CONSTRUCT_OUT = ARTIFACTS / "constructor"
27 | TEST_OUT = ARTIFACTS / "test_output"
28 | LAB_OUT = ARTIFACTS / "app_dir"
29 |
30 | ROBOTLAB_DIR = ROOT / "robotlab"
31 | README = ROOT / "README.md"
32 |
33 | # for easy overriding in CI
34 | VERSION = os.environ.get("ROBOTLAB_VERSION", "2020.01.0")
35 | CONDA_VERSION = os.environ.get("CONDA_VERSION", "4.8.0")
36 | RF_VERSION = os.environ.get("RF_VERSION", "3.1.2")
37 | PY_MAX = os.environ.get("PY_MAX", "3.7.0a0")
38 | PY_MIN = os.environ.get("PY_MIN", "3.6")
39 | LABEXTENSIONS = os.environ.get(
40 | "LABEXTENSIONS",
41 | """
42 | @deathbeds/jupyterlab-starters@0.2.2a0
43 | @jupyter-widgets/jupyterlab-manager@1.1.0
44 | @jupyterlab/toc@1.0.1
45 | jupyterlab_robotmode@2.4.0
46 | jupyterlab-jupytext@1.1.0
47 | """.replace(
48 | "\n", " "
49 | ),
50 | ).split()
51 |
52 | CONDA_BUILD_ARGS = [
53 | "conda-build",
54 | "--output-folder",
55 | CONDA_OUT,
56 | "--cache-dir",
57 | CONDA_CACHE,
58 | "-c",
59 | "https://conda.anaconda.org/conda-forge",
60 | "-c",
61 | "https://conda.anaconda.org/anaconda",
62 | "--python",
63 | PY_MIN,
64 | ]
65 |
66 | CONSTRUCTOR_ARGS = [
67 | "constructor",
68 | "--verbose",
69 | "--cache-dir",
70 | str(CONSTRUCT_CACHE),
71 | "--output-dir",
72 | str(CONSTRUCT_OUT),
73 | ]
74 |
75 |
76 | def run(args, **kwargs):
77 | """ Probably unneccessary "convenience" wrapper
78 | """
79 | str_args = list(map(str, args))
80 | print("===\n", " ".join(str_args), "\n===")
81 | p = subprocess.Popen(str_args, **kwargs)
82 |
83 | try:
84 | p.wait()
85 | except KeyboardInterrupt as err:
86 | p.kill()
87 | p.wait()
88 | raise err
89 |
90 | return p.returncode
91 |
--------------------------------------------------------------------------------
/recipes/robotframework/meta.yaml:
--------------------------------------------------------------------------------
1 | {% set name = "robotframework" %}
2 | {% set version = "3.1.2" %}
3 |
4 | package:
5 | name: {{ name }}
6 | version: {{ version }}
7 |
8 | source:
9 | - url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.zip
10 | sha256: f10dd7c0c8c7962a4f80dd1e026b5db731b9391bc6e1f9ebb96d685eb1230dbc
11 | folder: dist
12 | - url: https://github.com/robotframework/robotframework/archive/v{{ version }}.tar.gz
13 | sha256: 1a8769bc40d334814b3eeb1dc945624c292f210fb4f2ff033a21cba4e9360864
14 | folder: src
15 | patches:
16 | - 70af9e3bab0217b0450d78c69e6c2ccb8f9c342d.patch
17 |
18 |
19 | build:
20 | number: 0
21 | noarch: python
22 | script:
23 | - cd dist
24 | - {{ PYTHON }} -m pip install . --no-deps --ignore-installed -vvv
25 | entry_points:
26 | - robot = robot.run:run_cli
27 | - rebot = robot.rebot:rebot_cli
28 |
29 | requirements:
30 | host:
31 | - pip
32 | - python
33 | run:
34 | - python
35 |
36 | test:
37 | requires:
38 | - docutils
39 | - enum34 # [py<35]
40 | - lxml
41 | - pillow
42 | - pygments
43 | - pyyaml
44 | source_files:
45 | - src/utest
46 | - src/atest
47 | - src/README.rst
48 | imports:
49 | - robot
50 | - robot.api
51 | - robot.conf
52 | - robot.htmldata
53 | - robot.libdocpkg
54 | - robot.libraries
55 | - robot.model
56 | - robot.output
57 | - robot.output.console
58 | - robot.parsing
59 | - robot.reporting
60 | - robot.result
61 | - robot.running
62 | - robot.running.arguments
63 | - robot.running.timeouts
64 | - robot.utils
65 | - robot.variables
66 | - robot.writer
67 | commands:
68 | - robot --version || [[ $? == 251 ]] # [unix]
69 | - rebot --version || [[ $? == 251 ]] # [unix]
70 |
71 |
72 | about:
73 | home: http://robotframework.org
74 | license: Apache-2.0
75 | license_file: dist/LICENSE.txt
76 | summary: Generic automation framework for acceptance testing and RPA
77 | doc_url: http://robotframework.org/robotframework/{{ version }}/RobotFrameworkUserGuide.html
78 | dev_url: https://github.com/robotframework/robotframework
79 | description: >
80 | Robot Framework is a generic open source automation framework for acceptance
81 | testing, acceptance test driven development (ATDD), and robotic process
82 | automation (RPA). It has simple plain text syntax and it can be extended
83 | easily with libraries implemented using Python or Java.
84 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/2_Lab/30_Tutorial.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation Try the Tutorial
3 | Force Tags starter:tutorial
4 | Library JupyterLibrary
5 | Resource ../../../resources/Browser.robot
6 | Resource ../../../resources/Selectors.robot
7 |
8 | *** Variables ***
9 | ${KERNEL LANGUAGE} Python 3
10 | ${TOKEN CELL 00} .jp-CodeCell:nth-child(3) .CodeMirror
11 |
12 | *** Test Cases ***
13 | Will the Tutorial Launch?
14 | [Documentation] Start the Tutorial
15 | Open RobotLab
16 | ${prefix} = Set Variable tutorial_
17 | Execute JupyterLab Command Close All
18 | Wait Until Page Contains Element ${XP LAUNCH SECTION}
19 | Capture Page Screenshot ${prefix}_0_before_starter.png
20 | Click Element ${CSS LAUNCH CARD TUTORIAL}
21 | Wait Until Page Contains Element ${XP FILE TREE TUTORIAL 00} timeout=10s
22 | Capture Page Screenshot ${prefix}_1_after_starter.png
23 |
24 | Will a Tutorial Notebook Run?
25 | [Documentation] Run the First Tutorial Notebook
26 | Open RobotLab
27 | ${prefix} = Set Variable tutorial_00_
28 | # Set Selenium Speed 0.25s
29 | Open the Tutorial Folder ${prefix}
30 | Open the Tutorial Notebook ${prefix}
31 | # TODO: get the url parametrized so that it can also be run
32 | # Run the Tutorial Notebook ${prefix}
33 |
34 | *** Keywords ***
35 | Open the Tutorial Folder
36 | [Arguments] ${prefix}
37 | [Documentation] Open the tutorial folder
38 | Execute JupyterLab Command Close All
39 | Maybe Open JupyterLab Sidebar File Browser
40 | Click Element ${CRUMBS HOME}
41 | Double Click Element ${XP FILE TREE TUTORIAL}
42 | Capture Page Screenshot ${prefix}_1_in_folder.png
43 |
44 | Open the Tutorial Notebook
45 | [Arguments] ${prefix}
46 | [Documentation] Open and prepare the tutorial notebook
47 | Wait Until Page Contains Element ${XP FILE TREE TUTORIAL 00} timeout=10s
48 | Double Click Element ${XP FILE TREE TUTORIAL 00}
49 | Wait Until Page Contains Element css:.jp-Notebook table timeout=10s
50 | Wait Until Page Contains ${KERNEL LANGUAGE} | Idle timeout=3s
51 | Capture Page Screenshot ${prefix}_2_after_launch.png
52 | Execute JupyterLab Command Clear All Outputs
53 |
54 | Run the Tutorial Notebook
55 | [Arguments] ${prefix}
56 | [Documentation] Actually run the tutorial notebook
57 | Click Element css:${TOKEN CELL 00}
58 | # this gem is because rfjpyl uses backticks...
59 | Set CodeMirror Value ${TOKEN CELL 00} *** Variables ***\n` + '\${token} ' +` ${TOKEN}
60 | Capture Page Screenshot ${prefix}_3_after_token.png
61 | Click Element ${CSS NOTEBOOK SAVE}
62 | Execute JupyterLab Command Run All Cells
63 | Wait Until Page Does Not Contain [*] timeout=20s
64 | Wait Until Page Contains ${KERNEL LANGUAGE} | Idle timeout=3s
65 | Click Element ${CSS NOTEBOOK SAVE}
66 | Execute JupyterLab Command Close All
67 |
--------------------------------------------------------------------------------
/tests/acceptance/RobotLab/2_Lab/40_Examples.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation Try the Examples
3 | Force Tags starter:example
4 | Library JupyterLibrary
5 | Resource ../../../resources/Browser.robot
6 | Resource ../../../resources/Lab.robot
7 | Resource ../../../resources/Selectors.robot
8 |
9 | *** Variables ***
10 | ${KERNEL LANGUAGE} Robot Framework
11 |
12 | *** Test Cases ***
13 | Will the Example Starter Launch?
14 | [Documentation] Start the Example
15 | [Tags] example:opencv
16 | Open RobotLab
17 | ${prefix} = Set Variable example_
18 | Execute JupyterLab Command Close All
19 | Wait Until Page Contains Element ${XP LAUNCH SECTION}
20 | Capture Page Screenshot ${prefix}_0_before_starter.png
21 | Click Element ${CSS LAUNCH CARD EXAMPLES}
22 | Wait Until Page Contains Element ${XP FILE TREE EXAMPLE OPENCV} timeout=10s
23 | Capture Page Screenshot ${prefix}_1_after_starter.png
24 |
25 | Will the OpenCV Notebook Run?
26 | [Documentation] Run the OpenCV Tutorial Notebook
27 | [Tags] example:opencv
28 | Open RobotLab
29 | ${prefix} = Set Variable example_opencv_
30 | Open the Example Folder ${prefix}
31 | Open the Example Notebook ${prefix} ${XP FILE TREE EXAMPLE OPENCV}
32 | Run the Example Notebook ${prefix}
33 | Capture Page Screenshot ${prefix}_6_after_run_all.png
34 | The Robot Popup Should Contain ${prefix} Log passed, 0 failed
35 | The Robot Popup Should Contain ${prefix} Report All tests passed
36 | Capture Page Screenshot ${prefix}_7_reported.png
37 | Screenshot Each Output of Active JupyterLab Document ${prefix}_8_all_
38 |
39 | *** Keywords ***
40 | Open the Example Folder
41 | [Arguments] ${prefix}
42 | [Documentation] Open the example folder
43 | Execute JupyterLab Command Close All
44 | Maybe Open JupyterLab Sidebar File Browser
45 | Click Element ${CRUMBS HOME}
46 | Double Click Element ${XP FILE TREE EXAMPLE}
47 | Capture Page Screenshot ${prefix}_1_in_folder.png
48 |
49 | Open the Example Notebook
50 | [Arguments] ${prefix} ${example}
51 | [Documentation] Open and prepare the example notebook
52 | Wait Until Page Contains Element ${example} timeout=10s
53 | Double Click Element ${example}
54 | Wait Until Page Contains ${KERNEL LANGUAGE} | Idle timeout=10s
55 | Capture Page Screenshot ${prefix}_2_after_launch.png
56 | Execute JupyterLab Command Clear All Outputs
57 | Sleep 1s
58 | Capture Page Screenshot ${prefix}_3_after_clean.png
59 |
60 | Run the Example Notebook
61 | [Arguments] ${prefix}
62 | [Documentation] Actually run the example notebook
63 | Execute JupyterLab Command Run All Cells
64 | Wait Until Page Does Not Contain [*] timeout=120s
65 | Wait Until Page Contains ${KERNEL LANGUAGE} | Idle timeout=120s
66 | Capture Page Screenshot ${prefix}_4_after_run.png
67 |
--------------------------------------------------------------------------------
/recipes/robotlab/meta.yaml:
--------------------------------------------------------------------------------
1 | {% set robot = "3.1.2" %}
2 | {% set robot_conda = ">=4.7.12,<4.8" %}
3 | {% set robot_fox = ">=68.0.2,<69" %}
4 | {% set robot_jupyterlab = "==1.2.4" %}
5 | {% set robot_node = ">=11,<12" %}
6 | {% set robot_pywinpty = ">=0.5.5" %}
7 | {% set robot_starters = ">=0.2.2a0,<0.3.0a0" %}
8 | {% set robot_widgets = ">=7.5.1" %}
9 | {% set robotkernel = "1.3.0" %}
10 |
11 | package:
12 | name: {% set name = "robotlab" %}{{ name }}
13 | version: {% set version = "2020.01.0" %}{{ version }}
14 |
15 | source:
16 | - path: ../../robotlab
17 | folder: robotlab
18 | - url: https://github.com/robots-from-jupyter/robotkernel/archive/{{ robotkernel }}.tar.gz
19 | sha256: e3c384621f37c9471ca0c65c44c8203c7a99207cbb155a70c7b9063f2b9832e8
20 | folder: robotkernel
21 | # we do the jupyterlab build off-line to keep conda-build time low
22 | - path: ../../_artifacts/app_dir
23 | folder: app_dir
24 |
25 | build:
26 | number: 0
27 | entry_points:
28 | - robotlab = robotlab.labapp:main
29 | - robotlab-extension = robotlab.labextensionapp:main
30 | - robotlab-shortcuts = robotlab.shortcuts:make_shortcuts
31 | - robotlab-examples = robotlab.examples:copy_robotkernel_examples
32 | - robotlab-tutorial = robotlab.tutorial:copy_robotkernel_tutorial
33 | script:
34 | - {{ PYTHON }} {{ RECIPE_DIR }}/builder.py # [unix]
35 | - {{ PYTHON }} {{ RECIPE_DIR }}\builder.py # [win]
36 | - cd robotlab
37 | - {{ PYTHON }} -m pip install --no-deps --ignore-installed --no-cache-dir -vvv .
38 |
39 | requirements:
40 | host:
41 | - pip
42 | - python
43 | run:
44 | - conda {{ robot_conda }}
45 | - firefox {{ robot_fox }}
46 | - geckodriver
47 | - ipywidgets {{ robot_widgets }}
48 | - jupyter-starters {{ robot_starters }}
49 | - jupyterlab {{ robot_jupyterlab }}
50 | - jupytext >=1.3.1
51 | - matplotlib-base >=3.1.2
52 | - nodejs {{ robot_node }}
53 | - py-opencv
54 | - pyshortcuts
55 | - python
56 | - pywinpty {{ robot_pywinpty }} # [win]
57 | - restinstance
58 | - rise >=5.6.0
59 | - robotframework =={{ robot }}
60 | - robotframework-jupyterlibrary
61 | - robotframework-seleniumscreenshots
62 | - robotframework-seleniumtestability
63 | - robotframework-whitelibrary # [win]
64 | - robotkernel =={{ robotkernel }}
65 |
66 | test:
67 | imports:
68 | - robotlab
69 | - robotlab.examples
70 | - robotlab.labextensionapp
71 | - robotlab.launch
72 | - robotlab.paths
73 | - robotlab.shortcuts
74 | - robotlab.tutorial
75 | commands:
76 | - robotlab --version
77 | - robotlab-extension list
78 | - robotlab-tutorial
79 | - robotlab-examples
80 | - cd robotkernel-examples
81 | - jupyter nbconvert --execute --ExecutePreprocessor.timeout=600 OpenCV.ipynb # [not osx]
82 | - cd ..
83 | - mkdir Desktop # [unix]
84 | - HOME=$(pwd) robotlab-shortcuts # [unix]
85 |
86 | about:
87 | home: https://github.com/robots-from-jupyter/robotlab
88 | license: BSD-3-Clause
89 | license_family: BSD
90 | license_file: robotlab/LICENSE
91 | summary: A JupyterLab built for robotkernel as part of the RobotLab distribution
92 |
--------------------------------------------------------------------------------
/recipes/robotlab/builder.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | import os, sys, shutil, json, platform, re
3 |
4 | PLATFORM = platform.system().lower()
5 |
6 | SRC_DIR = Path(os.environ["SRC_DIR"])
7 | PREFIX = Path(os.environ["PREFIX"])
8 |
9 | APP = SRC_DIR / "app_dir"
10 |
11 | WWW = PREFIX / "var" / "www"
12 | ETC = PREFIX / "etc" / "jupyter" / "jupyter_notebook_config.d"
13 | SHARE = PREFIX / "share" / "jupyter"
14 |
15 | KERNEL = SRC_DIR / "robotkernel"
16 | EXAMPLES = WWW / "robotkernel-examples"
17 | TUTORIAL = WWW / "robotkernel-tutorial"
18 | NOTEBOOKS = {
19 | EXAMPLES: KERNEL / "examples",
20 | TUTORIAL: KERNEL / "src" / "robotkernel" / "resources" / "notebooks" / "tutorial"
21 | }
22 | SVG = SRC_DIR / "robotlab" / "src" / "robotlab" / "icons" / "starter.svg"
23 |
24 | OPENCV_OSX = """
25 | ${prefix} = Evaluate __import__("sys").prefix
26 | Create WebDriver Firefox executable_path=${prefix}${/}bin${/}geckodriver firefox_binary=${prefix}${/}bin${/}firefox
27 | Go To https://www.google.com/?hl=en
28 | """
29 |
30 |
31 | print("making directories...")
32 | [d.mkdir(exist_ok=True, parents=True) for d in [SHARE, ETC, WWW]]
33 |
34 | print("copying lab...")
35 | shutil.rmtree(APP / "staging", ignore_errors=True)
36 | shutil.copytree(APP, SHARE / "robotlab")
37 |
38 | print("copying notebooks...")
39 | NOT_A_NOTEBOOK = lambda d, paths: [p for p in paths if not p.endswith(".ipynb")]
40 | [
41 | shutil.copytree(src, dest, ignore=NOT_A_NOTEBOOK)
42 | for dest, src in NOTEBOOKS.items()
43 | ]
44 |
45 | print("hacking OpenCV Notebook on OSX")
46 |
47 | if PLATFORM == "darwin":
48 | opencv = EXAMPLES / "OpenCV.ipynb"
49 | nb = json.loads(opencv.read_text())
50 | for cell in nb["cells"]:
51 | if cell["cell_type"] == "code":
52 | lines = cell["source"]
53 | for i, line in enumerate(lines):
54 | if re.findall(r"\s+Open browser", line, flags=re.I):
55 | lines[i] = OPENCV_OSX
56 | print(lines)
57 | cell["source"] = lines
58 |
59 | opencv.write_text(json.dumps(nb, indent=2))
60 |
61 |
62 | print("making starters...")
63 | (ETC / "robotlab-starters.json").write_text(json.dumps({
64 | "StarterManager": {
65 | "extra_starters": {
66 | "robotkernel-quickstart": {
67 | "label": "",
68 | "description": "",
69 | "type": "notebook",
70 | "py_src": "robotkernel",
71 | "src": "resources/starter/quickstart-starter.ipynb"
72 | },
73 | "robotkernel-tutorial": {
74 | "label": "Tutorial",
75 | "description": "Tutorial for Robot Framework on Jupyter",
76 | "type": "copy",
77 | "py_src": "robotkernel",
78 | "src": "resources/notebooks/tutorial",
79 | "icon": SVG.read_text().replace("jp-icon3", "jp-icon-contrast3")
80 | },
81 | "robotkernel-examples": {
82 | "type": "copy",
83 | "label": "Samples",
84 | "description": "Miscellanous examples of using RobotKernel",
85 | "icon": SVG.read_text().replace("jp-icon2", "jp-icon-contrast1"),
86 | "src": str(EXAMPLES)
87 | }
88 | }
89 | }
90 | }, indent=2))
91 |
--------------------------------------------------------------------------------
/ci/job.selftest.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | products:
3 | - RobotLab
4 | # - MiniRobot
5 | # - ExoRobot
6 | platforms:
7 | - name: Linux
8 | vmImage: ubuntu-16.04
9 | activate: ""
10 | - name: MacOSX
11 | vmImage: macos-10.13
12 | activate: ""
13 | - name: Windows
14 | vmImage: vs2017-win2016
15 | activate: call activate &&
16 |
17 | jobs:
18 | - ${{ each product in parameters.products }}:
19 | - ${{ each platform in parameters.platforms }}:
20 | - job: ${{ product }}${{ platform.name }}Test
21 | condition: succeeded()
22 | dependsOn:
23 | - ${{ product }}${{ platform.name }}Build
24 | pool:
25 | vmImage: ${{ platform.vmImage }}
26 |
27 | steps:
28 | - task: DownloadPipelineArtifact@0
29 | inputs:
30 | artifactName: ${{ product }} for ${{ platform.name }} $(Build.BuildId)
31 | targetPath: _artifacts/constructor
32 | displayName: restore installer
33 |
34 | - ${{ if not(eq(platform.name, 'Windows')) }}:
35 | - script: bash _artifacts/constructor/${{ product }}-$(ROBOTLAB_VERSION)-${{ platform.name }}-x86_64.sh -fbp _${{ product }}
36 | displayName: run installer
37 | - script: . ./_${{ product }}/bin/activate ./_${{ product }} && python -m scripts.test robot ${{ product }} --headless --in-product --dryrun
38 | displayName: acceptance tests (dry run)
39 | - script: . ./_${{ product }}/bin/activate ./_${{ product }} && python -m scripts.test robot ${{ product }} --headless --in-product
40 | displayName: acceptance tests
41 |
42 | - ${{ if eq(platform.name, 'Windows') }}:
43 | - script: |
44 | @echo on
45 | echo %HOME%
46 | md "%cd%\_${{ product }}"
47 | start /wait "" "_artifacts\constructor\${{ product }}-$(ROBOTLAB_VERSION)-Windows-x86_64.exe" /InstallationType=JustMe /AddToPath=0 /RegisterPython=0 /S /D=%cd%\_${{ product }}
48 | displayName: run installer
49 | - script: |
50 | @echo on
51 | call "%cd%\_${{ product }}\Scripts\activate.bat" "%cd%\_${{ product }}"
52 | python -m scripts.test robot ${{ product }} --headless --in-product --dryrun
53 | displayName: acceptance tests (dry run)
54 | - script: |
55 | @echo on
56 | call "%cd%\_${{ product }}\Scripts\activate.bat" "%cd%\_${{ product }}"
57 | python -m scripts.test robot ${{ product }} --headless --in-product
58 | displayName: acceptance tests
59 |
60 | - ${{ if eq(platform.name, 'MacOSX') }}:
61 | - script: chmod -R 777 _artifacts
62 | displayName: fix artifact permissions
63 |
64 | - task: PublishTestResults@2
65 | displayName: publish test results
66 | inputs:
67 | testResultsFiles: _artifacts/test_output/**/*.xunit.xml
68 | condition: always()
69 |
70 | - task: PublishPipelineArtifact@0
71 | displayName: publish robot output
72 | inputs:
73 | targetPath: _artifacts/test_output
74 | artifactName: ${{ product }} ${{ platform.name }} Output $(Build.BuildId)
75 | condition: always()
76 |
--------------------------------------------------------------------------------
/anaconda-project.yml:
--------------------------------------------------------------------------------
1 | name: robotlab
2 |
3 | commands:
4 | integrity:
5 | unix: python -m scripts.integrity
6 | env_spec: _qa
7 |
8 | lint:
9 | unix: python -m scripts.lint
10 | env_spec: _qa
11 |
12 | build:
13 | unix: python -m scripts.build
14 | windows: python -m scripts.build
15 | env_spec: _robots_from_jupyter
16 |
17 | build:lab:
18 | unix: python -m scripts.build lab
19 | windows: python -m scripts.build lab
20 | env_spec: _qa
21 |
22 | test:
23 | unix: python -m scripts.test
24 | windows: python -m scripts.test
25 | env_spec: _test
26 |
27 | combine:
28 | unix: python -m scripts.combine
29 | env_spec: _qa
30 |
31 | robotlab:setup:
32 | unix: cd robotlab && python -m pip install -e . --ignore-installed --no-deps -vv
33 | windows: cd robotlab && python -m pip install -e . --ignore-installed --no-deps -vv
34 | env_spec: robotlab-dev
35 |
36 | robotlab:
37 | unix: robotlab
38 | windows: robotlab
39 | env_spec: robotlab-dev
40 |
41 | robotlab:launch:
42 | unix: python -m robotlab.launch
43 | windows: python -m robotlab.launch
44 | env_spec: robotlab-dev
45 |
46 | robotlab:build:
47 | unix: robotlab build
48 | windows: robotlab build
49 | env_spec: robotlab-dev
50 |
51 | channels:
52 | - https://conda.anaconda.org/anaconda
53 | - https://conda.anaconda.org/conda-forge
54 |
55 | env_specs:
56 | _robots_from_jupyter:
57 | description: the main build/test environment
58 | channels:
59 | - https://conda.anaconda.org/anaconda
60 | - https://conda.anaconda.org/conda-forge
61 | packages:
62 | - conda >=4.8,<4.9.0a0
63 | - conda-build >=3.18.11,<3.19.0a0
64 | - conda-verify
65 | - constructor >=3,<3.1
66 | - firefox >=68.0.2,<69
67 | - geckodriver
68 | - pillow
69 | - python >=3.6,<3.7.0a0
70 | - python-libarchive-c
71 | - ripgrep
72 | - robotframework
73 | - robotframework-seleniumlibrary >=4.1.0,<5
74 |
75 | _lab:
76 | packages:
77 | - jupyterlab ==1.2.4
78 | - nodejs >=11,<12
79 | - python >=3.6,<3.7.0a0
80 |
81 | _qa:
82 | inherit_from:
83 | - _lab
84 | packages:
85 | - black
86 | - flake8
87 | - robotframework-lint
88 |
89 | _test:
90 | inherit_from:
91 | - _robots_from_jupyter
92 | channels:
93 | - ./_artifacts/conda-bld
94 | packages:
95 | - robotframework-jupyterlibrary
96 |
97 | robotlab-dev:
98 | description: basically what goes in the constructor for interactive dev/test
99 | inherit_from:
100 | - _lab
101 | channels:
102 | - ./_artifacts/conda-bld
103 | packages:
104 | - conda
105 | - firefox
106 | - jupyter-starters
107 | - jupytext
108 | - matplotlib
109 | - pyshortcuts
110 | - restinstance
111 | - rise
112 | - robotframework-seleniumscreenshots
113 | - robotframework-seleniumtestability
114 | - robotkernel
115 |
116 | robotlab-dev-win:
117 | inherit_from:
118 | - robotlab-dev
119 | packages:
120 | - robotframework-whitelibrary
121 |
122 | robotlab-test:
123 | channels:
124 | - https://conda.anaconda.org/conda-forge
125 | - https://conda.anaconda.org/anaconda
126 | - ./_artifacts/conda-bld
127 | packages:
128 | - robotlab
129 |
--------------------------------------------------------------------------------
/scripts/build.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | from jinja2 import Template
4 |
5 | from . import (
6 | CONDA_BUILD_ARGS,
7 | CONDA_OUT,
8 | CONDA_VERSION,
9 | CONSTRUCT_DIR,
10 | CONSTRUCT_OUT,
11 | CONSTRUCTOR_ARGS,
12 | LAB_OUT,
13 | LABEXTENSIONS,
14 | PY_MAX,
15 | PY_MIN,
16 | RECIPE_DIR,
17 | RF_VERSION,
18 | run,
19 | VERSION,
20 | )
21 |
22 |
23 | def build_conda(packages=None, force=False, no_test=False):
24 | """ Build some packages (mostly re-arching conda-forge `noarch: python`)
25 | """
26 |
27 | [
28 | p.unlink()
29 | for p in (
30 | list(CONDA_OUT.rglob("*.json"))
31 | + list(CONDA_OUT.rglob("*.json.bz2"))
32 | )
33 | ]
34 |
35 | if packages:
36 | force = True
37 | else:
38 | packages = ["."]
39 |
40 | extra_args = []
41 | extra_args += [] if force else ["--skip-existing"]
42 | extra_args += ["--no-test"] if no_test else []
43 |
44 | rc = 0
45 |
46 | args = [*CONDA_BUILD_ARGS, *extra_args, *packages]
47 | rc = rc or run(args, cwd=str(RECIPE_DIR))
48 |
49 | return rc
50 |
51 |
52 | def build_constructor(construct):
53 | """ Use the local build artifacts in constructor
54 | """
55 | construct_dir = CONSTRUCT_DIR / construct
56 |
57 | construct_yaml_in = Template(
58 | (construct_dir / "construct.yaml.in").read_text()
59 | )
60 |
61 | construct_yaml = construct_yaml_in.render(
62 | build_channel=CONDA_OUT.as_uri(),
63 | py_max=PY_MAX,
64 | py_min=PY_MIN,
65 | version=VERSION,
66 | rf_version=RF_VERSION,
67 | conda_version=CONDA_VERSION,
68 | )
69 |
70 | (construct_dir / "construct.yaml").write_text(construct_yaml)
71 |
72 | print(construct_yaml)
73 |
74 | CONSTRUCT_OUT.mkdir(exist_ok=True, parents=True)
75 |
76 | return run(CONSTRUCTOR_ARGS, cwd=str(construct_dir))
77 |
78 |
79 | def build_lab():
80 | JP = [sys.executable, "-m", "jupyter"]
81 | app_dir = ["--app-dir", LAB_OUT]
82 |
83 | rc = run(
84 | [
85 | *JP,
86 | "labextension",
87 | "install",
88 | "--no-build",
89 | *app_dir,
90 | *LABEXTENSIONS,
91 | ]
92 | )
93 |
94 | rc = rc or run(
95 | [
96 | *JP,
97 | "lab",
98 | "build",
99 | *app_dir,
100 | "--dev-build=False",
101 | "--minimize=True",
102 | "--name='RobotLab'",
103 | ]
104 | )
105 |
106 | rc or run([*JP, "labextension", "list"])
107 |
108 | return rc
109 |
110 |
111 | if __name__ == "__main__":
112 | rc = 1
113 |
114 | all_constructs = sorted(CONSTRUCT_DIR.glob("*/"))
115 |
116 | if len(sys.argv) > 1:
117 | it, rest = sys.argv[1], sys.argv[2:]
118 | if it == "lab":
119 | rc = build_lab()
120 | elif it == "conda":
121 | no_test = False
122 | if "--no-test" in rest:
123 | no_test = True
124 | rest.remove("--no-test")
125 | rc = build_conda(rest, no_test=no_test)
126 | elif it == "constructor":
127 | rc = 0
128 | constructs = rest or all_constructs
129 | print(f"building {constructs}")
130 | for construct in constructs:
131 | rc = rc or build_constructor(construct)
132 | else:
133 | rc = build_conda()
134 | print(f"building {all_constructs}")
135 | for construct in all_constructs:
136 | rc = rc or build_constructor(construct)
137 |
138 | sys.exit(rc)
139 |
--------------------------------------------------------------------------------
/scripts/test.py:
--------------------------------------------------------------------------------
1 | import os
2 | import shutil
3 | import sys
4 |
5 | from . import (
6 | run,
7 | TEST_DIR,
8 | TEST_OUT,
9 | PLATFORM,
10 | CONDA_OUT,
11 | CONDA_BUILD_ARGS,
12 | CONSTRUCT_OUT,
13 | )
14 |
15 |
16 | def test_conda(packages=None):
17 | rc = 0
18 | packages = packages or sorted(
19 | [
20 | pkg
21 | for pkg in CONDA_OUT.glob("*/*.tar.bz2")
22 | if "repodata" not in pkg.name
23 | ]
24 | )
25 | for pkg in packages:
26 | rc = rc or run([*CONDA_BUILD_ARGS, "--test", pkg])
27 | return rc
28 |
29 |
30 | def test_robot(
31 | product, robot_args=None, headless=False, in_product=False, dry_run=False
32 | ):
33 | stem = f"{product}.{PLATFORM}"
34 | output_path = TEST_OUT / product / PLATFORM.lower()
35 |
36 | robot_args = list(robot_args or [])
37 | robot_args += ["--include", f"product:{product}"]
38 |
39 | name = f"{product} {PLATFORM}"
40 |
41 | if dry_run:
42 | robot_args += ["--dryrun", "--settag", "dryrun"]
43 | stem += ".dryrun"
44 | name = f"{name} (Dry Run)"
45 | output_path = TEST_OUT / product / f"{PLATFORM.lower()}-dryrun"
46 |
47 | robot_args += os.environ.get("ROBOT_ARGS", "").split()
48 |
49 | if output_path.exists():
50 | shutil.rmtree(output_path)
51 |
52 | output_path.mkdir(parents=True)
53 |
54 | if headless:
55 | os.environ["MOZ_HEADLESS"] = "1"
56 |
57 | args = (
58 | [
59 | sys.executable,
60 | "-m",
61 | "robot",
62 | "--name",
63 | name,
64 | "--outputdir",
65 | output_path,
66 | "--output",
67 | TEST_OUT / f"{stem}.robot.xml",
68 | "--log",
69 | TEST_OUT / f"{stem}.log.html",
70 | "--report",
71 | TEST_OUT / f"{stem}.report.html",
72 | "--xunit",
73 | TEST_OUT / f"{stem}.xunit.xml",
74 | "--variable",
75 | f"OS:{PLATFORM}",
76 | "--variable",
77 | f"INSTALLER DIR:{CONSTRUCT_OUT}",
78 | "--variable",
79 | f"IN_PRODUCT:{int(in_product)}",
80 | ]
81 | + list(robot_args)
82 | + [str(TEST_DIR / "acceptance" / product)]
83 | )
84 | return run(args)
85 |
86 |
87 | if __name__ == "__main__":
88 | rc = 0
89 | headless = in_product = dry_run = False
90 | all_products = ["RobotLab"]
91 | # all_products = sorted(
92 | # [product.name for product in (TEST_DIR / "acceptance").glob("*/")]
93 |
94 | # )
95 | args = sys.argv[1:]
96 |
97 | if "--headless" in args:
98 | headless = True
99 | args.remove("--headless")
100 |
101 | if "--in-product" in args:
102 | in_product = True
103 | args.remove("--in-product")
104 |
105 | if "--dryrun" in args:
106 | dry_run = True
107 | args.remove("--dryrun")
108 |
109 | if not args:
110 | rc = test_conda()
111 | for product in all_products:
112 | rc = rc or test_robot(
113 | product, headless=headless, in_product=in_product
114 | )
115 | else:
116 | it, rest = args[0], args[1:]
117 |
118 | if it == "conda":
119 | rc = test_conda(rest)
120 | elif it == "robot":
121 | robot_args = []
122 | if "--" in rest:
123 | dash_index = rest.index("--")
124 | robot_args = rest[dash_index + 1 :]
125 | products = rest[: dash_index - 1]
126 | else:
127 | products = rest or all_products
128 |
129 | print(f"testing {products}")
130 | for product in products:
131 | rc = rc or test_robot(
132 | product,
133 | robot_args=robot_args,
134 | headless=headless,
135 | in_product=in_product,
136 | dry_run=dry_run,
137 | )
138 |
139 | sys.exit(rc)
140 |
--------------------------------------------------------------------------------
/tests/resources/Install.robot:
--------------------------------------------------------------------------------
1 | *** Settings ***
2 | Documentation Install a Product
3 | Library OperatingSystem
4 | Library Process
5 | Resource ./Cleanup.robot
6 |
7 | *** Variables ***
8 | ${INSTALLER VERSION} 2020.01.0
9 | ${INSTALL LOG} ${OUTPUT DIR}${/}00_installer.log
10 | &{GECKODRIVER} linux=bin${/}geckodriver darwin=bin${/}geckodriver windows=Scripts${/}geckodriver.exe
11 | &{FIREFOX} linux=bin${/}firefox darwin=bin${/}firefox windows=Library${/}bin${/}firefox.exe
12 |
13 | *** Keywords ***
14 | Run the installer
15 | [Arguments] ${product}
16 | [Documentation] Detect and tag the platform, then run the appropriate installer (if not already in robotlab)
17 | ${tmpdir} = Evaluate ${IN_PRODUCT} or __import__("tempfile").mkdtemp("RobotLab")
18 | ${path} = Set Variable ${OUTPUT DIR}
19 | ${product dir} = Set Variable If ${IN_PRODUCT} %{CONDA_PREFIX} ${tmpdir}
20 | Set Global Variable ${PRODUCT DIR} ${product dir}
21 | Set Global Variable ${FAKE HOME} ${path}${/}home
22 | Create Directory ${FAKE HOME}${/}Desktop
23 | ${rc} = Run Keyword If "${OS}" == "linux" Run the Linux Installer ${product}
24 | ... ELSE IF "${OS}" == "windows" Run the Windows Installer ${product}
25 | ... ELSE IF "${OS}" == "darwin" Run the OSX Installer ${product}
26 | ... ELSE Fatal Error Can't install on platform ${OS}!
27 | Should Be Equal as Integers ${rc} 0 msg=Couldn't complete installer, see ${INSTALL LOG}
28 | Wait Until Created ${ACTIVATE SCRIPT}
29 |
30 | Run the Linux installer
31 | [Arguments] ${product}
32 | [Documentation] Install on Linux
33 | ${result} = Run Keyword If not ${IN_PRODUCT} Run Process bash ${INSTALLER DIR}${/}${product}-${INSTALLER VERSION}-Linux-x86_64.sh -fbp
34 | ... ${PRODUCT DIR} stdout=${INSTALL LOG} stderr=STDOUT env:HOME=${FAKE HOME}
35 | Set Global Variable ${ACTIVATE SCRIPT} ${PRODUCT DIR}${/}bin${/}activate
36 | Set Global Variable ${ACTIVATE} . "${ACTIVATE SCRIPT}" "${PRODUCT DIR}" && set -eux
37 | Set Global Variable ${PRODUCT PATH ENV} ${PRODUCT DIR}${/}bin:%{PATH}
38 | Run Keyword If "${product}" == "RobotLab" Set Global Variable ${ROBOTLAB CMD} ${PRODUCT DIR}${/}bin${/}robotlab
39 | Run Keyword If "${product}" == "RobotLab" Set Global Variable ${ROBOTLAB SHORTCUT} RobotLab.desktop
40 | ${rc} = Set Variable If ${IN_PRODUCT} 0 ${result.rc}
41 | [Return] ${rc}
42 |
43 | Run the OSX installer
44 | [Arguments] ${product}
45 | [Documentation] Install on OSX
46 | ${result} = Run Keyword If not ${IN_PRODUCT} Run Process bash ${INSTALLER DIR}${/}${product}-${INSTALLER VERSION}-MacOSX-x86_64.sh -fbp
47 | ... ${PRODUCT DIR} stdout=${INSTALL LOG} stderr=STDOUT env:HOME=${FAKE HOME}
48 | Set Global Variable ${ACTIVATE SCRIPT} ${PRODUCT DIR}${/}bin${/}activate
49 | Set Global Variable ${ACTIVATE} set -ex && . "${ACTIVATE SCRIPT}" "${PRODUCT DIR}"
50 | Set Global Variable ${PRODUCT PATH ENV} ${PRODUCT DIR}${/}bin${:}%{PATH}
51 | Run Keyword If "${product}" == "RobotLab" Set Global Variable ${ROBOTLAB CMD} ${PRODUCT DIR}${/}bin${/}robotlab
52 | Run Keyword If "${product}" == "RobotLab" Set Global Variable ${ROBOTLAB SHORTCUT} RobotLab.app
53 | ${rc} = Set Variable If ${IN_PRODUCT} 0 ${result.rc}
54 | [Return] ${rc}
55 |
56 | Run the Windows installer
57 | [Arguments] ${product}
58 | [Documentation] Install on Windows
59 | ${installer} = Set Variable ${INSTALLER DIR}${/}${product}-${INSTALLER VERSION}-Windows-x86_64.exe
60 | ${args} = Set Variable /InstallationType=JustMe /AddToPath=0 /RegisterPython=0 /S /D=${PRODUCT DIR}
61 | ${result} = Run Keyword If not ${IN_PRODUCT} Run Process ${installer} ${args} stdout=${INSTALL LOG} stderr=STDOUT
62 | ... shell=True env:HOME=${FAKE HOME}
63 | Set Global Variable ${ACTIVATE SCRIPT} ${PRODUCT DIR}${/}Scripts${/}activate.bat
64 | Set Global Variable ${ACTIVATE} "${ACTIVATE SCRIPT}" "${PRODUCT DIR}"
65 | Set Global Variable ${PRODUCT PATH ENV} ${PRODUCT DIR}${:}${PRODUCT DIR}${/}Scripts${:}${PRODUCT DIR}${/}Library${/}bin${:}%{PATH}
66 | Run Keyword If "${product}" == "RobotLab" Set Global Variable ${ROBOTLAB CMD} ${PRODUCT DIR}${/}Scripts${/}robotlab.exe
67 | Run Keyword If "${product}" == "RobotLab" Set Global Variable ${ROBOTLAB SHORTCUT} RobotLab.lnk
68 | ${rc} = Set Variable If ${IN_PRODUCT} 0 ${result.rc}
69 | [Return] ${rc}
70 |
71 | Get RobotLab GeckoDriver
72 | [Documentation] Get the path to the bundled geckodriver
73 | [Return] ${PRODUCT DIR}${/}&{GECKODRIVER}[${OS}]
74 |
75 | Get RobotLab Firefox
76 | [Documentation] Get the path to the bundled firefox
77 | [Return] ${PRODUCT DIR}${/}${FIREFOX}[${OS}]
78 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/icons/lab.svg:
--------------------------------------------------------------------------------
1 |
2 |
97 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/icons/shell.svg:
--------------------------------------------------------------------------------
1 |
2 |
97 |
--------------------------------------------------------------------------------
/robotlab/src/robotlab/icons/master.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
150 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RobotLab [![Build Status][build-badge]][build-status]
2 |
3 | > A one-click installer for [Robot Framework][robotframework],
4 | [JupyterLab][jupyterlab], [Firefox][], and Friends
5 |
6 | ## Get RobotLab
7 | Start the download now for your platform:
8 |
9 | ### [Linux][] | [MacOSX][] | [Windows][]
10 |
11 | > ... or view the [release notes][release-notes].
12 |
13 | [Linux]: https://github.com/robots-from-jupyter/robotlab/releases/download/v2019.9.0/RobotLab-2019.9.0-Linux-x86_64.sh
14 | [MacOSX]: https://github.com/robots-from-jupyter/robotlab/releases/download/v2019.9.0/RobotLab-2019.9.0-MacOSX-x86_64.sh
15 | [Windows]: https://github.com/robots-from-jupyter/robotlab/releases/download/v2019.9.0/RobotLab-2019.9.0-Windows-x86_64.exe
16 | [release-notes]: https://github.com/robots-from-jupyter/robotlab/releases/tag/v2019.9.0
17 |
18 | ## Install RobotLab
19 | > You'll want at least 2GB available to install and run RobotLab
20 |
21 | - On Windows, double-click the installer
22 | - We recommend:
23 | - _don't_ add RobotLab to your `PATH`
24 | - _don't_ register RobotLab's python
25 | - On Linux/MacOSX
26 | - `bash RobotLab-*.sh`
27 | - follow the prompts
28 | - _don't_ install into your shell
29 |
30 | > **Remember** where you install RobotLab!
31 | >
32 | > We recommend someplace
33 | - **short**, e.g. `C:\robotlab` or `/home/myuser/robotlab`
34 | - with **no spaces** in the path, e.g. ~~`c:\Robot Lab`~~
35 | - **not shared** on something like Dropbox, or a network drive
36 |
37 |
38 | ## Run RobotLab
39 | During installation, RobotLab will try to create a desktop icon:
40 |
41 |
42 | ### _There is an icon on my desktop/menu_
43 | Click it to launch the RobotLab server in a console window. It will also attempt
44 | to launch the bundled Firefox. The application log will keep running in the
45 | background, and sometimes useful information will appear there.
46 |
47 | ### _Nope, no icon here_
48 | If you don't see an icon, launch a console, e.g. `bash` on Linux/MacOSX or
49 | `cmd.exe` on Windows.
50 |
51 | | | Linux/MacOSX | Windows
52 | |--|-|
53 | | start a prompt | open your terminal or console application | open `cmd.exe` from the start menu |
54 | | activate the robotlab environment | type `source /path/to/robolab/bin/activate` press ENTER | type `c:\path\to\robotlab\Scripts\activate` press ENTER
55 | | start robotlab | type `robotlab` press ENTER | type `robotlab` press ENTER
56 |
57 | ## _Still didn't work_
58 | If you're still stuck, open [an issue][robotlab-issues]. There should be some
59 | template information to provide.
60 |
61 | ## Advanced RobotLab Commands and Invocations
62 | ```bash
63 | # assuming you've already `activate`d
64 | robotlab [.] # basically just jupyterlab
65 | robotlab-tutorial [.] # copy the robotkernel tutorial to this directory
66 | robotlab-examples [.] # " " " examples " " "
67 | robotlab-shortcuts
68 | ```
69 |
70 | ## Uninstall RobotLab
71 | - Delete the installation directory.
72 | - Delete any desktop shortcuts.
73 | - That is all.
74 |
75 | ## Motivation
76 | While [Robot Framework][robotframework] has no dependencies beyond the Python
77 | standard library, using it for non-trivial testing or process automation usually
78 | requires a fair number of additional Python dependencies, and even some more
79 | exotic ones. We wanted to run a workshop for [RoboCon][] 2019 and show interactive
80 | editing/running with [robotkernel][].
81 |
82 | The focus of this workshop, running Robot tests and tasks interactively, required
83 | the Jupyter stack. To demonstrate some of its more advanced features, some fairly
84 | extensive extra libraries from both the Robot Framework and the scientific Python
85 | ecosystems were needed, and getting these to install smoothly on every attendee's
86 | computers can prove to be... interesting.
87 |
88 | To make a three-hour workshop reasonable, we needed a distribution approach that
89 | was:
90 | - easy to start, to that we could get to the Good Stuff
91 | - cross-platform, so that everyone could follow along
92 | - self-contained, so that it could be easily removed
93 | - offline-capable, so that we could handle intermittent network access
94 | - hackable by the user, so that we could fix Surprise Features
95 |
96 | > ### _Field Notes_
97 | >
98 | > _At our 2019 workshop, graciously hosted by [Siili][], (whose network was super fast!)
99 | > our room full of attendees, on three distributions of Linux, two versions of MacOSX
100 | > and two versions of Windows were all up and running in under 30 minutes. We got
101 | > through all of the [tutorial][] before lunch!_
102 |
103 | ## Tools
104 | RobotLab is built with:
105 | - [conda][], an OS-agnostic package manager
106 | - [anaconda-project][], a multi-environment manager and command executor
107 | - [conda-build][], the conda package builder
108 | - [constructor][conda-constructor], the installer-builder of conda packages
109 | - [azure pipelines][azure-pipelines], a continuous integration provider
110 |
111 |
112 | ## conda packaging
113 | Once it has matured, `robotkernel` will be available from [conda-forge][], the
114 | community-driven upstream of the Anaconda Distribution, which is also built
115 | with [constructor][conda-constructor].
116 |
117 | So for the RobotLab installers, and supporting examples and tutorials, we need to
118 | build a number of dependencies.
119 |
120 | ### robotlab
121 | [JupyterLab][]'s build chain has some negative externalities
122 | for end users, namely an install- or run-time dependency on NodeJS and npmjs.org
123 | when using any labextensions other than the built-in set (e.g. Notebook, Terminal,
124 | Console, Editor, etc.). Because, for the purposes of the workshop, we want to
125 | get to the Good Stuff of running Robot notebooks and not spend a bunch of time
126 | debugging `nodejs` and `webpack`, we've added a few choice JupyterLab extensions:
127 |
128 | - `jupyterlab_robotmode`: syntax highlighting for Robot Framework
129 | - `jupyterlab-jupytext`: ipynb/text pairing for your notebook
130 | - `@jupyterlab/toc`: a table of contents pane for Markdown headers
131 | - `@jupyter-widgets/jupyterlab-manager`: because widgets are always good
132 |
133 | All of these are built outside of the `conda-build` cycle.
134 |
135 | This asset, and all our dependencies, are wrapped into a conda package which
136 | exposes some useful commands, which can do most of the things `jupyter lab` can do,
137 | as well as create desktop shortcuts, and unpack the tutorial content.
138 |
139 | `robotlab` works like `jupyter lab`, while `robotlab-extension` works like
140 | `jupyter labextension`. This isn't a toy installation: with the bundled `nodejs`,
141 | an intrepid user can still install any of the [labextensions][] that are
142 | compatible with the version `robotlab` was built with: as of writing, `1.1.x`.
143 |
144 | ## [constructor][conda-constructor]
145 | All of the dependencies are captured in [construct.yaml.in][].
146 | In addition to required dependencies, a number of extra libraries are included to
147 | showcase some of the features of using Robot Framework interactively.
148 | - `JupyterLibrary` for testing Jupyter clients with robotframework
149 | - `SeleniumLibrary` for controlling browsers
150 | - `geckodriver` for interacting with...
151 | - `firefox`, the open source web browser
152 | - `opencv` for image-driven testing
153 | - `RESTInstance` for testing REST APIs, including swagger
154 |
155 | ## On Browsers and WebDrivers
156 | RobotLab includes Mozilla Firefox and `geckodriver`, with versions that will be
157 | supported for _years_, not _weeks_, by a team that is committed to open source
158 | and web standards.
159 |
160 | ### webdriver for Microsoft Internet Explorer
161 | It's pretty easy to [get `webdriver`][webdriver] for Microsoft Edge, but...
162 | - it but can't be redistributed
163 | - it has to match the version of Edge/Explorer exactly
164 |
165 | ### chromedriver for Google Chrome
166 | It's also pretty easy to get [chromedriver][] for Google Chrome, but...
167 | - it has to match the version of Chrome exactly
168 |
169 | # Work On RobotLab
170 | Contributions are welcome! See the [issues][] for outstanding work we've been
171 | discussing.
172 |
173 | > - Get [Miniconda][]
174 | > - Install [anaconda-project][]
175 | > - Clone [this repo][robotlab]
176 |
177 | From the command line e.g. `bash` or `cmd.exe` or the `Anaconda Prompt`, run:
178 | ```bash
179 | anaconda-project run build:lab
180 | anaconda-project run build
181 | ```
182 |
183 | ## Test Robotlab
184 | ```bash
185 | anaconda-project run test
186 | ```
187 |
188 | ## Checking RobotLab
189 |
190 | ```bash
191 | anaconda-project run lint
192 | anaconda-project run integrity
193 | ```
194 |
195 | [anaconda-project]: https://github.com/anaconda-platform/anaconda-project
196 | [azure-pipelines]: https://azure.microsoft.com/en-us/services/devops/pipelines/
197 | [build-badge]: https://dev.azure.com/robots-from-jupyter/robots-from-jupyter/_apis/build/status/robots-from-jupyter.robotlab?branchName=master
198 | [build-status]: https://dev.azure.com/robots-from-jupyter/robots-from-jupyter/_build/latest?definitionId=3?branchName=master
199 | [chromedriver]: https://chromedriver.chromium.org/downloads
200 | [conda-build]: https://github.com/conda/conda-build
201 | [conda-constructor]: https://github.com/conda/constructor
202 | [conda-forge]: https://github.com/conda-forge
203 | [conda]: https://github.com/conda/conda
204 | [construct.yaml.in]: ./constructor/construct.yaml.in
205 | [Firefox]: https://www.mozilla.org/en-US/firefox/
206 | [jupyterlab]: https://jupyterlab.readthedocs.io
207 | [labextensions]: https://www.npmjs.com/search?q=keywords:jupyterlab-extension
208 | [Miniconda]: https://conda.io/miniconda.html
209 | [RoboCon]: https://robocon.io
210 | [robotframework]: https://github.com/robotframework/robotframework
211 | [robotkernel]: https://github.com/robots-from-jupyter/robotkernel
212 | [robotlab]: https://github.com/robots-from-jupyter/robotlab
213 | [robotlab-issues]: https://github.com/robots-from-jupyter/robotlab/issues
214 | [Siili]: https://siili.com
215 | [tutorial]: https://github.com/robots-from-jupyter/robotkernel/tree/master/docs/notebooks
216 | [webdriver]: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/#downloads
217 |
--------------------------------------------------------------------------------
/recipes/robotframework/70af9e3bab0217b0450d78c69e6c2ccb8f9c342d.patch:
--------------------------------------------------------------------------------
1 | From 70af9e3bab0217b0450d78c69e6c2ccb8f9c342d Mon Sep 17 00:00:00 2001
2 | From: =?UTF-8?q?Pekka=20Kl=C3=A4rck?=
3 | Date: Tue, 22 Oct 2019 21:53:33 +0300
4 | Subject: [PATCH] Python 3.8 utest fixes: Consistent XML attributes order
5 |
6 | ---
7 | utest/result/golden.xml | 24 ++++++-------
8 | utest/result/goldenTwice.xml | 50 +++++++++++++--------------
9 | utest/result/test_resultserializer.py | 3 ++
10 | 3 files changed, 40 insertions(+), 37 deletions(-)
11 |
12 | diff --git a/utest/result/golden.xml b/utest/result/golden.xml
13 | index 6703b889b..a8e0b706c 100644
14 | --- a/utest/result/golden.xml
15 | +++ b/utest/result/golden.xml
16 | @@ -1,9 +1,9 @@
17 |
18 |
19 | -
20 | -
21 | +
22 | +
23 |
24 | -
25 | +
26 |
27 |
28 |
29 | @@ -11,8 +11,8 @@
30 |
31 | Test 1
32 |
33 | -Test 1
34 | -
35 | +Test 1
36 | +
37 |
38 |
39 |
40 | @@ -27,21 +27,21 @@
41 | Log on ${TEST NAME}
42 | TRACE
43 |
44 | -
45 | +
46 |
47 | -
48 | +
49 |
50 | Test case documentation
51 |
52 | t1
53 |
54 | -
55 | +
56 |
57 | Normal test cases
58 |
59 | My Value
60 |
61 | -
62 | +
63 |
64 |
65 |
66 | @@ -49,13 +49,13 @@
67 | All Tests
68 |
69 |
70 | -t1
71 | +t1
72 |
73 |
74 | -Normal
75 | +Normal
76 |
77 |
78 |
79 | - Error in file 'normal.html' in table 'Settings': Resource file 'nope' does not exist.
80 | + Error in file 'normal.html' in table 'Settings': Resource file 'nope' does not exist.
81 |
82 |
83 | diff --git a/utest/result/goldenTwice.xml b/utest/result/goldenTwice.xml
84 | index ea60eca81..b5f117079 100644
85 | --- a/utest/result/goldenTwice.xml
86 | +++ b/utest/result/goldenTwice.xml
87 | @@ -1,10 +1,10 @@
88 |
89 |
90 |
91 | -
92 | -
93 | +
94 | +
95 |
96 | -
97 | +
98 |
99 |
100 |
101 | @@ -12,8 +12,8 @@
102 |
103 | Test 1
104 |
105 | -Test 1
106 | -
107 | +Test 1
108 | +
109 |
110 |
111 |
112 | @@ -28,26 +28,26 @@
113 | Log on ${TEST NAME}
114 | TRACE
115 |
116 | -
117 | +
118 |
119 | -
120 | +
121 |
122 | Test case documentation
123 |
124 | t1
125 |
126 | -
127 | +
128 |
129 | Normal test cases
130 |
131 | My Value
132 |
133 | -
134 | +
135 |
136 | -
137 | -
138 | +
139 | +
140 |
141 | -
142 | +
143 |
144 |
145 |
146 | @@ -55,8 +55,8 @@
147 |
148 | Test 1
149 |
150 | -Test 1
151 | -
152 | +Test 1
153 | +
154 |
155 |
156 |
157 | @@ -71,23 +71,23 @@
158 | Log on ${TEST NAME}
159 | TRACE
160 |
161 | -
162 | +
163 |
164 | -
165 | +
166 |
167 | Test case documentation
168 |
169 | t1
170 |
171 | -
172 | +
173 |
174 | Normal test cases
175 |
176 | My Value
177 |
178 | -
179 | +
180 |
181 | -
182 | +
183 |
184 |
185 |
186 | @@ -95,16 +95,16 @@
187 | All Tests
188 |
189 |
190 | -t1
191 | +t1
192 |
193 |
194 | -Normal & Normal
195 | -Normal & Normal.Normal
196 | -Normal & Normal.Normal
197 | +Normal & Normal
198 | +Normal & Normal.Normal
199 | +Normal & Normal.Normal
200 |
201 |
202 |
203 | -Error in file 'normal.html' in table 'Settings': Resource file 'nope' does not exist.
204 | -Error in file 'normal.html' in table 'Settings': Resource file 'nope' does not exist.
205 | +Error in file 'normal.html' in table 'Settings': Resource file 'nope' does not exist.
206 | +Error in file 'normal.html' in table 'Settings': Resource file 'nope' does not exist.
207 |
208 |
209 | diff --git a/utest/result/test_resultserializer.py b/utest/result/test_resultserializer.py
210 | index e55679801..e310cf20f 100644
211 | --- a/utest/result/test_resultserializer.py
212 | +++ b/utest/result/test_resultserializer.py
213 | @@ -15,6 +15,9 @@
214 |
215 | class StreamXmlWriter(XmlWriter):
216 |
217 | + def _order_attrs(self, attrs):
218 | + return sorted(attrs)
219 | +
220 | def _create_output(self, output):
221 | return output
222 |
223 |
--------------------------------------------------------------------------------
/recipes/robotframework-whitelibrary/apache-2.0.txt:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/constructor/ExoRobot/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/constructor/MiniRobot/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/recipes/restinstance/apache-2.0.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------