Skip to content

Commit 9f52cd4

Browse files
committed
wip
1 parent edc02a1 commit 9f52cd4

File tree

2 files changed

+111
-41
lines changed

2 files changed

+111
-41
lines changed

config/laravel-playwright.php

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,62 @@
6565
* separators to split the class/alias from the id and column.
6666
*
6767
* eg:
68-
* This will trigger the "first" eloquent method to execute with a "where"
69-
* for the user with an id of 100. This User will then be passed to the
70-
* "createdBy" method on the factory.
68+
* This will trigger the "first" eloquent method to execute with a "where" clause for
69+
* the user with an id of 100. This User will then be passed to the "createdBy"
70+
* method on the factory.
71+
*
7172
* $state = [
7273
* 'createdBy' => [
7374
* ['user@100:id'],
74-
* ]
75+
* ],
76+
* ]
77+
*
78+
* Alternatively you could have passed the FQCN rather than the alias and left off the
79+
* 'id' column because that's the default. As follows:
80+
*
81+
* $state = [
82+
* 'createdBy' => [
83+
* ['\\App\\Models\\User@100'],
84+
* ],
85+
* ]
86+
*
87+
* eg:
88+
* This will use the `param_alias` commented out below to resolve the param for the endsAt
89+
* state method on the factory as a Carbon instance with the value to the right of the
90+
* separator. You can also pass multiple parameters to the state method that resolve using
91+
* aliases as defined below. Parameters for the param_alias should be wrapped in square
92+
* brackets as shown below.
93+
*
94+
* $state = [
95+
* 'endsAt' => [
96+
* ['carbon@[2023-12-25 23:59:59]'],
97+
* ],
98+
* 'liveBetween' => [
99+
* ['carbon@[2023-01-01 00:00:00]', 'carbon@[2023-12-25 23:59:59]'],
100+
* ],
101+
* 'comments' => [
102+
* ['collect@[hello,goodbye]'],
103+
* ],
75104
* ]
76105
*/
77-
'state_separator' => '@',
78-
'model_separator' => ':',
106+
107+
/**
108+
* Used to separate the alias from any other passed options. Should be used first.
109+
*/
110+
'alias_separator' => '@',
111+
112+
/**
113+
* If passing multiple params to be passed into an aliases callable, you can separate
114+
* them using this option.
115+
*/
116+
'param_separator' => ',',
117+
118+
/**
119+
* If you wish to resolve a model from the DB, you can optionally pass the column to compare
120+
* the value to in a where clause. The default column used is `id`. Use this separator to
121+
* separate the desired column from the rest of the passed options.
122+
*/
123+
'column_separator' => ':',
79124

80125
/**
81126
* You can optionally register aliases for models or other objects, rather than having
@@ -84,9 +129,14 @@
84129
* to instruct Laravel-Playwright how to construct an object with the parameters sent
85130
* from your Playwright test suite.
86131
*/
87-
'aliases' => [
132+
'model_aliases' => [
88133
// 'user' => 'App\\Models\\User',
134+
// 'post' => 'App\\Models\\Post',
135+
],
136+
137+
'param_aliases' => [
89138
// 'carbon' => fn($date) => \Carbon\Carbon::create($date),
139+
// 'collect' => fn($items) => \Illuminate\Support\Collection::make($items),
90140
],
91141

92142
],

src/Http/Controllers/LaravelPlaywrightController.php

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
namespace Leeovery\LaravelPlaywright\Http\Controllers;
44

5-
use Illuminate\Database\Eloquent\Factories\Factory;
6-
use Illuminate\Http\Request;
7-
use Illuminate\Routing\Route as RoutingRoute;
85
use Illuminate\Support\Arr;
9-
use Illuminate\Support\Facades\Artisan;
6+
use Illuminate\Support\Str;
7+
use Illuminate\Http\Request;
108
use Illuminate\Support\Facades\DB;
119
use Illuminate\Support\Facades\Route;
12-
use Illuminate\Support\Str;
10+
use Illuminate\Support\Facades\Artisan;
11+
use Illuminate\Routing\Route as RoutingRoute;
12+
use Illuminate\Database\Eloquent\Factories\Factory;
1313

