Protractor: تعطل المنقلة عندما يتم تمهيد التطبيق باستخدام ngUpgrade

تم إنشاؤها على ١٦ مايو ٢٠١٧  ·  51تعليقات  ·  مصدر: angular/protractor

أنا أعمل على ترحيل تطبيق AngularJS (1.6) إلى Angular (4) ولدي الآن تطبيق هجين ، تم تمهيده باستخدام NgUpgrade. يبدو أن هذا قد كسر تمامًا اختبارات المنقلة الخاصة بي.

سامحني إذا كان هذا مجرد شيء أفعله خطأ ، لكن لا يمكنني العثور على أي إجابة عن سبب عدم نجاح ذلك.

الخطأ الذي أحصل عليه هو:

فشل: انقضت المهلة في انتظار انتهاء مهام Angular غير المتزامنة بعد 11 ثانية. قد يكون هذا بسبب أن الصفحة الحالية ليست تطبيق Angular. يرجى الاطلاع على الأسئلة الشائعة لمزيد من التفاصيل: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting -for-angular

أثناء انتظار عنصر مع محدد المواقع - محدد المواقع: بواسطة (محدد css ، .toggle-abstract-button)

تغييرات التطبيق الهجين

يبدو أن التطبيق يعمل بشكل جيد ، ويعمل كلا المكونين AngularJS و Angular كما هو متوقع. التغييرات التي أجريتها في عملية التمهيد هي:

1 تمت إزالة تطبيق ng من علامة html:

<html lang="en" *ng-app="myapp">

2 تمت إضافة AppModules (NgModule) إلخ.

3 تم استخدام NgUpgrade لتشغيل التطبيق:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { UpgradeModule } from '@angular/upgrade/static';
import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
  const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
  upgrade.bootstrap(document.body, ['myapp'], {strictDi: true});
});

اختبارات المنقلة

بناءً على الخطأ أعلاه ، يبدو أن المشكلة مرتبطة بأي شيء تفعله المنقلة عندما تنتظر Angular. لدي كتلة beforeEach تقوم بتحميل صفحة تسجيل الدخول ، وتملأ التفاصيل وتسجيل الدخول. من الغريب أنها لا تزال تفتح الصفحة وتدخل النص في حقل اسم المستخدم ، لكنها تفشل بعد ذلك في المضي قدمًا إلى أبعد من ذلك.

لقد حاولت ولكن دون جدوى:

  • إضافة "rootElement: 'body'" إلى ملف تكوين منقلة
  • إضافة "ng12Hybrid: true" إلى ملف تكوين المنقلة - تلقيت رسالة تفيد بأنه لم يعد هناك حاجة إليه لأنه يكتشف تلقائيًا.
  • زيادة إعداد allScriptsTimeout من 11000 إلى 60000 ولا تزال مهلته منتهية.
  • إيقاف تشغيل إعداد waitForAngularEnabled. هذا يحل مشكلة حقول تسجيل الدخول ، ولكن بعد ذلك لا يعمل أي من نماذج http الخاصة بي وتفشل الاختبارات.

التعليق الأكثر فائدة

مرحبًا - نحن نعمل على تغيير للسماح لك بتهيئة المهام التي تنتظرها المنقلة ، والتي يمكن أن تساعدك في التعامل مع المشكلة المذكورة أعلاه. هذا تغيير واسع يشمل Zone.js و Angular وليس له وقت محدد للوصول (سيكون في نطاق الأسابيع). سيتم تحديث التقدم هنا.

ال 51 كومينتر

لدي مشكلة مماثلة تم حلها عن طريق تغليف رمز الترقية هذا على النحو التالي:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { UpgradeModule } from '@angular/upgrade/static';
import { AppModule } from './app.module';

angular.element(document).ready(() => {
  platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
    const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
    upgrade.bootstrap(document.body, ['myapp'], {strictDi: true});
  });
});

وفي التكوين ، لا أستخدم أيًا من هؤلاء:

//ng12Hybrid: true,
//useAllAngular2AppRoots: true,
//rootElement: 'body',

هل يمكنك إلقاء نظرة على https://github.com/angular/protractor/issues/4234 ومعرفة ما إذا كنت تواجه نفس المشكلة؟ أيضًا ، في ngUpgrade $interval سيتم الآن حظر Protractor حيث لم يحدث من قبل (https://github.com/angular/angular/issues/16349) ، لكني أعمل على ذلك.

Evilweed - شكرًا على الاقتراح ، للأسف لا يبدو أن هذا يحل المشكلة بالنسبة لي.

heathkit - لقد وجدت

