MOBILE-3947 behat: Fix some snapshot failures
@ -19,7 +19,7 @@
 | 
				
			|||||||
                <ion-row class="ion-justify-content-between ion-align-items-center ion-no-padding">
 | 
					                <ion-row class="ion-justify-content-between ion-align-items-center ion-no-padding">
 | 
				
			||||||
                    <ion-col class="addon-block-timeline-activity-main ion-no-padding">
 | 
					                    <ion-col class="addon-block-timeline-activity-main ion-no-padding">
 | 
				
			||||||
                        <ion-row class="ion-justify-content-between ion-align-items-center ion-nowrap ion-no-padding">
 | 
					                        <ion-row class="ion-justify-content-between ion-align-items-center ion-nowrap ion-no-padding">
 | 
				
			||||||
                            <ion-col class="addon-block-timeline-activity-time ion-no-padding">
 | 
					                            <ion-col class="addon-block-timeline-activity-time ion-no-padding ion-text-nowrap">
 | 
				
			||||||
                                <small>{{event.timesort * 1000 | coreFormatDate:"strftimetime24" }}</small>
 | 
					                                <small>{{event.timesort * 1000 | coreFormatDate:"strftimetime24" }}</small>
 | 
				
			||||||
                                <core-mod-icon *ngIf="event.iconUrl" [modicon]="event.iconUrl" [componentId]="event.instance"
 | 
					                                <core-mod-icon *ngIf="event.iconUrl" [modicon]="event.iconUrl" [componentId]="event.instance"
 | 
				
			||||||
                                    [modname]="event.modulename" [purpose]="event.purpose" />
 | 
					                                    [modname]="event.modulename" [purpose]="event.purpose" />
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,6 @@ Feature: Test messages navigation in the app
 | 
				
			|||||||
      | teacher | C1     | editingteacher |
 | 
					      | teacher | C1     | editingteacher |
 | 
				
			||||||
      | student | C1     | student        |
 | 
					      | student | C1     | student        |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @ionic7_failure
 | 
					 | 
				
			||||||
  Scenario: Avoid recursive links to profile
 | 
					  Scenario: Avoid recursive links to profile
 | 
				
			||||||
    Given I entered the app as "teacher"
 | 
					    Given I entered the app as "teacher"
 | 
				
			||||||
    When I press "Messages" in the app
 | 
					    When I press "Messages" in the app
 | 
				
			||||||
 | 
				
			|||||||
| 
		 Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB  | 
| 
		 Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB  | 
@ -58,7 +58,6 @@ Feature: Test basic usage of assignment activity in app
 | 
				
			|||||||
    Then I should find "Online text submissions" in the app
 | 
					    Then I should find "Online text submissions" in the app
 | 
				
			||||||
    And I should find "Submission test edited" in the app
 | 
					    And I should find "Submission test edited" in the app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @ionic7_failure
 | 
					 | 
				
			||||||
  Scenario: Edit/Add submission (online text) & Add new attempt from previous submission & Submit for grading
 | 
					  Scenario: Edit/Add submission (online text) & Add new attempt from previous submission & Submit for grading
 | 
				
			||||||
    # Submit first attempt as a student
 | 
					    # Submit first attempt as a student
 | 
				
			||||||
    Given I entered the assign activity "assignment1" on course "Course 1" as "student1" in the app
 | 
					    Given I entered the assign activity "assignment1" on course "Course 1" as "student1" in the app
 | 
				
			||||||
 | 
				
			|||||||
| 
		 Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB  | 
@ -191,7 +191,6 @@ Feature: Attempt a quiz in app
 | 
				
			|||||||
    Then I should find "The correct answer is: Berlin" in the app
 | 
					    Then I should find "The correct answer is: Berlin" in the app
 | 
				
			||||||
    And I should find "Mark 1.00 out of 1.00" in the app
 | 
					    And I should find "Mark 1.00 out of 1.00" in the app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @ionic7_failure
 | 
					 | 
				
			||||||
  Scenario: Submit a quiz & Review a quiz attempt
 | 
					  Scenario: Submit a quiz & Review a quiz attempt
 | 
				
			||||||
    Given I entered the quiz activity "Quiz 1" on course "Course 1" as "student1" in the app
 | 
					    Given I entered the quiz activity "Quiz 1" on course "Course 1" as "student1" in the app
 | 
				
			||||||
    When I press "Attempt quiz now" in the app
 | 
					    When I press "Attempt quiz now" in the app
 | 
				
			||||||
 | 
				
			|||||||
| 
		 Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB  | 
| 
		 Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB  | 
