#! /usr/bin/env python3 #
# BitBake Toaster UI tests implementation
#
# Copyright (C) 2023 Savoir-faire Linux
#
# SPDX-License-Identifier: GPL-2.0-only
#

import os
import random
import string
from unittest import skip
import pytest
from django.urls import reverse
from django.utils import timezone
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.select import Select
from selenium.common.exceptions import TimeoutException
from tests.functional.functional_helpers import SeleniumFunctionalTestCase
from orm.models import Build, Project, Target
from selenium.webdriver.common.by import By

from .utils import get_projectId_from_url, wait_until_build, wait_until_build_cancelled


@pytest.mark.django_db
@pytest.mark.order("last")
class TestProjectPage(SeleniumFunctionalTestCase):
    project_id = None
    PROJECT_NAME = 'TestProjectPage'

    def _create_project(self, project_name):
        """ Create/Test new project using:
          - Project Name: Any string
          - Release: Any string
          - Merge Toaster settings: True or False
        """
        self.get(reverse('newproject'))
        self.wait_until_visible('#new-project-name')
        self.find("#new-project-name").send_keys(project_name)
        select = Select(self.find("#projectversion"))
        select.select_by_value('3')

        # check merge toaster settings
        checkbox = self.find('.checkbox-mergeattr')
        if not checkbox.is_selected():
            checkbox.click()

        if self.PROJECT_NAME != 'TestProjectPage':
            # Reset project name if it's not the default one
            self.PROJECT_NAME = 'TestProjectPage'

        self.find("#create-project-button").click()

        try:
            self.wait_until_visible('#hint-error-project-name')
            url = reverse('project', args=(TestProjectPage.project_id, ))
            self.get(url)
            self.wait_until_visible('#config-nav', poll=3)
        except TimeoutException:
            self.wait_until_visible('#config-nav', poll=3)

    def _random_string(self, length):
        return ''.join(
            random.choice(string.ascii_letters) for _ in range(length)
        )

    def _navigate_to_project_page(self):
        # Navigate to project page
        if TestProjectPage.project_id is None:
            self._create_project(project_name=self._random_string(10))
            current_url = self.driver.current_url
            TestProjectPage.project_id = get_projectId_from_url(current_url)
        else:
            url = reverse('project', args=(TestProjectPage.project_id,))
            self.get(url)
        self.wait_until_visible('#config-nav')

    def _get_create_builds(self, **kwargs):
        """ Create a build and return the build object """
        # parameters for builds to associate with the projects
        now = timezone.now()
        self.project1_build_success = {
            'project': Project.objects.get(id=TestProjectPage.project_id),
            'started_on': now,
            'completed_on': now,
            'outcome': Build.SUCCEEDED
        }

        self.project1_build_failure = {
            'project': Project.objects.get(id=TestProjectPage.project_id),
            'started_on': now,
            'completed_on': now,
            'outcome': Build.FAILED
        }
        build1 = Build.objects.create(**self.project1_build_success)
        build2 = Build.objects.create(**self.project1_build_failure)

        # add some targets to these builds so they have recipe links
        # (and so we can find the row in the ToasterTable corresponding to
        # a particular build)
        Target.objects.create(build=build1, target='foo')
        Target.objects.create(build=build2, target='bar')

        if kwargs:
            # Create kwargs.get('success') builds with success status with target
            # and kwargs.get('failure') builds with failure status with target
            for i in range(kwargs.get('success', 0)):
                now = timezone.now()
                self.project1_build_success['started_on'] = now
                self.project1_build_success[
                    'completed_on'] = now - timezone.timedelta(days=i)
                build = Build.objects.create(**self.project1_build_success)
                Target.objects.create(build=build,
                                      target=f'{i}_success_recipe',
                                      task=f'{i}_success_task')

            for i in range(kwargs.get('failure', 0)):
                now = timezone.now()
                self.project1_build_failure['started_on'] = now
                self.project1_build_failure[
                    'completed_on'] = now - timezone.timedelta(days=i)
                build = Build.objects.create(**self.project1_build_failure)
                Target.objects.create(build=build,
                                      target=f'{i}_fail_recipe',
                                      task=f'{i}_fail_task')
        return build1, build2

    def _mixin_test_table_edit_column(
            self,
            table_id,
            edit_btn_id,
            list_check_box_id: list
    ):
        # Check edit column
        edit_column = self.find(f'#{edit_btn_id}')
        self.assertTrue(edit_column.is_displayed())
        edit_column.click()
        # Check dropdown is visible
        self.wait_until_visible('ul.dropdown-menu.editcol')
        for check_box_id in list_check_box_id:
            # Check that we can hide/show table column
            check_box = self.find(f'#{check_box_id}')
            th_class = str(check_box_id).replace('checkbox-', '')
            if check_box.is_selected():
                # check if column is visible in table
                self.assertTrue(
                    self.find(
                        f'#{table_id} thead th.{th_class}'
                    ).is_displayed(),
                    f"The {th_class} column is checked in EditColumn dropdown, but it's not visible in table"
                )
                check_box.click()
                # check if column is hidden in table
                self.assertFalse(
                    self.find(
                        f'#{table_id} thead th.{th_class}'
                    ).is_displayed(),
                    f"The {th_class} column is unchecked in EditColumn dropdown, but it's visible in table"
                )
            else:
                # check if column is hidden in table
                self.assertFalse(
                    self.find(
                        f'#{table_id} thead th.{th_class}'
                    ).is_displayed(),
                    f"The {th_class} column is unchecked in EditColumn dropdown, but it's visible in table"
                )
                check_box.click()
                # check if column is visible in table
                self.assertTrue(
                    self.find(
                        f'#{table_id} thead th.{th_class}'
                    ).is_displayed(),
                    f"The {th_class} column is checked in EditColumn dropdown, but it's not visible in table"
                )

    def _get_config_nav_item(self, index):
        config_nav = self.find('#config-nav')
        return config_nav.find_elements(By.TAG_NAME, 'li')[index]

    def _navigate_to_config_nav(self, nav_id, nav_index):
        # navigate to the project page
        self._navigate_to_project_page()
        # click on "Software recipe" tab
        soft_recipe = self._get_config_nav_item(nav_index)
        soft_recipe.click()
        self.wait_until_visible(f'#{nav_id}')

    def _mixin_test_table_show_rows(self, table_selector, **kwargs):
        """ Test the show rows feature in the builds table on the all builds page """
        def test_show_rows(row_to_show, show_row_link):
            # Check that we can show rows == row_to_show
            show_row_link.select_by_value(str(row_to_show))
            self.wait_until_visible(f'#{table_selector} tbody tr', poll=2)
            self.assertTrue(
                len(self.find_all(f'#{table_selector} tbody tr')) == row_to_show
            )
        self.wait_until_present(f'#{table_selector} tbody tr')
        show_rows = self.driver.find_elements(
            By.XPATH,
            f'//select[@class="form-control pagesize-{table_selector}"]'
        )
        rows_to_show = [10, 25, 50, 100, 150]
        to_skip = kwargs.get('to_skip', [])
        # Check show rows
        for show_row_link in show_rows:
            show_row_link = Select(show_row_link)
            for row_to_show in rows_to_show:
                if row_to_show not in to_skip:
                    test_show_rows(row_to_show, show_row_link)

    def _mixin_test_table_search_input(self, **kwargs):
        input_selector, input_text, searchBtn_selector, table_selector, *_ = kwargs.values()
        # Test search input
        self.wait_until_visible(f'#{input_selector}')
        recipe_input = self.find(f'#{input_selector}')
        recipe_input.send_keys(input_text)
        self.find(f'#{searchBtn_selector}').click()
        self.wait_until_visible(f'#{table_selector} tbody tr')
        rows = self.find_all(f'#{table_selector} tbody tr')
        self.assertTrue(len(rows) > 0)

    def test_create_project(self):
        """ Create/Test new project using:
          - Project Name: Any string
          - Release: Any string
          - Merge Toaster settings: True or False
        """
        self._create_project(project_name=self.PROJECT_NAME)

    def test_image_recipe_editColumn(self):
        """ Test the edit column feature in image recipe table on project page """
        self._get_create_builds(success=10, failure=10)

        url = reverse('projectimagerecipes', args=(TestProjectPage.project_id,))
        self.get(url)
        self.wait_until_present('#imagerecipestable tbody tr')

        column_list = [
            'get_description_or_summary', 'layer_version__get_vcs_reference',
            'layer_version__layer__name', 'license', 'recipe-file', 'section',
            'version'
        ]

        # Check that we can hide the edit column
        self._mixin_test_table_edit_column(
            'imagerecipestable',
            'edit-columns-button',
            [f'checkbox-{column}' for column in column_list]
        )

    def test_page_header_on_project_page(self):
        """ Check page header in project page:
          - AT LEFT -> Logo of Yocto project, displayed, clickable
          - "Toaster"+" Information icon", displayed, clickable
          - "Server Icon" + "All builds", displayed, clickable
          - "Directory Icon" + "All projects", displayed, clickable
          - "Book Icon" + "Documentation", displayed, clickable
          - AT RIGHT -> button "New project", displayed, clickable
        """
        # navigate to the project page
        self._navigate_to_project_page()

        # check page header
        # AT LEFT -> Logo of Yocto project
        logo = self.driver.find_element(
            By.XPATH,
            "//div[@class='toaster-navbar-brand']",
        )
        logo_img = logo.find_element(By.TAG_NAME, 'img')
        self.assertTrue(logo_img.is_displayed(),
                        'Logo of Yocto project not found')
        self.assertTrue(
            '/static/img/logo.png' in str(logo_img.get_attribute('src')),
            'Logo of Yocto project not found'
        )
        # "Toaster"+" Information icon", clickable
        toaster = self.driver.find_element(
            By.XPATH,
            "//div[@class='toaster-navbar-brand']//a[@class='brand']",
        )
        self.assertTrue(toaster.is_displayed(), 'Toaster not found')
        self.assertTrue(toaster.text == 'Toaster')
        info_sign = self.find('.glyphicon-info-sign')
        self.assertTrue(info_sign.is_displayed())

        # "Server Icon" + "All builds"
        all_builds = self.find('#navbar-all-builds')
        all_builds_link = all_builds.find_element(By.TAG_NAME, 'a')
        self.assertTrue("All builds" in all_builds_link.text)
        self.assertTrue(
            '/toastergui/builds/' in str(all_builds_link.get_attribute('href'))
        )
        server_icon = all_builds.find_element(By.TAG_NAME, 'i')
        self.assertTrue(
            server_icon.get_attribute('class') == 'glyphicon glyphicon-tasks'
        )
        self.assertTrue(server_icon.is_displayed())

        # "Directory Icon" + "All projects"
        all_projects = self.find('#navbar-all-projects')
        all_projects_link = all_projects.find_element(By.TAG_NAME, 'a')
        self.assertTrue("All projects" in all_projects_link.text)
        self.assertTrue(
            '/toastergui/projects/' in str(all_projects_link.get_attribute(
                'href'))
        )
        dir_icon = all_projects.find_element(By.TAG_NAME, 'i')
        self.assertTrue(
            dir_icon.get_attribute('class') == 'icon-folder-open'
        )
        self.assertTrue(dir_icon.is_displayed())

        # "Book Icon" + "Documentation"
        toaster_docs_link = self.find('#navbar-docs')
        toaster_docs_link_link = toaster_docs_link.find_element(By.TAG_NAME,
                                                                'a')
        self.assertTrue("Documentation" in toaster_docs_link_link.text)
        self.assertTrue(
            toaster_docs_link_link.get_attribute('href') == 'http://docs.yoctoproject.org/toaster-manual/index.html#toaster-user-manual'
        )
        book_icon = toaster_docs_link.find_element(By.TAG_NAME, 'i')
        self.assertTrue(
            book_icon.get_attribute('class') == 'glyphicon glyphicon-book'
        )
        self.assertTrue(book_icon.is_displayed())

        # AT RIGHT -> button "New project"
        new_project_button = self.find('#new-project-button')
        self.assertTrue(new_project_button.is_displayed())
        self.assertTrue(new_project_button.text == 'New project')
        new_project_button.click()
        self.assertTrue(
            '/toastergui/newproject/' in str(self.driver.current_url)
        )

    def test_edit_project_name(self):
        """ Test edit project name:
          - Click on "Edit" icon button
          - Change project name
          - Click on "Save" button
          - Check project name is changed
        """
        # navigate to the project page
        self._navigate_to_project_page()

        # click on "Edit" icon button
        self.wait_until_visible('#project-name-container')
        edit_button = self.find('#project-change-form-toggle')
        edit_button.click()
        project_name_input = self.find('#project-name-change-input')
        self.assertTrue(project_name_input.is_displayed())
        project_name_input.clear()
        project_name_input.send_keys('New Name')
        self.find('#project-name-change-btn').click()

        # check project name is changed
        self.wait_until_visible('#project-name-container')
        self.assertTrue(
            'New Name' in str(self.find('#project-name-container').text)
        )

    def test_project_page_tabs(self):
        """ Test project tabs:
          - "configuration" tab
          - "Builds" tab
          - "Import layers" tab
          - "New custom image" tab
          Check search box used to build recipes
        """
        # navigate to the project page
        self._navigate_to_project_page()

        # check "configuration" tab
        self.wait_until_visible('#topbar-configuration-tab')
        config_tab = self.find('#topbar-configuration-tab')
        self.assertTrue(config_tab.get_attribute('class') == 'active')
        self.assertTrue('Configuration' in str(config_tab.text))
        self.assertTrue(
            f"/toastergui/project/{TestProjectPage.project_id}" in str(self.driver.current_url)
        )

        def get_tabs():
            # tabs links list
            return self.driver.find_elements(
                By.XPATH,
                '//div[@id="project-topbar"]//li'
            )

        def check_tab_link(tab_index, tab_name, url):
            tab = get_tabs()[tab_index]
            tab_link = tab.find_element(By.TAG_NAME, 'a')
            self.assertTrue(url in tab_link.get_attribute('href'))
            self.assertTrue(tab_name in tab_link.text)
            self.assertTrue(tab.get_attribute('class') == 'active')

        # check "Builds" tab
        builds_tab = get_tabs()[1]
        builds_tab.find_element(By.TAG_NAME, 'a').click()
        check_tab_link(
            1,
            'Builds',
            f"/toastergui/project/{TestProjectPage.project_id}/builds"
        )

        # check "Import layers" tab
        import_layers_tab = get_tabs()[2]
        import_layers_tab.find_element(By.TAG_NAME, 'a').click()
        check_tab_link(
            2,
            'Import layer',
            f"/toastergui/project/{TestProjectPage.project_id}/importlayer"
        )

        # check "New custom image" tab
        new_custom_image_tab = get_tabs()[3]
        new_custom_image_tab.find_element(By.TAG_NAME, 'a').click()
        check_tab_link(
            3,
            'New custom image',
            f"/toastergui/project/{TestProjectPage.project_id}/newcustomimage"
        )

        # check search box can be use to build recipes
        search_box = self.find('#build-input')
        search_box.send_keys('core-image-minimal')
        self.find('#build-button').click()
        self.wait_until_visible('#latest-builds')
        lastest_builds = self.driver.find_elements(
            By.XPATH,
            '//div[@id="latest-builds"]',
        )
        last_build = lastest_builds[0]
        self.assertTrue(
            'core-image-minimal' in str(last_build.text)
        )

    def test_softwareRecipe_page(self):
        """ Test software recipe page
            - Check title "Compatible software recipes" is displayed
            - Check search input
            - Check "build recipe" button works
            - Check software recipe table feature(show/hide column, pagination)
        """
        self._navigate_to_config_nav('softwarerecipestable', 4)
        # check title "Compatible software recipes" is displayed
        self.assertTrue("Compatible software recipes" in self.get_page_source())
        # Test search input
        self._mixin_test_table_search_input(
            input_selector='search-input-softwarerecipestable',
            input_text='busybox',
            searchBtn_selector='search-submit-softwarerecipestable',
            table_selector='softwarerecipestable'
        )
        # check "build recipe" button works
        rows = self.find_all('#softwarerecipestable tbody tr')
        image_to_build = rows[0]
        build_btn = image_to_build.find_element(
            By.XPATH,
            '//td[@class="add-del-layers"]//a[1]'
        )
        build_btn.click()
        build_state = wait_until_build(self, 'queued cloning starting parsing failed')
        lastest_builds = self.driver.find_elements(
            By.XPATH,
            '//div[@id="latest-builds"]/div'
        )
        self.assertTrue(len(lastest_builds) > 0)
        last_build = lastest_builds[0]
        cancel_button = last_build.find_element(
            By.XPATH,
            '//span[@class="cancel-build-btn pull-right alert-link"]',
        )
        cancel_button.click()
        if 'starting' not in build_state:  # change build state when cancelled in starting state
            wait_until_build_cancelled(self)

        # check software recipe table feature(show/hide column, pagination)
        self._navigate_to_config_nav('softwarerecipestable', 4)
        column_list = [
            'get_description_or_summary',
            'layer_version__get_vcs_reference',
            'layer_version__layer__name',
            'license',
            'recipe-file',
            'section',
            'version',
        ]
        self._mixin_test_table_edit_column(
            'softwarerecipestable',
            'edit-columns-button',
            [f'checkbox-{column}' for column in column_list]
        )
        self._navigate_to_config_nav('softwarerecipestable', 4)
        # check show rows(pagination)
        self._mixin_test_table_show_rows(
            table_selector='softwarerecipestable',
            to_skip=[150],
        )

    def test_machines_page(self):
        """ Test Machine page
            - Check if title "Compatible machines" is displayed
            - Check search input
            - Check "Select machine" button works
            - Check "Add layer" button works
            - Check Machine table feature(show/hide column, pagination)
        """
        self._navigate_to_config_nav('machinestable', 5)
        # check title "Compatible software recipes" is displayed
        self.assertTrue("Compatible machines" in self.get_page_source())
        # Test search input
        self._mixin_test_table_search_input(
            input_selector='search-input-machinestable',
            input_text='qemux86-64',
            searchBtn_selector='search-submit-machinestable',
            table_selector='machinestable'
        )
        # check "Select machine" button works
        rows = self.find_all('#machinestable tbody tr')
        machine_to_select = rows[0]
        select_btn = machine_to_select.find_element(
            By.XPATH,
            '//td[@class="add-del-layers"]//a[1]'
        )
        select_btn.send_keys(Keys.RETURN)
        self.wait_until_visible('#config-nav')
        project_machine_name = self.find('#project-machine-name')
        self.assertTrue(
            'qemux86-64' in project_machine_name.text
        )
        # check "Add layer" button works
        self._navigate_to_config_nav('machinestable', 5)
        # Search for a machine whit layer not in project
        self._mixin_test_table_search_input(
            input_selector='search-input-machinestable',
            input_text='qemux86-64-tpm2',
            searchBtn_selector='search-submit-machinestable',
            table_selector='machinestable'
        )
        self.wait_until_visible('#machinestable tbody tr', poll=3)
        rows = self.find_all('#machinestable tbody tr')
        machine_to_add = rows[0]
        add_btn = machine_to_add.find_element(By.XPATH, '//td[@class="add-del-layers"]')
        add_btn.click()
        self.wait_until_visible('#change-notification')
        change_notification = self.find('#change-notification')
        self.assertTrue(
            f'You have added 1 layer to your project' in str(change_notification.text)
        )
        # check Machine table feature(show/hide column, pagination)
        self._navigate_to_config_nav('machinestable', 5)
        column_list = [
            'description',
            'layer_version__get_vcs_reference',
            'layer_version__layer__name',
            'machinefile',
        ]
        self._mixin_test_table_edit_column(
            'machinestable',
            'edit-columns-button',
            [f'checkbox-{column}' for column in column_list]
        )
        self._navigate_to_config_nav('machinestable', 5)
        # check show rows(pagination)
        self._mixin_test_table_show_rows(
            table_selector='machinestable',
            to_skip=[150],
        )

    def test_layers_page(self):
        """ Test layers page
            - Check if title "Compatible layerss" is displayed
            - Check search input
            - Check "Add layer" button works
            - Check "Remove layer" button works
            - Check layers table feature(show/hide column, pagination)
        """
        self._navigate_to_config_nav('layerstable', 6)
        # check title "Compatible layers" is displayed
        self.assertTrue("Compatible layers" in self.get_page_source())
        # Test search input
        input_text='meta-tanowrt'
        self._mixin_test_table_search_input(
            input_selector='search-input-layerstable',
            input_text=input_text,
            searchBtn_selector='search-submit-layerstable',
            table_selector='layerstable'
        )
        # check "Add layer" button works
        self.wait_until_visible('#layerstable tbody tr', poll=3)
        rows = self.find_all('#layerstable tbody tr')
        layer_to_add = rows[0]
        add_btn = layer_to_add.find_element(
            By.XPATH,
            '//td[@class="add-del-layers"]'
        )
        add_btn.click()
        # check modal is displayed
        self.wait_until_visible('#dependencies-modal', poll=3)
        list_dependencies = self.find_all('#dependencies-list li')
        # click on add-layers button
        add_layers_btn = self.driver.find_element(
            By.XPATH,
            '//form[@id="dependencies-modal-form"]//button[@class="btn btn-primary"]'
        )
        add_layers_btn.click()
        self.wait_until_visible('#change-notification')
        change_notification = self.find('#change-notification')
        self.assertTrue(
            f'You have added {len(list_dependencies)+1} layers to your project: {input_text} and its dependencies' in str(change_notification.text)
        )
        # check "Remove layer" button works
        self.wait_until_visible('#layerstable tbody tr', poll=3)
        rows = self.find_all('#layerstable tbody tr')
        layer_to_remove = rows[0]
        remove_btn = layer_to_remove.find_element(
            By.XPATH,
            '//td[@class="add-del-layers"]'
        )
        remove_btn.click()
        self.wait_until_visible('#change-notification', poll=2)
        change_notification = self.find('#change-notification')
        self.assertTrue(
            f'You have removed 1 layer from your project: {input_text}' in str(change_notification.text)
        )
        # check layers table feature(show/hide column, pagination)
        self._navigate_to_config_nav('layerstable', 6)
        column_list = [
            'dependencies',
            'revision',
            'layer__vcs_url',
            'git_subdir',
            'layer__summary',
        ]
        self._mixin_test_table_edit_column(
            'layerstable',
            'edit-columns-button',
            [f'checkbox-{column}' for column in column_list]
        )
        self._navigate_to_config_nav('layerstable', 6)
        # check show rows(pagination)
        self._mixin_test_table_show_rows(
            table_selector='layerstable',
            to_skip=[150],
        )

    def test_distro_page(self):
        """ Test distros page
            - Check if title "Compatible distros" is displayed
            - Check search input
            - Check "Add layer" button works
            - Check distro table feature(show/hide column, pagination)
        """
        self._navigate_to_config_nav('distrostable', 7)
        # check title "Compatible distros" is displayed
        self.assertTrue("Compatible Distros" in self.get_page_source())
        # Test search input
        input_text='poky-altcfg'
        self._mixin_test_table_search_input(
            input_selector='search-input-distrostable',
            input_text=input_text,
            searchBtn_selector='search-submit-distrostable',
            table_selector='distrostable'
        )
        # check "Add distro" button works
        rows = self.find_all('#distrostable tbody tr')
        distro_to_add = rows[0]
        add_btn = distro_to_add.find_element(
            By.XPATH,
            '//td[@class="add-del-layers"]//a[1]'
        )
        add_btn.click()
        self.wait_until_visible('#change-notification', poll=2)
        change_notification = self.find('#change-notification')
        self.assertTrue(
            f'You have changed the distro to: {input_text}' in str(change_notification.text)
        )
        # check distro table feature(show/hide column, pagination)
        self._navigate_to_config_nav('distrostable', 7)
        column_list = [
            'description',
            'templatefile',
            'layer_version__get_vcs_reference',
            'layer_version__layer__name',
        ]
        self._mixin_test_table_edit_column(
            'distrostable',
            'edit-columns-button',
            [f'checkbox-{column}' for column in column_list]
        )
        self._navigate_to_config_nav('distrostable', 7)
        # check show rows(pagination)
        self._mixin_test_table_show_rows(
            table_selector='distrostable',
            to_skip=[150],
        )

    def test_single_layer_page(self):
        """ Test layer page
            - Check if title is displayed
            - Check add/remove layer button works
            - Check tabs(layers, recipes, machines) are displayed
            - Check left section is displayed
                - Check layer name
                - Check layer summary
                - Check layer description
        """
        url = reverse("layerdetails", args=(TestProjectPage.project_id, 8))
        self.get(url)
        self.wait_until_visible('.page-header')
        # check title is displayed
        self.assertTrue(self.find('.page-header h1').is_displayed())

        # check add layer button works
        remove_layer_btn = self.find('#add-remove-layer-btn')
        remove_layer_btn.click()
        self.wait_until_visible('#change-notification', poll=2)
        change_notification = self.find('#change-notification')
        self.assertTrue(
            f'You have removed 1 layer from your project' in str(change_notification.text)
        )
        # check add layer button works, 18 is the random layer id
        add_layer_btn = self.find('#add-remove-layer-btn')
        add_layer_btn.click()
        self.wait_until_visible('#change-notification')
        change_notification = self.find('#change-notification')
        self.assertTrue(
            f'You have added 1 layer to your project' in str(change_notification.text)
        )
        # check tabs(layers, recipes, machines) are displayed
        tabs = self.find_all('.nav-tabs li')
        self.assertEqual(len(tabs), 3)
        # Check first tab
        tabs[0].click()
        self.assertTrue(
            'active' in str(self.find('#information').get_attribute('class'))
        )
        # Check second tab
        tabs[1].click()
        self.assertTrue(
            'active' in str(self.find('#recipes').get_attribute('class'))
        )
        # Check third tab
        tabs[2].click()
        self.assertTrue(
            'active' in str(self.find('#machines').get_attribute('class'))
        )
        # Check left section is displayed
        section = self.find('.well')
        # Check layer name
        self.assertTrue(
            section.find_element(By.XPATH, '//h2[1]').is_displayed()
        )
        # Check layer summary
        self.assertTrue("Summary" in section.text)
        # Check layer description
        self.assertTrue("Description" in section.text)

    def test_single_recipe_page(self):
        """ Test recipe page
            - Check if title is displayed
            - Check add recipe layer displayed
            - Check left section is displayed
                - Check recipe: name, summary, description, Version, Section,
                License, Approx. packages included, Approx. size, Recipe file
        """
        url = reverse("recipedetails", args=(TestProjectPage.project_id, 53428))
        self.get(url)
        self.wait_until_visible('.page-header')
        # check title is displayed
        self.assertTrue(self.find('.page-header h1').is_displayed())
        # check add recipe layer displayed
        add_recipe_layer_btn = self.find('#add-layer-btn')
        self.assertTrue(add_recipe_layer_btn.is_displayed())
        # check left section is displayed
        section = self.find('.well')
        # Check recipe name
        self.assertTrue(
            section.find_element(By.XPATH, '//h2[1]').is_displayed()
        )
        # Check recipe sections details info are displayed
        self.assertTrue("Summary" in section.text)
        self.assertTrue("Description" in section.text)
        self.assertTrue("Version" in section.text)
        self.assertTrue("Section" in section.text)
        self.assertTrue("License" in section.text)
        self.assertTrue("Approx. packages included" in section.text)
        self.assertTrue("Approx. package size" in section.text)
        self.assertTrue("Recipe file" in section.text)
