# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

AUTHOR = "Chrome OS Team"
NAME = "PyAuto Basic"
TIME = "SHORT"
TEST_CATEGORY = "Functional"
TEST_CLASS = "suite"
TEST_TYPE = "server"

DOC = """
This test suite runs pyauto-based tests (other than the ones in
desktopui_PyAutoFunctionalTests).
desktopui_PyAutoFunctionalTests contains the chrome tests that expect chrome
to be logged in.  The set of tests in this suite can have login as a part of
their usecase.
"""


# Uses pyauto in autotest tests
TESTS = [
    'desktopui_UrlFetch',
# crosbug.com/20024
#    'desktopui_PyAutoChromeFirstRender',
]

# Produces gtest-style output
GTESTS = [
    ('desktopui_PyAutoFunctionalTests', {
        'suite': 'CHROMEOS_LOGIN',
        'auto_login': False,
        'as_chronos': False,
        'tag': 'CHROMEOS_LOGIN',
    }),
    ('desktopui_PyAutoFunctionalTests', {
        'suite': 'CHROMEOS_VOLUME',
        'auto_login': False,
        'as_chronos': False,
        'tag': 'CHROMEOS_VOLUME',
    }),
    ('desktopui_PyAutoFunctionalTests', {
        'suite': 'CHROMEOS_FLASH',
        'auto_login': True,
        'as_chronos': True,
        'tag': 'CHROMEOS_FLASH',
    }),
]


def run_client_test(machine):
    client = hosts.create_host(machine)
    client_at = autotest.Autotest(client)
    for test in TESTS:
        client_at.run_test(test)

    for test in GTESTS:
        gtest_runner.run(test, machine)


job.parallel_on_machines(run_client_test, machines)
