loggedIn()) { $this->logout(); } } /** * Creates and authenticates a user with the given role(s). * * @Given I am logged in as a user with the :role role(s) * @Given I am logged in as a/an :role */ public function assertAuthenticatedByRole($role) { // Check if a user with this role is already logged in. if (!$this->loggedInWithRole($role)) { // Create user (and project) $user = (object) array( 'name' => $this->getRandom()->name(8), 'pass' => $this->getRandom()->name(16), 'role' => $role, ); $user->mail = "{$user->name}@example.com"; $this->userCreate($user); $roles = explode(',', $role); $roles = array_map('trim', $roles); foreach ($roles as $role) { if (!in_array(strtolower($role), array('authenticated', 'authenticated user'))) { // Only add roles other than 'authenticated user'. $this->getDriver()->userAddRole($user, $role); } } // Login. $this->login(); } } /** * Creates and authenticates a user with the given role(s) and given fields. * | field_user_name | John | * | field_user_surname | Smith | * | ... | ... | * * @Given I am logged in as a user with the :role role(s) and I have the following fields: */ public function assertAuthenticatedByRoleWithGivenFields($role, TableNode $fields) { // Check if a user with this role is already logged in. if (!$this->loggedInWithRole($role)) { // Create user (and project) $user = (object) array( 'name' => $this->getRandom()->name(8), 'pass' => $this->getRandom()->name(16), 'role' => $role, ); $user->mail = "{$user->name}@example.com"; // Assign fields to user before creation. foreach ($fields->getRowsHash() as $field => $value) { $user->{$field} = $value; } $this->userCreate($user); $roles = explode(',', $role); $roles = array_map('trim', $roles); foreach ($roles as $role) { if (!in_array(strtolower($role), array('authenticated', 'authenticated user'))) { // Only add roles other than 'authenticated user'. $this->getDriver()->userAddRole($user, $role); } } // Login. $this->login(); } } /** * @Given I am logged in as :name */ public function assertLoggedInByName($name) { if (!isset($this->users[$name])) { throw new \Exception(sprintf('No user with %s name is registered with the driver.', $name)); } // Change internal current user. $this->user = $this->users[$name]; // Login. $this->login(); } /** * @Given I am logged in as a user with the :permissions permission(s) */ public function assertLoggedInWithPermissions($permissions) { // Create user. $user = (object) array( 'name' => $this->getRandom()->name(8), 'pass' => $this->getRandom()->name(16), ); $user->mail = "{$user->name}@example.com"; $this->userCreate($user); // Create and assign a temporary role with given permissions. $permissions = array_map('trim', explode(',', $permissions)); $rid = $this->getDriver()->roleCreate($permissions); $this->getDriver()->userAddRole($user, $rid); $this->roles[] = $rid; // Login. $this->login(); } /** * Retrieve a table row containing specified text from a given element. * * @param \Behat\Mink\Element\Element * @param string * The text to search for in the table row. * * @return \Behat\Mink\Element\NodeElement * * @throws \Exception */ public function getTableRow(Element $element, $search) { $rows = $element->findAll('css', 'tr'); if (empty($rows)) { throw new \Exception(sprintf('No rows found on the page %s', $this->getSession()->getCurrentUrl())); } foreach ($rows as $row) { if (strpos($row->getText(), $search) !== FALSE) { return $row; } } throw new \Exception(sprintf('Failed to find a row containing "%s" on the page %s', $search, $this->getSession()->getCurrentUrl())); } /** * Find text in a table row containing given text. * * @Then I should see (the text ):text in the :rowText row */ public function assertTextInTableRow($text, $rowText) { $row = $this->getTableRow($this->getSession()->getPage(), $rowText); if (strpos($row->getText(), $text) === FALSE) { throw new \Exception(sprintf('Found a row containing "%s", but it did not contain the text "%s".', $rowText, $text)); } } /** * Asset text not in a table row containing given text. * * @Then I should not see (the text ):text in the :rowText row */ public function assertTextNotInTableRow($text, $rowText) { $row = $this->getTableRow($this->getSession()->getPage(), $rowText); if (strpos($row->getText(), $text) !== FALSE) { throw new \Exception(sprintf('Found a row containing "%s", but it contained the text "%s".', $rowText, $text)); } } /** * Attempts to find a link in a table row containing giving text. This is for * administrative pages such as the administer content types screen found at * `admin/structure/types`. * * @Given I click :link in the :rowText row * @Then I (should )see the :link in the :rowText row */ public function assertClickInTableRow($link, $rowText) { $page = $this->getSession()->getPage(); if ($link_element = $this->getTableRow($page, $rowText)->findLink($link)) { // Click the link and return. $link_element->click(); return; } throw new \Exception(sprintf('Found a row containing "%s", but no "%s" link on the page %s', $rowText, $link, $this->getSession()->getCurrentUrl())); } /** * @Given the cache has been cleared */ public function assertCacheClear() { $this->getDriver()->clearCache(); } /** * @Given I run cron */ public function assertCron() { $this->getDriver()->runCron(); } /** * Creates content of the given type. * * @Given I am viewing a/an :type (content )with the title :title * @Given a/an :type (content )with the title :title */ public function createNode($type, $title) { // @todo make this easily extensible. $node = (object) array( 'title' => $title, 'type' => $type, ); $saved = $this->nodeCreate($node); // Set internal page on the new node. $this->getSession()->visit($this->locatePath('/node/' . $saved->nid)); } /** * Creates content authored by the current user. * * @Given I am viewing my :type (content )with the title :title */ public function createMyNode($type, $title) { if (!isset($this->user->uid)) { throw new \Exception(sprintf('There is no current logged in user to create a node for.')); } $node = (object) array( 'title' => $title, 'type' => $type, 'body' => $this->getRandom()->name(255), 'uid' => $this->user->uid, ); $saved = $this->nodeCreate($node); // Set internal page on the new node. $this->getSession()->visit($this->locatePath('/node/' . $saved->nid)); } /** * Creates content of a given type provided in the form: * | title | author | status | created | * | My title | Joe Editor | 1 | 2014-10-17 8:00am | * | ... | ... | ... | ... | * * @Given :type content: */ public function createNodes($type, TableNode $nodesTable) { foreach ($nodesTable->getHash() as $nodeHash) { $node = (object) $nodeHash; $node->type = $type; $this->nodeCreate($node); } } /** * Creates content of the given type, provided in the form: * | title | My node | * | Field One | My field value | * | author | Joe Editor | * | status | 1 | * | ... | ... | * * @Given I am viewing a/an :type( content): */ public function assertViewingNode($type, TableNode $fields) { $node = (object) array( 'type' => $type, ); foreach ($fields->getRowsHash() as $field => $value) { $node->{$field} = $value; } $saved = $this->nodeCreate($node); // Set internal browser on the node. $this->getSession()->visit($this->locatePath('/node/' . $saved->nid)); } /** * Asserts that a given content type is editable. * * @Then I should be able to edit a/an :type( content) */ public function assertEditNodeOfType($type) { $node = (object) array( 'type' => $type, 'title' => "Test $type", ); $saved = $this->nodeCreate($node); // Set internal browser on the node edit page. $this->getSession()->visit($this->locatePath('/node/' . $saved->nid . '/edit')); // Test status. $this->assertSession()->statusCodeEquals('200'); } /** * Creates a term on an existing vocabulary. * * @Given I am viewing a/an :vocabulary term with the name :name * @Given a/an :vocabulary term with the name :name */ public function createTerm($vocabulary, $name) { // @todo make this easily extensible. $term = (object) array( 'name' => $name, 'vocabulary_machine_name' => $vocabulary, 'description' => $this->getRandom()->name(255), ); $saved = $this->termCreate($term); // Set internal page on the term. $this->getSession()->visit($this->locatePath('/taxonomy/term/' . $saved->tid)); } /** * Creates multiple users. * * Provide user data in the following format: * * | name | mail | roles | * | user foo | foo@bar.com | role1, role2 | * * @Given users: */ public function createUsers(TableNode $usersTable) { foreach ($usersTable->getHash() as $userHash) { // Split out roles to process after user is created. $roles = array(); if (isset($userHash['roles'])) { $roles = explode(',', $userHash['roles']); $roles = array_filter(array_map('trim', $roles)); unset($userHash['roles']); } $user = (object) $userHash; // Set a password. if (!isset($user->pass)) { $user->pass = $this->getRandom()->name(); } $this->userCreate($user); // Assign roles. foreach ($roles as $role) { $this->getDriver()->userAddRole($user, $role); } } } /** * Creates one or more terms on an existing vocabulary. * * Provide term data in the following format: * * | name | parent | description | weight | taxonomy_field_image | * | Snook | Fish | Marine fish | 10 | snook-123.jpg | * | ... | ... | ... | ... | ... | * * Only the 'name' field is required. * * @Given :vocabulary terms: */ public function createTerms($vocabulary, TableNode $termsTable) { foreach ($termsTable->getHash() as $termsHash) { $term = (object) $termsHash; $term->vocabulary_machine_name = $vocabulary; $this->termCreate($term); } } /** * Creates one or more languages. * * @Given the/these (following )languages are available: * * Provide language data in the following format: * * | langcode | * | en | * | fr | * * @param TableNode $langcodesTable * The table listing languages by their ISO code. */ public function createLanguages(TableNode $langcodesTable) { foreach ($langcodesTable->getHash() as $row) { $language = (object) array( 'langcode' => $row['languages'], ); $this->languageCreate($language); } } /** * Pauses the scenario until the user presses a key. Useful when debugging a scenario. * * @Then (I )break */ public function iPutABreakpoint() { fwrite(STDOUT, "\033[s \033[93m[Breakpoint] Press \033[1;93m[RETURN]\033[0;93m to continue, or 'q' to quit...\033[0m"); do { $line = trim(fgets(STDIN, 1024)); //Note: this assumes ASCII encoding. Should probably be revamped to //handle other character sets. $charCode = ord($line); switch($charCode){ case 0: //CR case 121: //y case 89: //Y break 2; // case 78: //N // case 110: //n case 113: //q case 81: //Q throw new \Exception("Exiting test intentionally."); default: fwrite(STDOUT, sprintf("\nInvalid entry '%s'. Please enter 'y', 'q', or the enter key.\n", $line)); break; } } while (true); fwrite(STDOUT, "\033[u"); } }