    /*

    Siesta 5.3.0
    Copyright(c) 2009-2019 Bryntum AB
    https://bryntum.com/contact
    https://bryntum.com/products/siesta/license

    */
    /**
    @class Siesta.Project.Browser.ExtJS
    @extends Siesta.Project.Browser
    @mixin Siesta.Project.Browser.ExtJSCore

    Class, representing the browser project. This class provides a web-based UI and defines some additional configuration options.

    The default value of the `testClass` configuration option in this class is {@link Siesta.Test.ExtJS}, which inherits from
    {@link Siesta.Test.Browser} and contains various ExtJS-specific assertions. So, use this project class, when testing an ExtJS application.

    This file is for reference only, for a getting start guide and manual, please refer to <a href="#!/guide/getting_started_browser">Siesta getting started in browser environment</a> guide.

    Synopsys
    ========

        var project = new Siesta.Project.Browser.ExtJS();

        project.configure({
            title     : 'Awesome ExtJS Application Test Suite',

            transparentEx       : true,

            autoCheckGlobals    : true,
            expectedGlobals     : [
                'Ext',
                'Sch'
            ],

            preload : [
                "http://cdn.sencha.io/ext-4.0.2a/ext-all-debug.js",
                "../awesome-project-all.js",
                {
                    text    : "console.log('preload completed')"
                }
            ]
        })

        project.plan(
            // simple string - url relative to project file
            'sanity.t.js',

            // test file descriptor with own configuration options
            {
                url     : 'basic.t.js',

                // replace `preload` option of project
                preload : [
                    "http://cdn.sencha.io/ext-4.0.6/ext-all-debug.js",
                    "../awesome-project-all.js"
                ]
            },

            // groups ("folders") of test files (possibly with own options)
            {
                group       : 'Sanity',

                autoCheckGlobals    : false,

                items       : [
                    'data/crud.t.js',
                    ...
                ]
            },
            ...
        )

    */

    Class('Siesta.Project.Browser.ExtJS', {

        isa     : Siesta.Project.Browser,

        does    : [
            Siesta.Project.Browser.ExtJSCore
        ],

        has     : {
            /**
             * @cfg {Class} testClass The test class which will be used for creating test instances, defaults to {@link Siesta.Test.ExtJS}.
             * You can subclass {@link Siesta.Test.ExtJS} and provide a new class.
             *
             * This option can be also specified in the test file descriptor.
             */
            testClass               : Siesta.Test.ExtJS,

            /**
             * @cfg {Boolean} waitForExtReady
             *
             * By default the `StartTest` function will be executed after `Ext.onReady`. Set to `false` to launch `StartTest` immediately.
             *
             * This option can be also specified in the test file descriptor.
             */
            waitForExtReady         : true,

            /**
             * @cfg {Boolean} waitForAppReady
             *
             * Setting this configuration option to "true" will cause Siesta to wait until the ExtJS MVC application on the test page will become ready,
             * before starting the test. More precisely, it will wait till the "launched" property of the application, specified
             * in the `Ext.manifest.name` to be `true`.
             *
             * This option can (and probably should) be also specified in the test file descriptor.
             */
            waitForAppReady         : false,

            extVersion              : null,

            /**
             * @cfg {Boolean} failOnMultipleComponentMatches
             *
             * True to fail when providing a Component Query matching multiple components. False to warn only.
             * Component Queries should ideally always be unique to identify only one target in the DOM.
             */
            failOnMultipleComponentMatches   : false,

            extVersionRegExp        : /ext(?:js)?-(\d\.\d+\.\d+.*?)\//,

            contentManagerClass     : Siesta.Content.Manager.Browser.ExtJSCore,

            // Required by Ext JS 6
            innerHtmlHead           : '<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">'
        },

        methods : {

            setup : function (callback) {
                var me      = this

                /*
                    This is to be able to pass "next" function form the chain step to the Ext as callback:
                        function (next) {
                            resourceStore.reload({
                                callback : next
                            })
                        }
                    For some reason, Ext performs "isFunction" check on the callback value and only calls it if this check passes
                    (assuming programmer does not know what he is doing)
                    "isFunction" check in turn relies on the presence of this property in the Function prototype

                    This line can be removed once "isFunction" in Ext will become cross-context or Ext will stop
                    using "isFunction" check for callbacks
                */
                Function.prototype.$extIsFunction = true;

                this.SUPER(function () {
                    callback()
                })
            },

            getNewTestConfiguration : function (desc, scopeProvider, contentManager, launchState) {
                var config          = this.SUPERARG(arguments)

                config.waitForExtReady  = this.getDescriptorConfig(desc, 'waitForExtReady')
                config.waitForAppReady  = this.getDescriptorConfig(desc, 'waitForAppReady')

                return config
            },

            findExtVersion : function () {
                var me      = this

                var found

                this.mainPreset.eachResource(function (resource) {
                    var match   = me.extVersionRegExp.exec(resource.url)

                    if (match) {
                        found   = match[ 1 ]

                        return false
                    }
                })

                return found
            }
        }
    })

    // backward compat
    Class('Siesta.Harness.Browser.ExtJS', { isa : Siesta.Project.Browser.ExtJS })