Protractor: Busur derajat dan bootstrap manual sudut

Dibuat pada 30 Agu 2013  ·  49Komentar  ·  Sumber: angular/protractor

Saya mengalami masalah saat menjalankan busur derajat 0.8 dan mengalami masalah saat menjalankan busur derajat di aplikasi kami yang di-bootstrap secara manual.

Berikut adalah beberapa cuplikan yang mengungkapkan bagian yang relevan dari aplikasi dan penyiapan:
indeks.html:

 <script type="text/javascript" data-main="js/main" src="js/libraries/require.js"></script>

js/main.js:

require({
    shim: {
        .... snip ..
            }
           }, 
  ['require', ..... ], function(require) {
    return require(['bootstrap']);

bootstrap.js:

var appElm = $('html');
appElm.addClass('ng-app'); // this
angular.bootstrap(document, ['app']);

Ini berfungsi dalam praktik dan Angular dimulai dengan cara yang benar. Ketika saya melihat sumber html, saya tidak dapat melihat atribut ng-app muncul di elemen html. Mungkin Busur Derajat juga gagal melakukannya?

Saya menggunakan konfigurasi sampel busur derajat dan mengubah nilai yang relevan agar sesuai dengan aplikasi saya:

specs: [
    '../src/test/javascript/protractorSpec/*_spec.js',
  ],
  baseUrl: 'http://localhost:8080/Viewer/',
  rootElement: 'html',

Tes sampel:

describe('List SMC Charts', function() {
        var ptor= protractor.getInstance();

        beforeEach(function() {
          ptor.get('#/smcChart');
        });

        it('list, no filter', function() {
          var selectOption = ptor.findElement(ptor.By.input("selectOption"));
        });
});

Ketika saya menjalankan tes ini, dua kesalahan muncul:

 1) List SMC Charts   list, no filter
   Message:
     Error: Angular could not be found on the page http://localhost:8080/Viewer/#/smcChart
   Stacktrace:
     Error: Angular could not be found on the page http://localhost:8080/Viewer/#/smcChart
    at /usr/local/lib/node_modules/protractor/lib/protractor.js:392:15

dan

2) List SMC Charts list, no filter
   Message:
     TypeError: Cannot call method 'input' of undefined
   Stacktrace:
     TypeError: Cannot call method 'input' of undefined
    at null.<anonymous> (/Users/........//Viewer/src/test/javascript/protractorSpec/some_spec.js:9:55)

Kesalahan pertama tampaknya yang paling penting, tetapi kesalahan terakhir juga cukup menarik. Tampak bagi saya bahwa baris: ptor.By.input tidak berfungsi.

Ada ide?

untriaged discussion

Komentar yang paling membantu

@sjelin Apa cara terdokumentasi untuk mendukung bootstrap manual? Saya tidak dapat menemukan informasi yang relevan untuk busur derajat 5.0.

Semua 49 komentar

Apakah kode Angular disertakan pada halaman? Sepertinya Anda membutuhkan shim, bootstrap, dan lainnya tetapi angular.min.js tidak ditampilkan.

'app': {
            deps: ['libraries/angular', 'libraries/angular-resource', 'libraries/angular-strap']
        },

Cuplikan di atas berada di dalam elemen{} shim, saya tidak memasukkannya ke dalam cuplikan karena tampaknya tidak terlalu relevan bagi saya. Tapi beginilah cara angular.js dimuat.

Hai,

Ya, Protractor saat ini mengharapkan aplikasi ng, jadi situs yang di-bootstrap secara manual akan mengalami masalah. Berharap untuk mendapatkan solusi untuk ini segera didokumentasikan.

Oke thx updatenya. Setelah Anda menemukan solusi, dapatkah Anda mempostingnya di masalah ini?

Maaf atas respons yang lambat - Anda harus dapat memperbaikinya dengan melakukan

describe('List SMC Charts', function() {
        var ptor= protractor.getInstance();

        beforeEach(function() {
          ptor.driver.get('#/smcChart'); // Just use the plain old webdriver here, it won't complain if Angular isn't loaded yet.
        });

        it('list, no filter', function() {
          var selectOption = ptor.findElement(ptor.By.input("selectOption"));
        });
});

Apakah Anda mengatur variabel ptor di suatu tempat? misalnya var ptor = protractor.getInstance() ?

Ada pembaruan tentang ini? Perbaikan yang Anda sarankan tidak berfungsi untuk saya ([email protected], [email protected])

Saya memiliki kombinasi canggung dari layar login non-sudut diikuti oleh requirejs, aplikasi yang di-bootstrap secara manual:

describe('User levels', function() {
    var ptor, driver;

    var findByName = function (name) {
        return driver.findElement(protractor.By.name(name));
    };

    describe('Editors', function() {
        ptor = protractor.getInstance();
        driver = ptor.driver;
        it('Can log in', function() {
            driver.get('http://localhost:8000/');
            findByName('login').sendKeys('test_editor');
            findByName('pass').sendKeys('rubbish');
            driver.findElement(protractor.By.css('button[type="submit"]')).click();
        }, 20000);

        it('Shows the homepage', function() {
            var el = ptor.findElement(protractor.By.css('h1[field="pageTitle"]'));
            expect(el.getText()).toEqual('Welcome to Home');
        }, 30000);

    });
});

Dan main.js saya :

require([
    'angular',
    'app'
], function (angular, app) {
    'use strict';
    var body = document.body, name = app.name;
    body.setAttribute('ng-app', name);
    body.setAttribute('id', 'ng-app');
    angular.bootstrap(body, [name]);
});

Bagian login berfungsi dan saya dapat melihat kilasan halaman yang dilindungi dimuat sebelum busur derajat keluar dengan UnknownError: javascript error: angular is not defined . Saya sudah mencoba memuat ulang halaman dengan driver.get('...') & bahkan ptor.get('...') tetapi tidak ada yang berhasil.

Setiap petunjuk/saran/perbaikan diterima dengan terima kasih.

@magnetised Anda memerlukan beberapa cara untuk memberi tahu pengujian Anda untuk menunggu hingga login selesai sebelum mencoba tes lainnya. Saya pikir yang terjadi adalah Anda mencoba menggunakan ptor.findElement sebelum Angular dimuat di halaman.

Spesifikasi 'Dapat masuk' Anda harus diakhiri dengan pernyataan tunggu yang memeriksa beberapa kondisi untuk aplikasi Anda. Lihat contohnya di sini - https://github.com/angular/protractor/blob/master/spec/login/viaConfigConf.js

@juliemr Brilian, itu bekerja dengan sempurna.

Saya telah mengerti bahwa busur derajat akan melakukan "tunggu sampai sudut dimuat" tetapi saya kira Anda tidak dapat menutupi semua kasing.

Terima kasih lagi.

Saya memiliki pengaturan yang persis sama. @juliemr apakah Anda keberatan membagikan solusi Anda. Apa kondisi menunggu Anda? Terima kasih!

@jorgenfb Saya ingin tahu apakah maksud Anda komentar itu ditujukan kepada saya?

Solusi saya hanya melibatkan menunggu router sudut untuk boot dan mengubah url dari '/' kosong yang diarahkan oleh sistem login Anda, ke rute default - dalam kasus kami '/#view'.

Saya membuatnya menjadi fungsi yang bisa saya gunakan kembali di semua tes:

var waitUntilLoaded = function() {
    ptor.wait(function() {
      return ptor.driver.getCurrentUrl().then(function(url) {
        return /view/.test(url);
      });
    });
};

Saya tidak tahu apakah ini akan berhasil untuk Anda, itu tergantung pada konfigurasi perutean Anda.

@juliemr Terima kasih, bekerja seperti pesona :)

