import os
import sys
import uuid
sys.path.append(os.getcwd())

import selenium.webdriver.common.by as by
from selenium.webdriver.support.ui import WebDriverWait

from base import UITestCase


_ordered_counter = 0


def ordered(func):
    global _ordered_counter
    func.counter = _ordered_counter
    _ordered_counter += 1
    return func


class OrderedMethodMetaclass(type):
    prefix = 'test_'

    def __new__(meta, name, bases, dct):
        test_methods, other = [], []
        for key, value in dct.items():
            if key.startswith(meta.prefix):
                test_methods.append((key, value))
            else:
                other.append((key, value))
        test_methods = sorted(test_methods, key=lambda pair: pair[1].counter)
        prefix_len = len(meta.prefix)
        dct = {}
        for index, (method_name, method) in enumerate(test_methods):
            method_name = '{0}{1:03d}_{2}'.format(
                meta.prefix, index, method_name[prefix_len:])
            delattr(method, 'counter')
            dct[method_name] = method

        dct.update(dict(other))
        return super(OrderedMethodMetaclass, meta).__new__(
            meta, name, bases, dct)


class OrderedMethodsUITestCase(UITestCase):
    __metaclass__ = OrderedMethodMetaclass


class TestSuiteOneSmokeTests(OrderedMethodsUITestCase):
    """This class keeps smoke tests which check operability of all main panels
    """
    @ordered
    def test_smoke_environments_panel(self):
        self.go_to_submenu('Environments')

        self.assertIn('Environments',
                      self.driver.find_element_by_xpath(
                          ".//*[@class='page-header']").text)

    @ordered
    def test_smoke_applications_panel(self):
        self.go_to_submenu('Applications')

        self.assertIn('Applications',
                      self.driver.find_element_by_xpath(
                          ".//*[@class='page-header']").text)

    @ordered
    def test_smoke_statistics_panel(self):
        self.go_to_submenu('Statistics')

        self.assertIn('Murano Status',
                      self.driver.find_element_by_xpath(
                          ".//*[@class='page-header']").text)

    @ordered
    def test_smoke_images_panel(self):
        self.navigate_to('Manage')
        self.go_to_submenu('Images')

        self.assertIn('Marked Images',
                      self.driver.find_element_by_xpath(
                          ".//*[@class='page-header']").text)

    @ordered
    def test_smoke_package_definitions_panel(self):
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')

        self.assertIn('Package Definitions',
                      self.driver.find_element_by_xpath(
                          ".//*[@class='page-header']").text)