هل يمكنك نشر الخطأ الكامل الخاص بك؟ من المفترض أن تُظهر المهام المعلقة في رسالة الخطأ ، ولكن من المحتمل أن تفقد بعض المهام. على سبيل المثال ، لن يظهر الخطأ حتى الآن المهام المعلقة من الجانب الزاوي. إذا كان لديك مهام غير متزامنة تعمل لفترة طويلة في الجزء الزاوي من التطبيق الخاص بك ، فستحتاج إلى تشغيل تلك المهام خارج المنطقة الزاويّة لتجنب حظر المنقلة. (انظر https://github.com/angular/protractor/blob/master/docs/timeouts.md)

شكرا مرة أخرى على الرد. تفاصيل الخطأ أدناه. هناك عدد قليل من الأشياء ملاحظة:

  • يحتوي ملف الاختبار الخاص بي على كتلة beforeAll والتي من المفترض أن تملأ حقول اسم المستخدم وكلمة المرور لتسجيل الدخول. تملأ حقل اسم المستخدم بنجاح ولكن تنتهي المهلة في waitForAngular ولا تملأ حقل كلمة المرور. هذا ما يبدو أن النصف الأول من الخطأ يدور حوله. النصف الثاني هو اختبار الفشل الفعلي (وهو أمر منطقي ، لأنه فشل في تسجيل الدخول وبالتالي لم يكن العنصر موجودًا).

  • يشير الخطأ إلى أن المشكلة قد تنجم عن استدعاء HTTP ، لذلك ربما لا يكون الفاصل الزمني $ أو المهلة $.

  • ليس لدي الكثير في الجانب الزاوي في الوقت الحالي ، فكلها تقريبًا لا تزال AngularJS. لا يصل الأمر إلى حد إظهار المكون Angular الجديد لأنه لا يتمكن من تسجيل الدخول (لذلك أشك في أن استدعاء http يتعلق بمكون Angular 4)

  Message:
    Failed: Timed out waiting for asynchronous Angular tasks to finish after 11 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular
    While waiting for element with locator - Locator: By(css selector, *[name="password"])
  Stack:
    ScriptTimeoutError: asynchronous script timeout: result was not received in 11 seconds
      (Session info: chrome=58.0.3029.110)
      (Driver info: chromedriver=2.29.461585,platform=Mac OS X 10.12.4 x86_64) (WARNING: The server did not provide any stacktrace information)
    Command duration or timeout: 11.07 seconds
    Build info: version: '3.4.0', revision: 'unknown', time: 'unknown'
    System info: host: 'Matt.lan', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.12.4', java.version: '1.8.0_111'
    Driver info: org.openqa.selenium.chrome.ChromeDriver
    Capabilities [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEnabled=false, networkConnectionEnabled=false, chrome={chromedriverVersion=2.29.461585, takesHeapSnapshot=true, pageLoadStrategy=normal, databaseEnabled=false, handlesAlerts=true, hasTouchScreen=false, version=58.0.3029.110, platform=MAC, browserConnectionEnabled=false, nativeEvents=true, acceptSslCerts=true, locationContextEnabled=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true, unexpectedAlertBehaviour=}]
    Session ID: 40deafceb49b72b1c0188ad0895c1179
        at Object.checkLegacyResponse (/Users/matt/web-app/node_modules/selenium-webdriver/lib/error.js:505:15)
        at parseHttpResponse (/Users/matt/web-app/node_modules/selenium-webdriver/lib/http.js:509:13)
        at doSend.then.response (/Users/matt/web-app/node_modules/selenium-webdriver/lib/http.js:440:13)
        at process._tickCallback (internal/process/next_tick.js:109:7)
    From: Task: Protractor.waitForAngular() - Locator: By(css selector, *[name="password"])
        at thenableWebDriverProxy.schedule (/Users/matt/web-app/node_modules/selenium-webdriver/lib/webdriver.js:816:17)
        at ProtractorBrowser.executeAsyncScript_ (/Users/matt/web-app/node_modules/protractor/lib/browser.ts:608:24)
        at angularAppRoot.then (/Users/matt/web-app/node_modules/protractor/lib/browser.ts:642:23)
        at ManagedPromise.invokeCallback_ (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:1366:14)
        at TaskQueue.execute_ (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2970:14)
        at TaskQueue.executeNext_ (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2953:27)
        at asyncRun (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2813:27)
        at /Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:676:7
        at process._tickCallback (internal/process/next_tick.js:109:7)Error
        at ElementArrayFinder.applyAction_ (/Users/matt/web-app/node_modules/protractor/lib/element.ts:482:23)
        at ElementArrayFinder.(anonymous function).args [as sendKeys] (/Users/matt/web-app/node_modules/protractor/lib/element.ts:96:21)
        at ElementFinder.(anonymous function).args [as sendKeys] (/Users/matt/web-app/node_modules/protractor/lib/element.ts:873:14)
        at /Users/matt/web-app/e2e-tests/modules/authentication.js:83:38
        at ManagedPromise.invokeCallback_ (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:1366:14)
        at TaskQueue.execute_ (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2970:14)
        at TaskQueue.executeNext_ (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2953:27)
        at asyncRun (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2813:27)
        at /Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:676:7
        at process._tickCallback (internal/process/next_tick.js:109:7)
    From: Task: Run beforeAll in control flow
        at Object.<anonymous> (/Users/matt/web-app/node_modules/jasminewd2/index.js:94:19)
    From asynchronous test: 
    Error
        at Suite.<anonymous> (/Users/matt/web-app/e2e-tests/specs/home/asset.spec.js:28:3)
        at Object.<anonymous> (/Users/matt/web-app/e2e-tests/specs/home/asset.spec.js:7:1)
        at Module._compile (module.js:571:32)
        at Object.Module._extensions..js (module.js:580:10)
        at Module.load (module.js:488:32)
        at tryModuleLoad (module.js:447:12)
  Message:
    Failed: No element found using locator: By(css selector, .toggle-asset-summary-button)
  Stack:
    NoSuchElementError: No element found using locator: By(css selector, .toggle-asset-summary-button)
        at elementArrayFinder.getWebElements.then (/Users/matt/web-app/node_modules/protractor/lib/element.ts:851:17)
        at ManagedPromise.invokeCallback_ (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:1366:14)
        at TaskQueue.execute_ (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2970:14)
        at TaskQueue.executeNext_ (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2953:27)
        at asyncRun (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2813:27)
        at /Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:676:7
        at process._tickCallback (internal/process/next_tick.js:109:7)Error
        at ElementArrayFinder.applyAction_ (/Users/matt/web-app/node_modules/protractor/lib/element.ts:482:23)
        at ElementArrayFinder.(anonymous function).args [as click] (/Users/matt/web-app/node_modules/protractor/lib/element.ts:96:21)
        at ElementFinder.(anonymous function).args [as click] (/Users/matt/web-app/node_modules/protractor/lib/element.ts:873:14)
        at Page.showAssetSummaryComponent (/Users/matt/web-app/e2e-tests/specs/home/page-object.js:289:31)
        at Object.<anonymous> (/Users/matt/web-app/e2e-tests/specs/home/asset.spec.js:63:12)
        at /Users/matt/web-app/node_modules/jasminewd2/index.js:112:25
        at new ManagedPromise (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:1067:7)
        at ControlFlow.promise (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2396:12)
        at schedulerExecute (/Users/matt/web-app/node_modules/jasminewd2/index.js:95:18)
        at TaskQueue.execute_ (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2970:14)
    From: Task: Run fit("should open asset summary component") in control flow
        at Object.<anonymous> (/Users/matt/web-app/node_modules/jasminewd2/index.js:94:19)
        at /Users/matt/web-app/node_modules/jasminewd2/index.js:64:48
        at ControlFlow.emit (/Users/matt/web-app/node_modules/selenium-webdriver/lib/events.js:62:21)
        at ControlFlow.shutdown_ (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2565:10)
        at shutdownTask_.MicroTask (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2490:53)
        at MicroTask.asyncRun (/Users/matt/web-app/node_modules/selenium-webdriver/lib/promise.js:2619:9)
    From asynchronous test: 
    Error
        at Suite.<anonymous> (/Users/matt/web-app/e2e-tests/specs/home/asset.spec.js:62:5)
        at Suite.<anonymous> (/Users/matt/web-app/e2e-tests/specs/home/asset.spec.js:60:3)
        at Object.<anonymous> (/Users/matt/web-app/e2e-tests/specs/home/asset.spec.js:7:1)

نفس الشيء تمامًا - مع تكوين angular4 الجديد "quickstart" الجديد واختبار المنقلة الأساسي للغاية. كل شيء يعمل بشكل جيد في الوضع غير المختلط.

Failed: Timed out waiting for asynchronous Angular tasks to finish after 50 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular
    While waiting for element with locator - Locator: By(css selector, #loginModal h4)

ما زلت أرى هذه المشكلة.
باستخدام: @ angular / Upgrade 4.2.2
الذي يحتوي على الإصلاح من heathkit (https://github.com/angular/angular/pull/16836) للحصول على قابلية الاختبار API مستقرة ، ولكن لا يزال يبدو أنه لا يعمل

إذا كان بإمكان شخص ما مشاركة الريبو الذي يوضح المشكلة ، فسأبحث في الأمر أكثر.

ما اكتشفته حتى الآن

بعد بعض البحث ، اكتشفت أحد أسباب المهلة التي أراها (أو أحدها ، أظن أنه ليس السبب الوحيد). اتضح أن إحدى التبعيات التي أستخدمها هي استدعاء window.setTimeout() وهو ما يمنع منقلة من المزامنة (في حالتي ، إنها
الزاوي لحظة .

كان هذا يعمل بشكل جيد عندما كان تطبيقي يعمل فقط AngularJS ولكنه تسبب في مشكلة انتهاء المهلة عند التمهيد كتطبيق مختلط (على الأرجح بسبب طريقة تشغيله في المناطق).

مثال الريبو

لقد قمت بإنشاء نموذج الريبو على https://github.com/mattwilson1024/angular-hybrid . إنه تطبيق هجين (NgUpgrade) مع الأجزاء التالية:

  • يتم توفير الصفحة الخارجية (صفحة الأحرف) بواسطة AngularJS (1.6).
  • تحتوي الصفحة على CharacterListComponent ، وهو مكون Angular (4) تم تخفيضه.
  • يستخدم CharacterListComponent مكون Angular 4 آخر ، مكون CharacterDetail.

يحتوي الفرع الرئيسي على تطبيق العمل واختبارات منقلة واحدة لا تمر بأي مشكلة.

يضيف فرع اللحظة الزاوية تبعية على مكتبة angular-moment ويستخدم التوجيه am-time-ago به لإضافة تسمية إلى الصفحة توضح عدد السنوات الماضية منذ الحلقة الأولى. التطبيق نفسه يعمل بشكل جيد ، لكن فشل اختبار المنقلة الآن.

المهلات

لتأكيد حدوث ذلك ، حاولت إضافة أنواع مختلفة من المهلة إلى وحدة التحكم AngularJS ، مع النتائج التالية. أكد هذا أن الفاصل الزمني $ يعمل ، لكن $ timeout أو setInterval أو setTimeout لا يعمل.

function sayHello() { console.log('Hello, world'); }

$interval(sayHello, 30000); // Succeeds (with Angular 4.2.0 and later - see https://github.com/angular/angular/pull/16836)
$timeout(sayHello, 30000); // Fails - Timed out waiting for asynchronous Angular tasks to finish after 11 seconds
setInterval(sayHello, 30000); // Fails - Timed out waiting for asynchronous Angular tasks to finish after 11 seconds
setTimeout(sayHello, 300000); // Fails - Timed out waiting for asynchronous Angular tasks to finish after 11 seconds

الخطوات التالية

بعد أن تمكنت من تعقب ما يحدث ، ما زلت غير متأكد من الحل. أفهم أنه قد يكون من الضروري تشغيل أجزاء معينة من التعليمات البرمجية "خارج المنطقة الزاويّة" ، على الرغم من أنني لست متأكدًا من كيفية القيام بذلك من مقاطع AngularJS حيث لا أمتلك فئة TypeScript لإدخال المنطقة وما إلى ذلك.

حتى مع ذلك ، إذا كانت شفرة المشكلة تحدث داخل مكتبة تابعة لجهة خارجية (كما هو الحال في مثالي مع لحظة الزاوية) - فما هي الطريقة للتعامل مع هذه المشكلة لجعل الاختبارات تعمل كما فعلت قبل الترقية إلى الإعداد الهجين؟

يتم تعيين المناطق في النافذة ، لذلك لا تحتاج إلى حقن NgZone. يمكنك الركض خارج المنطقة الزاويّة في AngularJS مثل هذا

if (Zone && Zone.current.name === 'angular') {
  let angularZone = Zone.current;
  Zone.parent.run(() => {
    $timeout(() => {
       // Stuff here is run outside the Angular zone and will not be change detected
       angularZone.run(() => {
         // Inside the zone and will be change detected.
       });
    }, 500);
  });
}

أنت محق في أن أي استخدام لـ setTimeout أو setInterval ، حتى في رمز جهة خارجية ، يمكن أن يحظر استقرار المنقلة ويسبب انقضاء المهلات. نحن نضيف تتبع المهام إلى Angular و AngularJS مما يجعل من السهل تصحيح هذه المشاكل من خلال إظهار المكان الذي جاءت منه المهمة غير المتزامنة التي انقضت مهلة المنقلة عليها. من الناحية الواقعية ، سوف يستغرق الأمر شهرين قبل أن نتمكن من إدخال ذلك في المنقلة.

فيما يتعلق باللحظة الزاوية ، قد يكون أفضل خيار لك هو إرسال PR لهم مما يجعلها مدركة للمنطقة كما هو موضح أعلاه. بخلاف ذلك ، يمكنك بشكل انتقائي إيقاف تشغيل waitForAngular واستخدام browser.wait و ExpectedConditions بدلاً من ذلك. نحن نعمل على واجهة برمجة تطبيقات انتظار أكثر مرونة تتيح لك التحكم في المهام التي تنتظرها ، ولكن هذا لا يزال بعيد المنال.

في حالتنا ، يمكن كتابة الاختبارات بالطريقة العامة (بدون المزامنة الزاويّة) ( browser.ignoreSynchronization = true باستخدام ECs ، وما إلى ذلك) ، لكنها تفشل عند تعيين browser.ignoreSynchronization = false; مع "Error while waiting for Protractor to sync with the page: "Cannot read property '$$testability' of undefined"

يؤدي هذا بشكل أساسي إلى إبطال مجموعة الاختبار الآلي E2E بالكامل .

باستخدام منقلة 5.1.2 ، إذا قمت بتعيين ng12Hybrid: true أحصل على الرسالة:

لقد قمت بتعيين ng12Hybrid. اعتبارًا من Protractor 4.1.0 ، يمكن لـ Protractor تلقائيًا الاستدلال على ما إذا كنت تستخدم تطبيق ngUpgrade (طالما تم تحميل ng1 قبل استدعاء platformBrowserDynamic ()) ، ولم تعد هذه العلامة مطلوبة لمعظم المستخدمين

لذلك من الواضح أن وثائق angular.io قديمة هنا: https://angular.io/guide/upgrade#e2e -tests

الكلمات الأخيرة الشهيرة من نفس المستند:

لا تهتم اختبارات E2E حقًا بالهيكل الداخلي لمكونات التطبيق. هذا يعني أيضًا أنه على الرغم من قيامك بتعديل المشروع قليلاً أثناء الترقية ، يجب أن تستمر مجموعة اختبار E2E في اجتياز تعديلات طفيفة فقط. أنت لم تغير كيف يتصرف التطبيق من وجهة نظر المستخدم.

في ضوء هذا البيان على angular.io:

heathkit نشكرك على النصيحة حول الجري داخل وخارج المناطق ، ولكن لكي نكون صادقين ، فإننا نبحث عن حل يعمل مع رمز AngularJS الموجود لدينا ، كما هو. لدينا مجموعة منقلة شاملة تعتمد على مزامنة AngularJS الضمنية. هدفنا هو ترحيل AngularJS الخاص بنا إلى Angular باستخدام ngUpgrade ، ولكن هذه المشكلة مع عدم القدرة على تشغيل مجموعة Protractor الحالية في وضع الترقية المختلط قد أحبطت مبادرتنا. سيكون الإصلاح المعقول موضع ترحيب كبير في الوقت الحالي.

إذا فعلنا شيئًا خاطئًا بشكل أساسي ، فنحن بالتأكيد نود أن نعرف ماذا.

تواجه نفس المشكلة! : 0

نرى نفس الشيء هنا: AngularJS 1.6 -> Angular 4.2.4

أي شخص يعرف أي نوع من الحلول ، مهما كان حجمها؟ بدون العودة إلى 1.6 هذا هو.

@ quinw68 - يقترح heathkit طريقة لتشغيل الكود خارج "المنطقة" الزاويّة في إجابته السابقة في هذا الموضوع. أعتقد أن هذا يعني إجراء تغييرات على الكود المصدري لتطبيقك لجعله يعمل ، وقد يعتمد أيضًا على مكتبات الطرف الثالث التي تضيف الدعم. أرجوا أن تصحح لي إذا كنت مخطئا.

هناك "حل بديل" آخر أدركه وهو التعامل مع تطبيقك الحالي كما لو أنه لم يعد تطبيق AngularJS. هذا يعني أنه سيتعين عليك تغيير اختبارات منقلة بحيث لا تنتظر Angular بطبيعتها بعد الآن ، ولكن تحقق صراحةً من وجود العناصر على الصفحة قبل الاستعلام عنها عن حالتها. اعتمادًا على حجم التطبيق الخاص بك ، قد تكون هذه مهمة شاقة.

امل ان يساعد.

بقدر ما أفهم المشكلة ، هذا ليس خاصًا بترقية ngUpgrade ، ولكنه خاص بالزاوية. أعني ، حتى في تطبيق Angular (2+) الخالص ، فإن الحصول على setTimeout طويل (إما بشكل مباشر أو عبر مكتبة تابعة لجهة خارجية) سيؤدي إلى انقضاء مهلة المنقلة.

heathkit ، هل يمكنك تأكيد ذلك أو هل

gkalpak أنت محق في أن هذه مشكلة خاصة بزاوية ، لكن الناس يواجهونها عندما يستخدمون ngUpgrade مع تطبيق AngularJS كبير.

في AngularJS ، تنتظر المنقلة فقط المهام غير المتزامنة التي تبدأ بـ $browser.defer() - بشكل أساسي فقط $timeout و $http في كود التطبيق. بمجرد أن يبدأ شخص ما في استخدام ngUpgrade ، ستبدأ مهلة اختبارات Protractor الحالية بسبب المكالمات الطويلة setTimeout (من المحتمل أن تكون من مكتبات الطرف الثالث) حيث لم يفعلوا ذلك من قبل. في الغالب ، تكمن المشكلة في أن ngUpgrade تعمل على النحو المنشود ، والآن يخضع تطبيق AngularJS واختبارات المنقلة فجأة لدلالات Angular (2+).

إذن ، كيف يمكن للمرء أن يحل هذا لتطبيق Angular خالص؟ ماذا سيفعل المرء إذا كانت مكتبة Angular لجهة خارجية تعين setTimeout طويلًا ، مما يتسبب في انقضاء مهلة المنقلة؟

vikerman سمعت أنك ستساعد في الحصول على عضو جديد في الفريق وتشغيله قريبًا جدًا ، لذا قم بتعيينه لك حتى يكون على متنه.

ليس لدينا حقًا إجابة جيدة للحالة التي يحدد فيها تطبيق جهة خارجية مهلة طويلة. في الوقت الحالي ، كل ما يمكنك فعله هو إيقاف waitForAngular والاعتماد على ExpectedConditions ، لكن هذا ليس مثاليًا. أعمل على إضافة ميزة إلى Protractor من شأنها أن تمنح الأشخاص مزيدًا من التحكم في المهام الكبيرة التي تنتظرها اختباراتهم ، ولكن لا يزال هذا بعيدًا.

heathkitvikerman هل من تحديث لهذا واحد من فضلك؟

واجه المشروع الذي أعمل عليه هذه المشكلة من قبل لكنهم قاموا بلف وظيفة الاستقصاء المستمر للتشغيل خارج المنطقة الزاوية بحيث لا يؤثر ذلك على browser.waitForAngular () ؛

شكراً جزيلاً لفريق منقلة / المساهمين . كانت المنقلة حجر الأساس لتطبيقي لأنه يعاني من عدد قليل جدًا من مشكلات الإنتاج على مدار عشرات الإصدارات على مدار 3 سنوات ، وأكثر من 200 خدمة ، وتوجيهات ، ومكونات ، ووحدات تحكم مع حوالي 400 اختبار منقلة e2e.

هذا تذكير جيد بمدى اعتمادي على منقلة ولكن هذه المشكلة أوقفت ترقية Angular الخاصة بي في مساراتها بعد تخصيص أسبوعين لمجرد إعادة ترقية ngUpgrade والاحتياجات الإضافية. تم ذلك ولكن الآن لا يمكن تشغيل اختبارات e2e وتوقف النشر بدون مسار مرئي للأمام (حتى الآن).

بفضل المعلومات الرائعة من @ mattwilson1024 ، تأكدت من عدم استخدام $timeout ، setTimeout ، setInterval في تطبيقنا.

لكنني اكتشفت أن angular-ui-bootstrap (الإصدار 2.5.6) و ui-select (الإصدار 0.19.8) يستخدمان $timeout . أنا أستخدم كلا المكتبتين على نطاق واسع. يبدو أن الكثير من الآخرين يعتمدون عليها أيضًا - angular-ui-bootstrap - 400k npm download / mo ، ui-select 100k + / mo.

أنشأ angular-ui-bootstrap مشكلة في عام 2015 لاستبدال $ timeout بفاصل $ على وجه التحديد بسبب هذه المشكلة ولكن للأسف قرر "يجب إصلاح هذا الخطأ في المنقلة وليس هنا. إغلاق هذا." أيضًا ، لم يعد angular-ui-bootstrap يقدم تحديثات في liu من إصدار Angular @ ng-bootstrap / ng-bootstrap الذي هو في مرحلة تجريبية.

أنا مندهش عندما أرى مكتبات زاوية مستخدمة بشكل كبير لا تضمن صلاحية المنقلة. في هذا الصدد ، أتفق مع heathkit على أن تلك المكتبات بحاجة إلى إصلاح نفسها. ولكن ، آمل أن تتمكن منقلة من التدخل وتخفيف كل ذلك بضربة واحدة. حتى الحل الجميل سيكون ذهبيًا. أشعر بخيبة أمل لأنني سأضطر إلى التراجع عن ترقية ngUpgrade في الوقت الحالي حتى أكتشف كل تلك التبعيات التي $timeout ، وربما بدلاً من مجرد تضمين ngGrade والبدء في اختيار العناصر للترقية عندما يكون ذلك ممكنًا ، من المحتمل أن يكون لديك تبعية للترقية أو الترحيل من عناصر الطرف الثالث مع إضافة ngUpgrade. قرف.

أواصل البحث عن تطبيقي (متهمون محددون يتسببون في المهلة (المهلات) ، وكيفية المضي قدمًا ، وما إلى ذلك) وسأبلغ عن أي شيء قد يكون مفيدًا للآخرين.

حيث وجدت $ timeout:
الزاوي واجهة المستخدم التمهيدية v2.5.6

  • UibAlertController
  • UibCarouselController
  • UibDatepickerPopupController
  • UibTypeaheadController
  • UibTooltip

تحديد واجهة المستخدم

  • ui اختر
  • uiSelectMultiple
  • uiSelectSingle
  • uiSelectSort
  • uisOpenClose

المورد الزاوي $resource يحقن ويستخدم $timeout
مرشح الزاوية ( $window.setTimeout )

مرحبًا - نحن نعمل على تغيير للسماح لك بتهيئة المهام التي تنتظرها المنقلة ، والتي يمكن أن تساعدك في التعامل مع المشكلة المذكورة أعلاه. هذا تغيير واسع يشمل Zone.js و Angular وليس له وقت محدد للوصول (سيكون في نطاق الأسابيع). سيتم تحديث التقدم هنا.

لدي نفس المشكلة عندما أقوم بتشغيل تطبيق [email protected].
شكرًا على التعليقات أعلاه ، وخاصة @ mattwilson1024 و tonybranfort ، مما يساعدني على فهم المشكلة بشكل أفضل.

لقد وجدت عملًا في حالتي ، عن طريق إضافة browser.ignoreSynchronization = true/false; حول الرمز الذي انتهت المهلة.

على سبيل المثال ، أجرى أحد الاختبارات الخاصة بي تحديدًا بسيطًا في مجموعة من أزرار الاختيار ، وتوقع أن يتم تحديد الخيار الصحيح:

it('should be able to pick option', function () {
        expect(myPage.optionSelected()).toBe(false);
        myPage.pickOption('Option 1');
        expect(myPage.anyOptionSelected()).toBe(true);
        expect(myPage.getSelectedOption()).toBe('Option 1');
});

عندما أحاول تصحيح هذا الرمز ، وجدت أن المهلة حدثت في الخطوة الأخيرة. أفترض أن المشكلة الأساسية هي أداة من angular-ui-bootstrap ، باستخدام مهلة $: https://github.com/angular-ui/bootstrap/blob/master/src/tooltip/tooltip.js

ومع ذلك ، لا توجد مكالمات غير متزامنة في هذا الاختبار. إذن ما أفعله هو ببساطة إضافة ignoreSynchronization في البداية وإعادة تعيينه في النهاية:

it('should be able to pick a font', function () {
        browser.ignoreSynchronization = true;  // tell protractor do not waitForAngular
        expect(myPage.optionSelected()).toBe(false);
        myPage.PickOption('Option 1');
        expect(myPage.anyOptionSelected()).toBe(true);
        expect(myPage.getSelectedOption()).toBe('Option 1');
        browser.ignoreSynchronization = false;  // reset the flag
});

لا أعرف ما إذا كانت هذه هي الطريقة الموصى بها أم أنها ستجعل الاختبارات أكثر هشاشة. ولكن بالنسبة للاختبارات التي لا تتطلب أي مكالمات غير متزامنة ولكنها لا تزال تعاني من مشكلة انتهاء المهلة ، فيجب إصلاحها.

مرحبًا vikerman - أي تحديث بخصوص هذا؟ https://github.com/angular/protractor/issues/4290#issuecomment -337094393

vikerman هل هناك أي تحديث على هذا؟

هل لديك أي شخص نصيحة جيدة حول كيفية العثور على هذه المهلات طويلة المدى حتى أتمكن من إخراجها من طلبي؟

من : المنبوذ (s؟) في جزيرة AngularJS الذين تقطعت بهم السبل بسبب المنقلة العدد رقم 4290
إلى:juliemrvikerman

أهوي! هل يمكننا الحصول على تحديث حول هذه المسألة؟ آخر تحديث في 16 أكتوبر كان وقتًا مقدرًا للوصول في "ترتيب الأسابيع". أو الرجاء إغلاق هذه المشكلة حتى نتمكن من المضي قدمًا.

هذه هي الطوافات التي أفكر بها حاليًا:

  • استبدل كل زاوية ui-bootstrap / ui-select . هذا مهم بالنسبة لي. يجب القيام به على أي حال ولكن ما يقلقني هو أن شيئًا آخر سيظهر وسأظل عالقًا في AngularJS بعد هذا العمل. الدرس المستفاد: لف مكونات الطرف الثالث بمكوناتي الخاصة.
  • waitForAngularEnabled(false) لجميع الاختبارات كما اقترحهvladotesanovic. أنا متشكك في هذا لتطبيق بأكمله لكنني لم أختبره. أستخدم waitForAngularEnabled في موقف واحد فقط الآن ولحالة محددة جدًا فقط.
  • قم بترقية التطبيق بالكامل إلى Angular بدلاً من AngularJS / Angular جنبًا إلى جنب الهجرة المتزايدة: لا ، فقط ليس خيارًا مع مواردي.
  • الهجرة إلى Vue أو React بدلاً من Angular. على رأس القائمة خاصة بالنظر إلى أن كلاهما يمكن أن يتعايش مع AngularJs.
  • انتقل إلى محرك
  • أو إصلاح من # 4290 ويمكنني إلغاء تعليق هذه الأسطر القليلة اللازمة لبدء استخدام ngUpgrade :)

فريقنا بصدد ترقية تطبيقنا المعقد واختبارات المنقلة تفشل عند بدء التشغيل باستخدام NgUpgrade. اضطررنا إلى التراجع عن تغييراتنا لأننا الآن لا نستطيع التعامل مع جميع الاختبارات الفاشلة التي تعتبر نتائج إيجابية خاطئة.

أين نحن من هذه القضية؟ أشعر بالقلق من أنني سأضطر إلى الانتقال إلى إطار اختبار مختلف حتى نتمكن من الحفاظ على خططنا لترقية Angular.

tonybranfort : في نفس المركب تمامًا ... نحن نعتمد بشدة على ui-select و angular-ui-bootstrap - هذا مانع رئيسي لترقيتنا. يبدو أنك قد أخذت زمام المبادرة في هذه المشكلة ، ومع ذلك ، يرجى إطلاعنا على آخر المستجدات! 😁

نحن نواجه نفس المشكلة. هل يمكن لشخص من المنقلة أن يطلعنا على هذا من فضلك؟

نحن في منتصف الطريق نحو ترقية تطبيقنا من Angular V1 ونكره أن يكون لدينا هذا السبب هو العودة إلى V1 والتخلي عن جميع الأعمال المنجزة للترقية إلى Angular V5 حتى الآن.

بعد إجراء تصويت آخر هنا ، نحن بصدد ترقية تطبيقنا إلى Angular ونستخدم حاليًا تطبيقًا مجزأًا waitForAngularEnabled(false) لتمريرها دون تعريض المجموعة بأكملها لمخاطر أكبر. إنه غير مثالي بشكل غير عادي ، ومع ذلك ، فإن الحل الأفضل سيكون موضع تقدير كبير.

لقد واجهنا هذه المشكلة أيضًا ، خاصةً عندما يتعلق الأمر بخدمة الفاصل الزمني $. أحيانًا تنتظر المنقلة ذلك وأحيانًا لا تنتظرها - لم أجد النمط بعد.

تحرير وقت طويل: يبدو أنه يعتمد على وقت استدعاء الفاصل الزمني (في المنطقة أم لا)

مرحبًا vikerman - هل تنتظرها المنقلة؟

نفس المشكلة هنا.

vikerman هل هناك أي تحديث أو حل بديل؟

نحن نواجه نفس المشكلات. سيكون رائعا إذا كان هناك بعض التقدم في هذه المسألة.

للأسف ، لدي نفس المشكلة. هل يلوح في الأفق أي تقدم بخصوص هذا؟

نحن نضيف تتبع المهام إلى Angular و AngularJS مما يجعل من السهل تصحيح هذه المشاكل من خلال إظهار المكان الذي جاءت منه المهمة غير المتزامنة التي انقضت مهلة المنقلة عليها.

heathkit هل تم هذا بالفعل في مكان ما؟ نواجه صعوبة في تحديد تلك الأماكن في قاعدة الرموز الخاصة بنا.

كما سيكون من الجيد الحصول على بعض الوثائق التي تنتظرها المنقلة بحماس. يبدو أن هذا قد عفا عليه الزمن: https://www.protractortest.org/#/system -setup. يذكر فقط استبدال $timeout بـ $interval . لا شيء بخصوص setTimeout أو setInterval.
بعض المستندات هنا: http://www.protractortest.org/#/timeouts. ولكن لا توجد تلميحات حول كيفية اكتشافها ...

أعتقد أن هذا سيساعدك على إجراء اختبارات "الهجين الزاوي + المنقلة". ساعدني. تحقق من الرابط: https://github.com/ui-router/angular-hybrid/issues/39#issuecomment -309057814

لقد أحرزنا تقدمًا بسيطًا في فهم ما يحدث مع هذه المشكلة. يبدو أننا نمتلك نفس الشيء. يبدو أن دورة المراقبة / الخلاصة angularjs التي تمت ترقيتها تعمل بشكل مختلف قليلاً ويمكن أن تتيح بعض حلقات دورة الهضم اللانهائية. وجدنا 1 مع طرف ثالث كنا نستخدمه ، ونحقق في الطرف التالي. ولكن بشكل أساسي ، كان المراقب يتسبب في تغيير الشيء الذي تتم مشاهدته ، مما يتسبب في تشغيله ، وما إلى ذلك. لاختبار ما إذا كنت تواجه نفس المشكلة ، في Chrome ، افتح فقط أدوات التطوير ، وانتقل إلى الأداء ، وسجل بضع ثوانٍ ، و معرفة ما إذا كان لديك مكالمات NgZone يتم إجراؤها كثيرًا. إذا قمت بذلك ، فعندئذٍ في مكان ما في شفرتك لديك دورة ملخص لا نهائية. يمكن أن يساعدك البحث في المكالمات على توجيهك في اتجاه سببها

يمكنك أيضًا تعديل ملف zone.js المحلي قليلاً وإضافة سجلات وحدة التحكم حيث يتم تصحيح مهام المهلة / الفاصل الزمني لمعرفة ما يطلق عليها. طريقة سهلة للقيام بذلك:

try {
  throw new Error("track");
} catch(err) {
  console.debug(err);
}

تحرير: ممتع للغاية لتنسيق التعليمات البرمجية على الهاتف المحمول!

vikerman هل لديك أي تحديث على هذا؟ سيكون رائعًا إذا كان بإمكانك إبداء رأيك حول متى سيتم إصلاح ذلك قريبًا؟ شكرا.

يمكنك أيضًا تعديل ملف zone.js المحلي قليلاً وإضافة سجلات وحدة التحكم حيث يتم تصحيح مهام المهلة / الفاصل الزمني لمعرفة ما يطلق عليها. طريقة سهلة للقيام بذلك:

try {
  throw new Error("track");
} catch(err) {
  console.debug(err);
}

تحرير: ممتع للغاية لتنسيق التعليمات البرمجية على الهاتف المحمول!

أين ستضع هذا الرمز لتتبع المهلات / الفترات الزمنية؟

maurycyg patchTimer -> وظيفة الغرض

هذا الخيط محبط للرؤية. هل هناك أي تحديث على ذلك؟

الحل المحتمل لعدم استخدام $timeout هو تجاوزه بـ $interval (لمكتبات الطرف الثالث)
حل الكود أدناه مشكلة المهلة بالنسبة لي (تمت إضافة فحص المتصفح فقط في حالة). في حالتي ، كانت المشكلة ناتجة عن مكونات angular-bootstrap ، والتي تسمى بلا حدود مهلة $ مع 0 تأخير.

app.config(function($provide) {
    function isUnderProtractor() {
        var nav = window.navigator;
        var lowercasedUserAgent = nav.userAgent;
        return !lowercasedUserAgent || lowercasedUserAgent.contains('protractor');
    }

    if (isUnderE2ETest()) {
        $provide.decorator('$timeout', ['$interval', '$delegate', function($interval, $delegate) {
            var newTimeout = function(fn, delay, invokeApply, pass) {
                if (!delay)
                    return $interval(fn, delay, 1, invokeApply, pass);
                else
                    return $delegate(fn, delay, invokeApply, pass);
            };
            newTimeout.cancel = $delegate.cancel;
            return newTimeout;
        }]);
    }
}

بدءًا من zone.js v0.8.9 ، يمكنك اختيار وحدات واجهة برمجة تطبيقات الويب التي تريد تصحيحها لتقليل الحمل الناتج عن تصحيح هذه الوحدات.
https://github.com/angular/zone.js/blob/master/MODULE.md

أضف ملف zone-flags.ts بالمحتوى أدناه
(window as any).__Zone_disable_timers = true;

قم باستيراده في polyfills.ts قبل zone.js

import './zone-flags';
import 'zone.js/dist/zone';  // Included with Angular CLI.

يبدو أن الحل أعلاه مع تعطيل مؤقتات المنطقة يعبث مع Obserables (على سبيل المثال asyncValidators). الحل الذي نجح أخيرًا بالنسبة لي هو setTimeout الترقيع القرد.

platformBrowserDynamic().bootstrapModule(AppModule)
.then((moduleRef: NgModuleRef<AppModule>) => {
  const ngZone: NgZone = moduleRef.injector.get(NgZone);
  const originalSetTimeout = window.setTimeout;
  (window as any).setTimeout = function setTimeout(fn, ms) {
    return ngZone.runOutsideAngular(() => {
      return originalSetTimeout(() => {
        ngZone.run(fn);
      }, ms);
    });
  };
})

ربما لا تكمن المشكلة في المنقلة نفسها ، ولكن في كود التطبيق.

مع الانتقال من Angular JS الذي يستخدم دورة ملخص لتتبع التغييرات ، إلى Hybrid App مع Angular2 + witch يستخدم zone.js لاكتشاف التغييرات ، بدأت منقلة في الانخفاض مع المهلات.

تبدأ المنقلة بإجراء الاختبار التالي فقط عندما يكون التطبيق مستقرًا. الاستقرار في حالة التطبيق المختلط يعني استقرار جزء Angular JS من التطبيق وجزء Angular2 + من التطبيق. يجب أن يكون كلا الجزأين مستقرين.

يتم تعريف الاستقرار الزاوي JS من خلال $$testability.whenStable . يتم تحديد استقرار Angular 2+ من خلال window.getAngularTestability(...).whenStable . يمكنك تصحيح كود المنقلة وسترى بنفسك. للقيام بذلك أضف العبارة debugger; إلى ملف waitForAngular _ \ node_modules \ منقلة \ build \ clientsidescripts.js_ file؛
ستلاحظ أن استقرار منطقة Angular2 + لا يحدث أبدًا. لتحقيق الاستقرار ، يجب إكمال جميع المهام الدقيقة والمهام الكبيرة .

الآن نحن نفهم القضية. يكون الجزء الزاوي 2+ من التطبيق دائمًا غير مستقر ، وبالتالي تنتظر المنقلة إلى أجل غير مسمى حتى تصبح مستقرة وتنخفض مع انقضاء المهلات. لا ينبغي أن يتغير استقرار Angular JS في حالة التطبيق المختلط ولا يؤثر على مهلات المنقلة. من هذا المنطلق يمكننا أن نستنتج أنه من الضروري إصلاح عدم استقرار منطقة Angular2 + ومن ثم ستبدأ المنقلة في العمل كما هو متوقع.

أول محاولة لإصلاح:
نظرًا لضيق الوقت وأردت إصلاح كل شيء دفعة واحدة ، فقد كتبت رمزًا يأخذ جدول المهام خارج منطقة Angular2 +.

    $provide.decorator("$animateCss", ["$delegate", createDecorator]);
    $provide.decorator("$http", ["$delegate", createDecorator]);
    $provide.decorator("$timeout", ["$delegate", createDecorator]);
    $provide.decorator("$interval", ["$delegate", createDecorator]);
    $provide.decorator("$q", ["$delegate", createDecorator]);
    $provide.decorator("$xhrFactory", ["$delegate", createDecorator]);
    $provide.decorator("$templateRequest", ["$delegate", createDecorator]);
    $provide.decorator("$httpBackend", ["$delegate", createDecorator]);

    $provide.decorator("$animate", ["$delegate", createDecorator]);
    $provide.decorator("$rootScope", ["$delegate", createDecorator]);
    $provide.decorator("$templateCache", ["$delegate", createDecorator]);
    $provide.decorator("$browser", ["$delegate", createDecorator]);

    function runInRootZone(fn, ...args) {
        if (window.Zone.current.parent) {
            return window.Zone.current.parent.run(() => runInRootZone(fn, ...args));
        }

        return fn(...args);
    }

    function decorate(decorator, $delegate) {

        const keys = Object.keys($delegate);
        for (let i = 0; i < keys.length; i++) {

            const key = keys[i];
            if (angular.isFunction($delegate[key])) {
                decorator[key] = createDecoratorForFunctionLikeService($delegate[key]);
            } else {
                if (decorator[key] !== $delegate[key]) {
                    decorator[key] = $delegate[key];
                }
            }
        }
    }

    function createDecoratorForFunctionLikeService($delegate) {

        function decorator(...args) {
            return runInRootZone($delegate, ...args);
        }

        decorate(decorator, $delegate);

        return decorator;
    }

    function createDecoratorForService($delegate) {

        decorate($delegate, $delegate);

        return $delegate;
    }

    function createDecorator($delegate) {
        if (angular.isFunction($delegate)) {
            return createDecoratorForFunctionLikeService($delegate);
        }
        return createDecoratorForService($delegate);
    }

على الرغم من أن هذا النهج قد أثبت أنه عملي ، كما أظهر الوقت ، فإن هذا النهج له عيوبه الخاصة. السبب الرئيسي هو أنه من المستحيل تحديد المنطقة التي ستكون (الجذر أو الزاوية) لجزء معين من التطبيق المختلط. للتشغيل العادي ، يتطلب Angular2 + أن يكون دائمًا في المنطقة الزاويّة ، ويمكن أن يتسبب المصممون في تواجد مكونات Angular2 + في منطقة الجذر. تشير ngUpgrade إلى أن المنطقة الزاويّة تغطي معظم التطبيقات.

لتجنب ذلك ، كانت هناك محاولة إصلاح ثانية مع تحليل أعمق للأسباب ، والتخلي عن الديكور والعودة إلى الإصدار الأصلي.

الآن نحن بحاجة إلى فهم الرمز الذي يجعل المنطقة غير مستقرة. لهذا الغرض ، يحتوي zone.js على أدوات مساعدة خاصة ، مثل _TaskTrackingZoneSpec_ (_ \ node_modules \ zone.js \ dist \ task-tracking.js_) ، مما يسمح بتتبع المهام الموجودة في المنطقة ومكان إنشائها ( creationLocation ). أيضًا ، في بداية الجزء Angular2 + من التطبيق ، احفظ Angular zone (window as any).a9Zone = (upgradeModule as any).ngZone._inner; وأضف هذا الرمز في مكان ما

$rootScope.$watch(function () {
    if (window.a9Zone) {
        console.log("Angular2+ task count:", window.a9Zone._zoneDelegate._taskCounts);

        // Optional.
        window.getAllAngularTestabilities().forEach(_ => {
            _.taskTrackingZone.macroTasks.forEach(t => {
                console.log(t, t.creationLocation);
            });
        });
    }
});

وبالتالي ، ابحث عن الأماكن في التطبيق حيث تكون المهام الدقيقة والمهام الكبيرة في المنطقة لفترة طويلة (_microTasks.lenght! == 0 && macroTasks.lenght! == 0_).

فأنت بحاجة إلى إخراج هذا الرمز من المنطقة الزاويّة. للقيام بذلك ، لف الكود في ngZone.runOutsideAngular . ومع ذلك ، قم بذلك بحذر شديد وتأكد من عدم ظهور منطقة الجذر في المكان الذي لا تحتاج إليه.

بعد استقرار المنطقة الزاوية ، لن تسقط المنقلة مع انقضاء المهلة .

أتمنى أن يساعدك هذا.

توصلت إلى اختراق مؤقت لحل هذه المشكلة عن طريق تجاوز وظيفة waitForAngular بالمنطق أدناه.

onPrepare: function() {

            var script = "var callback = arguments[arguments.length - 1];" +
                "angular.element(document.querySelector(\"body\")).injector()"+
                ".get(\"$browser\").notifyWhenNoOutstandingRequests(callback)");

            browser.waitForAngular = function() {
                return browser.executeAsyncScript(script)
            };
}
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات