コード例 #1
0
	beforeEach(function(done) {
		catchSpy = jasmine.createSpy("catchSpy");
		if (travis) {
			browser = wd.promiseChainRemote("http://*****:*****@ondemand.saucelabs.com/wd/hub", 80);
		} else {
			browser = wd.promiseChainRemote("0.0.0.0", 4723);
		}
		browser.on('status', function(info) {
		  console.log('status\n', arguments);
		});
		browser.on('command', function(eventType, command, response) {
		  console.log('command\n', arguments);
		});
		browser.on('http', function(meth, path, data) {
		  console.log('http\n', arguments);
		});

		browser.init(desired)
		.catch(function(err){
			console.log(err);
		})
		.then(function() {
			console.log(arguments);
			done();
		})
		.catch(function(err) {
			console.log(err);
			throw err;
		})
	}, APPIUM_INIT_TIMEOUT);
コード例 #2
0
  it('should create and destroy Android sessions', async function () {
    try {
      // Connect to Appium server
      driver = SAUCE_TESTING
        ? await wd.promiseChainRemote(serverConfig)
        : await wd.promiseChainRemote(serverConfig, SAUCE_USERNAME, SAUCE_ACCESS_KEY);

      // add the name to the desired capabilities
      const sauceCaps = SAUCE_TESTING
        ? {
          name: 'Android Create Session Test',
        }
        : {};

      // Start the session
      await driver.init({
        ...androidCaps,
        ...sauceCaps,
        app: androidApiDemos,
      });

      // Check that we're running the ApiDemos app by checking package and activity
      const activity = await driver.getCurrentActivity();
      const pkg = await driver.getCurrentPackage();
      assert.equal(`${pkg}${activity}`, 'io.appium.android.apis.ApiDemos');
    } finally {
      // Quit the session, no matter what happens
      await driver.quit();
    }
  });
コード例 #3
0
ファイル: index.js プロジェクト: ciscospark/spark-js-sdk
  createBrowser: function createBrowser(pkg, browserDef) {
    if (!pkg) {
      throw new Error('pkg is required');
    }

    if (!browserDef) {
      browserDef = {browserName: 'chrome'};
    }

    if (!browserDef) {
      throw new Error('No browser definition available');
    }

    browserDef = defaults(browserDef, {
      build: process.env.BUILD_NUMBER || `local-${process.env.USER}-${pkg.name}-${Date.now()}`,
      name: `${pkg.name} (automation)`,
      public: 'team',
      tunnelIdentifier: process.env.SC_TUNNEL_IDENTIFIER
    });

    const browser = process.env.SC_TUNNEL_IDENTIFIER ? wd.promiseChainRemote('ondemand.saucelabs.com', 80) : wd.promiseChainRemote();

    return browser.init(browserDef)
      .setImplicitWaitTimeout(10000)
      .setWindowSize(1600, 1200)
      .then(() => browser);
  },
コード例 #4
0
  it('should create and destroy Android browser session', async function () {
    try {
      // Connect to Appium server
      driver = SAUCE_TESTING
        ? await wd.promiseChainRemote(serverConfig)
        : await wd.promiseChainRemote(serverConfig, SAUCE_USERNAME, SAUCE_ACCESS_KEY);

      // add the name to the desired capabilities
      const sauceCaps = SAUCE_TESTING
        ? {
          name: 'Android Create Web Session Test',
        }
        : {};

      // Start the session
      await driver.init({
        ...androidCaps,
        ...sauceCaps,
        browserName: 'Chrome',
      });

      // Navigate to google.com
      await driver.get('https://www.google.com');

      // Test that it was successful by checking the document title
      const pageTitle = await driver.title();
      assert.equal(pageTitle, 'Google');
    } finally {
      // Quit the session, no matter what happens
      await driver.quit();
    }
  });
コード例 #5
0
ファイル: driver-e2e-specs.js プロジェクト: slavazhuk/appium
 it('should not be able to run two FakeDriver sessions simultaneously when one is unique', async function () {
   let uniqueCaps = _.clone(caps);
   uniqueCaps.uniqueApp = true;
   let driver1 = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
   let [sessionId1] = await driver1.init(uniqueCaps);
   should.exist(sessionId1);
   sessionId1.should.be.a('string');
   let driver2 = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
   await driver2.init(caps).should.eventually.be.rejected;
   await driver1.quit();
 });