class TestSuiteTwoSanityTests(OrderedMethodsUITestCase):
    @ordered
    def test_create_delete_environment(self):
        """Test check ability to create and delete environment

        Scenario:
            1. Create environment
            2. Navigate to this environment
            3. Go back to environment list and delete created environment
        """
        self.go_to_submenu('Environments')
        self.create_environment('test_create_del_env')

        self.delete_environment('test_create_del_env')
        self.assertFalse(self.check_element_on_page(by.By.LINK_TEXT,
                                                    'test_create_del_env'))

    @ordered
    def test_edit_environment(self):
        """Test check ability to change environment name

        Scenario:
            1. Create environment
            2. Change environment's name
            3. Check that there is renamed environment is in environment list
        """
        self.go_to_submenu('Environments')
        self.create_environment('test_edit_env')
        self.go_to_submenu('Environments')
        self.driver.find_element_by_link_text('test_edit_env')

        self.edit_environment(old_name='test_edit_env', new_name='edited_env')
        self.assertTrue(self.check_element_on_page(by.By.LINK_TEXT,
                                                   'edited_env'))
        self.assertFalse(self.check_element_on_page(by.By.LINK_TEXT,
                                                    'test_edit_env'))

    @ordered
    def test_rename_image(self):
        """Test check ability to mark murano image

        Scenario:
            1. Navigate to Images page
            2. Click on button "Mark Image"
            3. Fill the form and submit it
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Images')
        self.driver.find_element_by_id(
            'marked_images__action_mark_image').click()

        self.select_from_list('image', 'TestImageForDeletion')
        self.fill_field(by.By.ID, 'id_title', 'New Image')
        self.select_from_list('type', 'Murano Demo')

        self.select_and_click_element('Mark')

    @ordered
    def test_delete_image(self):
        """Test check ability to delete image

        Scenario:
            1. Navigate to Images page
            2. Create test image
            3. Select created image and click on "Delete Metadata"
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Images')
        self.driver.find_element_by_id(
            'marked_images__action_mark_image').click()

        self.select_from_list('image', 'TestImageForDeletion')
        self.fill_field(by.By.ID, 'id_title', 'Image for deletion')
        self.select_from_list('type', 'Murano Demo')

        self.select_and_click_element('Mark')

        element_id = self.get_element_id('TestImageForDeletion')
        self.driver.find_element_by_id(
            "marked_images__row_%s__action_delete" % element_id).click()
        self.confirm_deletion()
        self.assertFalse(self.check_element_on_page(by.By.LINK_TEXT,
                                                    'TestImageForDeletion'))

    @ordered
    def test_check_image_info(self):
        """Test check ability to view image details

        Scenario:
            1. Navigate to Images page
            2. Create test image
            3. Click on the name of selected image, check image info
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Images')
        self.driver.find_element_by_id(
            'marked_images__action_mark_image').click()

        self.image_title = "TestImage-{0}".format(uuid.uuid4())
        self.select_from_list('image', 'TestImageForDeletion')
        self.fill_field(by.By.ID, 'id_title', self.image_title)
        self.select_from_list('type', 'Murano Demo')

        self.select_and_click_element('Mark')

        self.driver.find_element_by_link_text('TestImageForDeletion').click()
        self.assertIn("{0}".format(self.image_title),
                      self.driver.page_source)

    @ordered
    def test_check_domain_name_field_validation(self):
        """Test checks that validation of domain name field work
        and appropriate error message is appeared after entering
        incorrect domain name

        Scenario:
            1. Navigate to Environments page
            2. Create environment and start to create MockApp service
            3. Set "a" as a domain name and verify error message
            4. Set "aa" as a domain name and check that error message
            didn't appear
            5. Set "@ct!v3" as a domain name and verify error message
            6. Set "active.com" as a domain name and check that error message
            didn't appear
            7. Set "domain" as a domain name and verify error message
            8. Set "domain.com" as a domain name and check that error message
            didn't appear
            9. Set "morethan15symbols.beforedot" as a domain name and
            verify error message
            10. Set "lessthan15.beforedot" as a domain name and check that
            error message didn't appear
            11. Set ".domain.local" as a domain name and
            verify error message
            12. Set "domain.local" as a domain name and check that
            error message didn't appear
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')
        testapp_id = self.get_element_id('MockApp')

        self.navigate_to('Application_Catalog')
        self.go_to_submenu('Applications')

        self.select_and_click_action_for_app('quick-add', testapp_id)
        field_id = "{0}_0-domain".format(testapp_id)

        self.fill_field(by.By.ID, field_id, value='a')
        self.assertTrue(self.check_that_error_message_is_correct(
            'Ensure this value has at least 2 characters (it has 1).', 1))

        self.fill_field(by.By.ID, field_id, value='aa')
        self.assertFalse(self.check_that_error_message_is_correct(
            'Ensure this value has at least 2 characters (it has 1).', 1))

        self.fill_field(by.By.ID, field_id, value='@ct!v3')
        self.assertTrue(self.check_that_error_message_is_correct(
            'Only letters, numbers and dashes in the middle are allowed.', 1))

        self.fill_field(by.By.ID, field_id, value='active.com')
        self.assertFalse(self.check_that_error_message_is_correct(
            'Only letters, numbers and dashes in the middle are allowed.', 1))

        self.fill_field(by.By.ID, field_id, value='domain')
        self.assertTrue(self.check_that_error_message_is_correct(
            'Single-level domain is not appropriate.', 1))

        self.fill_field(by.By.ID, field_id, value='domain.com')
        self.assertFalse(self.check_that_error_message_is_correct(
            'Single-level domain is not appropriate.', 1))

        self.fill_field(by.By.ID, field_id,
                        value='morethan15symbols.beforedot')
        self.assertTrue(self.check_that_error_message_is_correct(
            'NetBIOS name cannot be shorter than'
            ' 1 symbol and longer than 15 symbols.', 1))

        self.fill_field(by.By.ID, field_id,
                        value='lessthan15.beforedot')
        self.assertFalse(self.check_that_error_message_is_correct(
            'NetBIOS name cannot be shorter than'
            ' 1 symbol and longer than 15 symbols.', 1))

        self.fill_field(by.By.ID, field_id, value='.domain.local')
        self.assertTrue(self.check_that_error_message_is_correct(
            'Period characters are allowed only when '
            'they are used to delimit the components of domain style names',
            1))

        self.fill_field(by.By.ID, field_id, value='domain.local')
        self.assertFalse(self.check_that_error_message_is_correct(
            'Period characters are allowed only when '
            'they are used to delimit the components of domain style names',
            1))

    @ordered
    def test_check_app_name_validation(self):
        """Test checks validation of field that usually define
        application name

        Scenario:
            1. Navigate to Application Catalog > Applications
            2. Start to create Mock App
            3. Check a set of names, if current name isn't valid
            appropriate error message should appears
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')
        testapp_id = self.get_element_id('MockApp')

        self.navigate_to('Application_Catalog')
        self.go_to_submenu('Applications')

        self.select_and_click_action_for_app('quick-add', testapp_id)
        field_id = "{0}_0-name".format(testapp_id)

        self.fill_field(by.By.ID, field_id, value='a')
        self.assertTrue(self.check_that_error_message_is_correct(
            'Ensure this value has at least 2 characters (it has 1).', 1))

        self.fill_field(by.By.ID, field_id, value='@pp')
        self.assertTrue(self.check_that_error_message_is_correct(
            'Just letters, numbers, underscores and hyphens are allowed.', 1))

        self.fill_field(by.By.ID, field_id, value='AppL1')
        self.driver.find_element_by_xpath(
            self.elements.get('button', 'ButtonSubmit')).click()
        WebDriverWait(self.driver, 10).until(lambda s: s.find_element(
            by.By.LINK_TEXT, '+').is_displayed())

    @ordered
    def test_check_required_field(self):
        """Test checks that fields with parameter 'required=True' in yaml form
        are truly required and can't be omitted

        Scenario:
            1. Navigate to Application Catalog > Applications
            2. Start to create MockApp
            3. Don't type app name in the 'Application Name'
            field that is required and click 'Next',check that there is
            error message
            4. Set app name and click 'Next',
            check that there is no error message
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')
        testapp_id = self.get_element_id('MockApp')

        self.navigate_to('Application_Catalog')
        self.go_to_submenu('Applications')

        self.select_and_click_action_for_app('quick-add', testapp_id)

        self.driver.find_element_by_xpath(
            self.elements.get('button', 'ButtonSubmit')).click()
        self.assertTrue(self.check_that_error_message_is_correct(
            'This field is required.', 1))

        self.fill_field(by.By.ID, "{0}_0-name".format(testapp_id), "name")
        self.driver.find_element_by_xpath(
            self.elements.get('button', 'ButtonSubmit')).click()

        WebDriverWait(self.driver, 10).until(lambda s: s.find_element(
            by.By.LINK_TEXT, '+').is_displayed())

    @ordered
    def test_integer_field_validation(self):
        """Test checks that only numbers can be written in integer field

        Scenario:
            1. Navigate to Application Catalog > Applications
            2. Start to create MockApp
            3. Set random string in the integer field and verify error message
            4. Set number from allowable range in the integer field,
            check that there is no error message
            5. Set number that not in allowable range and check error message
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')
        testapp_id = self.get_element_id('MockApp')

        self.navigate_to('Application_Catalog')
        self.go_to_submenu('Applications')

        self.select_and_click_action_for_app('quick-add', testapp_id)
        field_id = "{0}_0-integer".format(testapp_id)

        self.fill_field(by.By.ID, "{0}_0-name".format(testapp_id), "name")

        self.fill_field(by.By.ID, field_id, value='0')
        self.assertTrue(self.check_that_error_message_is_correct(
            'Ensure this value is greater than or equal to 1.', 1))

        self.fill_field(by.By.ID, field_id, value='101')
        self.assertTrue(self.check_that_error_message_is_correct(
            'Ensure this value is less than or equal to 100.', 1))

        self.fill_field(by.By.ID, field_id, value='aaa')
        self.assertTrue(self.check_that_error_message_is_correct(
            'Enter a whole number.', 1))

        self.fill_field(by.By.ID, field_id, "55")
        self.driver.find_element_by_xpath(
            self.elements.get('button', 'ButtonSubmit')).click()

        WebDriverWait(self.driver, 10).until(lambda s: s.find_element(
            by.By.LINK_TEXT, '+').is_displayed())

    @ordered
    def test_password_validation(self):
        """Test checks password validation

        Scenario:
            1. Navigate to Application Catalog > Applications
            2. Start to create MockApp
            3. Set weak password consisting of numbers,
            check that error message appears
            4. Set different passwords to Password field and Confirm password
            field, check that validation failed
            5. Set correct password. Validation has to pass
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')
        testapp_id = self.get_element_id('MockApp')

        self.navigate_to('Application_Catalog')
        self.go_to_submenu('Applications')

        self.select_and_click_action_for_app('quick-add', testapp_id)
        field_id = "{0}_0-adminPassword".format(testapp_id)

        self.fill_field(by.By.ID, "{0}_0-name".format(testapp_id), "name")

        self.fill_field(by.By.ID, field_id, value='123456')
        self.assertTrue(self.check_that_error_message_is_correct(
            'The password must contain at least one letter', 1))
        self.driver.find_element_by_xpath(
            self.elements.get('button', 'ButtonSubmit')).click()
        self.fill_field(by.By.ID, "{0}-clone".format(field_id),
                        value='P@ssw0rd')
        self.assertFalse(self.check_that_error_message_is_correct(
            'Passwords do not match', 1))
        self.fill_field(by.By.ID, field_id, value='P@ssw0rd')
        self.driver.find_element_by_xpath(
            self.elements.get('button', 'ButtonSubmit')).click()
        WebDriverWait(self.driver, 10).until(lambda s: s.find_element(
            by.By.LINK_TEXT, '+').is_displayed())

    @ordered
    def test_check_transitions_from_one_wizard_to_another(self):
        """Test checks that transitions "Next" and "Back" are not broken

        Scenario:
            1. Navigate to Application Catalog > Applications
            2. Start to create MockApp
            3. Set app name and click on "Next", check that second wizard step
            will appear
            4. Click 'Back' and check that first wizard step is shown
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')
        testapp_id = self.get_element_id('MockApp')

        self.navigate_to('Application_Catalog')
        self.go_to_submenu('Applications')

        self.select_and_click_action_for_app('quick-add', testapp_id)

        self.fill_field(by.By.ID, "{0}_0-name".format(testapp_id), "name")
        self.driver.find_element_by_xpath(
            self.elements.get('button', 'ButtonSubmit')).click()

        WebDriverWait(self.driver, 10).until(lambda s: s.find_element(
            by.By.LINK_TEXT, '+').is_displayed())

        self.driver.find_element_by_id(
            'wizard_{0}_btn'.format(testapp_id)).click()

        WebDriverWait(self.driver, 10).until(lambda s: s.find_element(
            by.By.ID, "{0}_0-name".format(testapp_id)).is_displayed())

    @ordered
    def test_check_ability_create_two_dependent_apps(self):
        """Test checks that using one creation form it is possible to
        add to related apps in the one environment

        Scenario:
            1. Navigate to Application Catalog > Applications
            2. Start to create MockApp
            3. Set app name and click on "Next"
            4. Click '+' and verify that creation of second app is possible
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')
        testapp_id = self.get_element_id('MockApp')

        self.navigate_to('Application_Catalog')
        self.go_to_submenu('Applications')

        self.select_and_click_action_for_app('quick-add', testapp_id)

        self.fill_field(by.By.ID, "{0}_0-name".format(testapp_id), "app1")
        self.driver.find_element_by_xpath(
            self.elements.get('button', 'ButtonSubmit')).click()

        self.driver.find_element_by_link_text('+').click()
        self.fill_field(by.By.ID, "{0}_0-name".format(testapp_id), "app2")

    @ordered
    def test_creation_deletion_app(self):
        """Test check ability to create and delete test app

        Scenario:
            1. Navigate to 'Application Catalog'
            2. Click on 'Quick Deploy' for MockApp application
            3. Create TestApp app by filling the creation form
            4. Delete TestApp app from environment
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')
        testapp_id = self.get_element_id('MockApp')

        self.navigate_to('Application_Catalog')
        self.go_to_submenu('Applications')

        self.select_and_click_action_for_app('quick-add', testapp_id)

        self.fill_field(by.By.ID, '{0}_0-name'.format(testapp_id), 'TestA')
        self.driver.find_element_by_xpath(
            self.elements.get('button', 'ButtonSubmit')).click()

        self.driver.find_element_by_xpath(
            self.elements.get('button', 'InputSubmit')).click()

        self.select_from_list('2-osImage', self.linux_image)
        self.driver.find_element_by_xpath(
            self.elements.get('button', 'InputSubmit')).click()

        self.assertTrue(self.check_element_on_page(by.By.LINK_TEXT,
                                                   'TestA'))
        self.delete_component('TestA')
        self.assertFalse(self.check_element_on_page(by.By.LINK_TEXT,
                                                    'TestA'))

    @ordered
    def test_modify_package_name(self):
        """Test check ability to change name of the package

        Scenario:
            1. Navigate to 'Package Definitions' page
            2. Select package and click on 'Modify Package'
            3. Rename package
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')
        self.select_action_for_package('PostgreSQL',
                                       'modify_package')
        self.fill_field(by.By.ID, 'id_name', 'PostgreSQL-modified')
        self.driver.find_element_by_xpath(
            self.elements.get('button', 'InputSubmit')).click()

        self.assertTrue(self.check_element_on_page(
            by.By.XPATH, './/*[@data-display="PostgreSQL-modified"]'))

        self.select_action_for_package('PostgreSQL-modified',
                                       'modify_package')
        self.fill_field(by.By.ID, 'id_name', 'PostgreSQL')
        self.driver.find_element_by_xpath(
            self.elements.get('button', 'InputSubmit')).click()

        self.assertTrue(self.check_element_on_page(
            by.By.XPATH, './/*[@data-display="PostgreSQL"]'))

    @ordered
    def test_modify_package_add_tag(self):
        """Test check ability to add file in composed service

        Scenario:
            1. Navigate to 'Package Definitions' page
            2. Click on "Compose Service"  and create new service
            3. Manage composed service: add file
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')
        self.select_action_for_package('PostgreSQL',
                                       'modify_package')

        self.fill_field(by.By.ID, 'id_tags', 'TEST_TAG')
        self.modify_package('tags', 'TEST_TAG')

        app_id = self.get_element_id('PostgreSQL')

        self.navigate_to('Application_Catalog')
        self.go_to_submenu('Applications')
        self.select_and_click_action_for_app('details', app_id)
        self.check_element_on_page(
            ".//*[@id='content_body']/div[2]/div/div/div[2]/div[2]/ul/li[6]",
            'TEST_TAG')

    @ordered
    def test_download_package(self):
        """Test check ability to download package from repository

        Scenario:
            1. Navigate to 'Package Definitions' page
            2. Select PostgreSQL package and click on "More>Download Package"
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')

        self.select_action_for_package('PostgreSQL', 'more')
        self.select_action_for_package('PostgreSQL', 'download_package')

    @ordered
    def test_check_opportunity_to_toggle_package(self):
        """Test check ability to make package active or inactive

        Scenario:
            1. Navigate to 'Package Definitions' page
            2. Select some package and make it inactive ("More>Toggle Package")
            3. Check that package became inactive
            4. Select some package and make it active ("More>Toggle Package ")
            5. Check that package became active
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')

        self.select_action_for_package('PostgreSQL', 'more')
        self.select_action_for_package('PostgreSQL', 'toggle_enabled')

        self.assertTrue(self.check_package_parameter(
            'PostgreSQL', '3', 'False'))

        self.select_action_for_package('PostgreSQL', 'more')
        self.select_action_for_package('PostgreSQL', 'toggle_enabled')

        self.assertTrue(self.check_package_parameter(
            'PostgreSQL', '3', 'True'))

    @ordered
    def test_check_info_about_app(self):
        """Test checks that information about app is available and truly.

        Scenario:
            1. Navigate to 'Application Catalog > Applications' panel
            2. Choose some application and click on 'More info'
            3. Verify info about application
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')

        app_id = self.get_element_id('PostgreSQL')

        self.navigate_to('Application_Catalog')
        self.go_to_submenu('Applications')
        self.select_and_click_action_for_app('details', app_id)

        self.assertIn('PostgreSQL is a powerful', self.driver.page_source)
        self.driver.find_element_by_link_text('Requirements').click()
        self.driver.find_element_by_link_text('License').click()

    @ordered
    def test_check_search_option(self):
        """Test checks that 'Search' option is operable.

        Scenario:
            1. Navigate to 'Application Catalog > Applications' panel
            2. Set search criterion in the search field(e.g 'Telnet')
            3. Click on 'Filter' and check result
        """
        self.go_to_submenu('Applications')
        self.fill_field(by.By.NAME, 'search', 'Telnet')
        self.driver.find_element_by_id('apps__action_filter').click()

        self.assertIn('Telnet', self.driver.page_source)
        self.assertNotIn('PostgreSQL', self.driver.page_source)

    @ordered
    def test_filter_by_category(self):
        """Test checks ability to filter applications by category
        in Application Catalog page

        Scenario:
            1. Navigate to 'Application Catalog' panel
            2. Select 'Databases' category in 'App Category' dropdown menu
            3. Verify that PostgreSQL is shown
            4. Select 'Microsoft Services' category in
            'App Category' dropdown menu
            5. Verify that AD is shown
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')

        package_category1 = self.get_element_id('PostgreSQL')
        package_category2 = self.get_element_id('Active Directory')

        self.navigate_to('Application_Catalog')
        self.go_to_submenu('Applications')
        self.driver.find_element_by_xpath(".//*[@href='#']").click()
        self.driver.find_element_by_link_text('Databases').click()

        self.assertTrue(self.check_element_on_page(
            by.By.XPATH, ".//*[@href='/{0}/murano/catalog/details/{1}']".
            format(self.url_prefix, package_category1)))

        self.driver.find_element_by_xpath(".//*[@href='#']").click()
        self.driver.find_element_by_link_text('Microsoft Services').click()

        self.assertTrue(self.check_element_on_page(
            by.By.XPATH, ".//*[@href='/{0}/murano/catalog/details/{1}']".
            format(self.url_prefix, package_category2)))

    @ordered
    def test_check_option_switch_env(self):
        """Test checks ability to switch environment and add app in other env

        Scenario:
            1. Navigate to 'Application Catalog>Environments' panel
            2. Create environment 'env1'
            3. Create environment 'env2'
            4. Navigate to 'Application Catalog>Application Catalog'
            5. Click on 'Environment' panel
            6. Switch to env2
            7. Add application in env2
            8. Navigate to 'Application Catalog>Environments'
            and go to the env2
            9. Check that added application is here
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')

        testapp_id = self.get_element_id('MockApp')

        self.navigate_to('Application_Catalog')
        self.go_to_submenu('Environments')
        self.create_environment('env1')
        self.go_to_submenu('Environments')
        self.assertTrue(self.check_element_on_page(by.By.LINK_TEXT,
                                                   'env1'))
        self.create_environment('env2')
        self.go_to_submenu('Environments')
        self.assertTrue(self.check_element_on_page(by.By.LINK_TEXT,
                                                   'env2'))

        env_id = self.get_element_id('env2')

        self.go_to_submenu('Applications')
        self.driver.find_element_by_xpath(
            ".//*[@id='environment_switcher']/a").click()

        self.driver.find_element_by_link_text("env2").click()

        self.select_and_click_action_for_app(
            'add', '{0}/{1}'.format(testapp_id, env_id))

        self.fill_field(by.By.ID, '{0}_0-name'.format(testapp_id), 'TestA')
        self.driver.find_element_by_xpath(
            self.elements.get('button', 'ButtonSubmit')).click()

        self.driver.find_element_by_xpath(
            self.elements.get('button', 'InputSubmit')).click()

        self.select_from_list('2-osImage', self.linux_image)
        self.driver.find_element_by_xpath(
            self.elements.get('button', 'InputSubmit')).click()

        self.driver.find_element_by_xpath(
            self.elements.get('button', 'InputSubmit')).click()

        self.assertTrue(self.check_element_on_page(by.By.LINK_TEXT,
                                                   'TestA'))

    @ordered
    def test_modify_description(self):
        """Test check ability to change description of the package

        Scenario:
            1. Navigate to 'Package Definitions' page
            2. Select package and click on 'Modify Package'
            3. Change description
        """
        self.navigate_to('Manage')
        self.go_to_submenu('Package Definitions')
        self.select_action_for_package('PostgreSQL',
                                       'modify_package')

        self.modify_package('description', 'New Description')

        self.navigate_to('Application_Catalog')
        self.go_to_submenu('Applications')
        self.check_element_on_page(
            ".//*[@class='app-description']",
            'New Description')