@ -10,20 +10,20 @@
 | 
				
			|||||||
        <ion-select id="{{row.id}}" [name]="row.name" [(ngModel)]="row.selected" interface="action-sheet" [disabled]="row.disabled"
 | 
					        <ion-select id="{{row.id}}" [name]="row.name" [(ngModel)]="row.selected" interface="action-sheet" [disabled]="row.disabled"
 | 
				
			||||||
            [cancelText]="'core.cancel' | translate"
 | 
					            [cancelText]="'core.cancel' | translate"
 | 
				
			||||||
            [ngClass]="{'addon-qtype-match-correct': row.isCorrect === 1,'addon-qtype-match-incorrect': row.isCorrect === 0}">
 | 
					            [ngClass]="{'addon-qtype-match-correct': row.isCorrect === 1,'addon-qtype-match-incorrect': row.isCorrect === 0}">
 | 
				
			||||||
            <div slot="label">
 | 
					            <div slot="label" class="flew-row">
 | 
				
			||||||
                <core-format-text [component]="component" [componentId]="componentId" [text]="row.text" [contextLevel]="contextLevel"
 | 
					                <core-format-text [component]="component" [componentId]="componentId" [text]="row.text" [contextLevel]="contextLevel"
 | 
				
			||||||
                    [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
 | 
					                    [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
 | 
				
			||||||
                <label class="accesshide" for="{{row.id}}" *ngIf="row.accessibilityLabel">
 | 
					                <label class="accesshide" for="{{row.id}}" *ngIf="row.accessibilityLabel">
 | 
				
			||||||
                    {{ row.accessibilityLabel }}
 | 
					                    {{ row.accessibilityLabel }}
 | 
				
			||||||
                </label>
 | 
					                </label>
 | 
				
			||||||
 | 
					                <ion-icon *ngIf="row.isCorrect === 1" class="core-correct-icon" name="fas-check" color="success" slot="end"
 | 
				
			||||||
 | 
					                    [attr.aria-label]="'core.question.correct' | translate" />
 | 
				
			||||||
 | 
					                <ion-icon *ngIf="row.isCorrect === 0" class="core-correct-icon" name="fas-xmark" color="danger" slot="end"
 | 
				
			||||||
 | 
					                    [attr.aria-label]="'core.question.incorrect' | translate" />
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <ion-select-option *ngFor="let option of row.options" [value]="option.value">
 | 
					            <ion-select-option *ngFor="let option of row.options" [value]="option.value">
 | 
				
			||||||
                {{option.label}}
 | 
					                {{option.label}}
 | 
				
			||||||
            </ion-select-option>
 | 
					            </ion-select-option>
 | 
				
			||||||
        </ion-select>
 | 
					        </ion-select>
 | 
				
			||||||
        <ion-icon *ngIf="row.isCorrect === 1" class="core-correct-icon" name="fas-check" color="success" slot="end"
 | 
					 | 
				
			||||||
            [attr.aria-label]="'core.question.correct' | translate" />
 | 
					 | 
				
			||||||
        <ion-icon *ngIf="row.isCorrect === 0" class="core-correct-icon" name="fas-xmark" color="danger" slot="end"
 | 
					 | 
				
			||||||
            [attr.aria-label]="'core.question.incorrect' | translate" />
 | 
					 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
</section>
 | 
					</section>
 | 
				
			||||||
 | 
				
			|||||||
@ -10,4 +10,16 @@
 | 
				
			|||||||
    .addon-qtype-match-incorrect {
 | 
					    .addon-qtype-match-incorrect {
 | 
				
			||||||
        color: var(--danger);
 | 
					        color: var(--danger);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ion-select::part(label) {
 | 
				
			||||||
 | 
					        flex-grow: 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    div.flew-row {
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					        display: flex;
 | 
				
			||||||
 | 
					        flex-direction: row;
 | 
				
			||||||
 | 
					        justify-content: space-between;
 | 
				
			||||||
 | 
					        align-items: center;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,20 +18,21 @@
 | 
				
			|||||||
        <ion-item class="ion-text-wrap answer" *ngFor="let option of question.options">
 | 
					        <ion-item class="ion-text-wrap answer" *ngFor="let option of question.options">
 | 
				
			||||||
            <ion-checkbox [attr.name]="option.name" [(ngModel)]="option.checked" [disabled]="option.disabled"
 | 
					            <ion-checkbox [attr.name]="option.name" [(ngModel)]="option.checked" [disabled]="option.disabled"
 | 
				
			||||||
                [color]='(option.isCorrect === 1 ? "success": "") + (option.isCorrect === 0 ? "danger": "")'>
 | 
					                [color]='(option.isCorrect === 1 ? "success": "") + (option.isCorrect === 0 ? "danger": "")'>
 | 
				
			||||||
 | 
					                <div>
 | 
				
			||||||
                    <div [class]="option.class">
 | 
					                    <div [class]="option.class">
 | 
				
			||||||
                    <core-format-text [component]="component" [componentId]="componentId" [text]="option.text" [contextLevel]="contextLevel"
 | 
					                        <core-format-text [component]="component" [componentId]="componentId" [text]="option.text"
 | 
				
			||||||
                        [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
 | 
					                            [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
                    <div *ngIf="option.feedback" class="specificfeedback">
 | 
					                    <div *ngIf="option.feedback" class="specificfeedback">
 | 
				
			||||||
                        <core-format-text [component]="component" [componentId]="componentId" [text]="option.feedback"
 | 
					                        <core-format-text [component]="component" [componentId]="componentId" [text]="option.feedback"
 | 
				
			||||||
                            [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
 | 
					                            [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </ion-checkbox>
 | 
					                <ion-icon *ngIf="option.isCorrect === 1" class="core-correct-icon" name="fas-check" color="success"
 | 
				
			||||||
 | 
					 | 
				
			||||||
            <ion-icon slot="end" *ngIf="option.isCorrect === 1" class="core-correct-icon" name="fas-check" color="success"
 | 
					 | 
				
			||||||
                    [attr.aria-label]="'core.question.correct' | translate" />
 | 
					                    [attr.aria-label]="'core.question.correct' | translate" />
 | 
				
			||||||
            <ion-icon slot="end" *ngIf="option.isCorrect === 0" class="core-correct-icon" name="fas-xmark" color="danger"
 | 
					                <ion-icon *ngIf="option.isCorrect === 0" class="core-correct-icon" name="fas-xmark" color="danger"
 | 
				
			||||||
                    [attr.aria-label]="'core.question.incorrect' | translate" />
 | 
					                    [attr.aria-label]="'core.question.incorrect' | translate" />
 | 
				
			||||||
 | 
					            </ion-checkbox>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <!-- ion-checkbox doesn't use an input. Create a hidden input to hold the value. -->
 | 
					            <!-- ion-checkbox doesn't use an input. Create a hidden input to hold the value. -->
 | 
				
			||||||
            <input type="hidden" [ngModel]="option.checked" [attr.name]="option.name">
 | 
					            <input type="hidden" [ngModel]="option.checked" [attr.name]="option.name">
 | 
				
			||||||
@ -43,20 +44,21 @@
 | 
				
			|||||||
        <ion-item class="ion-text-wrap answer" *ngFor="let option of question.options">
 | 
					        <ion-item class="ion-text-wrap answer" *ngFor="let option of question.options">
 | 
				
			||||||
            <ion-radio [value]="option.value" [disabled]="option.disabled"
 | 
					            <ion-radio [value]="option.value" [disabled]="option.disabled"
 | 
				
			||||||
                [color]='(option.isCorrect === 1 ? "success": "") + (option.isCorrect === 0 ? "danger": "")'>
 | 
					                [color]='(option.isCorrect === 1 ? "success": "") + (option.isCorrect === 0 ? "danger": "")'>
 | 
				
			||||||
 | 
					                <div>
 | 
				
			||||||
                    <div [class]="option.class">
 | 
					                    <div [class]="option.class">
 | 
				
			||||||
                    <core-format-text [component]="component" [componentId]="componentId" [text]="option.text" [contextLevel]="contextLevel"
 | 
					                        <core-format-text [component]="component" [componentId]="componentId" [text]="option.text"
 | 
				
			||||||
                        [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
 | 
					                            [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
                    <div *ngIf="option.feedback" class="specificfeedback">
 | 
					                    <div *ngIf="option.feedback" class="specificfeedback">
 | 
				
			||||||
                        <core-format-text [component]="component" [componentId]="componentId" [text]="option.feedback"
 | 
					                        <core-format-text [component]="component" [componentId]="componentId" [text]="option.feedback"
 | 
				
			||||||
                            [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
 | 
					                            [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId" />
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </ion-radio>
 | 
					                <ion-icon *ngIf="option.isCorrect === 1" class="core-correct-icon" name="fas-check" color="success"
 | 
				
			||||||
 | 
					 | 
				
			||||||
            <ion-icon slot="end" *ngIf="option.isCorrect === 1" class="core-correct-icon" name="fas-check" color="success"
 | 
					 | 
				
			||||||
                    [attr.aria-label]="'core.question.correct' | translate" />
 | 
					                    [attr.aria-label]="'core.question.correct' | translate" />
 | 
				
			||||||
            <ion-icon slot="end" *ngIf="option.isCorrect === 0" class="core-correct-icon" name="fas-xmark" color="danger"
 | 
					                <ion-icon *ngIf="option.isCorrect === 0" class="core-correct-icon" name="fas-xmark" color="danger"
 | 
				
			||||||
                    [attr.aria-label]="'core.question.incorrect' | translate" />
 | 
					                    [attr.aria-label]="'core.question.incorrect' | translate" />
 | 
				
			||||||
 | 
					            </ion-radio>
 | 
				
			||||||
        </ion-item>
 | 
					        </ion-item>
 | 
				
			||||||
        <ion-button *ngIf="!question.disabled" class="ion-text-wrap ion-margin-top" expand="block" fill="outline"
 | 
					        <ion-button *ngIf="!question.disabled" class="ion-text-wrap ion-margin-top" expand="block" fill="outline"
 | 
				
			||||||
            [disabled]="!question.singleChoiceModel" (click)="clear()" type="button">
 | 
					            [disabled]="!question.singleChoiceModel" (click)="clear()" type="button">
 | 
				
			||||||
 | 
				
			|||||||
@ -6,15 +6,24 @@
 | 
				
			|||||||
        padding: 0 .7em;
 | 
					        padding: 0 .7em;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .answer {
 | 
					 | 
				
			||||||
        line-height: 2em;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .d-flex {
 | 
					    .d-flex {
 | 
				
			||||||
        display: flex !important;
 | 
					        display: flex !important;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .answer .answernumber {
 | 
					    .answer {
 | 
				
			||||||
 | 
					        line-height: 2em;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .answernumber {
 | 
				
			||||||
            min-width: 1.5em;
 | 
					            min-width: 1.5em;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ion-checkbox::part(label),
 | 
				
			||||||
 | 
					        ion-radio::part(label) {
 | 
				
			||||||
 | 
					            width: 100%;
 | 
				
			||||||
 | 
					            display: flex;
 | 
				
			||||||
 | 
					            flex-direction: row;
 | 
				
			||||||
 | 
					            justify-content: space-between;
 | 
				
			||||||
 | 
					            align-items: center;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,8 @@
 | 
				
			|||||||
 | 
					@use "theme/globals" as *;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:host {
 | 
					:host {
 | 
				
			||||||
 | 
					    display: contents;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    --textarea-background: var(--core-input-background);
 | 
					    --textarea-background: var(--core-input-background);
 | 
				
			||||||
    --textarea-color: var(--core-input-text);
 | 
					    --textarea-color: var(--core-input-text);
 | 
				
			||||||
    --textarea-border-width: var(--core-input-border-width);
 | 
					    --textarea-border-width: var(--core-input-border-width);
 | 
				
			||||||
@ -6,7 +10,6 @@
 | 
				
			|||||||
    --textarea-radius: var(--radius-xl);
 | 
					    --textarea-radius: var(--radius-xl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    form {
 | 
					    form {
 | 
				
			||||||
        position: relative;
 | 
					 | 
				
			||||||
        display: flex;
 | 
					        display: flex;
 | 
				
			||||||
        align-items: center;
 | 
					        align-items: center;
 | 
				
			||||||
        width: 100%;
 | 
					        width: 100%;
 | 
				
			||||||
@ -27,10 +30,15 @@
 | 
				
			|||||||
        min-height: var(--a11y-min-target-size);
 | 
					        min-height: var(--a11y-min-target-size);
 | 
				
			||||||
        line-height: 20px;
 | 
					        line-height: 20px;
 | 
				
			||||||
        padding: 10px;
 | 
					        padding: 10px;
 | 
				
			||||||
        margin: 4px 8px;
 | 
					        @include margin(4px, 0px, 4px, 8px);
 | 
				
			||||||
        resize: vertical;
 | 
					        resize: vertical;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ion-button {
 | 
				
			||||||
 | 
					        --padding-start: 16px;
 | 
				
			||||||
 | 
					        --padding-end: 16px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .core-send-message-input::placeholder {
 | 
					    .core-send-message-input::placeholder {
 | 
				
			||||||
        color: var(--ion-placeholder-color);
 | 
					        color: var(--ion-placeholder-color);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -150,7 +150,6 @@ Feature: Test basic usage of comments in app
 | 
				
			|||||||
    When I press the back button in the app
 | 
					    When I press the back button in the app
 | 
				
			||||||
    And I should find "Comments (1)" in the app
 | 
					    And I should find "Comments (1)" in the app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @ionic7_failure
 | 
					 | 
				
			||||||
  Scenario: Add comments offline & Delete comments offline & Sync comments (glossary)
 | 
					  Scenario: Add comments offline & Delete comments offline & Sync comments (glossary)
 | 
				
			||||||
    Given I entered the glossary activity "Test glossary" on course "Course 1" as "teacher1" in the app
 | 
					    Given I entered the glossary activity "Test glossary" on course "Course 1" as "teacher1" in the app
 | 
				
			||||||
    And I press "Add a new entry" in the app
 | 
					    And I press "Add a new entry" in the app
 | 
				
			||||||
@ -229,7 +228,6 @@ Feature: Test basic usage of comments in app
 | 
				
			|||||||
    When I press the back button in the app
 | 
					    When I press the back button in the app
 | 
				
			||||||
    Then I should find "Comments (0)" in the app
 | 
					    Then I should find "Comments (0)" in the app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @ionic7_failure
 | 
					 | 
				
			||||||
  Scenario: Add comments offline & Delete comments offline & Sync comments (blogs)
 | 
					  Scenario: Add comments offline & Delete comments offline & Sync comments (blogs)
 | 
				
			||||||
    # Create blog as a teacher
 | 
					    # Create blog as a teacher
 | 
				
			||||||
    Given the following "core_blog > entries" exist:
 | 
					    Given the following "core_blog > entries" exist:
 | 
				
			||||||
 | 
				
			|||||||
@ -80,7 +80,6 @@ Feature: Test basic usage of one course in app
 | 
				
			|||||||
    And I click on "Move right" "link" in the "assignment" activity
 | 
					    And I click on "Move right" "link" in the "assignment" activity
 | 
				
			||||||
    And I log out
 | 
					    And I log out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @ionic7_failure
 | 
					 | 
				
			||||||
  Scenario: View course contents
 | 
					  Scenario: View course contents
 | 
				
			||||||
    When I entered the course "Course 1" as "student1" in the app
 | 
					    When I entered the course "Course 1" as "student1" in the app
 | 
				
			||||||
    Then the header should be "Course 1" in the app
 | 
					    Then the header should be "Course 1" in the app
 | 
				
			||||||
 | 
				
			|||||||
| 
		 Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB  | 
@ -66,10 +66,6 @@
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .core-login-methods {
 | 
					    .core-login-methods {
 | 
				
			||||||
        form .item.item-input {
 | 
					 | 
				
			||||||
            margin-bottom: 16px;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        form .item,
 | 
					        form .item,
 | 
				
			||||||
        form .item ion-label {
 | 
					        form .item ion-label {
 | 
				
			||||||
            --background: var(--core-login-input-background);
 | 
					            --background: var(--core-login-input-background);
 | 
				
			||||||
 | 
				
			|||||||
@ -41,7 +41,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            <div class="core-login-methods">
 | 
					            <div class="core-login-methods">
 | 
				
			||||||
                <form [formGroup]="credForm" (ngSubmit)="login($event)" class="core-login-form" #credentialsForm *ngIf="!isBrowserSSO">
 | 
					                <form [formGroup]="credForm" (ngSubmit)="login($event)" class="core-login-form" #credentialsForm *ngIf="!isBrowserSSO">
 | 
				
			||||||
                    <ion-item lines="inset">
 | 
					                    <ion-item class="ion-margin-bottom" lines="inset">
 | 
				
			||||||
                        <ion-input type="text" name="username" placeholder="{{ 'core.login.username' | translate }}"
 | 
					                        <ion-input type="text" name="username" placeholder="{{ 'core.login.username' | translate }}"
 | 
				
			||||||
                            formControlName="username" autocapitalize="none" autocorrect="off" autocomplete="username" enterkeyhint="next"
 | 
					                            formControlName="username" autocapitalize="none" autocorrect="off" autocomplete="username" enterkeyhint="next"
 | 
				
			||||||
                            required="true" [attr.aria-label]="'core.login.username' | translate " />
 | 
					                            required="true" [attr.aria-label]="'core.login.username' | translate " />
 | 
				
			||||||
 | 
				
			|||||||
@ -25,7 +25,6 @@ Feature: Test basic usage of login in app
 | 
				
			|||||||
    Then I should not find "Skip" in the app
 | 
					    Then I should not find "Skip" in the app
 | 
				
			||||||
    And I should find "Connect to Moodle" in the app
 | 
					    And I should find "Connect to Moodle" in the app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @ionic7_failure
 | 
					 | 
				
			||||||
  Scenario: Add a new account in the app & Site name in displayed when adding a new account
 | 
					  Scenario: Add a new account in the app & Site name in displayed when adding a new account
 | 
				
			||||||
    When I launch the app
 | 
					    When I launch the app
 | 
				
			||||||
    And I set the field "Your site" to "$WWWROOT" in the app
 | 
					    And I set the field "Your site" to "$WWWROOT" in the app
 | 
				
			||||||
 | 
				
			|||||||
| 
		 Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB  | 
| 
		 Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB  | 
@ -1,8 +1,7 @@
 | 
				
			|||||||
<form (ngSubmit)="submitForm($event)" role="search" #searchForm>
 | 
					<form (ngSubmit)="submitForm($event)" role="search" #searchForm>
 | 
				
			||||||
    <ion-item class="search-box">
 | 
					 | 
				
			||||||
    <ion-input [attr.aria-label]="placeholder" type="search" name="search" [(ngModel)]="searchText" [placeholder]="placeholder"
 | 
					    <ion-input [attr.aria-label]="placeholder" type="search" name="search" [(ngModel)]="searchText" [placeholder]="placeholder"
 | 
				
			||||||
        [autocorrect]="autocorrect" [spellcheck]="spellcheck" [core-auto-focus]="autoFocus" [disabled]="disabled" role="searchbox"
 | 
					        [autocorrect]="autocorrect" [spellcheck]="spellcheck" [core-auto-focus]="autoFocus" [disabled]="disabled" role="searchbox"
 | 
				
			||||||
            (ionFocus)="focus($event)" />
 | 
					        (ionFocus)="focus($event)">
 | 
				
			||||||
        <ion-button slot="end" fill="clear" type="submit" [attr.aria-label]="searchLabel"
 | 
					        <ion-button slot="end" fill="clear" type="submit" [attr.aria-label]="searchLabel"
 | 
				
			||||||
            [disabled]="disabled || !searchText || (searchText.length < lengthCheck)">
 | 
					            [disabled]="disabled || !searchText || (searchText.length < lengthCheck)">
 | 
				
			||||||
            <ion-icon name="fas-magnifying-glass" slot="icon-only" aria-hidden="true" />
 | 
					            <ion-icon name="fas-magnifying-glass" slot="icon-only" aria-hidden="true" />
 | 
				
			||||||
@ -11,7 +10,7 @@
 | 
				
			|||||||
            [disabled]="searched === '' || disabled" (click)="clearForm()">
 | 
					            [disabled]="searched === '' || disabled" (click)="clearForm()">
 | 
				
			||||||
            <ion-icon name="fas-delete-left" slot="icon-only" aria-hidden="true" flip-rtl />
 | 
					            <ion-icon name="fas-delete-left" slot="icon-only" aria-hidden="true" flip-rtl />
 | 
				
			||||||
        </ion-button>
 | 
					        </ion-button>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-input>
 | 
				
			||||||
    <ion-list class="core-search-history" [hidden]="!historyShown">
 | 
					    <ion-list class="core-search-history" [hidden]="!historyShown">
 | 
				
			||||||
        <ion-item button class="ion-text-wrap" *ngFor="let item of history" (click)="historyClicked($event, item.searchedtext)" tabindex="0"
 | 
					        <ion-item button class="ion-text-wrap" *ngFor="let item of history" (click)="historyClicked($event, item.searchedtext)" tabindex="0"
 | 
				
			||||||
            [detail]="true">
 | 
					            [detail]="true">
 | 
				
			||||||
 | 
				
			|||||||
@ -17,14 +17,21 @@
 | 
				
			|||||||
        background: var(--core-search-box-background);
 | 
					        background: var(--core-search-box-background);
 | 
				
			||||||
        color: var(--core-search-box-border-color);
 | 
					        color: var(--core-search-box-border-color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .search-box {
 | 
					 | 
				
			||||||
        --min-height: var(--search-height);
 | 
					        --min-height: var(--search-height);
 | 
				
			||||||
            border-radius: var(--core-search-box-border-radius);
 | 
					
 | 
				
			||||||
 | 
					        ion-input {
 | 
				
			||||||
 | 
					            --padding-start: 16px;
 | 
				
			||||||
 | 
					            --padding-end: 16px;
 | 
				
			||||||
 | 
					            --border-radius: var(--core-search-box-border-radius);
 | 
				
			||||||
 | 
					            min-height: var(--search-height);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ion-button.button {
 | 
					        ion-button.button {
 | 
				
			||||||
            margin: 0;
 | 
					            margin: 0;
 | 
				
			||||||
            --a11y-min-target-size: var(--search-height);
 | 
					            --a11y-min-target-size: var(--search-height);
 | 
				
			||||||
 | 
					            --padding-start: 0px;
 | 
				
			||||||
 | 
					            --padding-end: 0px;
 | 
				
			||||||
 | 
					            font-size: 12px;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -41,23 +48,15 @@
 | 
				
			|||||||
            --background: var(--light);
 | 
					            --background: var(--light);
 | 
				
			||||||
            cursor: pointer;
 | 
					            cursor: pointer;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ion-label {
 | 
					 | 
				
			||||||
        margin: 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ion-input {
 | 
					 | 
				
			||||||
        --padding-start: 0px;
 | 
					 | 
				
			||||||
        --padding-end: 0px;
 | 
					 | 
				
			||||||
        padding-left: 0;
 | 
					 | 
				
			||||||
        padding-right: 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ion-item {
 | 
					        ion-item {
 | 
				
			||||||
            --min-height: var(--a11y-min-target-size);
 | 
					            --min-height: var(--a11y-min-target-size);
 | 
				
			||||||
            --border-width: 0px;
 | 
					            --border-width: 0px;
 | 
				
			||||||
            --background: var(--core-search-box-background);
 | 
					            --background: var(--core-search-box-background);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ion-label {
 | 
				
			||||||
 | 
					                margin: 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -14,14 +14,14 @@
 | 
				
			|||||||
    </ion-refresher>
 | 
					    </ion-refresher>
 | 
				
			||||||
    <core-loading [hideUntil]="userLoaded">
 | 
					    <core-loading [hideUntil]="userLoaded">
 | 
				
			||||||
        <ion-list *ngIf="user">
 | 
					        <ion-list *ngIf="user">
 | 
				
			||||||
            <ion-item class="ion-text-center core-user-profile-maininfo ion-text-wrap" [lines]="user.description ? null : 'full'">
 | 
					            <ion-item class="ion-text-center core-user-profile-maininfo ion-text-wrap" [lines]="user.description ? 'none' : 'full'">
 | 
				
			||||||
 | 
					                <ion-label>
 | 
				
			||||||
                    <core-user-avatar [user]="user" [userId]="user.id" [linkProfile]="false" [checkOnline]="!canChangeProfilePicture">
 | 
					                    <core-user-avatar [user]="user" [userId]="user.id" [linkProfile]="false" [checkOnline]="!canChangeProfilePicture">
 | 
				
			||||||
                        <ion-button class="edit-avatar" *ngIf="canChangeProfilePicture" (click)="changeProfilePicture()"
 | 
					                        <ion-button class="edit-avatar" *ngIf="canChangeProfilePicture" (click)="changeProfilePicture()"
 | 
				
			||||||
                            [attr.aria-label]="'core.user.newpicture' | translate" fill="clear">
 | 
					                            [attr.aria-label]="'core.user.newpicture' | translate" fill="clear">
 | 
				
			||||||
                            <ion-icon slot="icon-only" name="fas-pen" aria-hidden="true" />
 | 
					                            <ion-icon slot="icon-only" name="fas-pen" aria-hidden="true" />
 | 
				
			||||||
                        </ion-button>
 | 
					                        </ion-button>
 | 
				
			||||||
                    </core-user-avatar>
 | 
					                    </core-user-avatar>
 | 
				
			||||||
                <ion-label>
 | 
					 | 
				
			||||||
                    <h2>{{ user.fullname }}</h2>
 | 
					                    <h2>{{ user.fullname }}</h2>
 | 
				
			||||||
                </ion-label>
 | 
					                </ion-label>
 | 
				
			||||||
            </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,15 @@
 | 
				
			|||||||
:host {
 | 
					:host {
 | 
				
			||||||
    .core-user-profile-maininfo {
 | 
					    .core-user-profile-maininfo {
 | 
				
			||||||
        padding-top: 16px;
 | 
					        padding-top: 16px;
 | 
				
			||||||
        &::part(native) {
 | 
					        ion-label {
 | 
				
			||||||
 | 
					            display: flex;
 | 
				
			||||||
            flex-direction: column;
 | 
					            flex-direction: column;
 | 
				
			||||||
 | 
					            align-items: center;
 | 
				
			||||||
 | 
					            margin-top: 0px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            h2 {
 | 
				
			||||||
 | 
					                margin-top: 10px;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    core-user-avatar {
 | 
					    core-user-avatar {
 | 
				
			||||||
 | 
				
			|||||||
@ -54,7 +54,6 @@ Feature: Test basic usage of user features
 | 
				
			|||||||
    When I press "Reconnect" in the app
 | 
					    When I press "Reconnect" in the app
 | 
				
			||||||
    Then I should find "Acceptance test site" in the app
 | 
					    Then I should find "Acceptance test site" in the app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @ionic7_failure
 | 
					 | 
				
			||||||
  Scenario: View profile
 | 
					  Scenario: View profile
 | 
				
			||||||
    Given the following "custom profile fields" exist:
 | 
					    Given the following "custom profile fields" exist:
 | 
				
			||||||
      | datatype | shortname  | name           | required | param1 |
 | 
					      | datatype | shortname  | name           | required | param1 |
 | 
				
			||||||
 | 
				
			|||||||
| 
		 Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB  | 
@ -72,7 +72,6 @@ Feature: It navigates properly in pages with a split-view component.
 | 
				
			|||||||
    And I should find "User account" in the app
 | 
					    And I should find "User account" in the app
 | 
				
			||||||
    But I should not find "Back" in the app
 | 
					    But I should not find "Back" in the app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @ionic7_failure
 | 
					 | 
				
			||||||
  Scenario: Navigate in grades tab on tablet
 | 
					  Scenario: Navigate in grades tab on tablet
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Open user menu
 | 
					    # Open user menu
 | 
				
			||||||
 | 
				
			|||||||
| 
		 Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 34 KiB  | 
@ -253,6 +253,9 @@ ion-tabs.hide-header ion-header {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
ion-footer {
 | 
					ion-footer {
 | 
				
			||||||
    background-color: var(--contrast-background);
 | 
					    background-color: var(--contrast-background);
 | 
				
			||||||
 | 
					    > ion-toolbar:only-child {
 | 
				
			||||||
 | 
					        top: 1px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Ionic icon.
 | 
					// Ionic icon.
 | 
				
			||||||
@ -290,6 +293,11 @@ button,
 | 
				
			|||||||
[role="button"] {
 | 
					[role="button"] {
 | 
				
			||||||
    min-height: var(--a11y-min-target-size);
 | 
					    min-height: var(--a11y-min-target-size);
 | 
				
			||||||
    min-width: var(--a11y-min-target-size);
 | 
					    min-width: var(--a11y-min-target-size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &.button-large {
 | 
				
			||||||
 | 
					        min-height: 2.8em;
 | 
				
			||||||
 | 
					        min-width: 2.8em
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ion-fab-button {
 | 
					ion-fab-button {
 | 
				
			||||||
@ -1015,15 +1023,19 @@ ion-action-sheet.md {
 | 
				
			|||||||
ion-radio,
 | 
					ion-radio,
 | 
				
			||||||
input[type=radio],
 | 
					input[type=radio],
 | 
				
			||||||
.select-alert.ios .alert-radio-icon {
 | 
					.select-alert.ios .alert-radio-icon {
 | 
				
			||||||
    --color: var(--text-color);
 | 
					 | 
				
			||||||
    --color-checked: var(--color);
 | 
					 | 
				
			||||||
    --border-radius: 50%;
 | 
					    --border-radius: 50%;
 | 
				
			||||||
    --border-width: 2px;
 | 
					    --border-width: 2px;
 | 
				
			||||||
    --outer-border-width: 2px;
 | 
					    --outer-border-width: 2px;
 | 
				
			||||||
    --border-style: solid;
 | 
					    --border-style: solid;
 | 
				
			||||||
    --inner-border-radius: 50%;
 | 
					    --inner-border-radius: 50%;
 | 
				
			||||||
    --size: 20px;
 | 
					    --size: 20px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:not(.ion-color) {
 | 
				
			||||||
 | 
					        --color: var(--text-color);
 | 
				
			||||||
 | 
					        --color-checked: var(--color);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ios ion-radio,
 | 
					.ios ion-radio,
 | 
				
			||||||
.ios input[type=radio],
 | 
					.ios input[type=radio],
 | 
				
			||||||
@ -1108,14 +1120,18 @@ input[type=radio],
 | 
				
			|||||||
ion-checkbox,
 | 
					ion-checkbox,
 | 
				
			||||||
input[type=checkbox] {
 | 
					input[type=checkbox] {
 | 
				
			||||||
    --border-radius: 2px;
 | 
					    --border-radius: 2px;
 | 
				
			||||||
    --border-color-checked: var(--text-color);
 | 
					 | 
				
			||||||
    --checkbox-background-checked: var(--text-color);
 | 
					 | 
				
			||||||
    --checkmark-color: var(--contrast-background);
 | 
					 | 
				
			||||||
    --border-width: 2px;
 | 
					    --border-width: 2px;
 | 
				
			||||||
    --outer-border-width: 2px;
 | 
					    --outer-border-width: 2px;
 | 
				
			||||||
    --border-style: solid;
 | 
					    --border-style: solid;
 | 
				
			||||||
    --size: 20px;
 | 
					    --size: 20px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:not(.ion-color) {
 | 
				
			||||||
 | 
					        --border-color-checked: var(--text-color);
 | 
				
			||||||
 | 
					        --checkbox-background-checked: var(--text-color);
 | 
				
			||||||
 | 
					        --checkmark-color: var(--contrast-background);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ios input[type=checkbox] {
 | 
					.ios input[type=checkbox] {
 | 
				
			||||||
    --outer-border-width: 1px;
 | 
					    --outer-border-width: 1px;
 | 
				
			||||||
@ -1406,23 +1422,27 @@ audio.core-media-adapt-width {
 | 
				
			|||||||
    width: 100%;
 | 
					    width: 100%;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ion-item {
 | 
					ion-item.item-lines-default {
 | 
				
			||||||
    // font-size: var(--text-size);
 | 
					 | 
				
			||||||
    --inner-border-width: 0px;
 | 
					    --inner-border-width: 0px;
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ion-item.item-lines-full {
 | 
					 | 
				
			||||||
    --inner-border-width: 0px;
 | 
					 | 
				
			||||||
    --border-width: 0 0 1px 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ion-item.item-lines-inset {
 | 
					 | 
				
			||||||
    --inner-border-width: 0 0 1px 0;
 | 
					 | 
				
			||||||
    --border-width: 0px;
 | 
					    --border-width: 0px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ion-item.item-input.ios {
 | 
					ion-item.ion-valid,
 | 
				
			||||||
 | 
					ion-item.ion-invalid {
 | 
				
			||||||
    --inner-border-width: 0 0 1px 0;
 | 
					    --inner-border-width: 0 0 1px 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &.ion-touched {
 | 
				
			||||||
 | 
					        &.ion-invalid {
 | 
				
			||||||
 | 
					            --ion-item-border-color: var(--highlight-color-invalid);
 | 
				
			||||||
 | 
					            --highlight-background: var(--ion-item-border-color);
 | 
				
			||||||
 | 
					            --border-color: var(--ion-item-border-color);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        &.ion-valid {
 | 
				
			||||||
 | 
					            --ion-item-border-color: var(--highlight-color-valid);
 | 
				
			||||||
 | 
					            --highlight-background: var(--ion-item-border-color);
 | 
				
			||||||
 | 
					            --border-color: var(--ion-item-border-color);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Fake item.
 | 
					// Fake item.
 | 
				
			||||||
 | 
				
			|||||||