コード例 #6
0
ファイル: driver-e2e-specs.js プロジェクト: slavazhuk/appium
 it('should be able to run two FakeDriver sessions simultaneously', async function () {
   let driver1 = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
   let [sessionId1] = await driver1.init(caps);
   should.exist(sessionId1);
   sessionId1.should.be.a('string');
   let driver2 = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
   let [sessionId2] = await driver2.init(caps);
   should.exist(sessionId2);
   sessionId2.should.be.a('string');
   sessionId1.should.not.equal(sessionId2);
   await driver1.quit();
   await driver2.quit();
 });
 it('should start parallel sessions and return WDA status for each of them', async function () {
   const sessionsPromisesMapping = new Map();
   for (const [devName, serverPort, wdaPort] of _.zip(DEVICES.slice(0, SESSIONS_COUNT),
                                                      _.range(DEFAULT_SERVER_PORT, DEFAULT_SERVER_PORT + SESSIONS_COUNT),
                                                      _.range(DEFAULT_WDA_PORT, DEFAULT_WDA_PORT + SESSIONS_COUNT))) {
     const driverPromise = wd.promiseChainRemote(HOST, serverPort);
     const serverPromise = startServer(serverPort, HOST);
     const caps = Object.assign({}, UICATALOG_CAPS, {
       deviceName: devName,
       wdaLocalPort: wdaPort,
     });
     sessionsPromisesMapping.set(serverPromise, [driverPromise, caps]);
   }
   const initPromisesMapping = new Map();
   for (const [sessionPromise, driverPromiseInfo] of sessionsPromisesMapping.entries()) {
     const [driverPromise, caps] = driverPromiseInfo;
     const session = await sessionPromise;
     const driver = await driverPromise;
     sessionsMapping.set(session, driver);
     initPromisesMapping.set(driver, driver.init(caps));
   }
   for (const [driver, initPromise] of initPromisesMapping.entries()) {
     await initPromise;
     const status = await driver.status();
     status.wda.should.exist;
   }
 });
コード例 #8
0
ファイル: snapshot.js プロジェクト: Haroenv/howtocenterincss
    suiteSetup(done => {
      b = wd.promiseChainRemote(remoteConfig);

      b.on('status', function(info) {
          console.log(info.cyan);
      });
      b.on('command', function(eventType, command, response) {
          console.log(' > ' + eventType.cyan, command, (response || '').grey);
      });
      b.on('http', function(meth, path, data) {
          console.log(' > ' + meth.magenta, path, (data || '').grey);
      });

      b
        .init(browser)
        .setWindowSize(400, 400)
        .elementByTagName('html')
        .getSize()
        .then(size => {
          // Browser titles/bars short change you, so set it so the document's
          // 400x400.
          return b.setWindowSize(400 + (400 - size.width), 400 + (400 - size.height));
        })
        .nodeify(done);
    });
コード例 #9
0
ファイル: shared.js プロジェクト: AzGoalie/ddf
    before(function () {


        exports.url = 'http://localhost:' + this.mochaOptions.expressPort;
        exports.timeout = argv.timeout || this.mochaOptions.timeout || 30000;

        // need reference in order to take screenshots
        browser = this.browser;
        // remove listener before adding since this is called before each test suites
        this.browser.removeListener('command', handleCommand).on('command', handleCommand);

        if (argv.browser) {
            this.browser = wd.promiseChainRemote()
                .init({browserName: argv.browser || 'chrome'});
        }

        if (argv.verbose) {
            debugLogging(this.browser);
        }

        return this.browser
            .setAsyncScriptTimeout(exports.timeout)
            .setWindowSize(1080, 1080)
            .get(argv.url || exports.url);
    });
