Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new E2E helper commands to avoid anti patterns #17005

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Auth.php
Expand Up @@ -1724,7 +1724,8 @@ public static function dropdownLogin(bool $display = true, $rand = 1)
'display' => false,
'rand' => $rand,
'value' => $default,
'width' => '100%'
'width' => '100%',
'data-cy' => 'LoginAuthDropdown',
]);

if ($display) {
Expand Down
6 changes: 6 additions & 0 deletions src/Dropdown.php
Expand Up @@ -2127,6 +2127,7 @@ public static function showAdvanceDateRestrictionSwitch($enabled = 0)
* - noselect2 : if true, don't use select2 lib
* - templateResult : if not empty, call this as template results of select2
* - templateSelection : if not empty, call this as template selection of select2
* - data-cy : data-cy attribute for e2e testing
*
* Permit to use optgroup defining items in arrays
* array('optgroupname' => array('key1' => 'val1',
Expand Down Expand Up @@ -2164,6 +2165,7 @@ public static function showFromArray($name, array $elements, $options = [])
$param['templateSelection'] = "templateSelection";
$param['track_changes'] = "true";
$param['init'] = true;
$param['data-cy'] = null;

if (is_array($options) && count($options)) {
if (isset($options['value']) && strlen($options['value'])) {
Expand Down Expand Up @@ -2252,6 +2254,10 @@ public static function showFromArray($name, array $elements, $options = [])
$output .= " data-track-changes=''";
}

if (!empty($param['data-cy'])) {
$output .= " data-cy='{$param['data-cy']}'";
AdrienClairembault marked this conversation as resolved.
Show resolved Hide resolved
}

$output .= '>';
$max_option_size = 0;
foreach ($elements as $key => $val) {
Expand Down
38 changes: 34 additions & 4 deletions templates/pages/login.html.twig
Expand Up @@ -50,7 +50,15 @@
</div>
<div class="mb-3">
<label class="form-label" for="login_name">{{ __('Login') }}</label>
<input type="text" class="form-control" id="login_name" name="{{ namfield }}" placeholder="" tabindex="1"/>
<input
type="text"
class="form-control"
id="login_name"
name="{{ namfield }}"
placeholder=""
tabindex="1"
data-cy="UsernameInput"
/>
</div>
<div class="mb-4">
<label class="form-label" for="login_password">
Expand Down Expand Up @@ -80,7 +88,16 @@
{% endif %}
{% endif %}
</label>
<input type="password" class="form-control" id="login_password" name="{{ pwdfield }}" placeholder="" autocomplete="off" tabindex="2"/>
<input
type="password"
class="form-control"
id="login_password"
name="{{ pwdfield }}"
placeholder=""
autocomplete="off"
tabindex="2"
data-cy="PasswordInput"
/>
</div>

{% if constant('GLPI_DEMO_MODE') %}
Expand All @@ -100,14 +117,27 @@
{% if config('login_remember_time') %}
<div class="mb-2">
<label class="form-check" for="login_remember">
<input type="checkbox" class="form-check-input" id="login_remember" name="{{ rmbfield }}" {{ config('login_remember_default') ? 'checked' : '' }}/>
<input
type="checkbox"
class="form-check-input"
id="login_remember"
name="{{ rmbfield }}"
{{ config('login_remember_default') ? 'checked' : '' }}
data-cy="RememberMeCheckbox"
/>
<span class="form-check-label">{{ __('Remember me') }}</span>
</label>
</div>
{% endif %}

<div class="form-footer">
<button type="submit" name="submit" class="btn btn-primary w-100" tabindex="3">
<button
type="submit"
name="submit"
class="btn btn-primary w-100"
tabindex="3"
data-cy="LoginButton"
>
{{ __('Sign in') }}
</button>
</div>
Expand Down
80 changes: 52 additions & 28 deletions tests/cypress/support/commands.js
Expand Up @@ -48,13 +48,13 @@ Cypress.Commands.add('login', (username = 'e2e_tests', password = 'glpi') => {
cy.blockGLPIDashboards();
cy.visit('/');
cy.title().should('eq', 'Authentication - GLPI');
cy.get('#login_name').type(username);
cy.get('input[type="password"]').type(password);
cy.get('#login_remember').check();
cy.getBySelector('UsernameInput').type(username);
cy.getBySelector('PasswordInput').type(password);
cy.getBySelector('RememberMeCheckbox').check();
// Select 'local' from the 'auth' dropdown
cy.get('select[name="auth"]').select('local', { force: true });
cy.getBySelector('LoginAuthDropdown').select('local', { force: true });

cy.get('button[type="submit"]').click();
cy.getBySelector('LoginButton').click();
// After logging in, the url should contain /front/central.php or /front/helpdesk.public.php
cy.url().should('match', /\/front\/(central|helpdesk.public).php/);
},
Expand Down Expand Up @@ -154,30 +154,36 @@ Cypress.Commands.add('awaitTinyMCE', {
Cypress.Commands.overwrite('type', (originalFn, subject, text, options) => {
// If the subject is a textarea, see if there is a TinyMCE editor for it
// If there is, set the content of the editor instead of the textarea
if (subject.is('textarea')) {
cy.get(`textarea[name="${subject.attr('name')}"]`).invoke('attr', 'id').then((textarea_id) => {
cy.window().then((win) => {
if (win.tinymce.get(textarea_id)) {
if (options !== undefined && options.interactive) {
// Use 'should' off the 'window()' to wait for the required property to be set.
cy.window().should('satisfy', () => {
return typeof win.tinymce.get(textarea_id).dom.doc !== 'undefined';
});
cy.wrap(win.tinymce.get(textarea_id).dom.doc).within(() => {
cy.get('#tinymce[contenteditable="true"]').should('exist');
cy.get('#tinymce p').type(text, options);
});
} else {
win.tinymce.get(textarea_id).setContent(text);
}
return;
}
originalFn(subject, text, options);
});
});
return;
if (!subject.is('textarea')) {
return originalFn(subject, text, options);
}
return originalFn(subject, text, options);

cy.window().as('win');
cy
.get(`textarea[name="${subject.attr('name')}"]`)
.invoke('attr', 'id')
.as('textarea_id')
;

cy.getMany(["@win", "@textarea_id"]).then(([win, textarea_id]) => {
if (!win.tinymce.get(textarea_id)) {
return originalFn(subject, text, options);
}

if (options === undefined || !options.interactive) {
win.tinymce.get(textarea_id).setContent(text);
return;
}

// Use 'should' off the 'window()' to wait for the required property to be set.
cy.window().should('satisfy', () => {
return typeof win.tinymce.get(textarea_id).dom.doc !== 'undefined';
});
cy.wrap(win.tinymce.get(textarea_id).dom.doc).within(() => {
cy.get('#tinymce[contenteditable="true"]').should('exist');
cy.get('#tinymce p').type(text, options);
});
});
});

/**
Expand Down Expand Up @@ -262,3 +268,21 @@ Cypress.Commands.add('validateSelect2Loading', {prevSubject: true}, (subject) =>
});
});
});

Cypress.Commands.add('getBySelector', (selector, ...args) => {
const escaped_selector = Cypress.$.escapeSelector(selector);
return cy.get(`[data-cy=${escaped_selector}]`, ...args);
});

Cypress.Commands.add('findBySelector', {prevSubject: true}, (subject, selector, ...args) => {
const escaped_selector = Cypress.$.escapeSelector(selector);
return subject.find(`[data-cy=${escaped_selector}]`, ...args);
});

Cypress.Commands.add("getMany", (names) => {
const values = [];
for (const arg of names) {
cy.get(arg).then((value) => values.push(value));
}
return cy.wrap(values);
});