Вход Регистрация
Файл: gapps/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php
Строк: 807
<?php

namespace IlluminateFoundationTestingConcerns;

use 
Closure;
use 
InvalidArgumentException;
use 
IlluminateHttpUploadedFile;
use 
SymfonyComponentDomCrawlerForm;
use 
SymfonyComponentDomCrawlerCrawler;
use 
IlluminateFoundationTestingHttpException;
use 
IlluminateFoundationTestingConstraintsHasText;
use 
IlluminateFoundationTestingConstraintsHasLink;
use 
IlluminateFoundationTestingConstraintsHasValue;
use 
IlluminateFoundationTestingConstraintsHasSource;
use 
IlluminateFoundationTestingConstraintsIsChecked;
use 
IlluminateFoundationTestingConstraintsHasElement;
use 
IlluminateFoundationTestingConstraintsIsSelected;
use 
IlluminateFoundationTestingConstraintsHasInElement;
use 
IlluminateFoundationTestingConstraintsPageConstraint;
use 
IlluminateFoundationTestingConstraintsReversePageConstraint;
use 
PHPUnit_Framework_ExpectationFailedException as PHPUnitException;

trait 
InteractsWithPages
{
    
/**
     * The DomCrawler instance.
     *
     * @var SymfonyComponentDomCrawlerCrawler
     */
    
protected $crawler;

    
/**
     * Nested crawler instances used by the "within" method.
     *
     * @var array
     */
    
protected $subCrawlers = [];

    
/**
     * All of the stored inputs for the current page.
     *
     * @var array
     */
    
protected $inputs = [];

    
/**
     * All of the stored uploads for the current page.
     *
     * @var array
     */
    
protected $uploads = [];

    
/**
     * Visit the given URI with a GET request.
     *
     * @param  string  $uri
     * @return $this
     */
    
public function visit($uri)
    {
        return 
$this->makeRequest('GET'$uri);
    }

    
/**
     * Make a request to the application and create a Crawler instance.
     *
     * @param  string  $method
     * @param  string  $uri
     * @param  array  $parameters
     * @param  array  $cookies
     * @param  array  $files
     * @return $this
     */
    
protected function makeRequest($method$uri$parameters = [], $cookies = [], $files = [])
    {
        
$uri $this->prepareUrlForRequest($uri);

        
$this->call($method$uri$parameters$cookies$files);

        
$this->clearInputs()->followRedirects()->assertPageLoaded($uri);

        
$this->currentUri $this->app->make('request')->fullUrl();

        
$this->crawler = new Crawler($this->response->getContent(), $this->currentUri);

        return 
$this;
    }

    
/**
     * Clean the crawler and the subcrawlers values to reset the page context.
     *
     * @return void
     */
    
protected function resetPageContext()
    {
        
$this->crawler null;

        
$this->subCrawlers = [];
    }

    
/**
     * Make a request to the application using the given form.
     *
     * @param  SymfonyComponentDomCrawlerForm  $form
     * @param  array  $uploads
     * @return $this
     */
    
protected function makeRequestUsingForm(Form $form, array $uploads = [])
    {
        
$files $this->convertUploadsForTesting($form$uploads);

        return 
$this->makeRequest(
            
$form->getMethod(), $form->getUri(), $this->extractParametersFromForm($form), [], $files
        
);
    }

    
/**
     * Extract the parameters from the given form.
     *
     * @param  SymfonyComponentDomCrawlerForm  $form
     * @return array
     */
    
protected function extractParametersFromForm(Form $form)
    {
        
parse_str(http_build_query($form->getValues()), $parameters);

        return 
$parameters;
    }

    
/**
     * Follow redirects from the last response.
     *
     * @return $this
     */
    
protected function followRedirects()
    {
        while (
$this->response->isRedirect()) {
            
$this->makeRequest('GET'$this->response->getTargetUrl());
        }

        return 
$this;
    }

    
/**
     * Clear the inputs for the current page.
     *
     * @return $this
     */
    
protected function clearInputs()
    {
        
$this->inputs = [];

        
$this->uploads = [];

        return 
$this;
    }

    
/**
     * Assert that the current page matches a given URI.
     *
     * @param  string  $uri
     * @return $this
     */
    
protected function seePageIs($uri)
    {
        
$this->assertPageLoaded($uri $this->prepareUrlForRequest($uri));

        
$this->assertEquals(
            
$uri$this->currentUri"Did not land on expected page [{$uri}].n"
        
);

        return 
$this;
    }

    
/**
     * Assert that a given page successfully loaded.
     *
     * @param  string  $uri
     * @param  string|null  $message
     * @return void
     *
     * @throws IlluminateFoundationTestingHttpException
     */
    
protected function assertPageLoaded($uri$message null)
    {
        
$status $this->response->getStatusCode();

        try {
            
$this->assertEquals(200$status);
        } catch (
PHPUnitException $e) {
            
$message $message ?: "A request to [{$uri}] failed. Received status code [{$status}].";

            
$responseException = isset($this->response->exception)
                    ? 
$this->response->exception null;

            throw new 
HttpException($messagenull$responseException);
        }
    }

    
/**
     * Narrow the test content to a specific area of the page.
     *
     * @param  string  $element
     * @param  Closure  $callback
     * @return $this
     */
    
public function within($elementClosure $callback)
    {
        
$this->subCrawlers[] = $this->crawler()->filter($element);

        
$callback();

        
array_pop($this->subCrawlers);

        return 
$this;
    }

    
/**
     * Get the current crawler according to the test context.
     *
     * @return SymfonyComponentDomCrawlerCrawler
     */
    
protected function crawler()
    {
        if (! empty(
$this->subCrawlers)) {
            return 
end($this->subCrawlers);
        }

        return 
$this->crawler;
    }

    
/**
     * Assert the given constraint.
     *
     * @param  IlluminateFoundationTestingConstraintsPageConstraint  $constraint
     * @param  bool  $reverse
     * @param  string  $message
     * @return $this
     */
    
protected function assertInPage(PageConstraint $constraint$reverse false$message '')
    {
        if (
$reverse) {
            
$constraint = new ReversePageConstraint($constraint);
        }

        
self::assertThat(
            
$this->crawler() ?: $this->response->getContent(),
            
$constraint$message
        
);

        return 
$this;
    }

    
/**
     * Assert that a given string is seen on the current HTML.
     *
     * @param  string  $text
     * @param  bool  $negate
     * @return $this
     */
    
public function see($text$negate false)
    {
        return 
$this->assertInPage(new HasSource($text), $negate);
    }

    
/**
     * Assert that a given string is not seen on the current HTML.
     *
     * @param  string  $text
     * @return $this
     */
    
public function dontSee($text)
    {
        return 
$this->assertInPage(new HasSource($text), true);
    }

    
/**
     * Assert that an element is present on the page.
     *
     * @param  string  $selector
     * @param  array  $attributes
     * @param  bool  $negate
     * @return $this
     */
    
public function seeElement($selector, array $attributes = [], $negate false)
    {
        return 
$this->assertInPage(new HasElement($selector$attributes), $negate);
    }

    
/**
     * Assert that an element is not present on the page.
     *
     * @param  string  $selector
     * @param  array  $attributes
     * @return $this
     */
    
public function dontSeeElement($selector, array $attributes = [])
    {
        return 
$this->assertInPage(new HasElement($selector$attributes), true);
    }

    
/**
     * Assert that a given string is seen on the current text.
     *
     * @param  string  $text
     * @param  bool  $negate
     * @return $this
     */
    
public function seeText($text$negate false)
    {
        return 
$this->assertInPage(new HasText($text), $negate);
    }

    
/**
     * Assert that a given string is not seen on the current text.
     *
     * @param  string  $text
     * @return $this
     */
    
public function dontSeeText($text)
    {
        return 
$this->assertInPage(new HasText($text), true);
    }

    
/**
     * Assert that a given string is seen inside an element.
     *
     * @param  string  $element
     * @param  string  $text
     * @param  bool  $negate
     * @return $this
     */
    
public function seeInElement($element$text$negate false)
    {
        return 
$this->assertInPage(new HasInElement($element$text), $negate);
    }

    
/**
     * Assert that a given string is not seen inside an element.
     *
     * @param  string  $element
     * @param  string  $text
     * @return $this
     */
    
public function dontSeeInElement($element$text)
    {
        return 
$this->assertInPage(new HasInElement($element$text), true);
    }

    
/**
     * Assert that a given link is seen on the page.
     *
     * @param  string $text
     * @param  string|null $url
     * @param  bool  $negate
     * @return $this
     */
    
public function seeLink($text$url null$negate false)
    {
        return 
$this->assertInPage(new HasLink($text$url), $negate);
    }

    
/**
     * Assert that a given link is not seen on the page.
     *
     * @param  string  $text
     * @param  string|null  $url
     * @return $this
     */
    
public function dontSeeLink($text$url null)
    {
        return 
$this->assertInPage(new HasLink($text$url), true);
    }

    
/**
     * Assert that an input field contains the given value.
     *
     * @param  string  $selector
     * @param  string  $expected
     * @param  bool  $negate
     * @return $this
     */
    
public function seeInField($selector$expected$negate false)
    {
        return 
$this->assertInPage(new HasValue($selector$expected), $negate);
    }

    
/**
     * Assert that an input field does not contain the given value.
     *
     * @param  string  $selector
     * @param  string  $value
     * @return $this
     */
    
public function dontSeeInField($selector$value)
    {
        return 
$this->assertInPage(new HasValue($selector$value), true);
    }

    
/**
     * Assert that the expected value is selected.
     *
     * @param  string  $selector
     * @param  string  $value
     * @param  bool  $negate
     * @return $this
     */
    
public function seeIsSelected($selector$value$negate false)
    {
        return 
$this->assertInPage(new IsSelected($selector$value), $negate);
    }

    
/**
     * Assert that the given value is not selected.
     *
     * @param  string  $selector
     * @param  string  $value
     * @return $this
     */
    
public function dontSeeIsSelected($selector$value)
    {
        return 
$this->assertInPage(new IsSelected($selector$value), true);
    }

    
/**
     * Assert that the given checkbox is selected.
     *
     * @param  string  $selector
     * @param  bool  $negate
     * @return $this
     */
    
public function seeIsChecked($selector$negate false)
    {
        return 
$this->assertInPage(new IsChecked($selector), $negate);
    }

    
/**
     * Assert that the given checkbox is not selected.
     *
     * @param  string  $selector
     * @return $this
     */
    
public function dontSeeIsChecked($selector)
    {
        return 
$this->assertInPage(new IsChecked($selector), true);
    }

    
/**
     * Click a link with the given body, name, or ID attribute.
     *
     * @param  string  $name
     * @return $this
     *
     * @throws InvalidArgumentException
     */
    
protected function click($name)
    {
        
$link $this->crawler()->selectLink($name);

        if (! 
count($link)) {
            
$link $this->filterByNameOrId($name'a');

            if (! 
count($link)) {
                throw new 
InvalidArgumentException(
                    
"Could not find a link with a body, name, or ID attribute of [{$name}]."
                
);
            }
        }

        
$this->visit($link->link()->getUri());

        return 
$this;
    }

    
/**
     * Fill an input field with the given text.
     *
     * @param  string  $text
     * @param  string  $element
     * @return $this
     */
    
protected function type($text$element)
    {
        return 
$this->storeInput($element$text);
    }

    
/**
     * Check a checkbox on the page.
     *
     * @param  string  $element
     * @return $this
     */
    
protected function check($element)
    {
        return 
$this->storeInput($elementtrue);
    }

    
/**
     * Uncheck a checkbox on the page.
     *
     * @param  string  $element
     * @return $this
     */
    
protected function uncheck($element)
    {
        return 
$this->storeInput($elementfalse);
    }

    
/**
     * Select an option from a drop-down.
     *
     * @param  string  $option
     * @param  string  $element
     * @return $this
     */
    
protected function select($option$element)
    {
        return 
$this->storeInput($element$option);
    }

    
/**
     * Attach a file to a form field on the page.
     *
     * @param  string  $absolutePath
     * @param  string  $element
     * @return $this
     */
    
protected function attach($absolutePath$element)
    {
        
$this->uploads[$element] = $absolutePath;

        return 
$this->storeInput($element$absolutePath);
    }

    
/**
     * Submit a form using the button with the given text value.
     *
     * @param  string  $buttonText
     * @return $this
     */
    
protected function press($buttonText)
    {
        return 
$this->submitForm($buttonText$this->inputs$this->uploads);
    }

    
/**
     * Submit a form on the page with the given input.
     *
     * @param  string  $buttonText
     * @param  array  $inputs
     * @param  array  $uploads
     * @return $this
     */
    
protected function submitForm($buttonText$inputs = [], $uploads = [])
    {
        
$this->makeRequestUsingForm($this->fillForm($buttonText$inputs), $uploads);

        return 
$this;
    }

    
/**
     * Fill the form with the given data.
     *
     * @param  string  $buttonText
     * @param  array  $inputs
     * @return SymfonyComponentDomCrawlerForm
     */
    
protected function fillForm($buttonText$inputs = [])
    {
        if (! 
is_string($buttonText)) {
            
$inputs $buttonText;

            
$buttonText null;
        }

        return 
$this->getForm($buttonText)->setValues($inputs);
    }

    
/**
     * Get the form from the page with the given submit button text.
     *
     * @param  string|null  $buttonText
     * @return SymfonyComponentDomCrawlerForm
     *
     * @throws InvalidArgumentException
     */
    
protected function getForm($buttonText null)
    {
        try {
            if (
$buttonText) {
                return 
$this->crawler()->selectButton($buttonText)->form();
            }

            return 
$this->crawler()->filter('form')->form();
        } catch (
InvalidArgumentException $e) {
            throw new 
InvalidArgumentException(
                
"Could not find a form that has submit button [{$buttonText}]."
            
);
        }
    }

    
/**
     * Store a form input in the local array.
     *
     * @param  string  $element
     * @param  string  $text
     * @return $this
     */
    
protected function storeInput($element$text)
    {
        
$this->assertFilterProducesResults($element);

        
$element str_replace('#'''$element);

        
$this->inputs[$element] = $text;

        return 
$this;
    }

    
/**
     * Assert that a filtered Crawler returns nodes.
     *
     * @param  string  $filter
     * @return void
     *
     * @throws InvalidArgumentException
     */
    
protected function assertFilterProducesResults($filter)
    {
        
$crawler $this->filterByNameOrId($filter);

        if (! 
count($crawler)) {
            throw new 
InvalidArgumentException(
                
"Nothing matched the filter [{$filter}] CSS query provided for [{$this->currentUri}]."
            
);
        }
    }

    
/**
     * Filter elements according to the given name or ID attribute.
     *
     * @param  string  $name
     * @param  array|string  $elements
     * @return SymfonyComponentDomCrawlerCrawler
     */
    
protected function filterByNameOrId($name$elements '*')
    {
        
$name str_replace('#'''$name);

        
$id str_replace(['['']'], ['\[''\]'], $name);

        
$elements is_array($elements) ? $elements : [$elements];

        
array_walk($elements, function (&$element) use ($name$id) {
            
$element "{$element}#{$id}{$element}[name='{$name}']";
        });

        return 
$this->crawler()->filter(implode(', '$elements));
    }

    
/**
     * Convert the given uploads to UploadedFile instances.
     *
     * @param  SymfonyComponentDomCrawlerForm  $form
     * @param  array  $uploads
     * @return array
     */
    
protected function convertUploadsForTesting(Form $form, array $uploads)
    {
        
$files $form->getFiles();

        
$names array_keys($files);

        
$files array_map(function (array $file$name) use ($uploads) {
            return isset(
$uploads[$name])
                        ? 
$this->getUploadedFileForTesting($file$uploads$name)
                        : 
$file;
        }, 
$files$names);

        return 
array_combine($names$files);
    }

    
/**
     * Create an UploadedFile instance for testing.
     *
     * @param  array  $file
     * @param  array  $uploads
     * @param  string  $name
     * @return IlluminateHttpUploadedFile
     */
    
protected function getUploadedFileForTesting($file$uploads$name)
    {
        return new 
UploadedFile(
            
$file['tmp_name'], basename($uploads[$name]), $file['type'], $file['size'], $file['error'], true
        
);
    }
}
Онлайн: 1
Реклама