コード例 #10
0
ファイル: wd-extension-spec.js プロジェクト: sideroad/wd-ct
 it('should get HTML markup error', function (done) {
     var b = wd.promiseChainRemote("ondemand.saucelabs.com", 80, process.env.SAUCE_USERNAME, process.env.SAUCE_ACCESS_KEY);
     b.init({
         browserName: 'internet explorer',
         version: '8',
         'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER
      })
      .get('http://localhost:8000/')
      .getMarkupWarning()
      .then(function(warnings){
         warnings.should.have.length(0);
      })
      .get('http://localhost:8000/index-invalid-markup.html')
      .getMarkupWarning()
      .then(function(warnings){
         warnings.should.have.length(6);
         warnings.should.deep.equal([
             'line 7 column 4 - Warning: missing </span> before </p>',
             'line 8 column 4 - Warning: inserting implicit <span>',
             'line 8 column 22 - Warning: inserting implicit <p>',
             'line 10 column 5 - Warning: inserting implicit <span>',
             'line 10 column 14 - Warning: missing <li>',
             'line 10 column 14 - Warning: inserting implicit <span>'
         ]);
      })
      .then(function(){
         return b.quit();
      })
      .done(function(){
         done();
      }, function(err){
         done(err);
      });
 });
コード例 #11
0
      before(function(done) {
        wd.configureHttp({
          timeout: 60000,
          retryDelay: 15000,
          retries: 5,
          baseUrl: baseURL
        });

        if (conf.sauce) {
          conf.remote = _.defaults(conf.remote, {
            username: sauceUsername,
            accessKey: sauceAccessKey
          });
        }
        browser = wd.promiseChainRemote(conf.remote);

        if (conf.debug) {
          browser.on('status', function(info) {
            console.log(info.cyan);
          });
          browser.on('command', function(eventType, command, response) {
            console.log(' > ' + eventType.cyan, command, (response || '').grey);
          });
          browser.on('http', function(meth, path, data) {
            console.log(' > ' + meth.magenta, path, (data || '').grey);
          });
        }

        browser.init(conf.capabilities).nodeify(done);
      });
コード例 #12
0
describe('Appium test', function() {
    this.timeout(120000);

    var desired = {
        "appium-version": "1.0",
        platformName: "Android",
        platformVersion: "5.1",
        deviceName: "xxxxxx",
        app: "~/app-release.apk",
        "app-package": "org.mozilla.magnet",
        "app-activity": "org.mozilla.magnet.MainActivity"
    };

    var browser = wd.promiseChainRemote("127.0.0.1", 4723);

    before(function() {
        return browser
        .init(desired)
        .setImplicitWaitTimeout(120000);
    });

    it('should find the close button', function(done) {
    return browser
        .elementByXPath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.view.View[1]/android.widget.ScrollView[1]/android.view.View[1]/android.view.View[1]/android.view.View[1]/android.view.View[1]/android.view.View[1]/android.widget.ImageView[1]").click()
        .elementByXPath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.view.View[2]/android.view.View[1]/android.widget.ImageView[1]")
        .isDisplayed().should.eventually.be.true
        .nodeify(done)
    });

    after(function() {
    //add code here
    browser.quit()
    });

});
コード例 #13
0
 before(function() {
   browser = wd.promiseChainRemote("localhost", 4723);
   $ = wdQuery(browser);
   return browser
     .init({
       'app-package': (process.env.APPIUM === "android") ? 'org.devgeeks.encryptr' : undefined,
       'app-activity': (process.env.APPIUM === "android") ? '.Encryptr' : undefined,
       name: "Encryptr",
       platformName: (process.env.APPIUM === "android") ? "Android" : "iOS",
       platformVersion: '8.4',
       deviceName: (process.env.APPIUM === "android") ? 'Android VM' : 'iPhone 6',
       app: appURL,
       implicitWaitMs: 500
     })
     .contexts()
     .then(function(contexts) {
       console.log(contexts);
       return browser;
     })
     .setImplicitWaitTimeout(20000)
     .context((process.env.APPIUM === "android") ? 'WEBVIEW_org.devgeeks.encryptr' : 'WEBVIEW_1');
     // .setAsyncScriptTimeout(30000)
     //.windowHandles()
     //.then(function(handles) {
       //console.log(handles);
       //return (process.env.APPIUM === "android") ? browser.window(handles[1]) : browser.window(handles[0]);
     //});
 });