Saya mengalami masalah yang sama (ditemukan di SO di: http://stackoverflow.com/questions/19391813/protractor-fails-to-find-angular ) dengan Busur Derajat tidak menemukan Angular meskipun Angular dimuat dan berjalan dengan sangat jelas. Apakah solusi mudah (menguji tanpa mencoba menemukan Angular) seperti yang seharusnya kita tempuh? Tampaknya mengalahkan tujuan Busur Derajat yang secara khusus dibangun untuk menguji aplikasi Angular.
edit: Saya juga harus mencatat bahwa solusi yang diusulkan dalam masalah ini tidak berfungsi untuk saya.

+1 untuk memiliki dokumentasi bootstrap manual sudut yang lebih baik

apakah ini masih relevan?

Sejujurnya saya tidak tahu karena saya sudah berhenti mencoba dan tidak punya waktu untuk kembali dan melihat apakah ada sesuatu yang berubah. Mempertimbangkan perubahan versi sejak saat itu, jika Anda ingin menutup ini, saya tidak akan membantah. Itu selalu dapat dibuka kembali nanti.

Saya baru saja mulai menggunakan busur derajat hari ini dan aplikasi kami menggunakan require.js... jika ada pembaruan sehubungan dengan pengujian aplikasi yang di-bootstrap secara manual, saya, misalnya, tertarik. :-)

Masalah yang sama disini. Mendapat aplikasi dengan halaman login di luar aplikasi sudut. Solusi dalam komentar sebelumnya tampaknya sudah ketinggalan zaman. Sangat ingin memperbarui dokumen tentang cara menguji skenario semacam itu.

@hankduan Ya, saya pikir begitu.

Saya sedang berjuang dengan masalah ini sekarang. Latar belakangnya serupa: Saya memiliki aplikasi yang lebih besar yang dependensinya dikelola melalui RequireJS.


Saya telah memperbarui aplikasi saya menggunakan window.name='NG_DEFER_BOOTSTRAP!'; & angular.resumeBootstrap() , namun tetap tidak berfungsi.

Mengatakan ini, saya tidak tahu apa yang harus dilakukan selanjutnya. Untuk penyelidikan lebih lanjut, saya telah menyiapkan kasus uji di https://github.com/knalli/protractor-with-deferred-bootstrap

  • git clone https://github.com/knalli/protractor-with-deferred-bootstrap.git
  • cd protractor-with-deferred-bootstrap
  • npm install
  • npm run-script webdriver (Server Selenium)
  • npm run-script server (Server Aplikasi Demo melayani aplikasi AJS mini)
  • npm run-script e2e-test (menjalankan busur derajat...)

Hasilnya adalah

Using the selenium server at http://localhost:4444/wd/hub
Login: Click
Login: Waiting...
A Jasmine spec timed out. Resetting the WebDriver Control Flow.
The last active task was: 
unknown
F

