commit
7b9b365ce0
|
@ -21,7 +21,7 @@
|
||||||
</ion-header>
|
</ion-header>
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
<core-iframe *ngIf="loaded && src" [src]="src" [iframeWidth]="scormWidth" [iframeHeight]="scormHeight"
|
<core-iframe *ngIf="loaded" id="scorm_object" [src]="src" [iframeWidth]="scormWidth" [iframeHeight]="scormHeight"
|
||||||
[showFullscreenOnToolbar]="true" [autoFullscreenOnRotate]="true">
|
[showFullscreenOnToolbar]="true" [autoFullscreenOnRotate]="true">
|
||||||
</core-iframe>
|
</core-iframe>
|
||||||
|
|
||||||
|
|
|
@ -426,6 +426,11 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
(<any> window).API = this.dataModel;
|
(<any> window).API = this.dataModel;
|
||||||
} else {
|
} else {
|
||||||
|
// Changing SCO. First unload the existing SCO to make sure the callback to send the data has been called.
|
||||||
|
this.src = '';
|
||||||
|
|
||||||
|
await CoreUtils.nextTick();
|
||||||
|
|
||||||
// Load the SCO in the existing model.
|
// Load the SCO in the existing model.
|
||||||
this.dataModel.loadSco(sco.id);
|
this.dataModel.loadSco(sco.id);
|
||||||
}
|
}
|
||||||
|
@ -436,7 +441,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
this.calculateNavigationItems(sco.id);
|
this.calculateNavigationItems(sco.id);
|
||||||
|
|
||||||
// Load the SCO source.
|
// Load the SCO source.
|
||||||
this.loadScoSrc(sco);
|
this.src = await AddonModScorm.getScoSrc(this.scorm, sco);
|
||||||
|
|
||||||
if (sco.scormtype == 'asset') {
|
if (sco.scormtype == 'asset') {
|
||||||
// Mark the asset as completed.
|
// Mark the asset as completed.
|
||||||
|
@ -446,25 +451,6 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
|
||||||
this.logEvent(sco.id);
|
this.logEvent(sco.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Load SCO src.
|
|
||||||
*
|
|
||||||
* @param sco SCO to load.
|
|
||||||
* @returns Promise resolved when done.
|
|
||||||
*/
|
|
||||||
protected async loadScoSrc(sco: AddonModScormScoWithData): Promise<void> {
|
|
||||||
const src = await AddonModScorm.getScoSrc(this.scorm, sco);
|
|
||||||
|
|
||||||
if (src == this.src) {
|
|
||||||
// Re-loading same page. Set it to empty and then re-set the src in the next digest so it detects it has changed.
|
|
||||||
this.src = '';
|
|
||||||
|
|
||||||
await CoreUtils.nextTick();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.src = src;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an SCO, mark it as completed.
|
* Given an SCO, mark it as completed.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
@mod @mod_scorm @app @javascript @_switch_iframe
|
||||||
|
Feature: Test basic usage of SCORM activity in app
|
||||||
|
In order to play a SCORM while using the mobile app
|
||||||
|
As a student
|
||||||
|
I need basic SCORM functionality to work
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given the following "users" exist:
|
||||||
|
| username | firstname | lastname | email |
|
||||||
|
| teacher1 | Teacher | teacher | teacher1@example.com |
|
||||||
|
| student1 | Student | student | student1@example.com |
|
||||||
|
And the following "courses" exist:
|
||||||
|
| fullname | shortname | category |
|
||||||
|
| Course 1 | C1 | 0 |
|
||||||
|
And the following "course enrolments" exist:
|
||||||
|
| user | course | role |
|
||||||
|
| teacher1 | C1 | editingteacher |
|
||||||
|
| student1 | C1 | student |
|
||||||
|
|
||||||
|
Scenario: Resume progress when re-entering SCORM
|
||||||
|
Given the following "activities" exist:
|
||||||
|
| activity | name | intro | course | idnumber | packagefilepath |
|
||||||
|
| scorm | Basic SCORM | SCORM description | C1 | scorm | mod/scorm/tests/packages/RuntimeMinimumCalls_SCORM12-mini.zip |
|
||||||
|
And I entered the course "Course 1" as "student1" in the app
|
||||||
|
When I press "Basic SCORM" in the app
|
||||||
|
And I press "Enter" in the app
|
||||||
|
And I press "Disable fullscreen" in the app
|
||||||
|
Then I should find "2 / 11" in the app
|
||||||
|
And I switch to "scorm_object" iframe
|
||||||
|
And I should see "Play of the game"
|
||||||
|
|
||||||
|
When I switch to the main frame
|
||||||
|
And I press "Next" in the app
|
||||||
|
And I press "Next" in the app
|
||||||
|
Then I should find "4 / 11" in the app
|
||||||
|
And I switch to "scorm_object" iframe
|
||||||
|
And I should see "Scoring"
|
||||||
|
|
||||||
|
When I switch to the main frame
|
||||||
|
And I press the back button in the app
|
||||||
|
And I wait loading to finish in the app
|
||||||
|
Then I should find "1" within "Number of attempts you have made" "ion-item" in the app
|
||||||
|
And I should find "3" within "Grade reported" "ion-item" in the app
|
||||||
|
|
||||||
|
When I press "Enter" in the app
|
||||||
|
And I press "Disable fullscreen" in the app
|
||||||
|
Then I should find "5 / 11" in the app
|
||||||
|
And I switch to "scorm_object" iframe
|
||||||
|
And I should see "Other Scoring Systems"
|
||||||
|
|
||||||
|
Scenario: TOC displays the right status and opens the right SCO
|
||||||
|
Given the following "activities" exist:
|
||||||
|
| activity | name | intro | course | idnumber | displaycoursestructure | packagefilepath |
|
||||||
|
| scorm | Basic SCORM | SCORM description | C1 | scorm | 1 | mod/scorm/tests/packages/RuntimeMinimumCalls_SCORM12-mini.zip |
|
||||||
|
And I entered the course "Course 1" as "student1" in the app
|
||||||
|
When I press "Basic SCORM" in the app
|
||||||
|
Then I should find "Not attempted" within "How to Play" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Par?" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Keeping Score" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Other Scoring Systems" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "The Rules of Golf" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Playing Golf Quiz" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "How to Have Fun Playing Golf" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "How to Make Friends Playing Golf" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Having Fun Quiz" "ion-item" in the app
|
||||||
|
|
||||||
|
When I press "Enter" in the app
|
||||||
|
And I press "Disable fullscreen" in the app
|
||||||
|
And I press "TOC" in the app
|
||||||
|
Then I should find "Not attempted" within "How to Play" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Par?" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Keeping Score" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Other Scoring Systems" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "The Rules of Golf" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Playing Golf Quiz" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "How to Have Fun Playing Golf" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "How to Make Friends Playing Golf" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Having Fun Quiz" "ion-item" in the app
|
||||||
|
|
||||||
|
When I press "Close" in the app
|
||||||
|
And I press "Next" in the app
|
||||||
|
And I press "TOC" in the app
|
||||||
|
Then I should find "Completed" within "How to Play" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Par?" "ion-item" in the app
|
||||||
|
|
||||||
|
When I press "The Rules of Golf" in the app
|
||||||
|
Then I should find "6 / 11" in the app
|
||||||
|
And I switch to "scorm_object" iframe
|
||||||
|
And I should see "The Rules of Golf"
|
||||||
|
|
||||||
|
When I switch to the main frame
|
||||||
|
And I press "TOC" in the app
|
||||||
|
Then I should find "Completed" within "How to Play" "ion-item" in the app
|
||||||
|
And I should find "Completed" within "Par?" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Keeping Score" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Other Scoring Systems" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "The Rules of Golf" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Playing Golf Quiz" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "How to Have Fun Playing Golf" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "How to Make Friends Playing Golf" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Having Fun Quiz" "ion-item" in the app
|
||||||
|
|
||||||
|
When I press "Close" in the app
|
||||||
|
And I press the back button in the app
|
||||||
|
And I wait loading to finish in the app
|
||||||
|
Then I should find "Completed" within "How to Play" "ion-item" in the app
|
||||||
|
And I should find "Completed" within "Par?" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Keeping Score" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Other Scoring Systems" "ion-item" in the app
|
||||||
|
And I should find "Completed" within "The Rules of Golf" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Playing Golf Quiz" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "How to Have Fun Playing Golf" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "How to Make Friends Playing Golf" "ion-item" in the app
|
||||||
|
And I should find "Not attempted" within "Having Fun Quiz" "ion-item" in the app
|
||||||
|
|
||||||
|
When I press "How to Have Fun Playing Golf" in the app
|
||||||
|
Then I should find "9 / 11" in the app
|
||||||
|
And I switch to "scorm_object" iframe
|
||||||
|
And I should see "How to Have Fun Golfing"
|
||||||
|
|
||||||
|
Scenario: Preview SCORM
|
||||||
|
Given the following "activities" exist:
|
||||||
|
| activity | name | intro | course | idnumber | packagefilepath |
|
||||||
|
| scorm | Basic SCORM | SCORM description | C1 | scorm | mod/scorm/tests/packages/RuntimeMinimumCalls_SCORM12-mini.zip |
|
||||||
|
And I entered the course "Course 1" as "teacher1" in the app
|
||||||
|
When I press "Basic SCORM" in the app
|
||||||
|
Then I should find "0" within "Number of attempts you have made" "ion-item" in the app
|
||||||
|
|
||||||
|
When I press "Preview" in the app
|
||||||
|
And I press "Disable fullscreen" in the app
|
||||||
|
And I press "TOC" in the app
|
||||||
|
Then I should find "Preview mode" in the app
|
||||||
|
|
||||||
|
When I press "Close" in the app
|
||||||
|
And I press "Next" in the app
|
||||||
|
And I press "Next" in the app
|
||||||
|
And I press "Next" in the app
|
||||||
|
And I press "Next" in the app
|
||||||
|
And I press "Next" in the app
|
||||||
|
And I press "Next" in the app
|
||||||
|
And I press "Next" in the app
|
||||||
|
And I press "Next" in the app
|
||||||
|
Then I should find "11 / 11" in the app
|
||||||
|
|
||||||
|
When I press the back button in the app
|
||||||
|
And I wait loading to finish in the app
|
||||||
|
Then I should find "1" within "Number of attempts you have made" "ion-item" in the app
|
||||||
|
And I should find "9" within "Grade reported" "ion-item" in the app
|
||||||
|
|
||||||
|
# Check that Preview doesn't start a new attempt.
|
||||||
|
When I press "Start a new attempt" in the app
|
||||||
|
And I press "Preview" in the app
|
||||||
|
And I press "Disable fullscreen" in the app
|
||||||
|
And I press "TOC" in the app
|
||||||
|
Then I should find "Complete" within "How to Play" "ion-item" in the app
|
||||||
|
And I should find "Complete" within "Having Fun Quiz" "ion-item" in the app
|
||||||
|
|
||||||
|
When I press "Close" in the app
|
||||||
|
And I press the back button in the app
|
||||||
|
And I wait loading to finish in the app
|
||||||
|
Then I should find "1" within "Number of attempts you have made" "ion-item" in the app
|
||||||
|
|
||||||
|
Scenario: Unsupported SCORM
|
||||||
|
Given the following "activities" exist:
|
||||||
|
| activity | name | course | idnumber | packagefilepath |
|
||||||
|
| scorm | SCORM 1.2 | C1 | scorm2 | mod/scorm/tests/packages/RuntimeBasicCalls_SCORM20043rdEdition.zip |
|
||||||
|
And I entered the course "Course 1" as "student1" in the app
|
||||||
|
When I press "SCORM 1.2" in the app
|
||||||
|
Then I should find "Sorry, the application only supports SCORM 1.2." in the app
|
|
@ -11,7 +11,7 @@
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</core-navbar-buttons>
|
</core-navbar-buttons>
|
||||||
|
|
||||||
<iframe #iframe class="core-iframe" [ngStyle]="{'width': iframeWidth, 'height': iframeHeight}" [src]="safeUrl"
|
<iframe #iframe class="core-iframe" [attr.id]="id" [ngStyle]="{'width': iframeWidth, 'height': iframeHeight}" [src]="safeUrl"
|
||||||
[attr.allowfullscreen]="allowFullscreen ? 'allowfullscreen' : null" [class.core-iframe-loading]="loading">
|
[attr.allowfullscreen]="allowFullscreen ? 'allowfullscreen' : null" [class.core-iframe-loading]="loading">
|
||||||
</iframe>
|
</iframe>
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ export class CoreIframeComponent implements OnChanges, OnDestroy {
|
||||||
|
|
||||||
@ViewChild('iframe') iframe?: ElementRef;
|
@ViewChild('iframe') iframe?: ElementRef;
|
||||||
@Input() src?: string;
|
@Input() src?: string;
|
||||||
|
@Input() id: string | null = null;
|
||||||
@Input() iframeWidth?: string;
|
@Input() iframeWidth?: string;
|
||||||
@Input() iframeHeight?: string;
|
@Input() iframeHeight?: string;
|
||||||
@Input() allowFullscreen?: boolean | string;
|
@Input() allowFullscreen?: boolean | string;
|
||||||
|
@ -160,10 +161,10 @@ export class CoreIframeComponent implements OnChanges, OnDestroy {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = changes.src.currentValue;
|
let url = this.src;
|
||||||
|
|
||||||
if (!CoreUrlUtils.isLocalFileUrl(url)) {
|
if (url && !CoreUrlUtils.isLocalFileUrl(url)) {
|
||||||
url = CoreUrlUtils.getYoutubeEmbedUrl(changes.src.currentValue) || changes.src.currentValue;
|
url = CoreUrlUtils.getYoutubeEmbedUrl(url) || url;
|
||||||
this.displayHelp = CoreIframeUtils.shouldDisplayHelpForUrl(url);
|
this.displayHelp = CoreIframeUtils.shouldDisplayHelpForUrl(url);
|
||||||
|
|
||||||
const currentSite = CoreSites.getCurrentSite();
|
const currentSite = CoreSites.getCurrentSite();
|
||||||
|
@ -181,7 +182,7 @@ export class CoreIframeComponent implements OnChanges, OnDestroy {
|
||||||
await CoreIframeUtils.fixIframeCookies(url);
|
await CoreIframeUtils.fixIframeCookies(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.safeUrl = DomSanitizer.bypassSecurityTrustResourceUrl(CoreFile.convertFileSrc(url));
|
this.safeUrl = DomSanitizer.bypassSecurityTrustResourceUrl(url ? CoreFile.convertFileSrc(url) : '');
|
||||||
|
|
||||||
// Now that the URL has been set, initialize the iframe. Wait for the iframe to the added to the DOM.
|
// Now that the URL has been set, initialize the iframe. Wait for the iframe to the added to the DOM.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
|
@ -236,15 +236,27 @@ export class TestingBehatBlockingService {
|
||||||
NgZone.run(() => {
|
NgZone.run(() => {
|
||||||
const index = requestIndex++;
|
const index = requestIndex++;
|
||||||
const key = 'httprequest-' + index;
|
const key = 'httprequest-' + index;
|
||||||
|
const isAsync = args[2] !== false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Add to the list of pending requests.
|
// Add to the list of pending requests.
|
||||||
TestingBehatBlocking.block(key);
|
TestingBehatBlocking.block(key);
|
||||||
|
|
||||||
// Detect when it finishes and remove it from the list.
|
// Detect when it finishes and remove it from the list.
|
||||||
this.addEventListener('loadend', () => {
|
if (isAsync) {
|
||||||
TestingBehatBlocking.unblock(key);
|
this.addEventListener('loadend', () => {
|
||||||
});
|
TestingBehatBlocking.unblock(key);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const realSend = this.send;
|
||||||
|
this.send = (...args) => {
|
||||||
|
try {
|
||||||
|
return realSend.apply(this, args);
|
||||||
|
} finally {
|
||||||
|
TestingBehatBlocking.unblock(key);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return realOpen.apply(this, args);
|
return realOpen.apply(this, args);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
Loading…
Reference in New Issue