コード例 #14
0
ファイル: SeleniumDriver.js プロジェクト: AndreLeifert/mimik
 init: function(config) {
     this._super.call(this, config);
     // wd will default to local firefox if no options are specified
     this.client = wd.promiseChainRemote(this.profile); //wd.remote(this.profile);
     this.client.on('status', function(info) {
         logger.debug('[selenium driver] client event "status"', info);
     });
     this.client.on('http', function(meth, path) {
         logger.debug('[selenium driver] client event "http"', meth, path);
     });
     this.client.on('command', function(eventType, command) {
         logger.debug('[selenium driver] client event "command"', eventType, command);
     });
     this.client.on('error', function() {
         logger.debug('[selenium driver] client event "error"', arguments);
     });
 /*
     // webdriverio events
     this.client.on('end', function() {
         logger.debug('[selenium driver] client event "end"', arguments);
     });
     this.client.on('init', function(e) {
         logger.debug('[selenium driver] client event "init"', e);
     });
     this.client.on('error', function(e) {
         logger.debug('[selenium driver] client event "error"', e.err);
     });
     this.client.on('result', function(e) {
         logger.debug('[selenium driver] client event "result"');
     });
 */
 },
コード例 #15
0
 it('should start a session', async () => {
   let driver = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
   let [sessionId] = await driver.init(caps);
   should.exist(sessionId);
   sessionId.should.be.a('string');
   await driver.quit();
 });
コード例 #16
0
ファイル: test.js プロジェクト: gizur/trailerapp_tests
  before(function () {
    var serverConfig = process.env.SAUCE ?
      serverConfigs.sauce : serverConfigs.local;
    driver = wd.promiseChainRemote(serverConfig);
    configure(driver);

    var desired = {
      browserName: '',
      'appium-version': '1.5',
      platformName: 'iOS',
      platformVersion: '9.2',
      deviceName: 'iPhone Simulator', //'iPhone Simulator','iPhone 6s'
      app: 'Besiktning/platforms/ios/build/emulator/Besiktning.app'
    };

    return driver.init(desired)
      .elementsByIosUIAutomation('.tableViews()[0].cells()', function (err, el) {
        el.elementByIosUIAutomation('.elements()["UICatalog"]', function (err, el) {
          el.getAttribute('name', function (err, name) {
            console.log(name);
          });
        });
      })
      .contexts().then(function (contexts) {
        // get list of available views. Returns array: ["NATIVE_APP","WEBVIEW_1"]
        debug(contexts);
        return driver.context(contexts[1]); // choose the webview context
      })
  });
コード例 #17
0
 before(function () {
   require("./itest-niacin/appium-helpers.js").configureWd(wd);
   driver = wd.promiseChainRemote(setup.serverConfig);
   return driver
     .init(setup.desired)
     .setImplicitWaitTimeout(3000);
 });
コード例 #18
0
describe('Webview', () => {
  let server;
  let driver = wd.promiseChainRemote(HOST, PORT);
  before(async () => {
    server = await startServer(PORT, HOST);
  });

  after(() => {
    // TODO I don't think this is actually shutting the server down, figure
    // that out
    server.close();
  });

  it('should start a session, navigate to url, get title', async function () {
    this.timeout(120 * 1000);
    await driver.init(DEFAULT_CAPS);
    let contexts = await driver.contexts();
    contexts.length.should.equal(2);

    let urlBar = await driver.elementByClassName('UIATextField');
    let button = await driver.elementByClassName('UIAButton');
    await urlBar.sendKeys('appium.io');
    await button.click();

    await driver.context('WEBVIEW_1');
    let title = await driver.title();
    title.should.equal('Appium: Mobile App Automation Made Awesome.');

    await driver.quit();
  });

});
コード例 #19
0
ファイル: sauce.js プロジェクト: AndyRoyal/when
	function runAutomatedTests (tunnel) {
		var browser = webdriver.promiseChainRemote(
			opts['remote-host'],
			opts['remote-port'],
			username,
			accessKey);

		browser.on('status', function (info) {
			console.log('\x1b[36m%s\x1b[0m', info);
		});
		browser.on('command', function (meth, path) {
			console.log(' > \x1b[33m%s\x1b[0m: %s', meth, path);
		});

		var outcome = opts.browsers.reduce(function (result, env) {
			return when(result, function () {
				return testWith(browser, env);
			});
		}, void 0);

		outcome.finally(function () {
			console.log('Stopping buster');
			buster.kill();

			console.log('Closing tunnel to Sauce Labs');
			tunnel.close();

			process.exit(suiteFailed ? 1 : 0);
		}).done();
	}
