Wait for Preload tp complete - Early app state check (ExtJS)

Get help with testing, discuss unit testing strategies etc.
Post Reply
User avatar
KaguChan
Posts: 10
Joined: Mon Jul 08, 2019 3:24 pm

Wait for Preload tp complete - Early app state check (ExtJS)

Post by KaguChan » Tue Jul 09, 2019 1:25 pm

Hello there,

right now we're trying out siesta, which seems good so far.

But we're encountering one specific problem:
How to wait for preloads to complete?

The scenario is the following:

Code: Select all

project.configure({
  title: 'Tests',
  preload: [
    {
      text: "console.log('preload started')",
    },
    'node_modules/sinon/pkg/sinon.js',
    'tests/api_stub.js',
    {
      text: "console.log('preload completed')",
    },
  ],
  loaderPath: { // i just tried it out while playing arround, but i guess for cmd i have to use another approach...
    'Ext.ux': 'node_modules/@sencha/ext-core/test/resources/ux',
  },
});

project.plan({
  group: '[Integration][Authorized][Mobile]',
  pageUrl: 'index.html?testing&phone',
  preload: 'inherit',
  alsoPreload: ['tests/hooks/loggedOut.js'], // for test purposes - actually we want the user to be logged in here
  items: [
    {
      title: 'Test Mobile capabilities',
      url: 'tests/integration/authorized/mobile/mobile.spec.js',
    },
  ],
});

Code: Select all

  launch() {
    // Run test hooks if registered - hooks will run only when in debug mode
    // and when ?testing is given in application url
    TestHook.run();

    Log.trace(['Application', 'launch'], 'Launching application...');

    const mode = Ext.isMobileBrowser ? 'mobile' : 'desktop';
    Log.trace(['Application', 'launch'], `Loading application in ${mode} mode...`, Ext.tags);

    this.isLoggedIn = User.isLoggedIn();
    Log.trace(['Application', 'launch'], `User is logged ${this.isLoggedIn ? 'in' : 'out'}`);

    if (this.isLoggedIn) {
      return this.initWs(WS_URL, this.initState); // initialize a websocket connection, then the state manager
    }
    return this.showMain();
  },
Checking the console, we can see that the preload starts when the "initializing" text vanishes, but finnishes when extjs already did everything it needs - which is too late in this case.
  • The api stub is registered too late, so we cant fetch requests to /state on our server and fake them via sinon
  • The alsoPreload: loggedOut is registered too late, so we cannot stub the login check:

Code: Select all

sinon.stub(User, 'isLoggedIn').returns(false);
We even tried to inject hooks, but the hooks, which are loaded via the preload, are injected way too late as well.

Is there a clean way to do stuff like this?
Ive also read this blog post: https://www.bryntum.com/blog/mocking-ajax-calls-with-siesta/ which is good for testing stuff after initialization, but some stuff requiring the api happens right within the initialization - how to mock these calls properly?

best regards
Kai Böse

=> log / load order / whatever:

Code: Select all

preload started
Util.js?_dc=1562670758808:1135 [W] An existing reference is being overwritten for Test Mobile capabilities.app. See the appProperty config.
Log.js?_dc=1562670758808:21 [ Application init ] Initialising application...
Log.js?_dc=1562670758808:21 [ TESTING run ] run test hooks
Log.js?_dc=1562670758808:21 [ Application launch ] Launching application...
Log.js?_dc=1562670758808:21 [ Application launch ] Loading application in mobile mode...
Log.js?_dc=1562670758808:21 [ Application launch ] User is logged in
Log.js?_dc=1562670758808:21 [ Application initWs ] Initialising Websocket...
Log.js?_dc=1562670758808:21 [ Application onUnmatchedRoute ] Redirect to undefined
Log.js?_dc=1562670758808:21 [ Application initState ] Initialising state manager...
Log.js?_dc=1562670758808:21 [ Application showMain ] Loading app entry xtype: main
Log.js?_dc=1562670758808:21 [ MainController onBeforeRender ] Render process started - applying default listeners and data
Log.js?_dc=1562670758808:21 [ MainController onBeforeRender ] Navigation ready event fired
Log.js?_dc=1562670758808:21 [ Application showMain ] Register mobile view viewModel definition
Log.js?_dc=1562670758808:21 [ MainController onMainRouteUpdate ] kundensuche - undefined
Log.js?_dc=1562670758808:21 [ MainController checkAndRunRoute ] kundensuche - undefined; force: no
Log.js?_dc=1562670758808:21 [ MainController doMainRouteUpdate ] customerSearch attempted to be displayed...
api_stub.js:28 LULULULULULULU
VM51342:1 preload completed
loggedOut.js:5 LÖLÖLÖLÖLÖLÖLÖLÖLÖÖLÖLÖ