Failures:

diikuti oleh

UnknownError: unknown error: [ng:btstrpd] App Already Bootstrapped with this Element '

Kesalahan terakhir sedikit aneh dan bahkan mungkin menyesatkan: Tes telah dilakukan (berhasil sejauh harapan baik-baik saja dan apa yang dapat kita lihat di browser).

Crosscheck: Jika saya mengalihkan aplikasi demo ke bootstrap non-deferred dengan manual include (varian ini tersedia di cabang no-deferred ), maka itu akan berhasil.


Saya sudah mencoba beberapa yang disebut "solusi":

  1. http://www.sebdangerfield.me.uk/2014/01/angularjs-protractor-app-already-bootstrapped-error/
    Tidak relevan atau menyesatkan --> tidak ada perbedaan.
  2. https://github.com/angular/protractor/issues/325#issuecomment -36738048 menggunakan protractor.getInstance() dan ignoreSynchronization --> tidak ada perbedaan
  3. https://github.com/angular/protractor/issues/325#issuecomment -30701683 menambal clientSideScripts.js/waitForAngular --> tidak ada perbedaan

Saya menulis tes busur derajat pertama saya kemarin dan memiliki masalah yang sama dengan knali.

Terima kasih telah menulis contoh @knali. Saya akan melihatnya dalam beberapa hari

Jadi busur derajat saya menguji semua berfungsi (kecuali untuk satu kegagalan tapi itu salah saya :-P ).
Beri tahu saya jika ini tidak membantu.
Inilah pengaturan saya:

versi busur derajat:
Versi 1.0.0-rc4
selenium mandiri:
terbaru
chromedriver:
terbaru

File yang pasti relevan:

konfigurasi

/*jshint expr: true*/
/*global browser: true*/
var TEST_DIR =  '../tests/';
exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub'
,  specs : [     '../tests/e2e/_protractor.js'       ]
,  capabilities: {'browserName': 'chrome'    }
,  chromeDriver: './chromedriver'  // <---- I remember not being able to get chromedriver working 
                                                    // for some reason, so I just downloaded the executable and put it
                                                    // in my config directory
,  onPrepare: function() {
    "use strict";
    browser.driver.get('http://localhost:5000/register');
    browser.driver.wait(function() {
      return browser.driver.getCurrentUrl().then(function(url) {
        return /\#\/registration/.test(url);
      });
    });
  }
    //  chromeOnly: true,
    //  baseUrl: 'http://localhost:5000/register'
,  jasmineNodeOpts: {
    showColors: true
  }
};

_busur derajat.js

/*jshint expr: true, undef: true */
/* global element: true, by: true, browser: true, model:true */
(function(){
  "use strict";

var RegistrationPage = function(){
  browser.driver.wait(function() {
    return browser.driver.getCurrentUrl().then(function(url) {
      return /\#\/registration/.test(url);
    });
  });
};
  var account = new RegistrationPage();

  account.elem = element.all(by.name('account_exists'));
  account.accountNumber = element(by.name('account_number'));
  account.submitAccountButton = element(by.css('#account_input button'));

  account.selectHasAccount = function(){
    account.elem.get(0).click();
    return browser.getCurrentUrl();
  };

  account.enterAccountNumber = function(keys){

    account.selectHasAccount().then(function(){
      account.accountNumber.sendKeys(keys);
      return account.submitAccountButton.click()
        .then(function(){
          return browser.getCurrentUrl();
      });
      //this wont log because already returned ^
//      console.log('need to return again');
    });
  };
  account.noAccount = function(){
    account.elem.get(1).click();
  };

describe('registration page', function() {
  it("will survive", function(){
    var registrationPage = new RegistrationPage()
    , title = browser.getTitle();
    expect(title).toBe('Web Shop | Homepage');
  });
  it('will change route on account_exists radiobox click', function(){
    var elem = element.all(by.name('account_exists'))
    , _url;
    elem.get(0).click()
    .then(function(){
      _url = browser.getCurrentUrl().then(function(_url){
        expect(_url).toBe('http://localhost:5000/register#/registration/has');
      });
    })
    .then(function(){
        elem.get(1).click().then(function(){
          _url = browser.getCurrentUrl();
          expect(_url).toBe('http://localhost:5000/register#/registration/no');
        });
      });
  });
  describe('navigate the hasAccount path:', function(){
    it('will click hasAccount which will cause a route change.', function () {
      expect(account.selectHasAccount()).toBe('http://localhost:5000/register#/registration/has');
    });
    it("will submit a valid account number", function(){
      expect(account.enterAccountNumber('1231231231')).toBe('http://localhost:5000/register#/user');
    });
  });
  it('will click noAccount which will cause a route change.', function () {
    var  _url;
    account.noAccount();
    _url = browser.getCurrentUrl();
    expect(_url).toBe('http://localhost:5000/register#/registration/no');
  });
});
})();

Membutuhkan/main.js:

var pathToJQuery
if('querySelector' in document
  && 'localStorage' in window
  && 'addEventListener' in window) {
  //ie9+ and all browsers
  pathToJQuery = 'lib/jquery/dist/jquery'
} else {
  //ie8 and ie7
  pathToJQuery = 'lib/jquery-1.7.2.min'
}
requirejs.config({

      paths : {

//        Paths

          "reg": 'js/registration'
        , "com": 'js/common'
        , "init": 'js/init'
        , "regD": 'js/registration/directives'
        , "regC": 'js/registration/controllers'
        , "regS": 'js/registration/services'
        , "regM": 'js/registration/modules'
//
//        Frameworks
        ,  "angular": "lib/angular/angular"
        ,  "angular.animate" : "lib/angular-animate/angular-animate"
        ,  "jquery": pathToJQuery   //< = == v    long story; don't judge me.
        ,  "jqueryMigrate" : "lib/jquery-migrate/jquery-migrate"
        ,  "mocks": "lib/angular-mocks/angular-mocks"
        ,  "ui_router": "lib/angular-ui-router/release/angular-ui-router"
        ,  "Q": "lib/q/q"

//        Init
        ,  "apps_init" : 'js/init/apps_init'
        ,  "apps_bootstrap" : 'js/init/apps_bootstrap'
//        ,  "jquery_bootstrap" : 'js/init/jquery_bootstrap'
        ,  "registration": "js/init/registration"

//       Common

//         Registration
        ,  "registration": "js/registration/registration"
//         Controllers
        ,  "account.controller" : 'js/registration/controllers/account.controller'
        ,  "user.controller" : 'js/registration/controllers/user.controller'
//         Directives
        ,  "account.directive" : 'js/registration/directives/account.directive'
//    Services
        , "user.service" : "js/registration/services/user.service"
    }
,     shim: {
        'angular': {
            exports : 'angular'
        }
    ,   'angular.animate' : {deps: ['angular']}
    ,   'jqueryMigrate' : {deps: ['jquery']}
    ,   'ui_router' : ['angular']
    ,   'mocks': { deps: ['angular'], 'exports': 'angular.mock' }
}
});

if( pathToJQuery ===  'lib/jquery/dist/jquery' ){
  requirejs([
        'angular' , 'jquery' , 'jqueryMigrate', 'init/jquery_bootstrap', 'init/apps_bootstrap' ]
      , function(angular, jquery, jquery_bootstrap, apps_bootstrap) {
      }
  );
} else {
  requirejs([
      'angular' , 'jquery' , 'jqueryMigrate', 'init/jquery_bootstrap', 'init/apps_bootstrap' ]
    , function(angular, jquery, jqueryMigrate, jquery_bootstrap, apps_bootstrap) {
    }
  );
}
console.log("working");

File yang berpotensi membantu:

tampilan default (stang)

<!DOCTYPE html>
<html xmlns:ng="http://angularjs.org"
            xmlns:fab="http://angularjs.org"
            xmlns:ui ="http://angularjs.org"
            lang = "en" class = "no-js" >
<head >
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<meta charset="utf-8">
<link rel="shortcut icon" type="image/x-icon" media="all" href="/images/favicon.ico" />
<script type="text/javascript" src="lib/modernizr.js"></script>

<!-- Default ie theme files:-->
<!--[if lte IE 9]><script type="text/javascript">console = {}; console.log = function(){};</script><![endif]-->
<!--[if IE 8]><link type="text/css" rel="stylesheet" href="build/css/ie8/theme.css" /><![endif]-->

<!--[if IE 7]><link type="text/css" rel="stylesheet" href="build/css/ie7/theme.css" /><![endif]-->

<!-- Normal styles -->
<link type="text/css" href="css/style.css" rel="stylesheet">


<!--[if IE 8]> <link type="text/css" rel="stylesheet" href="build/css/ie8/ie_8.css"  /> <![endif]-->
<!--[if IE 7]> <link type="text/css" rel="stylesheet" href="build/css/ie7/lte_ie7.css"/> <link type="text/css" rel="stylesheet" href="build/css/ie7/ie_7.css" /><![endif]-->


<script data-main="main" src="lib/requirejs/require.js"></script>
</head >

<body class = "page-homepage language-en" >
<div id = "wrapper" >
    <div id = "page" data-currency-iso-code = "USD" >
        {{> _header}}
        <a href = "#skip-to-content" class = "skiptocontent" >Skip to content</a >
        <a href = "#skiptonavigation" class = "skiptonavigation" >Skip to navigation menu</a >
    <!--[if lte IE 10]> <p class="browsehappy" style="margin-top: 10px; ">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p><![endif]-->
    <main ng-cloak id = "content" role = "main" class = "page_main <!--[if IE7]>ng-cloak<![endif]-->" >

        </main>
    </div >
</div >
</body >

</html >

controller.js (konfigurasi server)