コード例 #20
0
ファイル: wd-extension-spec.js プロジェクト: sideroad/wd-ct
 it('should output log for unsupported warnings on IE', function (done) {
     var b = wd.promiseChainRemote("ondemand.saucelabs.com", 80, process.env.SAUCE_USERNAME, process.env.SAUCE_ACCESS_KEY );
     b.init({
         browserName: 'internet explorer',
         'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER
      })
      .get('http://localhost:8000/')
      .getBrowserErrors()
      .then(function(errs){
         errs.should.have.length(0);
      })
      .elementByCss('#throw-error')
      .click()
      .getBrowserErrors()
      .then(function(errs){
         errs.should.have.length(0);
      })
      .then(function(){
         return b.quit();
      })
      .done(function(){
         done();
      }, function(err){
         done(err);
      });
 });
コード例 #21
0
module.exports = function(){
  var config = this.data;
  var taskSucceeded = this.async();
  grunt.verbose.write('webdriver remote', JSON.stringify(config.webdriver.remote));
  var browser = wd.promiseChainRemote(config.webdriver.remote);

  browser.on('status', function(info) {
    grunt.verbose.writeln(info);
  });

  browser.on('command', function(meth, path, data) {
    grunt.verbose.writeln(' > ' + meth, path, data || '');
  });

  browser
    .init(config.browser || {})
    .get(config.url)
    .then(function(){return browser;})
    .then(getJSReport)
    .then(config.onComplete && config.onComplete.bind(browser), config.onError && config.onError.bind(browser))
    .fail(grunt.verbose.writeln.bind(grunt.verbose))
    .fin(function(){
      if (grunt.option('webdriver-keep-open')) return;
      grunt.verbose.writeln('Closing the browser window. To keep it open, pass the --webdriver-keep-open flag to grunt.');
      return browser.quit();
    })
    .done(
      taskSucceeded.bind(null,true),
      taskSucceeded.bind(null,false)
    )
  ;
}
コード例 #22
0
ファイル: wd-extension-spec.js プロジェクト: sideroad/wd-ct
 it('should type and fire events', function (done) {
     var b = wd.promiseChainRemote();
     b.init({
         browserName: 'firefox'
      })
      .get('http://localhost:8000/')
      .elementByCss('#text')
      .naturalType('abcde')
      .elementByCss('#logger')
      .text()
      .then(function(text){
         text.should.equal('abcde');
      })
      .elementByCss('#text')
      .naturalType('12345')
      .elementByCss('#logger')
      .text()
      .then(function(text){
         text.should.equal('12345');
      })
      .then(function(){
         return b.quit();
      })
      .done(function(){
         done();
      }, function(err){
         done(err);
      });
 });
