import sys from pathlib import Path import bs4 from docutils.core import publish_cmdline from invoke import task from rellu import initialize_labels, ReleaseNotesGenerator, Version from rellu.tasks import clean # noqa from robot.libdoc import libdoc assert Path.cwd() == Path(__file__).parent VERSION_PATTERN = '__version__ = "(.*)"' REPOSITORY = "robotframework/SeleniumLibrary" VERSION_PATH = Path("src/SeleniumLibrary/__init__.py") RELEASE_NOTES_PATH = Path("docs/SeleniumLibrary-{version}.rst") RELEASE_NOTES_TITLE = "SeleniumLibrary {version}" RELEASE_NOTES_INTRO = """ SeleniumLibrary_ is a web testing library for `Robot Framework`_ that utilizes the Selenium_ tool internally. SeleniumLibrary {version} is a new release with **UPDATE** enhancements and bug fixes. **ADD more intro stuff...** **REMOVE this section with final releases or otherwise if release notes contain all issues.** All issues targeted for SeleniumLibrary {version.milestone} can be found from the `issue tracker`_. **REMOVE ``--pre`` from the next command with final releases.** If you have pip_ installed, just run :: pip install --pre --upgrade robotframework-seleniumlibrary to install the latest available release or use :: pip install robotframework-seleniumlibrary=={version} to install exactly this version. Alternatively you can download the source distribution from PyPI_ and install it manually. SeleniumLibrary {version} was released on {date}. SeleniumLibrary supports Python **ADD VERSIONS**, Selenium **ADD VERSIONS** and Robot Framework **ADD VERSIONS**. .. _Robot Framework: http://robotframework.org .. _SeleniumLibrary: https://github.com/robotframework/SeleniumLibrary .. _Selenium: http://seleniumhq.org .. _pip: http://pip-installer.org .. _PyPI: https://pypi.python.org/pypi/robotframework-seleniumlibrary .. _issue tracker: https://github.com/robotframework/SeleniumLibrary/issues?q=milestone%3A{version.milestone} """ @task def kw_docs(ctx, version=None): """Generates the library keyword documentation. Args: version: Appends version to the end of the filename. Used for alpha and beta release. Documentation is generated by using the Libdoc tool. """ if version: out = Path(f"docs/SeleniumLibrary-{version}.html") else: out = Path("docs/SeleniumLibrary.html") libdoc(str(Path("src/SeleniumLibrary")), str(out)) with out.open("r") as file: data = file.read() soup = bs4.BeautifulSoup(data, "html.parser") script_async = soup.new_tag( "script", src="https://www.googletagmanager.com/gtag/js?id=UA-106835747-4" ) script_async.attrs["async"] = None soup.head.append(script_async) script_data = soup.new_tag("script") script_data.string = """ window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-106835747-4', { 'anonymize_ip': true, 'page_path': location.pathname+location.search+location.hash }); window.onhashchange = function() { gtag('event', 'HashChange', { 'event_category': 'Subsection', 'event_label': window.location.hash }); } """ soup.head.append(script_data) with out.open("w") as file: file.write(str(soup)) @task def project_docs(ctx): """Generate project documentation. These docs are visible at http://robotframework.org/SeleniumLibrary/. """ args = [ "--stylesheet=style.css,extra.css", "--link-stylesheet", "README.rst", "docs/index.html", ] publish_cmdline(writer_name="html5", argv=args) print(Path(args[-1]).absolute()) @task def set_version(ctx, version): """Set project version in `src/SeleniumLibrary/__init__.py`` file. Args: version: Project version to set or ``dev`` to set development version. Following PEP-440 compatible version numbers are supported: - Final version like 3.0 or 3.1.2. - Alpha, beta or release candidate with ``a``, ``b`` or ``rc`` postfix, respectively, and an incremented number like 3.0a1 or 3.0.1rc1. - Development version with ``.dev`` postfix and an incremented number like 3.0.dev1 or 3.1a1.dev2. When the given version is ``dev``, the existing version number is updated to the next suitable development version. For example, 3.0 -> 3.0.1.dev1, 3.1.1 -> 3.1.2.dev1, 3.2a1 -> 3.2a2.dev1, 3.2.dev1 -> 3.2.dev2. """ version = Version(version, VERSION_PATH, VERSION_PATTERN) version.write() print(version) @task def print_version(ctx): """Print the current project version.""" print(Version(path=VERSION_PATH)) @task def release_notes(ctx, version=None, username=None, password=None, write=False): """Generates release notes based on issues in the issue tracker. Args: version: Generate release notes for this version. If not given, generated them for the current version. username: GitHub username. password: GitHub password. write: When set to True, write release notes to a file overwriting possible existing file. Otherwise just print them to the terminal. Username and password can also be specified using ``GITHUB_USERNAME`` and ``GITHUB_PASSWORD`` environment variable, respectively. If they aren't specified at all, communication with GitHub is anonymous and typically pretty slow. """ version = Version(version, VERSION_PATH, VERSION_PATTERN) file = RELEASE_NOTES_PATH if write else sys.stdout generator = ReleaseNotesGenerator( REPOSITORY, RELEASE_NOTES_TITLE, RELEASE_NOTES_INTRO ) generator.generate(version, username, password, file) @task def init_labels(ctx, username=None, password=None): """Initialize project by setting labels in the issue tracker. Args: username: GitHub username. password: GitHub password. Username and password can also be specified using ``GITHUB_USERNAME`` and ``GITHUB_PASSWORD`` environment variable, respectively. Should only be executed once when taking ``rellu`` tooling to use or when labels it uses have changed. """ initialize_labels(REPOSITORY, username, password) @task def lint(ctx): """Runs black and flake8 for project Python code.""" ctx.run("black --config pyproject.toml tasks.py src/ utest/ atest/") ctx.run("flake8 --config .flake8 tasks.py src/ utest/ atest/") @task def gen_stub(ctx): """Generate stub/.pyi file for SeleniumLibrary/__init__.py. Stub files improves the IDE integration for Python usage. """ ctx.run("python gen_stub.py") @task def atest(ctx, suite=None): """Runs atest/run.py with headlesschrome. Args: suite: Select which suite to run. Example: inv utest --suite keywords/test_browsermanagement.py inv utest --suite keywords/test_selenium_options_parser.py::test_create_chrome_with_options """ command = "python atest/run.py headlesschrome" if suite: command = f"{command} --suite {suite}" ctx.run(command) @task def utest(ctx, suite=None): """Runs utest/run.py Args: suite: Select which suite to run. """ command = f"{sys.executable} utest/run.py" if suite: command = f"{command} --suite {suite}" ctx.run(command)