(function(){
    "use strict";

    //  node requires
    //==============================
    // express-hbs
    // express
    //
    const express = require('express')
        , portN = 5000
        , hbs = require('express-hbs')
        , app = express()
        , path = require('path')
        , Server = require('./server')
        , bodyParser = require('body-parser')
        , serveStatic = require('serve-static')
        , session = require('express-session')

    , router = express.Router()
    , logger  = require('morgan')
        , methodOverride = require('method-override')
        , errorhandler = require('errorhandler')


    //  view paths
    //==============================
    //
    //
    //
        , viewsD = __dirname + '/views/'
        , partialsD = viewsD + 'partials/'
        , layoutsD = viewsD + 'layouts/'
        , testsD =  __dirname + '/tests/'
    , publicD = __dirname + '/public/'
    , styleguideD = publicD+ '/styleguide/'
        , defaultF = layoutsD + 'default.hbs';
    //  Express setup.
    //==============================
    //
    //
    //
    app.use(express.static(publicD))
            .use(bodyParser())
            .use(logger('dev'))
            .use(methodOverride())
            .use(serveStatic(path.join(__dirname, 'public')))
            .use(errorhandler());

    app.set('view engine', 'hbs')
            .set('port', process.env.PORT || portN)
            .set('cache', false)
            .set('views', viewsD);

    app.engine('hbs', hbs.express3({
        partialsDir: partialsD,
        defaultLayout: defaultF,
        layoutsDir: layoutsD
    }));

    var indx = {};

    app.get( '/' ,function (req, res) {
        res.render(partialsD + '_home.hbs', indx);
    });

    app.get( '/register' ,function (req, res) {
        res.render(partialsD + '_register.hbs', indx);
    });

    new Server(app);

})();

server.js

module.exports = function(app){
  "use strict";
    var http = require('http');
    http.createServer(app).listen(app.get('port'), function(){
        console.log('Express server listening on port ' + app.get('port'));
    });
};


module.exports = function (app) {
    "use strict";
    var http = require ('http');
    http.createServer (app).listen (app.get ('port'),function () {
        console.log ('Express server listening on port ' + app.get ('port'));
    }).on ('error', function (e) {
        console.log ("got error: " + e.message);
    });
};

package.json (kutipan yang relevan)

"dependencies": {
    "body-parser": "^1.2.1",
    "bower": "^1.3.2",
    "errorhandler": "^1.0.1",
    "express": "^4.3.1",
    "express-hbs": "^0.7.9",
    "express-session": "^1.2.0",
    "node-dev": "^2.3.0"
  },

  "scripts": {
    "start": "node --harmony $* ./node_modules/.bin/node-dev controller.js",
  },
"devDependencies": {
  "browserstack-webdriver": "^2.41.1",
  "grunt-protractor-runner": "^1.0.0",
  "method-override": "^1.0.2",
    "morgan": "^1.1.1",
    "protractor": "^0.23.1",
    "requirejs": "^2.1.11",
    "serve-static": "^1.1.0",
},
  "author": "Andrew Luhring"

struktur file:

config/
   protractor.config.js
    chromedriver

server.js
controller.js

public/
   main.js
   js/
   lib/

tests/
   e2e/
      _protractor.js    <=== test file.

views/
  layouts/
      default.hbs

  partials/
      _head.hbs
      _register.hbs   <=== file being tested.

Cukup yakin itu seluruh pengaturan saya. Kupikir aku akan menggunakan verbose. Semoga membantu.

Yang perlu saya lakukan adalah:

  1. tambahkan bagian khusus tes ke URL, sehingga kode bootstrap saya tahu apakah itu berjalan 'normal' atau sebagai tes busur derajat, lalu hanya untuk tes
  2. panggil angular.bootstrap dari document.ready
  3. atur nama jendela untuk memulai dengan 'NG_DEFER_BOOTSTRAP!' sebelum memanggil angular.bootstrap
  4. atur atribut 'ng-app' pada elemen tingkat atas saya
  5. atur window.angular untuk menunjuk ke angular

Lihat https://github.com/mikaraento/protractor-reuse/blob/master/index.js

Bolehkah saya tahu mengapa skrip busur derajat yang dijalankan dengan sangat baik di browser chrome dan firefox tidak dapat mengeksekusi selalu di Internet Explorer?

Meskipun skrip yang sama dieksekusi dengan sempurna di browser lain, tidak dapat dieksekusi selalu sama di Internet Explorer. Saya sering mendapatkan kesalahan seperti pengecualian waktu habis sebagai
pesan: 'batas waktu: habis waktu setelah 30000 mdtk menunggu spesifikasi selesai',
jejak: { tumpukan: tidak terdefinisi } } ]
dan juga elemen terkadang tidak terdeteksi di Internet Explorer.

Meskipun saya menggunakan interval waktu default sebagai defaultTimeou tInterval:1000000 , dalam skrip saya, saya mendapatkan kesalahan yang disebutkan di atas saat menjalankan di Internet Explorer...

Adakah yang bisa membantu saya dalam hal ini?

Salam,
Santhosh Chunchu

Saya tidak melihat itu masalah dengan bootstrap manual saja? Atau apakah Anda dapat menjalankan aplikasi bootstrap manual yang sudah ada di Chrome dan Firefox?

@hankduan Apakah Anda sudah melihat kasus uji? Mungkin ada yang bisa kami bantu?