コード例 #23
0
ファイル: runner.js プロジェクト: angleman/strider
  async.map(browsers, function(conn, doneBrowser){
    var browser = wd.promiseChainRemote(remote)
    browser.init(conn)
    setTimeout(function(){
      /*
      browser.on('status', function(info) {
          console.log(info.cyan);
      });
      browser.on('command', function(meth, path, data) {
          console.log(' > ' + meth.yellow, path.grey, data || '');
      });
      browser.on('error', function(info) {
          console.log(red);
      });
      */
      browser.get("http://localhost:4000/")

      async.map(tests, function(suite, cb){
          console.log("[Browser:", conn, "] -> ", suite)
          require(suite)(browser, cb)
        },
        function(err, failure){
          browser.quit()
          doneBrowser(err)
        }
        )
      }, 2000)
    }
コード例 #24
0
    before(function(done) {
        browser = webdriver.promiseChainRemote(
            "localhost",
            4445,
            process.env.SAUCE_USERNAME,
            process.env.SAUCE_ACCESS_KEY
        );

        browser.on('status', function(info) {
            console.log(info);
        });
        browser.on('command', function(meth, path, data) {
            console.log(' > ' + meth, path, data || '');
        });

        var options = {
          browserName: 'chrome',
          version: '26',
          platform: 'Linux',
          tags: ["examples"],
          name: "This is an example test with mocha"
        };

        return browser
            .init(options)
            .get('http://localhost:3000/iove.html')
            .nodeify(done);
    });
コード例 #25
0
ファイル: wd-extension-spec.js プロジェクト: sideroad/wd-ct
 it('should select option', function (done) {
     var b = wd.promiseChainRemote();
     b.init({
         browserName: 'firefox'
      })
      .get('http://localhost:8000/')
      .elementByCss('#selectbox')
      .select('b')
      .elementByCss('#logger')
      .text()
      .then(function(text){
         text.should.equal('2');
      })
      .elementByCss('#selectbox')
      .select('c')
      .elementByCss('#logger')
      .text()
      .then(function(text){
         text.should.equal('3');
      })
      .then(function(){
         return b.quit();
      })
      .done(function(){
         done();
      }, function(err){
         done(err);
      });
 });
コード例 #26
0
ファイル: test-browser.js プロジェクト: AlfiyaZi/pouchdb
function startTest() {
  if (numBrowsers === finishedBrowsers) {
    return testsComplete();
  }
  if (!browsers.length) {
    return;
  }

  var currentTest = browsers.pop();
  console.log('[' + currentTest + '] starting');
  var client = wd.promiseChainRemote();
  client.init({
    browserName: currentTest
  }).get(testUrl).setAsyncScriptTimeout(testTimeout)
    .executeAsync('var cb = arguments[arguments.length - 1];QUnit.done(function( report ) {cb(report)});')
    .then(function (result) {
      finishedBrowsers++;
      if (!result.failed) {
        console.log('[' + currentTest + '] passed ' + result.passed + ' of ' + result.total + ' tests');
      } else {
        console.log('[' + currentTest + '] failed ' + result.failed + ' of ' + result.total + ' tests');
        return client.quit().then(function() {
          process.exit(2);
        })
      }
      results[currentTest] = result;
    }).quit()
    .then(startTest,function(e) {
      console.error(e);
      console.error('Doh, tests failed');
      client.quit();
      process.exit(3);
    });

}
コード例 #27
0
  function runTestsOnPhantom(fileGroup, opts, next) {
    var browser;
    var phantomPort = opts.phantomPort? opts.phantomPort : 4444;

    if (opts.usePromises) {
      browser = wd.promiseChainRemote({port: phantomPort});
    }
    else {
      browser = wd.remote({port: phantomPort});
    }
    grunt.log.writeln('Running webdriver tests against PhantomJS.');

    startPhantom(phantomPort, opts.ignoreSslErrors, function (err, phantomProc) {
      if (err) { return next(err); }
      browser.init({}, function () {
        runTestsForBrowser(opts, fileGroup, browser, function (err) {
          phantomProc.on('close', function () {
            grunt.log.writeln('Phantom exited.');
            next(err);
          });
          phantomProc.kill();
        });
      });
    });

  }
コード例 #28
0
 it('should fail gracefully when session has ended', async () => {
   let driver = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
   let [sessionId] = await driver.init(caps);
   should.exist(sessionId);
   sessionId.should.be.a('string');
   await driver.quit();
   await driver.title().should.eventually.be.rejectedWith(/terminated/);
 });
コード例 #29
0
ファイル: driver-e2e-specs.js プロジェクト: slavazhuk/appium
 it('should start and stop a session', async function () {
   let driver = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
   let [sessionId] = await driver.init(caps);
   should.exist(sessionId);
   sessionId.should.be.a('string');
   await driver.quit();
   await driver.title().should.eventually.be.rejectedWith(/terminated/);
 });
コード例 #30
0
function setup() {
  if (process.env.TRAVIS) {
    return sauceSetup();
  } else {
    driver = wd.promiseChainRemote('127.0.0.1', 4723);
    browser = driver.init(desired);
  }
}