Laravel 5: Creating Package

Laravel 5: Creating Package

I would not be surprised, if when I get back to it some time later it is not going to work. It took me awhile, lots of teeth gritting and almost a dozen tutorials to make it work and I am not entirely sure, why the heck attempts before successful one did not work.

Try reading also this.
Also this for some testing ideas.
Here is also not a bad read.

Want some laugh? Read this, how Laravel folks screwed up.


Step one

Create this folder structure inside of folder ‘packages’, which should be sitting in root path of your Laravel installation.
You can change names later.
But for now, stick “religiously” to naming and even case – to the letter and last dot.

Step two

Open your console and get into folder \imagecache :

Once inside of mentioned dir, run this command:

… and answer some questions. They are simple enough.

You should get something like this:

This is your package JSON file.
It should reside in topmost folder of your package – in this case: \imagecache.

Step three

Create files as shown on image:

  1. this is your service provider
  2. this is your work class, where you actually do something
  3. and this is your Facade, that allows to easy access toy your package output anywhere

And here is code.

service provider

class

facade

Step four

Now we have to register stuff with \config\app.

Open this file: config\app.php and add to :

and to:

Step five

Update your main composer file (composer.json), one that sits in root folder of your Laravel install.

Just find ‘autoload section and ADD THIS LINE marked content.

You have to run composer command – since you adjusted composer.json:

Step six

This is how you use it:

 

If you did all as outlined and LARAVEL DEITY is in good mood, you should see this:

BTW:

I tried to use this new Laravel auto-discovery of ServiceProviders, where you could spice up a bit composer.json:

… and do without adding:

… to app.providers, but I could not make it work.

 

Laravel 5: Testing – Laravel Dusk testing – login shortcut

Cheatsheet: Laravel Dusk testing – login shortcut

Create default user and quickly use it to login. However, there is a problem with this approach.

If you look into /test/Browser folder, you will see another called: /Pages.
Here’s what Laravel docs (5.6) have to say about this.

Scroll slightly below and you will see this Artisan command:

When you run it, it will create class Login inside of /Pages.
This will be our default user login shortcut class.

But it is not ready yet.
We have to prep it a bit to serve its purpose.
We will add loginUser() method to it.
This will be a method, that will be used behind scenes to log in defined there default user.

Before I go to this, a word of caution: do not name your login method login(), but anything else – I used loginUser(), as login() name goes head on with another, Laravel native login() method and is being overridden, giving you error like this, when you attempt to run your test:

Login methods clash was not spotted by me. All credit due is here

Our Login class with changes is below.
A few tidbits in method comments to make things easier to understand – when you learn (or forgot something), nothing seems to be obvious.

And here is Login class with changes:

Now, how to use it.


There is a PROBLEM with this approach.

It is good, if you use Laravel out of the box single level authorization, which is good for blog, when supported by user roles.

Simply you have single single admin and allow access rights based on roles.

In most cases I worked on, I needed 3 separate site areas, with two, that needed authentication.

Take ecommerce: backend admin / customer admin.
Take any company website, that allows users to have accounts: backend admin / customer admin.

You could try roles, but good luck with that.

You need multi-level authentication capacity
Note: what you find at the end of the link listed above, was written for Laravel 5.2 and may need some touchups.

Laravel does not have multi-level auth out of the box (as of 5.6)

So, if you are using Laravel provided single level authentication, you are in luck.

You can use this method described above.

You can also use methods stored in here:

Note:

If you are trying to use these methods and getting error to the tune of this:

… you have to override protected user() method from vendor\laravel\dusk\src\TestCase.php in:

  • your TestClass that extends tests\DuskTestCase, or
  • in tests\DuskTestCase.php itself

Whichever serves you best.

Class tests\DuskTestCase seems best, as all your TestClasses will extend it, so you do it once and use it from now on.

Now, as I mentioned these methods are rigged to serve Laravel built in authentication.

Just look into: \vendor\laravel\dusk\src\DuskServiceProvider.php and you’ll see rigged routes, like:

Then these routes work with hardcoded methods in vendor\laravel\dusk\src\Concerns\InteractsWithAuthentication.php:

You could set this for your needs in DuskServiceProvider, but that would also require rewriting methods in vendor\laravel\dusk\src\Concerns\InteractsWithAuthentication.php, which is nothing short of messing with core files, that can be replaced in next framework update.

Not really recommended.

You could overload these methods, but then, why not writing your own 😉

Better use other means of checking login.

They are all described in Tests section.

 

Laravel 5: Testing – Cheatsheet: Laravel Dusk testing – cookies

Cheatsheet: Laravel Dusk testing – cookies

Get, or set testing cookies.

