ProjectContext.php #1

  • //
  • guest/
  • thomas_gray/
  • jambox/
  • main/
  • swarm/
  • tests/
  • behat/
  • features/
  • bootstrap/
  • ProjectContext.php
  • View
  • Commits
  • Open Download .zip Download (12 KB)
<?php
/**
 * Perforce Swarm
 *
 * @copyright   2015 Perforce Software. All rights reserved.
 * @license     Please see LICENSE.txt in top-level folder of this distribution.
 * @version     <release>/<patch>
 */

 namespace BehatTests;

use Behat\Behat\Context\Step;

class ProjectContext extends AbstractContext
{
    const ELEMENT_PROJECT_NAME             = 'name';
    const ELEMENT_PROJECT_MEMBERS          = 'members';
    const ELEMENT_ADD_PROJECT_BUTTON_CSS   = '.project-add a';
    const ELEMENT_SAVE_PROJECT_BUTTON      = ".btn-primary[type='submit']";
    const ELEMENT_DONE_CSS                 = '.controls .branch-button .open .close-branch-btn';
    const ELEMENT_DESCRIPTION_CSS          = '.project-sidebar .description .first-line';
    const ELEMENT_METRIC_MEMBERS_CSS       = '.project-sidebar .metrics .members .count';
    const ELEMENT_METRIC_BRANCHES_CSS      = '.project-sidebar .metrics .branches .count';
    const ELEMENT_DROPDOWN_CSS             = '.control-group-members ul.dropdown-menu';
    const ELEMENT_ADD_BRANCH_CSS           = '.control-group.branches a';
    const ELEMENT_PROJECT_MEMBER_CSS       = '.project-sidebar .members img';
    const ELEMENT_PROJECT_BRANCH_CSS       = '.project-sidebar .branches a';
    const ELEMENT_PROJECTS_SIDEBAR_ROW_CSS = '.projects-sidebar tbody tr';

    // the number of branches that have been added to the current project (this is
    // needed because the branch element classes are dependant on the branch number)
    private $branchCount                   = 0;

    /**
     *  Call after attempting to save a project and before further interaction with the UI to
     *  ensure that the ajax call has completed.
     *  The function will wait until one of two conditions is met: a new page has been opened,
     *  or the Save button has been re-enabled.
     *
     * @param   $seconds     int     max timeout required for the assertion
     *
     * @return  bool         true    when we are no longer at the Add Project page, or
     *                               when the Save button is enabled
     * @throws \Exception            when neither condition is met after max seconds
     */
    public function waitUntilSavingRequestHasReturned($seconds = 5)
    {
        $button       = $this->getMinkContext()->findElementByType(self::ELEMENT_SAVE_PROJECT_BUTTON, 'css');
        $projectPage = $this->configParams['base_url'] . "/projects/add/";
        $start        = time();

        do {
            try {
                if ($this->getSession()->getCurrentUrl() !== $projectPage ||
                    $button->hasAttribute("disabled") == false) {
                    return true;
                }
            } catch (\Exception $e) {
                usleep(1000); // 1 ms sleep
            }
        } while ((time() - $start) < $seconds); // max 5 seconds
        throw new \Exception("Failed asserting that the Save button becomes enabled.");
    }

    /**
     * Clicks the project save button and waits for the project page to load
     *
     * @Given /^I click the "Save" button on the "Add Project" page$/
     */
    public function iClickTheSaveProjectButton()
    {
        $this->getMinkContext()->findElementByType(self::ELEMENT_SAVE_PROJECT_BUTTON, 'css')->click();
        $this->waitUntilSavingRequestHasReturned();

    }

    /**
     * @Then /^I should be redirected to "\/projects\/(?P<page>[^"]*)"$/
     */
    public function iShouldBeRedirectedToProjectPage($page)
    {
        $actual = $this->getSession()->getCurrentUrl();

        $base = $this->configParams['base_url'] . "/projects/";
        $expected = $base . $page;
        $expectedEncoded = $base . urlencode($page);

        // Note: it is not enough to check against the encoded only, as getCurrentUrl() returns the
        // encoded url for the chrome and firefox drivers and the decoded url for the safari driver
        assertTrue($actual === $expected || $actual === $expectedEncoded);
    }

    /**
     * @Then /^The "Save" button should be (enabled|disabled)$/
     */
    public function theSaveButtonShouldBeEnabledOrDisabled($enabled)
    {
        $button = $this->getMinkContext()->findElementByType(self::ELEMENT_SAVE_PROJECT_BUTTON, 'css');

        if ($enabled === "enabled") {
            assertEquals(false, $button->hasAttribute("disabled"));
        } else {
            assertEquals(true, $button->hasAttribute("disabled"));
        }
    }

