KarolZ wrote a comment+100 XP
1w ago
π₯ Lets blaze π₯
KarolZ liked a comment+100 XP
2w ago
@radmax @andrewdv8 @halvarado77
Solution for Browser Test Issues with File Upload Forms
I experienced the same issue and found a solution based on a comment from the next video. The problem occurs when using enctype="multipart/form-data" on forms with Playwright browser tests.
The Fix
The solution is to dynamically set the enctype attribute using Alpine.js, only when a file is actually selected.
Step 1: Update the form's x-data
In resources/views/idea/index.blade.php, add a new hasImage property to track when a file is selected:
<form
x-data="{
status : 'pending',
newLink: '',
links: [],
newStep: '',
steps: [],
hasImage: false
}"
action="{{ route('idea.store') }}"
method="POST"
class="space-y-4"
x-bind:enctype="hasImage ? 'multipart/form-data' : false"
>
Step 2: Replace static enctype with dynamic binding
Replace the static enctype="multipart/form-data" attribute with:
x-bind:enctype="hasImage ? 'multipart/form-data' : false"
Step 3: Update the file input
Add an @change event to the file input to toggle hasImage when a file is selected:
<input
type="file"
name="image"
accept="image/*"
@change="hasImage = $event.target.files.length > 0"
/>
Why This Works
This approach prevents the form from using multipart/form-data encoding when no image is uploaded, which resolves conflicts with Playwright browser tests. The enctype is only set when an actual file is selected by the user.
Benefits
- β Browser tests pass successfully without modifications to Composer packages
- β File uploads still work correctly for end users
- β No impact on form functionality
- β Clean, maintainable solution using Alpine.js
Test Results
After implementing these changes:
PASS Tests\Browser\CreateIdeaTest
β it creates a new idea (1.95s)
Tests: 1 passed (9 assertions)
Duration: 2.42s
Hope this helps!
KarolZ liked a comment+100 XP
1mo ago
Just an observation regarding the content of this lesson: since the instructor is using MS Windows, commands like:
php artisan make:controller Api\V1\TicketController --resource --model=Ticket --requests
will work fine and yield the intended result.
However, anyone using macOS or Linux will find out that this will NOT create a TicketController inside the Api -> v1 directory, but will instead create a ApiV1TicketController in the default Controllers directory.
This is because of the use of the backslash character: that works for Windows, but not in the other cases.
The correct syntax for macOS and Linux would use forward slashes, such as:
php artisan make:controller Api/V1/TicketController --resource --model=Ticket --requests
Not a big deal, but this is something that could bring confusion to beginners, so I thought I should mention it. Great course, thou!
KarolZ liked a comment+100 XP
1mo ago
@mhmdahmd2422 Not trivial at all if it saves time.
KarolZ liked a comment+100 XP
1mo ago
This may be trivial but --api flag when creating controller using artisan command will ditch the create and edit methods in the created controller instead of manually erasing them.
KarolZ liked a comment+100 XP
1mo ago
One can make the argument that it truly doesn't matter how complicated the code is, since the AI will fix whatever may be wrong with it. Personally, I'm a control freak like you and I want to know everything that's happening in "my" code. But philosophically speaking, this need for control is a relic of the pre-AI age. Beautiful, elegant, efficient code will all eventually be sacrificed at the altar of the AI's effectiveness and efficiency, which is a pity, because these are the strengths of Laravel
KarolZ liked a comment+100 XP
1mo ago
Please, turn this repo public or at least, acessible by us!
KarolZ wrote a comment+100 XP
1mo ago
@kumarayush Paste the test itself (code you wrote) not only error msg
KarolZ liked a comment+100 XP
2mos ago
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector;
use Rector\TypeDeclaration\Rector\Closure\AddClosureVoidReturnTypeWhereNoReturnRector;
use Rector\TypeDeclaration\Rector\StmtsAwareInterface\DeclareStrictTypesRector;
use RectorLaravel\Set\LaravelSetProvider;
return RectorConfig::configure()
->withPaths([
__DIR__.'/app',
__DIR__.'/bootstrap',
__DIR__.'/config',
__DIR__.'/public',
__DIR__.'/resources',
__DIR__.'/routes',
__DIR__.'/tests',
])
->withSkip([
__DIR__.'/bootstrap/cache',
__DIR__.'/storage',
__DIR__.'/vendor',
AddClosureVoidReturnTypeWhereNoReturnRector::class,
ReturnTypeFromStrictTypedCallRector::class,
ReturnUnionTypeRector::class,
DeclareStrictTypesRector::class => [
__DIR__.'/resources/views',
],
AddArrowFunctionReturnTypeRector::class,
])
->withPhpSets()
->withSetProviders(LaravelSetProvider::class)
->withImportNames()
->withComposerBased(laravel: true)
->withPreparedSets(
deadCode: true,
codeQuality: true,
typeDeclarations: true,
privatization: true,
earlyReturn: true,
)
->withRules([
DeclareStrictTypesRector::class,
]);
KarolZ liked a comment+100 XP
2mos ago
thanks for the trick about pushing a button and fire a different form. I didn't remeber that. :-)
KarolZ liked a comment+100 XP
2mos ago
@jeffreyway in every video, there's a moment cracks me up. This time, the super explanation for the 419 page expired.. typing fast enough ahahah.
KarolZ wrote a comment+100 XP
3mos ago
π woooo_hoooo !
and what a fancy new comment window π€
KarolZ liked a comment+100 XP
4mos ago
I didn't understand the homework, can clarify more?
KarolZ wrote a comment+100 XP
4mos ago
KarolZ liked a comment+100 XP
5mos ago
@nrthbound I continue to get confused on these two but the way I like to think about it is:
You use an Interface when you want to define a purely behavioral contract without any shared code or state.
You use an Abstract Class when you have shared code or state that need to be inherited by child classes, or when you want to provide a base implementation alongside method definitions.
To expand a little bit more:
When to Use an Interface:
Contract Definition: Use interfaces when you want to define a contract that multiple classes can implement. An interface specifies what methods a class must have, without any implementation.
Dynamic Behavior: When designing a system where components might need to be swapped out at runtime, interfaces provide a flexible way to ensure that those components adhere to a specific API.
No State: If you don't need to hold state (properties), and you're purely defining methods, interfaces should be preferred.
When to Use an Abstract Class:
Common Functionality: If you need to provide some default behavior or shared functionality among several classes, an abstract class allows you to implement methods that can be reused.
State Management: When you need to maintain state (properties), abstract classes can hold member variables and provide constructors to initialize them.
Base Class for Other Classes: If youβre creating a base class that may need to be extended by subclasses with additional features or functionality, use an abstract class to provide that base implementation.
Enhanced Control: Abstract classes allow you to define both abstract methods (which must be implemented by child classes) and concrete methods (with implementation), giving you more control over the inherited methods.
Hopefully that makes sense
KarolZ liked a comment+100 XP
5mos ago
This is the first time I figured out this abstract logic. The key point here is that the parent class is never used by itself, thus it's abstract. But it inherits to the children classes.
I will rewatch. Thanks Jeffrey!