[one_third]
set encrypted cookie()
get encrypted cookie()
[/one_third][one_third]
set plainCookie()
get plainCookie()
[/one_third][one_third_last]
addCookie
deleteCookie
[/one_third_last]


A small cookie reminder.

Parameter Description
name Required. Specifies the name of the cookie
value Optional. Specifies the value of the cookie
expire Optional. Specifies when the cookie expires. The value: time()+86400*30, will set the cookie to expire in 30 days. If this parameter is omitted or set to 0, the cookie will expire at the end of the session (when the browser closes). Default is 0
path Optional. Specifies the server path of the cookie. If set to “/”, the cookie will be available within the entire domain. If set to “/php/”, the cookie will only be available within the php directory and all sub-directories of php. The default value is the current directory that the cookie is being set in
domain Optional. Specifies the domain name of the cookie. To make the cookie available on all subdomains of example.com, set domain to “example.com”. Setting it to www.example.com will make the cookie only available in the www subdomain
secure Optional. Specifies whether or not the cookie should only be transmitted over a secure HTTPS connection. TRUE indicates that the cookie will only be set if a secure connection exists. Default is FALSE
httpOnly Optional. If set to TRUE the cookie will be accessible only through the HTTP protocol (the cookie will not be accessible by scripting languages). This setting can help to reduce identity theft through XSS attacks. Default is FALSE
above table taken from: w3schools.com



This is same as setting encrypted cookies, you just change method name cookie(), to plainCookie().
Click here to see how it is done


This is same as getting encrypted cookies, you just change method name cookie(), to plainCookie().
Click here to see how it is done


addCookie()

This method is used internally by cookie() and plainCookie() methods.
It is used pretty much same way.
It has last parameter $encrypt, which is set to true in cookie(), and to false in plainCookie().

For examples, look above.


deleteCookie()

 

 

Laravel 5: Testing – Cheatsheet: Laravel Dusk testing – delayed action

Cheatsheet: Laravel Dusk testing – delayed action

Wait for something to happen, or/and delay by some time.

[one_third]
whenAvailable
waitFor
waitUntilMissing
waitForText
[/one_third][one_third]
waitForLink
waitForLocation
waitUntil
waitForDialog
[/one_third][one_third_last]
waitForReload
waitUsing
[/one_third_last]


whenAvailable

waitFor

waitUntilMissing

waitForText

waitForLocation

waitUntil

waitForDialog

waitForReload

waitUsing

 

Laravel 5: Testing – Cheatsheet: Laravel Dusk testing element interactions

Cheatsheet: Laravel Dusk testing element interaction methods

Laravel Dusk: list of page elements interaction methods.

Dynamically assign, or remove values from page elements.

[one_third]
clickLink
value
text
attribute
keys
type
append
clear
select
[/one_third][one_third]
radio
check
uncheck
attach
press
pressAndWaitFor
script
drag
dragUp
[/one_third][one_third_last]
dragDown
dragLeft
dragRight
dragOffset
acceptDialog
typeInDialog
dismissDialog
[/one_third_last]


Methods listed above in dark color have not been tested (yet)

Important – Dialog Methods

This is not about modal dialogs, e.g. Bootstrap Modal Dialog.
This method tests these little pesky, page locking JavaScript
popups triggered by JS code alert(‘some stuff here’);


value

text

attribute

keys

type

append

clear

select

radio

check

uncheck

attach

press (click) button

pressAndWaitFor

script

 

 

Laravel 5: Testing – Cheatsheet: Laravel Dusk testing assertions

Cheatsheet: Laravel Dusk testing assertions

Laravel Dusk: list of assertions.


[one_third]
assertTitle
assertTitleContains
assertUrlIs
assertPathIs
assertPathBeginsWith
assertPathIsNot
assertFragmentIs
assertFragmentBeginsWith
assertFragmentIsNot
assertRouteIs
assertQueryStringHas
assertQueryStringMissing
assertHasCookie
assertCookieMissing
[/one_third][one_third]
assertCookieValue
assertPlainCookieValue
assertSourceHas
assertSourceMissing
assertSee
assertDontSee
assertSeeIn
assertDontSeeIn
assertSeeLink
assertDontSeeLink
assertInputValue
assertInputValueIsNot
assertChecked
assertNotChecked
[/one_third][one_third_last]
assertRadioSelected
assertRadioNotSelected
assertSelected
assertNotSelected
assertSelectHasOptions
assertSelectMissingOptions
assertSelectHasOption
assertSelectMissingOption
assertValue
assertVisible
assertPresent
assertMissing
assertDialogOpened
[/one_third_last]


Title

assertTitle

assertTitleContains

Url

assertUrlIs

Path (relative)

assertPathIs

assertPathBeginsWith

assertPathIsNot

Url fragment

What is url fragment?