    /**
     * @When /^I click the "Add Project" button$/
     */
    public function iClickTheAddProjectButton()
    {
        $this->getMinkContext()->findElementByType(self::ELEMENT_ADD_PROJECT_BUTTON_CSS, 'css')->click();
    }

    /**
     * @When /^I am on a newly opened "Add Project" page$/
     */
    public function iAmOnANewlyOpenedAddProjectPage()
    {
        $this->getSession()->visit($this->configParams['base_url']."/projects/add/");
    }

    /**
     * @Then /^I should be redirected to the "Add Project" page$/
     */
    public function iShouldBeRedirectedToTheAddProjectPage()
    {
        $this->getMinkContext()->waitUntilPageUrlLoads($this->configParams['base_url'] . "/projects/add/", 5);
    }

    /**
     * @When /^I add the member "([^"]*)" to the project$/
     */
    public function iAddTheMemberToTheProject($member)
    {
        $this->iEnterInputInTheMembersField($member);
        $this->iClickOnUserInDropdownList($member);
    }

    /**
     * @When /^I click on user "([^"]*)" in the dropdown list$/
     */
    public function iClickOnUserInDropdownList($userName)
    {
        $elementCss = self::ELEMENT_DROPDOWN_CSS . " li[data-value^=\"$userName\"]";
        $this->getMinkContext()->assertElementOnPage($elementCss);
        $this->getMinkContext()->findElementByType($elementCss, 'css')->click();
    }

    /**
     * @Then /^I should see an error "([^"]*)"$/
     */
    public function iShouldSeeAnError($error)
    {
        return new Step\Then("I should see \"$error\"");
    }

    /**
     * @Given /^I have created a project named "(?P<projectName>[^"]*)"$/
     * @Given /^I have created a project named "(?P<projectName>[^"]*)" with member "(?P<projectMember>[^"]*)"&/
     */
    public function iHaveCreatedAProject($projectName, $projectMember = "swarm-admin")
    {
        return array(
            new Step\When("I am on a newly opened \"Add Project\" page"),
            new Step\When("I enter \"$projectName\" in the \"Name\" field"),
            new Step\When("I add the member \"$projectMember\" to the project"),
            new Step\When("I click the \"Save\" button on the \"Add Project\" page")
        );
    }

    /**
     * @When /^I enter a valid name and project member$/
     */
    public function iEnterAValidNameAndMember()
    {
        return array(
            new Step\When("I enter \"SampleProject\" in the \"Name\" field"),
            new Step\When("I add the member \"swarm-admin\" to the project")
        );
    }

    /**
     * @When /^I click the "Add Branch" button$/
     */
    public function iClickTheAddBranchButton()
    {
        $this->getMinkContext()->findElementByType(self::ELEMENT_ADD_BRANCH_CSS, 'css')->click();
    }

    /**
     * @When /^I add a branch with name "([^"]*)" and mapping "([^"]*)"$/
     */
    public function iAddABranchWithNameAndMapping($name, $mapping)
    {
        $nameId  = "branch-name-" . $this->branchCount;
        $pathsId = "branch-paths-" . $this->branchCount;
        $this->branchCount++;

        $this->iClickTheAddBranchButton();
        $this->getMinkContext()->fillField($nameId, $name);
        $this->getMinkContext()->fillField($pathsId, $mapping);
        $this->iClickDoneButton();
    }

    /**
     * @Then /^I should see the project "([^"]*)" listed under "Projects"$/
     */
    public function iShouldSeeTheProjectListedUnder($projectName)
    {
        $this->getMinkContext()->waitUntilPageElementLoads(self::ELEMENT_PROJECTS_SIDEBAR_ROW_CSS, "css");

        $pageName = urlencode(strtolower($projectName));
        $projectCss = self::ELEMENT_PROJECTS_SIDEBAR_ROW_CSS . ".project a.name[href='/projects/" . $pageName . "']";
        return new Step\Then("I should see an \"$projectCss\" element");
    }