User avatar
nickolay
Core Developer
Core Developer
Posts: 3357
Joined: Mon May 16, 2011 10:48 am

Re: Wait for Preload tp complete - Early app state check (ExtJS)

Post by nickolay » Tue Jul 09, 2019 1:52 pm

Hi,

Not quite clear what you are trying to achieve, am I correct that you are trying to inject some mocking code during the application load?

When using `pageUrl` you can do that after the page has completely loaded (the regular `preload` option works like that). If that is too late, the best way probably will be to add some hook into the application itself, by analyzing the page url (as described in "Tesing Cmd App" guide).
We offer training in both Ext JS and our products, read more here.
Read the API documentation

User avatar
KaguChan
Posts: 10
Joined: Mon Jul 08, 2019 3:24 pm

Re: Wait for Preload tp complete - Early app state check (ExtJS)

Post by KaguChan » Tue Jul 09, 2019 2:02 pm

This is exactly what im trying right now:

Code: Select all

Ext.define('App.util.TestHook', {
  alternateClassName: ['TestHook'],
  singleton: true,

  hooks: [],

  register(fn) {
    this.hooks.push(fn);
  },

  run() {
    // <debug>
    if (Ext.isTesting) {
      Log.trace(['TESTING', 'run'], 'run test hooks', this.hooks);
      this.hooks.forEach((fn) => {
        Log.trace(['TESTING', 'HOOK'], 'run hook', fn);
        fn();
      });
    }
    // </debug>
  },
});
loggedOut.js:

Code: Select all

TestHook.register(() => {
  console.log('LALALALALALALALA');
  sinon.stub(User, 'isLoggedIn').returns(false);
});
console.log('LÖLÖLÖLÖLÖLÖLÖLÖLÖÖLÖLÖ');

Code: Select all

  launch() {
    // Run test hooks if registered - hooks will run only when in debug mode
    // and when ?testing is given in application url
    TestHook.run();

    Log.trace(['Application', 'launch'], 'Launching application...');

    const mode = Ext.isMobileBrowser ? 'mobile' : 'desktop';
    Log.trace(['Application', 'launch'], `Loading application in ${mode} mode...`, Ext.tags);

    this.isLoggedIn = User.isLoggedIn();
    Log.trace(['Application', 'launch'], `User is logged ${this.isLoggedIn ? 'in' : 'out'}`);

    if (this.isLoggedIn) {
      return this.initWs(WS_URL, this.initState);
    }
    return this.showMain();
  },

Code: Select all

project.plan({
  group: '[Integration][Authorized][Mobile]',
  // waitForAppReady: true,
  pageUrl: 'index.html?testing&phone', // run the page with `testing`
  preload: 'inherit',
  alsoPreload: ['tests/hooks/loggedOut.js'], // load the hook itself
  items: [
    {
      title: 'Test Mobile capabilities',
      url: 'tests/integration/authorized/mobile/mobile.spec.js',
    },
  ],
});
As you can see on the original post, the regarding console log fires after the application has been initialized - leeding the hook just beeing registered too late.

I know about the `waitForExtReady` and the `waitForAppReady` configuration, but both of them does not seem to change the subject in this case.

Basically what we need is to have to preload files to be loaded before the Ext.application.init is called (or between init and launch).

I will try out avoiding the launch function doing anything if in testing and calling it manually for testing purposes, but before i tried i dont know if this works well...

EDIT
doing nothing works... ideas always comes after asking some other people...

Code: Select all

  launch() {
    if (!Ext.isTesting) {
      this.runPage();
    }
    // In case we're testing, the app will be started manually
  },

  runPage() {
    this.started = true;
    // Run test hooks if registered - hooks will run only when in debug mode
    // and when ?testing is given in application url
    TestHook.run();

    Log.trace(['Application', 'launch'], 'Launching application...');

    const mode = Ext.isMobileBrowser ? 'mobile' : 'desktop';
    Log.trace(['Application', 'launch'], `Loading application in ${mode} mode...`, Ext.tags);

    this.isLoggedIn = User.isLoggedIn();
    Log.trace(['Application', 'launch'], `User is logged ${this.isLoggedIn ? 'in' : 'out'}`);

    if (this.isLoggedIn) {
      return this.initWs(WS_URL, this.initState);
    }
    return this.showMain();
  },
  
In the test:

Code: Select all

  d.chain(
    (next) => {
      Ext.getApplication().runPage();
      next();
    },
    // ...

Post Reply