assertFragmentIs

assertFragmentBeginsWith

assertFragmentIsNot

Route

assertRouteIs

Query: url params (GET key/val pairs) testing

assertQueryStringHas

assertQueryStringMissing

Cookie

assertHasCookie

assertCookieMissing

assertCookieValue

assertPlainCookieValue

HTML Source Code

assertSourceHas

assertSourceMissing

Text on page

assertSee

assertDontSee

Text on page inside of selectors

A few words about selectors.

Selectors seem to be HTML tags – see here, but also elements identified by ID, CLASS
They are case insensitive, your tag could be ‘H1’, but in assertion you can ask for ‘h1’.
Allows for text to be inside of other elements, like: a, label, input etc. – sample:


assertSeeIn

assertDontSeeIn

Link

Input

assertInputValue

assertInputValueIsNot

Checkbox

assertChecked

assertNotChecked

Radio

assertRadioSelected

assertRadioNotSelected

Drop-down (<select>)

assertSelected

assertNotSelected

assertSelectHasOptions

assertSelectMissingOptions

assertSelectHasOption

assertSelectMissingOption

Selector (form field etc.- all that have attr value) current value

assertValue

Visibility

assertVisible

seem to add functionality to all ‘see in code’ methods described above

assertPresent

assertMissing

Dialog Open

assertDialogOpened

 

Laravel 5: Testing – Laravel Dusk – browser testing – general info

Testing – Laravel Dusk – browser testing – general info

Laravel Dusk is enriched replacement for ‘Integrated Package’.

Laravel Dusk requires extra setup. More: read here.
Cheatsheets
Most used Testing assertions are described here:
  1. PHPunit testing
  2. Dusk browser testing (selenium-like)

Rest of them can be found in this directory: vendor\laravel\dusk\src\Concerns\

General
Generating Dusk test files

Running Dusk tests

You can run @group PHPUnit annotation:

… but you cannot run –testsuite:

Fortunately, you do not have to use php artisan dusk at all.
Just use standard phpunit commands for dusk using testsuites and groups and other annotations, e.g.:

or

For testsuite, you have to add to phpunit.xml:

 

Now you have access to all commands standard PHPUnit runs, like:

  • –filter <pattern> : Filter which tests to run.
  • –testsuite <pattern> : Filter which testsuite to run.
  • –group … : Only runs tests from the specified group(s).
  • –exclude-group … : Exclude tests from the specified group(s).
  • –list-groups : List available test groups.
  • –list-suites : List available test suites.
  • –test-suffix … : Only search for test in files with specified suffix(es)

 

More PHPUnit CLI commands – here.

Some samples
Creating Browsers

Browser is a set of instructions testing some functionality as user would by opening browser and interacting with it.

Lets take this ‘browser’ for example:

So, as you see in comments above, you just construct – step by step scenario, exactly resembling actions a normal user would do.
If this is not intuitive … I do not know what is.

Lets see another example, where actions had to be split among multiple ‘browsers’.

Great stuff.


Next page: detailed info about all available tools.

 

Laravel 5: Testing – Cheatsheet: Laravel specific PHPUnit testing assertion

Cheatsheet – Laravel Specific PHPUnit Testing Assertion

All PHPUnit docs page with all methods and annotations – see here

[one_third]
assertSuccessful
assertStatus
assertRedirect
assertHeader
assertHeaderMissing
assertPlainCookie
assertCookie
assertCookieExpired
assertCookieMissing
assertSee
assertSeeInOrder
[/one_third][one_third]
assertDontSee
assertSeeText
assertDontSeeText
assertSeeTextInOrder
assertJson
assertExactJson
assertJsonFragment
assertJsonMissing
assertJsonMissingExact
assertJsonStructure
assertJsonCount
[/one_third][one_third_last]
assertJsonValidationErrors
assertViewIs
assertViewHas
assertViewHasAll
assertViewMissing
assertSessionHas
assertSessionHasAll
assertSessionHasErrors
assertSessionHasErrorsIn
assertSessionMissing
[/one_third_last]


LARAVEL SPECIFIC TESTING HELPER METHODS

Check HTTP code
assertSuccessful

assertStatus

Redirects
assertRedirect

Headers
assertHeader

assertHeader

Cookies
assertPlainCookie

assertCookie

assertCookieExpired

assertCookieMissing

Check response page code – including HTML tags
assertSee

assertSeeInOrder

assertDontSee

Check response page code – text only
assertSeeText

assertDontSeeText

assertSeeTextInOrder

JSON
assertJson

assertExactJson

assertJsonFragment

assertJsonMissing

assertJsonMissingExact

assertJsonStructure

assertJsonCount

assertJsonValidationErrors

decodeResponseJson

Views
assertViewIs