    /**
     * @Then /^I should see the user list "([^"]*)"$/
     */
    public function iShouldSeeTheUserList($usersList)
    {
        $usersArray = explode(", ", $usersList);

        // check that drop-down list is visible
        $dropdownCss = self::ELEMENT_DROPDOWN_CSS . ":not([display='none'])";
        $this->getMinkContext()->assertElementOnPage($dropdownCss);

        // check that the drop-down contains each of the names in usersList
        foreach ($usersArray as $user) {
            $userCss = self::ELEMENT_DROPDOWN_CSS . " li[data-value^='$user']";
            $this->getMinkContext()->assertElementOnPage($userCss);
        }
    }

    /**
     * @Then /^I should see "([^"]*)", "([\d]+) Members", "([\d]+) Branches" under the "About" section$/
     */
    public function iShouldSeeMetricsUnderTheAboutSection($description, $members, $branches)
    {
        return array(
            new Step\Then("I should see \"$description\" in the \"" . self::ELEMENT_DESCRIPTION_CSS . "\" element"),
            new Step\Then("I should see \"$members\" in the \"" . self::ELEMENT_METRIC_MEMBERS_CSS . "\" element"),
            new Step\Then("I should see \"$branches\" in the \"" . self::ELEMENT_METRIC_BRANCHES_CSS . "\" element")

        );
    }

    /**
     * @Then /^I should see (users|branches) "(?P<list>[^"]*)" under "(?P<section>members|branches)"$/
     */
    public function iShouldSeeListUnderSection($list, $section)
    {
        $entriesArray = explode(", ", $list);

        foreach ($entriesArray as $entry) {
            if ($section === "members") {
                $this->getMinkContext()->assertElementOnPage(self::ELEMENT_PROJECT_MEMBER_CSS . "[data-user='$entry']");
            } else {
                $this->getMinkContext()->assertElementOnPage(self::ELEMENT_PROJECT_BRANCH_CSS . ":contains('$entry')");
            }
        }

    }

    /**
     * @When /^I click on the "x" next to "([^"]*)"$/
     */
    public function iClickOnTheXNextToName($userName)
    {
        // Click away from the drop-down picker to ensure it is closed. This is needed
        // because the chrome driver can't click a button if it is obscured by something else.
        $this->getMinkContext()->findElementByType("i.icon-user")->click();

        $removeButtonCss = ".multipicker-item[data-value^='$userName'] button.item-remove";
        $this->getMinkContext()->assertElementOnPage($removeButtonCss);
        $this->getMinkContext()->findElementByType($removeButtonCss, 'css')->click();
    }

    /**
     * @Given /^The list of users on the server includes "([^"]*)"$/
     */
    public function theListOfUsersOnTheServerIncludes($userList)
    {
        $usernameArray = explode(", ", $userList);

        foreach ($usernameArray as $username) {
            $this->getP4Context()->createRegularUser($username);
            $this->getP4Context()->instantiateWorker();
        }
    }

    /**
     * @When /^I click "Done" on the "Add Branch" window$/
     */
    public function iClickDoneButton()
    {
        $this->getMinkContext()->findElementByType(self::ELEMENT_DONE_CSS, 'css')->click();
    }

    /**
     * @When /^I enter "(?P<input>[^"]*)" in the "Name" field$/
     */
    public function iEnterInputInTheNameField($input)
    {
        $this->getMinkContext()->fillField(self::ELEMENT_PROJECT_NAME, $input);
    }

    /**
     * @When /^I enter "(?P<input>[^"]*)" in the "Members" field$/
     */
    public function iEnterInputInTheMembersField($input)
    {
        // wait until input is enabled
        $membersCss = "input#members:not([disabled])";
        $this->getMinkContext()->waitUntilPageElementLoads($membersCss);

        $this->getMinkContext()->fillField(self::ELEMENT_PROJECT_MEMBERS, $input);
    }

    /**
     * @Given /^I create a project "(?P<projectName>[^"]*)" with mapping "(?P<projectMapping>[^"]*)"$/
     */
    public function iCreateAProjectWithMapping($projectName, $projectMapping)
    {
        $this->iAmOnANewlyOpenedAddProjectPage();
        $this->iEnterInputInTheNameField($projectName);
        $this->iAddTheMemberToTheProject("swarm-admin");
        $this->iAddABranchWithNameAndMapping("Jam", $projectMapping);
        $this->iClickTheSaveProjectButton();

    }

    /**
     * @Then /^I should see the "(?P<projectName>[^"]*)" project header$/
     */
    public function iShouldSeeTheProjectHeader($projectName)
    {
        $this->getMinkContext()->assertElementOnPage(".project-navbar .brand:contains('$projectName')");
    }
}
# Change User Description Committed
#1 18730 Liz Lam clean up code and move things around