browser_documentation.html 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  4. <title>Documentation SimpleTest : le composant de navigation web scriptable</title>
  5. <link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
  6. </head>
  7. <body>
  8. <div class="menu_back"><div class="menu">
  9. <a href="index.html">SimpleTest</a>
  10. |
  11. <a href="overview.html">Overview</a>
  12. |
  13. <a href="unit_test_documentation.html">Unit tester</a>
  14. |
  15. <a href="group_test_documentation.html">Group tests</a>
  16. |
  17. <a href="mock_objects_documentation.html">Mock objects</a>
  18. |
  19. <a href="partial_mocks_documentation.html">Partial mocks</a>
  20. |
  21. <a href="reporter_documentation.html">Reporting</a>
  22. |
  23. <a href="expectation_documentation.html">Expectations</a>
  24. |
  25. <a href="web_tester_documentation.html">Web tester</a>
  26. |
  27. <a href="form_testing_documentation.html">Testing forms</a>
  28. |
  29. <a href="authentication_documentation.html">Authentication</a>
  30. |
  31. <a href="browser_documentation.html">Scriptable browser</a>
  32. </div></div>
  33. <h1>Documentation sur le navigateur scriptable</h1>
  34. This page...
  35. <ul>
  36. <li>
  37. Utiliser le <a href="#scripting">navigateur web dans des scripts</a>
  38. </li>
  39. <li>
  40. <a href="#deboguer">Déboguer</a> les erreurs sur les pages
  41. </li>
  42. <li>
  43. <a href="#unit">Tests complexes avec des navigateurs web multiples</a>
  44. </li>
  45. </ul>
  46. <div class="content">
  47. <p>
  48. Le composant de navigation web de SimpleTest peut être utilisé
  49. non seulement à l'extérieur de la classe <span class="new_code">WebTestCase</span>,
  50. mais aussi indépendamment du framework SimpleTest lui-même.
  51. </p>
  52. <h2>
  53. <a class="target" name="script"></a>Le navigateur scriptable</h2>
  54. <p>
  55. Vous pouvez utiliser le navigateur web dans des scripts PHP
  56. pour confirmer que des services marchent bien comme il faut
  57. ou pour extraire des informations à partir de ceux-ci de façon régulière.
  58. Par exemple, voici un petit script pour extraire
  59. le nombre de bogues ouverts dans PHP 5 à partir
  60. du <a href="http://www.php.net/">site web PHP</a>...
  61. <pre>
  62. &lt;?php
  63. require_once('simpletest/browser.php');
  64. $browser = &amp;new SimpleBrowser();
  65. $browser-&gt;get('http://php.net/');
  66. $browser-&gt;clickLink('reporting bugs');
  67. $browser-&gt;clickLink('statistics');
  68. $browser-&gt;clickLink('PHP 5 bugs only');
  69. $page = $browser-&gt;getContent();
  70. preg_match('/status=Open.*?by=Any.*?(\d+)&lt;\/a&gt;/', $page, $matches);
  71. print $matches[1];
  72. ?&gt;
  73. </pre>
  74. Bien sûr Il y a des méthodes plus simple pour réaliser
  75. cet exemple en PHP. Par exemple, vous pourriez juste
  76. utiliser la commande PHP <span class="new_code">file()</span> sur ce qui est
  77. ici une page fixe. Cependant, en utilisant des scripts
  78. avec le navigateur web vous vous autorisez l'authentification,
  79. la gestion des cookies, le chargement automatique des fenêtres,
  80. les redirections, la transmission de formulaires et la capacité
  81. d'examiner les entêtes.
  82. </p>
  83. <p>
  84. Ces méthodes qui se basent sur le contenu textuel des pages
  85. sont fragiles dans un site en constante évolution
  86. et vous voudrez employer une méthode plus directe
  87. pour accéder aux données de façon permanente,
  88. mais pour des tâches simples cette technique peut s'avérer
  89. une solution très rapide.
  90. </p>
  91. <p>
  92. Toutes les méthode de navigation utilisées dans <a href="web_tester_documentation.html">WebTestCase</a> sont présente dans la classe <span class="new_code">SimpleBrowser</span>, mais les assertions sont remplacées par de simples accesseurs. Voici une liste complète des méthodes de navigation de page à page...
  93. <table><tbody>
  94. <tr>
  95. <td><span class="new_code">addHeader($header)</span></td>
  96. <td>Ajouter une entête à chaque téléchargement</td>
  97. </tr>
  98. <tr>
  99. <td><span class="new_code">useProxy($proxy, $username, $password)</span></td>
  100. <td>Utilise ce proxy à partir de maintenant</td>
  101. </tr>
  102. <tr>
  103. <td><span class="new_code">head($url, $parameters)</span></td>
  104. <td>Effectue une requête HEAD</td>
  105. </tr>
  106. <tr>
  107. <td><span class="new_code">get($url, $parameters)</span></td>
  108. <td>Télécharge une page avec un GET</td>
  109. </tr>
  110. <tr>
  111. <td><span class="new_code">post($url, $parameters)</span></td>
  112. <td>Télécharge une page avec un POST</td>
  113. </tr>
  114. <tr>
  115. <td><span class="new_code">click($label)</span></td>
  116. <td>Suit un lien visible ou un bouton texte par son étiquette</td>
  117. </tr>
  118. <tr>
  119. <td><span class="new_code">clickLink($label)</span></td>
  120. <td>Suit un lien par son étiquette</td>
  121. </tr>
  122. <tr>
  123. <td><span class="new_code">isLink($label)</span></td>
  124. <td>Vérifie l'existance d'un lien par son étiquette</td>
  125. </tr>
  126. <tr>
  127. <td><span class="new_code">clickLinkById($id)</span></td>
  128. <td>Suit un lien par son attribut d'identification</td>
  129. </tr>
  130. <tr>
  131. <td><span class="new_code">isLinkById($id)</span></td>
  132. <td>Vérifie l'existance d'un lien par son attribut d'identification</td>
  133. </tr>
  134. <tr>
  135. <td><span class="new_code">getUrl()</span></td>
  136. <td>La page ou la fenêtre URL en cours</td>
  137. </tr>
  138. <tr>
  139. <td><span class="new_code">getTitle()</span></td>
  140. <td>Le titre de la page</td>
  141. </tr>
  142. <tr>
  143. <td><span class="new_code">getContent()</span></td>
  144. <td>Le page ou la fenêtre brute</td>
  145. </tr>
  146. <tr>
  147. <td><span class="new_code">getContentAsText()</span></td>
  148. <td>Sans code HTML à l'exception du text "alt"</td>
  149. </tr>
  150. <tr>
  151. <td><span class="new_code">retry()</span></td>
  152. <td>Répète la dernière requête</td>
  153. </tr>
  154. <tr>
  155. <td><span class="new_code">back()</span></td>
  156. <td>Utilise le bouton "précédent" du navigateur</td>
  157. </tr>
  158. <tr>
  159. <td><span class="new_code">forward()</span></td>
  160. <td>Utilise le bouton "suivant" du navigateur</td>
  161. </tr>
  162. <tr>
  163. <td><span class="new_code">authenticate($username, $password)</span></td>
  164. <td>Retente la page ou la fenêtre après une réponse 401</td>
  165. </tr>
  166. <tr>
  167. <td><span class="new_code">restart($date)</span></td>
  168. <td>Relance le navigateur pour une nouvelle session</td>
  169. </tr>
  170. <tr>
  171. <td><span class="new_code">ageCookies($interval)</span></td>
  172. <td>Change la date des cookies</td>
  173. </tr>
  174. <tr>
  175. <td><span class="new_code">setCookie($name, $value)</span></td>
  176. <td>Lance un nouveau cookie</td>
  177. </tr>
  178. <tr>
  179. <td><span class="new_code">getCookieValue($host, $path, $name)</span></td>
  180. <td>Lit le cookie le plus spécifique</td>
  181. </tr>
  182. <tr>
  183. <td><span class="new_code">getCurrentCookieValue($name)</span></td>
  184. <td>Lit le contenue du cookie en cours</td>
  185. </tr>
  186. </tbody></table>
  187. Les méthode <span class="new_code">SimpleBrowser::useProxy()</span> et
  188. <span class="new_code">SimpleBrowser::addHeader()</span> sont spéciales.
  189. Une fois appelées, elles continuent à s'appliquer sur les téléchargements suivants.
  190. </p>
  191. <p>
  192. Naviguer dans les formulaires est similaire à la <a href="form_testing_documentation.html">navigation des formulaires via WebTestCase</a>...
  193. <table><tbody>
  194. <tr>
  195. <td><span class="new_code">setField($label, $value)</span></td>
  196. <td>Modifie tous les champs avec cette étiquette ou ce nom</td>
  197. </tr>
  198. <tr>
  199. <td><span class="new_code">setFieldByName($name, $value)</span></td>
  200. <td>Modifie tous les champs avec ce nom</td>
  201. </tr>
  202. <tr>
  203. <td><span class="new_code">setFieldById($id, $value)</span></td>
  204. <td>Modifie tous les champs avec cet identifiant</td>
  205. </tr>
  206. <tr>
  207. <td><span class="new_code">getField($label)</span></td>
  208. <td>Accesseur de la valeur d'un élément de formulaire avec cette étiquette ou ce nom</td>
  209. </tr>
  210. <tr>
  211. <td><span class="new_code">getFieldByName($name)</span></td>
  212. <td>Accesseur de la valeur d'un élément de formulaire avec ce nom</td>
  213. </tr>
  214. <tr>
  215. <td><span class="new_code">getFieldById($id)</span></td>
  216. <td>Accesseur de la valeur de l'élément de formulaire avec cet identifiant</td>
  217. </tr>
  218. <tr>
  219. <td><span class="new_code">clickSubmit($label)</span></td>
  220. <td>Transmet le formulaire avec l'étiquette de son bouton</td>
  221. </tr>
  222. <tr>
  223. <td><span class="new_code">clickSubmitByName($name)</span></td>
  224. <td>Transmet le formulaire avec l'attribut de son bouton</td>
  225. </tr>
  226. <tr>
  227. <td><span class="new_code">clickSubmitById($id)</span></td>
  228. <td>Transmet le formulaire avec l'identifiant de son bouton</td>
  229. </tr>
  230. <tr>
  231. <td><span class="new_code">clickImage($label, $x, $y)</span></td>
  232. <td>Clique sur une balise input de type image par son titre (title="*") our son texte alternatif (alt="*")</td>
  233. </tr>
  234. <tr>
  235. <td><span class="new_code">clickImageByName($name, $x, $y)</span></td>
  236. <td>Clique sur une balise input de type image par son attribut (name="*")</td>
  237. </tr>
  238. <tr>
  239. <td><span class="new_code">clickImageById($id, $x, $y)</span></td>
  240. <td>Clique sur une balise input de type image par son identifiant (id="*")</td>
  241. </tr>
  242. <tr>
  243. <td><span class="new_code">submitFormById($id)</span></td>
  244. <td>Transmet le formulaire par son identifiant propre</td>
  245. </tr>
  246. </tbody></table>
  247. Au jourd d'aujourd'hui il n'existe pas beaucoup de méthodes pour lister
  248. les formulaires et les champs disponibles.
  249. <table><tbody>
  250. <tr>
  251. <td><span class="new_code">isClickable($label)</span></td>
  252. <td>Vérifie si un lien existe avec cette étiquette ou ce nom</td>
  253. </tr>
  254. <tr>
  255. <td><span class="new_code">isSubmit($label)</span></td>
  256. <td>Vérifie si un bouton existe avec cette étiquette ou ce nom</td>
  257. </tr>
  258. <tr>
  259. <td><span class="new_code">isImage($label)</span></td>
  260. <td>Vérifie si un bouton image existe avec cette étiquette ou ce nom</td>
  261. </tr>
  262. <tr>
  263. <td><span class="new_code">getLink($label)</span></td>
  264. <td>Trouve une URL à partir de son label</td>
  265. </tr>
  266. <tr>
  267. <td><span class="new_code">getLinkById($label)</span></td>
  268. <td>Trouve une URL à partir de son identifiant</td>
  269. </tr>
  270. <tr>
  271. <td><span class="new_code">getUrls()</span></td>
  272. <td>Liste l'ensemble des liens de la page courante</td>
  273. </tr>
  274. </tbody></table>
  275. Ce sera probablement
  276. ajouté dans des versions successives de SimpleTest.
  277. </p>
  278. <p>
  279. A l'intérieur d'une page, les fenêtres individuelles peuvent être
  280. sélectionnées. Si aucune sélection n'est réalisée alors
  281. toutes les fenêtres sont fusionnées ensemble dans
  282. une unique et grande page.
  283. Le contenu de la page en cours sera une concaténation des
  284. toutes les fenêtres dans l'ordre spécifié par les balises "frameset".
  285. <table><tbody>
  286. <tr>
  287. <td><span class="new_code">getFrames()</span></td>
  288. <td>Un déchargement de la structure de la fenêtre courante</td>
  289. </tr>
  290. <tr>
  291. <td><span class="new_code">getFrameFocus()</span></td>
  292. <td>L'index ou l'étiquette de la fenêtre en courante</td>
  293. </tr>
  294. <tr>
  295. <td><span class="new_code">setFrameFocusByIndex($choice)</span></td>
  296. <td>Sélectionne la fenêtre numérotée à partir de 1</td>
  297. </tr>
  298. <tr>
  299. <td><span class="new_code">setFrameFocus($name)</span></td>
  300. <td>Sélectionne une fenêtre par son étiquette</td>
  301. </tr>
  302. <tr>
  303. <td><span class="new_code">clearFrameFocus()</span></td>
  304. <td>Traite toutes les fenêtres comme une seule page</td>
  305. </tr>
  306. </tbody></table>
  307. Lorsqu'on est focalisé sur une fenêtre unique,
  308. le contenu viendra de celle-ci uniquement.
  309. Cela comprend les liens à cliquer et les formulaires à transmettre.
  310. </p>
  311. <h2>
  312. <a class="target" name="deboguer"></a>Où sont les erreurs ?</h2>
  313. <p>
  314. Toute cette masse de fonctionnalités est géniale
  315. lorsqu'on arrive à bien télécharger les pages,
  316. mais ce n'est pas toujours évident.
  317. Pour aider à découvrir les erreurs, le navigateur a aussi
  318. des méthodes pour aider au débogage.
  319. <table><tbody>
  320. <tr>
  321. <td><span class="new_code">setConnectionTimeout($timeout)</span></td>
  322. <td>Ferme la socket avec un délai trop long</td>
  323. </tr>
  324. <tr>
  325. <td><span class="new_code">getUrl()</span></td>
  326. <td>L'URL de la page chargée le plus récemment</td>
  327. </tr>
  328. <tr>
  329. <td><span class="new_code">getRequest()</span></td>
  330. <td>L'entête de la requête brute de la page ou de la fenêtre</td>
  331. </tr>
  332. <tr>
  333. <td><span class="new_code">getHeaders()</span></td>
  334. <td>L'entête de réponse de la page ou de la fenêtre</td>
  335. </tr>
  336. <tr>
  337. <td><span class="new_code">getTransportError()</span></td>
  338. <td>N'importe quel erreur au niveau de la socket dans le dernier téléchargement</td>
  339. </tr>
  340. <tr>
  341. <td><span class="new_code">getResponseCode()</span></td>
  342. <td>La réponse HTTP de la page ou de la fenêtre</td>
  343. </tr>
  344. <tr>
  345. <td><span class="new_code">getMimeType()</span></td>
  346. <td>Le type Mime de la page our de la fenêtre</td>
  347. </tr>
  348. <tr>
  349. <td><span class="new_code">getAuthentication()</span></td>
  350. <td>Le type d'authentification dans l'entête d'une provocation 401</td>
  351. </tr>
  352. <tr>
  353. <td><span class="new_code">getRealm()</span></td>
  354. <td>Le realm d'authentification dans l'entête d'une provocation 401</td>
  355. </tr>
  356. <tr>
  357. <td><span class="new_code">getBaseUrl()</span></td>
  358. <td>Uniquement la base de l'URL de la page chargée le plus récemment</td>
  359. </tr>
  360. <tr>
  361. <td><span class="new_code">setMaximumRedirects($max)</span></td>
  362. <td>Nombre de redirections avant que la page ne soit chargée automatiquement</td>
  363. </tr>
  364. <tr>
  365. <td><span class="new_code">setMaximumNestedFrames($max)</span></td>
  366. <td>Protection contre des framesets récursifs</td>
  367. </tr>
  368. <tr>
  369. <td><span class="new_code">ignoreFrames()</span></td>
  370. <td>Neutralise le support des fenêtres</td>
  371. </tr>
  372. <tr>
  373. <td><span class="new_code">useFrames()</span></td>
  374. <td>Autorise le support des fenêtres</td>
  375. </tr>
  376. </tbody></table>
  377. Les méthodes <span class="new_code">SimpleBrowser::setConnectionTimeout()</span>,
  378. <span class="new_code">SimpleBrowser::setMaximumRedirects()</span>,
  379. <span class="new_code">SimpleBrowser::setMaximumNestedFrames()</span>,
  380. <span class="new_code">SimpleBrowser::ignoreFrames()</span>
  381. et <span class="new_code">SimpleBrowser::useFrames()</span> continuent à s'appliquer
  382. sur toutes les requêtes suivantes.
  383. Les autres méthodes tiennent compte des fenêtres.
  384. Cela veut dire que si une fenêtre individuelle ne se charge pas,
  385. il suffit de se diriger vers elle avec
  386. <span class="new_code">SimpleBrowser::setFrameFocus()</span> : ensuite on utilisera
  387. <span class="new_code">SimpleBrowser::getRequest()</span>, etc. pour voir ce qui se passe.
  388. </p>
  389. <h2>
  390. <a class="target" name="unit"></a>Tests unitaires complexes avec des navigateurs multiples</h2>
  391. <p>
  392. Tout ce qui peut être fait dans
  393. <a href="web_tester_documentation.html">WebTestCase</a> peut maintenant
  394. être fait dans un <a href="unit_tester_documentation.html">UnitTestCase</a>.
  395. Ce qui revient à dire que nous pouvons librement mélanger
  396. des tests sur des objets de domaine avec l'interface web...
  397. <pre><strong>
  398. class TestOfRegistration extends UnitTestCase {
  399. function testNewUserAddedToAuthenticator() {</strong>
  400. $browser = new SimpleBrowser();
  401. $browser-&gt;get('http://my-site.com/register.php');
  402. $browser-&gt;setField('email', 'me@here');
  403. $browser-&gt;setField('password', 'Secret');
  404. $browser-&gt;clickSubmit('Register');
  405. <strong>
  406. $authenticator = new Authenticator();
  407. $member = $authenticator-&gt;findByEmail('me@here');
  408. $this-&gt;assertEqual($member-&gt;getPassword(), 'Secret');</strong>
  409. }
  410. }
  411. </pre>
  412. Bien que ça puisse être utile par convenance temporaire,
  413. je ne suis pas fan de ce genre de test. Ce test s'applique
  414. à plusieurs couches de l'application, ça implique qu'il est
  415. plus que probable qu'il faudra le remanier lorsque le code changera.
  416. </p>
  417. <p>
  418. Un cas plus utile d'utilisation directe du navigateur est
  419. le moment où le <span class="new_code">WebTestCase</span> ne peut plus suivre.
  420. Un exemple ? Quand deux navigateurs doivent être utilisés en même temps.
  421. </p>
  422. <p>
  423. Par exemple, supposons que nous voulions interdire
  424. des usages simultanés d'un site avec le même login d'identification.
  425. Ce scénario de test le vérifie...
  426. <pre>
  427. class TestOfSecurity extends UnitTestCase {
  428. function testNoMultipleLoginsFromSameUser() {
  429. $first = &amp;new SimpleBrowser();
  430. $first-&gt;get('http://my-site.com/login.php');
  431. $first-&gt;setField('name', 'Me');
  432. $first-&gt;setField('password', 'Secret');
  433. $first-&gt;clickSubmit('Enter');
  434. $this-&gt;assertEqual($first-&gt;getTitle(), 'Welcome');
  435. $second = &amp;new SimpleBrowser();
  436. $second-&gt;get('http://my-site.com/login.php');
  437. $second-&gt;setField('name', 'Me');
  438. $second-&gt;setField('password', 'Secret');
  439. $second-&gt;clickSubmit('Enter');
  440. $this-&gt;assertEqual($second-&gt;getTitle(), 'Access Denied');
  441. }
  442. }
  443. </pre>
  444. Vous pouvez aussi utiliser la classe <span class="new_code">SimpleBrowser</span>
  445. quand vous souhaitez écrire des scénarios de test en utilisant
  446. un autre outil que SimpleTest, comme PHPUnit par exemple.
  447. </p>
  448. </div>
  449. References and related information...
  450. <ul>
  451. <li>
  452. La page du projet SimpleTest sur
  453. <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
  454. </li>
  455. <li>
  456. La page de téléchargement de SimpleTest sur
  457. <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
  458. </li>
  459. <li>
  460. <a href="http://simpletest.org/api/">L'API de développeur pour SimpleTest</a>
  461. donne tous les détails sur les classes et les assertions disponibles.
  462. </li>
  463. </ul>
  464. <div class="menu_back"><div class="menu">
  465. <a href="index.html">SimpleTest</a>
  466. |
  467. <a href="overview.html">Overview</a>
  468. |
  469. <a href="unit_test_documentation.html">Unit tester</a>
  470. |
  471. <a href="group_test_documentation.html">Group tests</a>
  472. |
  473. <a href="mock_objects_documentation.html">Mock objects</a>
  474. |
  475. <a href="partial_mocks_documentation.html">Partial mocks</a>
  476. |
  477. <a href="reporter_documentation.html">Reporting</a>
  478. |
  479. <a href="expectation_documentation.html">Expectations</a>
  480. |
  481. <a href="web_tester_documentation.html">Web tester</a>
  482. |
  483. <a href="form_testing_documentation.html">Testing forms</a>
  484. |
  485. <a href="authentication_documentation.html">Authentication</a>
  486. |
  487. <a href="browser_documentation.html">Scriptable browser</a>
  488. </div></div>
  489. <div class="copyright">
  490. Copyright<br>Marcus Baker 2006
  491. </div>
  492. </body>
  493. </html>