Saya memiliki CL yang mengubah cara kerja bootstrap untuk busur derajat ( https://github.com/angular/protractor/pull/1155 ). Tujuan utamanya adalah untuk memperbaiki sejumlah masalah lain, tetapi saya pikir itu harus memperbaiki (atau setidaknya membantu) dengan bootstrap manual tergantung pada bagaimana Anda melakukan bootstrap. Namun, saya tidak pernah mengatur bootstrap manual untuk menguji, jadi ini hanya teoretis.

PR ini membutuhkan perubahan busur derajat dan perubahan Angular, sehingga mungkin tidak akan dirilis dalam waktu singkat.

Masalah ini tampaknya menjadi hasil pencarian teratas ketika mencari cara untuk secara manual bootstrap Angular untuk digunakan dengan Busur Derajat, jadi saya pikir ini adalah tempat yang bagus untuk menyarankan solusi lain. Ini berfungsi untuk kasus di mana seluruh antarmuka Anda adalah aplikasi Angular (daripada melakukan sesuatu seperti bootstrap pada div setelah login, seperti contoh di atas).

Meskipun dimungkinkan untuk menunda tes Busur Derajat hingga setelah Angular dimuat, dokumen Angular resmi menyatakan Anda tidak dapat melakukan bootstrap manual dengan Busur Derajat. Saya cenderung menghindar dari solusi yang tampaknya dilarang oleh dokumentasi resmi.

Solusi saya

Saya menggunakan Grunt untuk Concat/Uglify kode saya ke satu file JS, yang merupakan satu-satunya skrip yang dirujuk di index.html, dengan tag skrip. Sebut saja script.js. Dalam Pengembangan, saya menjalankan tugas Grunt yang berbeda, yang menggabungkan hanya file yang saya perlukan untuk memuat sisa file JS, secara terpisah, tidak sinkron, dan dengan cap waktu untuk mencegah caching. Kumpulan skrip yang diringkas ini menggantikan script.js saat saya sedang mengembangkan. Dalam kedua skenario, saya hanya memuat script.js dari index.html, dan dengan tag skrip.

Perkembangan

Jadi, dalam Pengembangan, saya harus melakukan bootstrap manual. Itu mudah karena saya dapat memasukkan satu file yang tidak saya gabungkan ke dalam Production JS, dan saya pastikan untuk memuat skrip ini setelah semua JS lainnya dimuat.

bootstrap_dev.js

        .element(document.body)
        .ready(function() {
            angular.bootstrap(document.body, ['App']);
        });

Produksi / Busur Derajat

Di Production, saya tidak bisa bootstrap secara manual karena Protractor tidak menyukainya. Dan saya menjalankan Busur Derajat terhadap kode Produksi saya. Saya juga menghapus atribut "ng-app" dari HTML saya, sehingga aplikasi tidak melakukan bootstrap sebelum waktunya dalam Pengembangan, sehingga bootstrap otomatis normal tidak terjadi. Saya menebus ini dalam produksi dengan meletakkan skrip sebelum semua JS lain di script.js.

bootstrap_prod.js

    window.document.body.setAttribute("ng-app", "myApp");

Ganti saja "myApp" dengan nama modul utama Anda.

Kesimpulan

Dalam Pengembangan, jika Anda melakukan hal di atas, Anda dapat memuat skrip Anda secara asinkron dan melakukan bootstrap manual. Tetapi jika Anda setuju dengan hanya menjalankan tes Busur Derajat Anda terhadap kode produksi (yang dapat dimuat dari satu file melalui tag skrip, cukup tambahkan direktif ng-app sebelum Angular dimuat sehingga ia melakukan bootstrap otomatis. Sekarang Anda memilikinya pemuatan skrip asinkron dari berbagai skrip Anda dalam Pengembangan, dan menjalankan tes Busur Derajat untuk kode produksi Anda.

Apa yang akhirnya berhasil bagi saya adalah menambahkan, di protractor.conf.js saya, fungsi berikut:

onPrepare: function() 
    {
        // implicit and page load timeouts
        browser.manage().timeouts().pageLoadTimeout(40000);
        browser.manage().timeouts().implicitlyWait(25000);

        // for non-angular page
        browser.ignoreSynchronization = true;

        // sign in before all tests
     }

Jika ada cara yang lebih baik untuk melakukannya, beri tahu saya =]

Punya masalah serupa. Menemukan info berguna ini:

Proses booting

Tidak ada perbedaan, bagaimana aplikasi ditingkatkan dalam produksi, tetapi dalam pengujian busur derajat melakukan itu:

  1. Mengubah window.name sehingga angular dijeda sebelum memulai: NG_DEFER_BOOTSTRAP! (ini adalah fitur sudut!)
  2. Melakukan hal-hal tiruan, lalu memanggil angular.resumeBoostrap() dan aplikasi benar-benar dimulai.

Jadi pastikan kode produksi Anda tidak bertentangan dengan proses ini, karena angular hanya dapat di-boost sekali, panggilan kedua ke angular.boostrap() atau angular.resumeBoostrap() akan merusak busur derajat atau aplikasi. Jadi, ng-app di body tidak diperlukan sama sekali, dan Anda dapat memanggil angular.boostrap() sendiri dan akan ditangani oleh busur derajat menggunakan NG_DEFER_BOOTSTRAP! dengan baik.

jendela.nama

Pastikan window.name tidak diubah oleh kode aplikasi apa pun saat memuat & mem-boot. Dalam kasus saya jquery melakukan itu, tidak tahu mengapa. Jquery yang sepenuhnya dihapus dari proyek saya dan pengujian berhasil. Ini adalah akar masalahnya!

Untuk saat ini, saya sedang mencari, bagaimana mengembalikan jquery tanpa merusak tes, karena itu dibutuhkan oleh proyek saya!

Akhirnya,

masalah kami ada di dua versi jQuery pada satu halaman (versi kedua dimuat oleh perpustakaan eksternal). Menghapusnya dan hanya menyisakan jQuery kami di halaman dan semuanya berfungsi.

Beberapa kode, mungkin membantu:

index.html

<body>
...
<script data-main="require.conf" type="text/javascript" src="bower_components/requirejs/require.js"></script>
</body>

memerlukan konfigurasi.js

...
 deps: ["proto/main"],
...

proto.js

// We just load deps and register the module:
 define(["deps"],function(){
   angular.module('proto'...
 }

proto/main.js

define(["require", "exports", "proto", "angular"], 
    function (require, exports) {

    angular.bootstrap(document, ['proto']);
});

dan, sebenarnya, spesifikasi tes

var protractor = require('protractor');
var ptor;
function prepareBrowser() {

    ptor = protractor.getInstance();

    return ptor.get(ptor["baseUrl"] + '/login').then(function () {
        console.log("got");       
        return ptor.waitForAngular().then(function () {
            console.log("ngwaited");
        });
    });
}
describe('container', function () {
    beforeEach(function () {
        return prepareBrowser();
    });
    describe('form tests', function () {
        it('form is shown', function () {
            expect($('[ng-controller=LoginContr]').isDisplayed()).toBeTruthy();
        });

    });
});

Keluaran

Using the selenium server at http://localhost:4444/wd/hub
got
ngwaited
container
  form tests
    form is shown - pass


Finished in 3.112 seconds
1 test, 1 assertion, 0 failures

Hore!

Saat kami beralih dari menggunakan ng-app ke angular.bootstrap() , menambahkan rootElement: 'div' ke projotractor.conf adalah satu-satunya perubahan yang kami perlukan agar busur derajat berfungsi kembali. Kami menggunakan sudut 1.3.0 dan busur derajat 1.3.1.

@jongunnip Ya itu juga berhasil untuk saya, terima kasih!

@mikaraento Ini berhasil untuk saya, terima kasih~

Hi guys, hal aneh yang relevan untuk thread ini.

Saya memiliki aplikasi sudut biasa - tidak ada persyaratan atau apa pun, saya menggunakan busur derajat 2.0.0.

Ketika saya menjalankan tes sistem pada lingkungan pementasan, itu berfungsi.
Ketika saya menjalankannya secara lokal itu memberi saya:
org.openqa.selenium.WebDriverException: unknown error: [ng:btstrpd] App Already Bootstrapped with this Element ... pesan

Ketika saya mengonfigurasi server Nginx untuk melayani sumber daya statis alih-alih grunt:server semuanya berfungsi.

Apakah penting jika saya menjalankannya dengan livereload dalam pengembangan?

Sepertinya server statis berperilaku berbeda, dan grunt melayani beberapa 404 atau pengalihan, jadi webdriver menjadi gila.

Halo semua,

setelah banyak waktu membaca dan membaca, saya menemukan satu solusi yang bekerja dengan baik untuk proyek saya ( memperbaiki alur eksekusi busur derajat )

  1. ketika membuka aplikasi ke busur derajat tambahkan ?protractor-test ke URL ( kode proyek )
  2. ubah kode bootstrap sudut menjadi seperti di bawah ini ( kode proyek )
if(location.href.indexOf("protractor-test") < 0){
  // start angular app
  angular.bootstrap(document, [module.name]);
} else {
  // start angular app to protractor tests
  window.name = 'NG_DEFER_BOOTSTRAP!' + window.name;
  angular.bootstrap(document, [module.name]);
}

dan akhirnya semua kembali bekerja lagi \o/

dengan salinan @juliemr

Saya baru-baru ini (hanya 1-2 minggu) mulai menggunakan Busur Derajat untuk menguji aplikasi Angular saya. Aplikasi saya memiliki ng-App yang ditentukan dalam tag tubuh pada halaman Login. Tes saya terus mengeluh mengatakan "Sudut tidak dapat ditemukan di halaman httP://(Alamat Situs Web): angular tidak pernah menyediakan resumeBootstrap" Tetapi eksekusi tes baik-baik saja. Tidak yakin tentang masalah ini (jika saya mengaktifkan parameter abaikan sinkronisasi browser maka itu berfungsi dengan baik, tetapi ini bukan cara yang benar), saya dapat mencoba apa yang disarankan Juliemr (gunakan driver lama untuk menavigasi), tetapi hanya mencoba memahami mengapa aplikasi saya mengeluh meskipun memiliki ng-App di tag tubuh. Perilaku Fungsional Aplikasi seperti ini.. Halaman Masuk..Setelah Masuk, klik beberapa tautan di Halaman Beranda dan itu membuka Jendela/Tab lain. Bisakah seseorang membantu saya menemukan langkah-langkah yang perlu diverifikasi semua untuk memastikan bootstrap dilakukan dengan cara otomatis (salah satunya adalah parameter ng-app dalam tag tubuh)? Apakah saya perlu memeriksa sesuatu di file bootstrap.js (Saya tidak melihat parameter ng-app di file bootstrap karena itu memeriksa. Terima kasih

Apakah ada pembaruan tentang masalah ini? Apa praktik atau metode terbaik untuk mengonfigurasi busur derajat agar berfungsi dengan aplikasi sudut yang tidak memiliki aplikasi ng? @erkobridee bisakah Anda menjelaskan contoh Anda lebih lanjut? Dan dapatkah seseorang menjelaskan cara menangani window.name dengan benar sehubungan dengan bagaimana busur derajat harus menunggu ketika sudut selesai memuat?

@juliemr Dengan Angular 1.5, bootstrap manual adalah cara yang lebih disukai untuk bootstrap. Apakah ada dukungan busur derajat yang diberkati di jalan?

+1 Saya pikir masalah ini harus menjadi prioritas yang lebih tinggi. Jika Busur Derajat tidak bekerja dengan bootstrap manual, maka tidak ada manfaat menggunakan Busur Derajat. Inti dari menggunakan Busur Derajat melalui Webdriver adalah bahwa Busur Derajat menangani semua sinkronisasi sudut untuk Anda.

Saya memiliki masalah yang sama. Perubahan apapun?

hai, apakah ada rencana atau proses untuk meningkatkan ini?

Anehnya tidak ada tanggapan. Saya memiliki aplikasi yang hilang ng-app dan saya tidak dapat menguji
mereka dengan busur derajat

Pada 16 Juli 2016 5:01 pagi, "millerwx" [email protected] menulis:

hai, apakah ada rencana atau proses untuk meningkatkan ini?


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/angular/protractor/issues/66#issuecomment -233104701,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AOghFs2ff0e-88DLafNGD3iCH8uCOgVaks5qWEmIgaJpZM4A82d7
.

Sampai saat ini di tahun 2016, ini masih menjadi masalah bagi saya. Saya mengikuti jawaban Magnetized untuk menyelesaikan masalah. Saya hanya melakukan beberapa perubahan. Apa yang bagus dan di luar cakupan percakapan adalah melacak juga pengalihan dan mendarat kembali di dalam aplikasi Anda. *Saya melakukannya dengan Babel, tetapi Anda dapat menulisnya di ES5.

`describe('layar login', ()=>{

var urlTimeout = 9000;

const waitForUrlRegex = (regex, urlMatcher )=>{

    return driver.wait(()=>{
        return driver.getCurrentUrl().then( (url)=>{
            return regex.test(url);
        });
    }, urlTimeout, "Expectation error: Timeout for url not matching " + urlMatcher );
};

const waitForRoute = (route)=>{
    return waitForUrlRegex( new RegExp( route + "$" ), route  );
}

const waitForUrl = (url)=>{
    return waitForUrlRegex( new RegExp( "^https?:\/\/" + url ), url );
}

it('should go to homepage and click login button', ()=>{

    driver.get( app_url, urlTimeout);

    //there is a redirect to welcome route
    expect( waitForRoute("welcome") ).toBe(true);

    const loginButton = element.all(by.className("login_button")).get(0);
    loginButton.click();
});

it( 'should enter credentials', ()=>{
    expect( waitForUrl( non_angular_login_url ) ).toBe(true);
    driver.findElement( by.name("user")).sendKeys( "username");
    driver.findElement( by.name("password")).sendKeys( "userpassword");
    driver.findElement( by.tagName("button")).click();
});

it( 'should go back to app, and continue testing', ()=>{
    expect( waitForRoute( "user-screen") ).toBe(true);
});

});`

config.onPrepare

onPrepare: ()=>{ require("babel-register"); global.driver = browser.driver; }

Jika Anda tidak ingin melihat pengalihan, cukup biarkan driver tidur dan kemudian mulai bekerja dengan busur derajat.

`driver.get( app_url+ "/#/selamat datang", urlTimeout);

    driver.sleep( 1000 );
    const loginButton = element.all(by.className("login_button")).get(0);
    loginButton.click();`

Kami sebenarnya mendukung bootstrap manual, informasi ini sudah lama. Bootstrapping akan menjadi lebih andal setelah kami menangani https://github.com/angular/protractor/issues/3857 juga.

@sjelin Apa cara terdokumentasi untuk mendukung bootstrap manual? Saya tidak dapat menemukan informasi yang relevan untuk busur derajat 5.0.

Saya menghadapi masalah yang sama saat bootstrap manual. dan menemukan solusi untuk dijalankan dengan grunt.
digunakan busur derajat versi 2.5.1.

  1. Sebutkan ini di file kasar Anda.

grunt.initConfig({ protractor: { options: { configFile: "protractor.conf.js", // Default protractor config file keepAlive: true, // If false, the grunt process stops when the test fails. noColor: false, // If true, protractor will not use colors in its output. args: { // Arguments passed to the command } }, e2e: { options: { // Stops Grunt process if a test fails keepAlive: true } } } })

  1. Instal npm install grunt-protractor-runner --save-dev dan tambahkan untuk memuat tugas grunt.loadNpmTasks('grunt-protractor-runner')

  2. Jalankan busur derajat dengan perintah berikut:
    grunt protractor
    atau dengan nama suite
    grunt protractor --suite suite_name

Tolong beri tahu saya jika itu berhasil untuk Anda.

Ini berhasil untuk saya.
browser.ignoreSynchronization = true;
browser.get(url);
browser.ignoreSynchronization = false;

Apakah halaman ini membantu?
0 / 5 - 0 peringkat