@@ -79,129 +79,6 @@ The most important part is the `_generated\AcceptanceTesterActions` trait, which
79
79
It knows which module executes which action and passes parameters into it.
80
80
This trait was created by running `codecept build` and is regenerated each time module or configuration changes.
81
81
82
- <<<<<<< HEAD
83
-
84
- ## PageObjects
85
-
86
- For acceptance and functional testing, we will not only need to have common actions being reused across different tests,
87
- we should have buttons, links and form fields being reused as well. For those cases we need to implement
88
- the [PageObject pattern](http://docs.seleniumhq.org/docs/06_test_design_considerations.jsp#page-object-design-pattern),
89
- which is widely used by test automation engineers. The PageObject pattern represents a web page as a class
90
- and the DOM elements on that page as its properties, and some basic interactions as its methods.
91
- PageObjects are very important when you are developing a flexible architecture of your tests.
92
- Do not hard-code complex CSS or XPath locators in your tests but rather move them into PageObject classes.
93
-
94
- Codeception can generate a PageObject class for you with command:
95
-
96
- {% highlight bash %}
97
-
98
- php vendor/bin/codecept generate:pageobject Login
99
-
100
- {% endhighlight %}
101
-
102
- This will create a `Login` class in `tests/_support/Page`.
103
- The basic PageObject is nothing more than an empty class with a few stubs.
104
- It is expected that you will populate it with the UI locators of a page it represents
105
- and then those locators will be used on a page.
106
- Locators are represented with public static properties:
107
-
108
- {% highlight php %}
109
-
110
- <?php
111
- namespace Page;
112
-
113
- class Login
114
- {
115
- public static $URL = '/login';
116
-
117
- public static $usernameField = '#mainForm #username';
118
- public static $passwordField = '#mainForm input[name=password]';
119
- public static $loginButton = '#mainForm input[type=submit]';
120
- }
121
-
122
- {% endhighlight %}
123
-
124
- And this is how this page object can be used in a test:
125
-
126
- {% highlight php %}
127
-
128
- <?php
129
- $I-> amOnPage(\Page\Login::$URL);
130
- $I->fillField(\Page\Login::$usernameField, 'bill evans');
131
- $I->fillField(\Page\Login::$passwordField, 'debby');
132
- $I->click(\Page\Login::$loginButton);
133
- $I->see('Welcome, bill');
134
-
135
- {% endhighlight %}
136
-
137
- As you see, you can freely change markup of your login page, and all the tests interacting with this page
138
- will have their locators updated according to properties of LoginPage class.
139
-
140
- But let's move further. The PageObject concept specifies that the methods for the page interaction should also be stored in a PageObject class.
141
-
142
- Let's define a `login` method in this class:
143
-
144
- {% highlight php %}
145
-
146
- <? php
147
- namespace Page;
148
-
149
- class Login
150
- {
151
- public static $URL = '/login';
152
-
153
- public static $usernameField = '#mainForm #username';
154
- public static $passwordField = '#mainForm input[name=password]';
155
- public static $loginButton = '#mainForm input[type=submit]';
156
-
157
- /**
158
- * @var AcceptanceTester
159
- */
160
- protected $tester;
161
-
162
- // we inject AcceptanceTester into our class
163
- public function __construct(\AcceptanceTester $I)
164
- {
165
- $this-> tester = $I;
166
- }
167
-
168
- public function login($name, $password)
169
- {
170
- $I = $this->tester;
171
-
172
- $I->amOnPage(self::$URL);
173
- $I->fillField(self::$usernameField, $name);
174
- $I->fillField(self::$passwordField, $password);
175
- $I->click(self::$loginButton);
176
- }
177
- }
178
-
179
- {% endhighlight %}
180
-
181
- If you specify which object you need for a test, Codeception will try to create it using the dependency injection container.
182
- In the case of a PageObject you should declare a class as a parameter for a test method:
183
-
184
- {% highlight php %}
185
-
186
- <? php
187
- class UserCest
188
- {
189
- function showUserProfile(AcceptanceTester $I, \Page\Login $loginPage)
190
- {
191
- $loginPage-> login('bill evans', 'debby');
192
- $I->amOnPage('/profile');
193
- $I->see('Bill Evans Profile', 'h1');
194
- }
195
- }
196
-
197
- {% endhighlight %}
198
-
199
- The dependency injection container can construct any object that requires any known class type.
200
- For instance, `Page\Login` required `AcceptanceTester`, and so it was injected into `Page\Login` constructor,
201
- and PageObject was created and passed into method arguments. You should explicitly specify
202
- the types of required objects for Codeception to know what objects should be created for a test.
203
- Dependency Injection will be described in the next chapter.
204
- =======
205
82
> Use actor classes to set common actions which can be used accross a suite.
206
83
207
84
@@ -405,98 +282,6 @@ If you feel like adding too many actions into your Actor class
405
282
406
283
> Use StepObjects when you have multiple areas of applications or multiple roles.
407
284
408
- >>>>>>> 82997221b762bc09876379f9f30906c9d364a4f5
409
-
410
- ## StepObjects
411
-
412
- StepObjects are great if you need some common functionality for a group of tests.
413
- Let's say you are going to test an admin area of a site. You probably won't need the same actions from the admin area
414
- while testing the front end, so it's a good idea to move these admin-specific tests into their own class.
415
- We call such a classes StepObjects.
416
-
417
- Lets create an Admin StepObject with the generator:
418
-
419
- {% highlight bash %}
420
-
421
- php vendor/bin/codecept generate:stepobject acceptance Admin
422
-
423
- {% endhighlight %}
424
-
425
- You can supply optional action names. Enter one at a time, followed by a newline.
426
- End with an empty line to continue to StepObject creation.
427
-
428
- {% highlight bash %}
429
-
430
- php vendor/bin/codecept generate:stepobject acceptance Admin
431
- Add action to StepObject class (ENTER to exit): loginAsAdmin
432
- Add action to StepObject class (ENTER to exit):
433
- StepObject was created in /tests/acceptance/_support/Step/Acceptance/Admin.php
434
-
435
- {% endhighlight %}
436
-
437
- This will generate a class in `/tests/_support/Step/Acceptance/Admin.php` similar to this:
438
-
439
- {% highlight php %}
440
-
441
- <? php
442
- namespace Step\Acceptance;
443
-
444
- class Admin extends \AcceptanceTester
445
- {
446
- public function loginAsAdmin()
447
- {
448
- $I = $this;
449
- }
450
- }
451
-
452
- {% endhighlight %}
453
-
454
- As you see, this class is very simple. It extends the `AcceptanceTester` class,
455
- meaning it can access all the methods and properties of `AcceptanceTester`.
456
-
457
- The `loginAsAdmin` method may be implemented like this:
458
-
459
- {% highlight php %}
460
-
461
- <?php
462
- namespace Step\Acceptance;
463
-
464
- class Admin extends \AcceptanceTester
465
- {
466
- public function loginAsAdmin()
467
- {
468
- $I = $this;
469
- $I-> amOnPage('/admin');
470
- $I->fillField('username', 'admin');
471
- $I->fillField('password', '123456');
472
- $I->click('Login');
473
- }
474
- }
475
-
476
- {% endhighlight %}
477
-
478
-
479
- StepObject can be instantiated automatically when used inside the Cest format:
480
-
481
- {% highlight php %}
482
-
483
- <? php
484
- class UserCest
485
- {
486
- function showUserProfile(\Step\Acceptance\Admin $I)
487
- {
488
- $I-> loginAsAdmin();
489
- $I->amOnPage('/admin/profile');
490
- $I->see('Admin Profile', 'h1');
491
- }
492
- }
493
-
494
- {% endhighlight %}
495
-
496
- If you have a complex interaction scenario, you may use several step objects in one test.
497
- If you feel like adding too many actions into your Actor class
498
- (which is AcceptanceTester in this case) consider moving some of them into separate StepObjects.
499
-
500
285
501
286
## Conclusion
502
287
0 commit comments