1414
class LaravelPlaywrightController
1515
{
@@ -119,11 +119,11 @@ public function tearDownEnv()
119119
public function routes()
120120
{
121121
return collect(Route::getRoutes()->getRoutes())
122-
->reject(fn (RoutingRoute $route) => Str::of($route->getName())
122+
->reject(fn(RoutingRoute $route) => Str::of($route->getName())
123123
->contains(config('laravel-playwright.route.ignore_names'))
124124
)
125-
->reject(fn (RoutingRoute $route) => is_null($route->getName()))
126-
->mapWithKeys(fn (RoutingRoute $route) => [
125+
->reject(fn(RoutingRoute $route) => is_null($route->getName()))
126+
->mapWithKeys(fn(RoutingRoute $route) => [
127127
$route->getName() => [
128128
'name' => $route->getName(),
129129
'uri' => $route->uri(),
@@ -150,7 +150,7 @@ public function login(Request $request)
150150
->first();
151151
}
152152

153-
if (! $user) {
153+
if (!$user) {
154154
$user = DB::transaction(function () use ($request) {
155155
return $this
156156
->factoryBuilder($this->userClassName($request), $request->input('state', []))
@@ -170,45 +170,27 @@ public function login(Request $request)
170170
protected function userClassName(Request $request)
171171
{
172172
if ($request->has('userModel')) {
173-
return $this->resolveClassAlias($request->input('userModel'));
173+
return $this->resolveModelAlias($request->input('userModel'));
174174
}
175175

176176
return config('laravel-playwright.factory.user');
177177
}
178178

179-
protected function resolveClassAlias(string $alias)
179+
protected function resolveModelAlias(string $alias)
180180
{
181-
return data_get(config('laravel-playwright.factory.aliases'), $alias, $alias);
181+
return data_get(config('laravel-playwright.factory.model_aliases'), $alias, $alias);
182182
}
183183

184184
protected function factoryBuilder($model, $states = []): Factory
185185
{
186-
$factory = $this->resolveClassAlias($model)::factory();
187-
188-
$stateSeparator = config('laravel-playwright.factory.state_separator');
189-
$modelSeparator = config('laravel-playwright.factory.model_separator');
186+
$factory = $this->resolveModelAlias($model)::factory();
190187

191188
foreach (Arr::wrap($states) as $state) {
192189
$attributes = [];
193190
if (is_array($state)) {
194-
$attributes = collect(...array_values($state))->map(function ($attribute) use (
195-
$modelSeparator,
196-
$stateSeparator
197-
) {
198-
if (! is_string($attribute) || ! str_contains($attribute, $stateSeparator)) {
199-
return $attribute;
200-
}
201-
202-
[$model, $id] = explode($stateSeparator, $attribute);
203-
[$id, $column] = array_pad(explode($modelSeparator, $id), 2, null);
204-
$column ??= 'id';
205-
206-
return $this->resolveClassAlias($model)::where($column, $id)->first();
207-
})->filter()->all();
208-
191+
$attributes = $this->buildUpStateAttributes($state);
209192
$state = array_key_first($state);
210193
}
211-
212194
$factory = $factory->{$state}(...$attributes);
213195
}
214196

@@ -252,14 +234,52 @@ public function factory(Request $request)
252234
)
253235
->count($request->integer('count', 1))
254236
->create($request->input('attributes'))
255-
->each(fn ($model) => $model->setHidden([])->setVisible([]))
237+
->each(fn($model) => $model->setHidden([])->setVisible([]))
256238
->load($request->input('load') ?? [])
257-
->pipe(fn ($collection) => $collection->count() > 1
239+
->pipe(fn($collection) => $collection->count() > 1
258240
? $collection
259241
: $collection->first());
260242
});
261243
}
262244

245+
protected function buildUpStateAttributes($state): array
246+
{
247+
if (!is_array($state)) {
248+
return [];
249+
}
250+
251+
$aliasSeparator = config('laravel-playwright.factory.alias_separator');
252+
$paramSeparator = config('laravel-playwright.factory.param_separator');
253+
$columnSeparator = config('laravel-playwright.factory.column_separator');
254+
255+
return collect(...array_values($state))->map(function ($attribute) use (
256+
$columnSeparator,
257+
$paramSeparator,
258+
$aliasSeparator
259+
) {
260+
if (!is_string($attribute) || !str_contains($attribute, $aliasSeparator)) {
261+
return $attribute;
262+
}
263+
264+
if (str_contains($attribute, '[') && str_contains($attribute, ']')) {
265+
[$alias, $options] = explode($aliasSeparator, $attribute);
266+
$options = str($options)->remove('[')->remove(']')->explode($paramSeparator);
267+
return value($this->resolveParamAlias($alias), ...$options);
268+
}
269+
270+
[$modelAlias, $options] = explode($aliasSeparator, $attribute);
271+
[$value, $column] = array_pad(explode($columnSeparator, $options), 2, null);
272+
$column ??= 'id';
273+
274+
return $this->resolveModelAlias($modelAlias)::where($column, $value)->first();
275+
})->filter()->all();
276+
}
277+
278+
protected function resolveParamAlias(string $alias): callable
279+
{
280+
return data_get(config('laravel-playwright.factory.param_aliases'), $alias, $alias);
281+
}
282+
263283
public function logout()
264284
{
265285
auth()->logout();

0 commit comments

Comments
 (0)