Home | History | Annotate | Download | only in photo
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 'use strict';
      6 
      7 /**
      8  * Test API for Chrome OS Image Editor.
      9  *
     10  * There are two ways to load Image Editor before testing:
     11  *   - open File Manager, and then click on an image file to open Image Editor;
     12  *   or
     13  *   - open tab with URL:
     14  *     chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/gallery.html
     15  *     and then call |galleryTestAPI.load('/Downloads/path/to/file.jpg')|.
     16  *
     17  *  After Image Editor is loaded, you can call methods from |galleryTestAPI| to
     18  *  emulate user actions and get feedback.
     19  */
     20 var galleryTestAPI = {
     21   /**
     22    * Open the Photo Editor.
     23    * @param {string} path Path to the directory or an image file.
     24    */
     25   load: function(path) {
     26     Gallery.openStandalone(path, null, function() {
     27       galleryTestAPI.waitFor_('loaded');
     28     });
     29   },
     30 
     31   /**
     32    * Responds with the selected file name.
     33    */
     34   getSelectedFileName: function() {
     35     galleryTestAPI.respond_(document.querySelector('.namebox').value);
     36   },
     37 
     38   /**
     39    * Toggles edit mode.
     40    */
     41   clickEditToggle: function() {
     42     galleryTestAPI.click('.edit');
     43     setTimeout(galleryTestAPI.respond_.bind(null, true), 0);
     44   },
     45 
     46   /**
     47    * Clicks arrow to select next image.
     48    */
     49   clickNextImageArrow: function() {
     50     galleryTestAPI.click('.arrow.right');
     51     galleryTestAPI.waitFor_('image-displayed');
     52   },
     53 
     54   /**
     55    * Clicks arrow to select previous image.
     56    */
     57   clickPreviousImageArrow: function() {
     58     galleryTestAPI.click('.arrow.left');
     59     galleryTestAPI.waitFor_('image-displayed');
     60   },
     61 
     62   /**
     63    * Clicks last thumbnail in ribbon to select an image.
     64    */
     65   clickLastRibbonThumbnail: function() {
     66     galleryTestAPI.clickRibbonThumbnail(true);
     67   },
     68 
     69   /**
     70    * Clicks first thumbnail in ribbon to select an image.
     71    */
     72   clickFirstRibbonThumbnail: function() {
     73     galleryTestAPI.clickRibbonThumbnail(false);
     74   },
     75 
     76   /**
     77    * Clicks thumbnail in ribbon.
     78    * @param {boolean} last Whether to click on last vs first.
     79    */
     80   clickRibbonThumbnail: function(last) {
     81     // TODO(dgozman): investigate why this timeout is required sometimes.
     82     setTimeout(function() {
     83       var nodes = document.querySelectorAll('.ribbon > :not([vanishing])');
     84       if (nodes.length == 0) {
     85         galleryTestAPI.respond_(false);
     86         return;
     87       }
     88       nodes[last ? nodes.length - 1 : 0].click();
     89       galleryTestAPI.waitFor_('image-displayed');
     90     }, 0);
     91   },
     92 
     93   /**
     94    * Clicks 'rotate left' tool.
     95    */
     96   clickRotateLeft: function() {
     97     galleryTestAPI.editAndRespond_(
     98         galleryTestAPI.click.bind(null, '.rotate_left'));
     99   },
    100 
    101   /**
    102    * Clicks 'rotate right' tool.
    103    */
    104   clickRotateRight: function() {
    105     galleryTestAPI.editAndRespond_(
    106         galleryTestAPI.click.bind(null, '.rotate_right'));
    107   },
    108 
    109   /**
    110    * Clicks 'undo' tool.
    111    */
    112   clickUndo: function() {
    113     galleryTestAPI.editAndRespond_(galleryTestAPI.click.bind(null, '.undo'));
    114   },
    115 
    116   /**
    117    * Clicks 'redo' tool.
    118    */
    119   clickRedo: function() {
    120     galleryTestAPI.editAndRespond_(galleryTestAPI.click.bind(null, '.redo'));
    121   },
    122 
    123   /**
    124    * Clicks 'autofix' tool.
    125    */
    126   clickAutofix: function() {
    127     galleryTestAPI.editAndRespond_(galleryTestAPI.click.bind(null, '.autofix'));
    128   },
    129 
    130   /**
    131    * Responds whether autofix tool is available.
    132    */
    133   isAutofixAvailable: function() {
    134     galleryTestAPI.respond_(
    135         !document.querySelector('.autofix').hasAttribute('disabled'));
    136   },
    137 
    138   /**
    139    * Performs a click on the element with specififc selector.
    140    * @param {string} selector CSS selector.
    141    */
    142   click: function(selector) {
    143     document.querySelector(selector).click();
    144   },
    145 
    146   /**
    147    * Waits until editor is ready, performs action and then responds.
    148    * @param {function} action The action to perform.
    149    * @private
    150    */
    151   editAndRespond_: function(action) {
    152     // TODO(dgozman): investigate why this is required sometimes.
    153     setTimeout(function() {
    154       action();
    155       galleryTestAPI.waitFor_('image-saved');
    156     }, 0);
    157   },
    158 
    159   /**
    160    * Waits for event fired and then calls a function.
    161    * @param {string} event Event name.
    162    * @param {function=} opt_callback Callback. If not passed,
    163    *     |galleryTestAPI.respond_(true)| is called.
    164    * @private
    165    */
    166   waitFor_: function(event, opt_callback) {
    167     var callback = opt_callback || galleryTestAPI.respond_.bind(null, true);
    168     var listener = function() {
    169       Gallery.instance.removeEventListener(event, listener);
    170       callback();
    171     };
    172     Gallery.instance.addEventListener(event, listener);
    173   },
    174 
    175   /**
    176    * @param {string|boolean|number} value Value to send back.
    177    * @private
    178    */
    179   respond_: function(value) {
    180     if (window.domAutomationController) {
    181       window.domAutomationController.send(value);
    182     } else if (galleryTestAPI.respondCallback) {
    183       galleryTestAPI.respondCallback(value);
    184     } else {
    185       console.log('playerTestAPI response: ' + value);
    186     }
    187   }
    188 };
    189 
    190 /**
    191  * Test example.
    192  */
    193 galleryTestAPI.testExample = function() {
    194   var api = galleryTestAPI;
    195   var PATH = '/Downloads/file.jpg';
    196 
    197   var steps = [
    198     function load() {
    199       if (!Gallery.instance) {
    200         api.load(PATH);
    201       } else {
    202         nextStep();
    203       }
    204     },
    205 
    206     function getName() { api.getSelectedFileName(); },
    207 
    208     function lastRibbon(filename) {
    209       console.log(filename);
    210       api.clickLastRibbonThumbnail();
    211     },
    212 
    213     function toggleEdit() { api.clickEditToggle(); },
    214 
    215     function rightArrow() { api.clickNextImageArrow(); },
    216 
    217     function rotateLeft() { api.clickRotateLeft(); },
    218 
    219     function rotateRight() { api.clickRotateRight(); },
    220 
    221     function undo() { api.clickUndo(); },
    222 
    223     function queryAutofix() { api.isAutofixAvailable(); },
    224 
    225     function autofix(available) {
    226       if (available) {
    227         api.clickAutofix();
    228       } else {
    229         nextStep();
    230       }
    231     },
    232 
    233     function done() { console.log('done'); }
    234   ];
    235 
    236   var step = 0;
    237 
    238   function nextStep() {
    239     ++step;
    240     console.log('nextStep calls: ' + steps[step - 1].name);
    241     steps[step - 1].apply(null, arguments);
    242   }
    243 
    244   api.respondCallback = nextStep;
    245   nextStep();
    246 };
    247