2015-09-01 2 views
0

Я пытаюсь создать функцию, которую я могу вызвать из любого теста, который будет смотреть на передаваемый элемент (текст ссылки, Css Selector, Xpath, ID), щелкнуть по элементу и затем проверить URL-адрес, который появляется после его загрузки. Проблема, с которой я сталкиваюсь, заключается в том, что она возвращается до завершения функции.Как дождаться завершения функции перед возвратом?

Я знаю, что мне нужно реализовать async и обратный вызов, но мне сложно понять структуру.

clickIDverifyURL: function clickByID (elementVar, elementURL){ 
     var rem = this.remote; 

     // if statements to look at elementVar and select the right one.. example: 
     // rem.setFindByTimeout(10000) 
     // .findByXpath (elementVar) 
     // .click() 
     // .end() 

     return this.remote 
      // if I code it right, I shouldn't need this sleep right? 
      .sleep(30000) 
      .getCurrentUrl() 
      .then(function(currURL) { 
       console.log(currURL); 
       try { 
        assert.strictEqual(currURL, elementURL, "This test checks to see if the current URL is correct.") 
       } 
       catch (e) 
       { 
        console.log(e) 
       } 
      }); 

    } 

Цените любую помощь или комментарии.

ответ

0

Вы на правильном пути. Предполагая, что вы хотите, чтобы нажать на элемент, ждать перехода страницы, а затем проверить полученный URL, вы могли бы сделать что-то вроде:

clickIDverifyURL: function (elementURL) { 
    return function (element) { 
     return this.parent 
      .then(function() { 
       return element.click(); 
      }) 

      // Wait for the page transition. This can be a sleep, or you can search for an 
      // element that should be on the new page (intern will implicitly wait for it 
      // to appear), or use pollUntil to wait for a more specific condition. 
      .sleep(1000) 

      // Get the page URL 
      .getCurrentUrl() 
      .then(function (url) { 
       assert.strictEqual(url, elementURL); 
      }); 
    } 
} 

Вы бы использовать его как:

.findElementByCssSelector('.someselector') 
.then(myModule.clickIDverifyURL('expectedURL')) 

clickIDVerifyURL принимает в некоторых данные конфигурации (ожидаемый URL) и возвращает функцию, которая может быть вызвана в обратном вызове then команды. Такие функции имеют свойство parent в их контексте, которое ссылается на родительскую цепочку команд (цепочка функций начинается с this.remote).

Обратите внимание, что методы, называемые Элементами, например element.click(), возвращают обещания, а не команды. Это означает, что могут использоваться только стандартные методы Promise, а не командные методы, такие как click, findElementByX и т. Д. Поэтому код выше начинается внутренней цепочкой от this.parent, а не element.

Update

Та же самая базовая структура работает для других типов вспомогательного метода. Например, если вы хотите использовать вспомогательный метод, чтобы сделать находку, это может выглядеть следующим образом:

findBySomething: function (selector) { 
    return function() { 
     var setContext = arguments[arguments.length - 1]; 
     return this.parent 
      .findByCssSelector(selector) 
      .then(function (element) { 
       setContext(element); 
      }); 
    } 
} 

Тогда вы могли бы сделать

this.remote 
    .then(myModule.findBySomething('.selector')) 
    .then(myModule.clickIDverifyURL('expected URL')) 
+0

Благодаря jason0x43. У меня есть лучшее представление о том, как его структурировать сейчас. Было бы целесообразно создать отдельный метод для типа элемента? Я хочу иметь возможность использовать регулярное выражение для разбивки первых символов, чтобы разработчики могли просто передать нам несколько различных элементов (либо селектор css, xpath, либо div id). Будет ли идти: 'myModule.findElement ('someselector ') .then (myModule.clickIDverifyURL (' expectedURL'))' если да, то, что должно быть findElement возвращение для поддержания цепи? – whatthestack

+0

Для этого вы можете сделать что-то вроде ... um, комментарий для этого не подходит. Я обновлю ответ ... – jason0x43

Смежные вопросы