'তারপরে' আসলে ক্যাস্পারজেএস-এ কী বোঝায়


97

আমি ওয়েবসাইটের মাধ্যমে একাধিক ক্লিক, সম্পূর্ণ ফর্ম, ডেটা পার্সিং ইত্যাদির স্বয়ংক্রিয় ব্যবহারের জন্য ক্যাস্পারজেএস ব্যবহার করছি।

ক্যাস্পার thenবিবৃতি আকারে পূর্বনির্ধারিত পদক্ষেপের একটি তালিকায় সংগঠিত বলে মনে হচ্ছে (তাদের উদাহরণটি এখানে দেখুন: http://casperjs.org/quickstart.html ) তবে এটি স্পষ্ট নয় যে পরবর্তী বিবৃতিটি আসলে চালানোর জন্য ট্রিগার করে।

উদাহরণস্বরূপ, thenসমস্ত মুলতুবি থাকা অনুরোধগুলি সম্পূর্ণ হওয়ার জন্য অপেক্ষা করছেন? না injectJSএকটি মুলতুবি অনুরোধ হিসাবে গণনা? আমার কাছে যদি কোনও thenবিবৃতি নেস্টেড থাকে - একটি openবিবৃতি শেষে শৃঙ্খলিত হয় তবে কি হবে ?

casper.thenOpen('http://example.com/list', function(){
    casper.page.injectJs('/libs/jquery.js');
    casper.evaluate(function(){
        var id = jQuery("span:contains('"+itemName+"')").closest("tr").find("input:first").val();
        casper.open("http://example.com/show/"+id); //what if 'then' was added here?
    });
});

casper.then(function(){
    //parse the 'show' page
});

আমি ক্যাস্পারজেএসে কীভাবে প্রবাহ কাজ করে তার একটি প্রযুক্তিগত ব্যাখ্যা খুঁজছি। আমার নির্দিষ্ট সমস্যাটি হ'ল আমার শেষ thenবিবৃতিটি (উপরে) আমার casper.openবক্তব্যের আগে চলেছে এবং আমি জানি না কেন।


4
আমি এখনও flowক্যাস্পারজসের জেনারেলের একটি ব্যাখ্যা খুঁজছি , তবে আমি আবিষ্কার করেছি যে আপনি মূলত কোনও evaluateকলের মধ্যে থেকে ক্যাস্পারকে উল্লেখ করতে পারবেন না । (যেমন আপনি কোনও নতুন ইউআরএল, লগ, ইকো ইত্যাদি খুলতে পারবেন না)। সুতরাং আমার ক্ষেত্রে মূল্যায়ন বলা হয়েছিল কিন্তু বাইরের বিশ্বের সাথে যোগাযোগের কোনও উপায় নেই।
bendytree

4
আমি ঠিক একই জিনিস ভাবছিলাম কিন্তু জিজ্ঞাসা করতে খুব অলস। ভাল প্রশ্ন!
নাথান

4
evaluate()কোডটির জন্য যা "ব্রাউজার" এ চলেছে, পৃষ্ঠার ডিওএম এ ফ্যান্টমজ ব্রাউজ করছে। সুতরাং সেখানে নেই casper.open, কিন্তু jQuery হতে পারে। সুতরাং আপনার উদাহরণটি কোনও অর্থহীন নয়, তবে আমি এখনও অবাক হয়েছি then()আসলে কী করে।
নাথান

উত্তর:


93

then()মূলত একটি স্ট্যাকে একটি নতুন নেভিগেশন পদক্ষেপ যুক্ত করে। একটি পদক্ষেপ একটি জাভাস্ক্রিপ্ট ফাংশন যা দুটি ভিন্ন জিনিস করতে পারে:

  1. পূর্ববর্তী পদক্ষেপের জন্য অপেক্ষা - যদি কোনও হয় - মৃত্যুদন্ড কার্যকর করা হচ্ছে
  2. অনুরোধ করা ইউআরএল এবং সম্পর্কিত পৃষ্ঠাটি লোড হওয়ার অপেক্ষায়

আসুন একটি সহজ নেভিগেশন দৃশ্যের নেওয়া যাক:

var casper = require('casper').create();

casper.start();

casper.then(function step1() {
    this.echo('this is step one');
});

casper.then(function step2() {
    this.echo('this is step two');
});

casper.thenOpen('http://google.com/', function step3() {
    this.echo('this is step 3 (google.com is loaded)');
});

আপনি এই জাতীয় স্ট্যাকের মধ্যে তৈরি সমস্ত পদক্ষেপ মুদ্রণ করতে পারেন:

require('utils').dump(casper.steps.map(function(step) {
    return step.toString();
}));

এটি দেয়:

$ casperjs test-steps.js
[
    "function step1() { this.echo('this is step one'); }",
    "function step2() { this.echo('this is step two'); }",
    "function _step() { this.open(location, settings); }",
    "function step3() { this.echo('this is step 3 (google.com is loaded)'); }"
]

_step()আমাদের জন্য ইউআরএল লোড করার জন্য ক্যাস্পারজেএস দ্বারা স্বয়ংক্রিয়ভাবে যুক্ত করা ফাংশনটি লক্ষ্য করুন ; যখন ইউআরএল লোড করা হয়, তখন স্ট্যাকের পরবর্তী ধাপে - যা step3()- বলা হয়।

আপনি যখন আপনার নেভিগেশন পদক্ষেপগুলি সংজ্ঞায়িত করেছেন, run()ক্রমান্বয়ে একে একে চালিত করুন:

casper.run();

পাদটীকা: কলব্যাক / শ্রোতাদের স্টাফ প্রতিশ্রুতি নিদর্শনটির একটি বাস্তবায়ন ।


ক্যাস্পেরজেজে ০.০.০-আরসি 1 তে, "টেস্ট-স্টেপস.জেএস" ফাংশন সংজ্ঞা স্ট্রিংয়ের সংগ্রহের পরিবর্তে [অবজেক্ট ডমওয়াইন্ডো] এর সংগ্রহ প্রদর্শন করছে।
স্টারলোক

[অবজেক্ট ডমওয়াইন্ডো] সংগ্রহটি এখনও 1.0.0-আরসি 4-এ ফলাফল; আমি আশ্চর্য হই যে এই ফাংশন সংজ্ঞাগুলি কোথায় গিয়েছিল ...
স্টারলোক

4
আমি প্রথমে ভেবেছিলাম ক্যাস্পারজেএস ফাংশনগুলি ডমওয়াইন্ডোতে রূপান্তর করার একটি নতুন কৌশল করছে তবে সমস্যাটি সত্যই ছিল "রিটার্ন দিস টু স্ট্রিং ()" বনাম "রিটার্ন স্টেপ.টোস্ট্রিং ()" - আমি উত্তরের জন্য একটি সম্পাদনা জমা দিয়েছি।
স্টারলোক

4
তথাকথিত 'স্ট্যাক' আসলে কি একটি সারি নয়? পদক্ষেপগুলি যথাযথভাবে কার্যকর করা হয়, যদি এটি স্ট্যাক হয়ে থাকে তবে আমরা কী পদক্ষেপ 3, পদক্ষেপ 2, পদক্ষেপ 1 আশা করতাম না?
শারবাণী

4
আমি মনে করি এটি অবশ্যই এর মতো হওয়া উচিত: আপনার কাছে স্টেপস স্ট্যাক রয়েছে। আপনি একটি পদক্ষেপ পপ অফ এবং এটি মূল্যায়ন। আপনি একটি খালি সারি তৈরি করেন। বর্তমান পদক্ষেপের প্রক্রিয়াজাতকরণের ফলে উত্পন্ন যে কোনও পদক্ষেপ এই সারিটিতে রাখা হবে। পদক্ষেপটি মূল্যায়ন শেষ হলে, সারিতে উত্পন্ন সমস্ত পদক্ষেপগুলি স্ট্যাকের শীর্ষে স্থাপন করা হবে তবে তাদের ক্রমের মধ্যে ক্রম সংরক্ষণ করা। (বিপরীত ক্রমে স্ট্যাকের দিকে চাপ দেওয়ার মতো) The
চিহ্নিত করুন

33

then() কেবল পদক্ষেপের একটি সিরিজ নিবন্ধভুক্ত।

run() এবং এর রানার ফাংশন, কলব্যাকস এবং শ্রোতাদের পরিবার হ'ল আসলে প্রতিটি পদক্ষেপ কার্যকর করার কাজটি করে।

যখনই কোনো পদক্ষেপ সম্পন্ন হলে CasperJS 3 পতাকা বিরুদ্ধে চেক করবে: pendingWait, loadInProgress, এবং navigationRequested। যদি এই পতাকাগুলির মধ্যে কোনও সত্য হয়, তবে কিছুই করবেন না, পরবর্তী সময় ( setIntervalশৈলী) পর্যন্ত অলস থাকুন । যদি এই পতাকাগুলির মধ্যে কোনওটিই সত্য না হয়, তবে পরবর্তী পদক্ষেপটি কার্যকর করা হবে।

ক্যাস্পারজেএস ১.০.০-আরসি ৪ হিসাবে, একটি ত্রুটি বিদ্যমান, যেখানে নির্দিষ্ট সময় ভিত্তিক পরিস্থিতিতে ক্যাস্পারজেএস-এর একটি loadInProgressবা navigationRequestedপতাকা উত্থাপনের সময় পাওয়ার আগে "পরবর্তী পদক্ষেপটি করার চেষ্টা করুন" পদ্ধতিটি ট্রিগার করা হবে । সমাধানটি হ'ল যে কোনও ধাপ ছাড়ার আগে এই পতাকাগুলির মধ্যে একটি বাড়াতে হবে যেখানে এই পতাকাগুলি উত্থাপিত হবে বলে মনে করা হয় (উদাঃ: আগে একটি পতাকা জিজ্ঞাসা করার আগে বা জিজ্ঞাসা করার পরে casper.click()), সম্ভবত:

(দ্রষ্টব্য: এটি যথাযথ ক্যাস্পারজেএস ফর্মের চেয়ে আরও বেশি চিত্রযুক্ত কোড ...)

step_one = function(){
    casper.click(/* something */);
    do_whatever_you_want()
    casper.click(/* something else */); // Click something else, why not?
    more_magic_that_you_like()
    here_be_dragons()
    // Raise a flag before exiting this "step"
    profit()
}

কোডটির একক লাইনে সমাধানটি গুটিয়ে নেওয়ার জন্য, আমি blockStep()এই গিথুব পুলের অনুরোধটি প্রসারিত করেছি click()এবং clickLabel()ব্যবহারের সময় আমরা প্রত্যাশিত আচরণ পাব এই গ্যারান্টি সাহায্য করার একটি উপায় হিসাবে then()। আরও তথ্য, ব্যবহারের ধরণ এবং সর্বনিম্ন পরীক্ষার ফাইলগুলির জন্য অনুরোধটি দেখুন।


4
খুব সহায়ক এবং দুর্দান্ত অন্তর্দৃষ্টি এবং পরামর্শ blockStep, আইএমএইচও
ব্রায়ান এম হান্ট

আমরা এখনও "চূড়ান্ত উত্তর" সমাধান নিয়ে আলোচনা করছি ... আমি আশা করি যে একবার আমি "গ্লোবাল ডিফল্ট" দিকটি বাস্তবায়িত হলে ক্যাস্পারজেএস এই উদ্যোগটি টানবে।
তারকাচিহ্ন

4
হ্যাঁ, এটি লক্ষ্য রাখুন। :)
স্টারলোক

আমাদের কি এর কোন সমাধান আছে? যদি হ্যাঁ তা কি?
সুরেন্দ্র সিং মালিক

এটি ব্যাখ্যা করার জন্য অনেক ধন্যবাদ। আজাক-ভারী অ্যাপ্লিকেশনটির জন্য আমার ক্যাস্পার ফাংশনাল টেস্টগুলি সমস্ত সময় এলোমেলোভাবে ব্যর্থ হওয়ায় এই আচরণটি আমাকে এক বছর ধরে হত্যা করছে।
ব্রেকেটজোনদেব

0

ক্যাস্পারজেএস ডকুমেন্টেশন অনুসারে :

then()

স্বাক্ষর: then(Function then)

একটি সহজ ফাংশন সরবরাহ করে এই পদ্ধতিটি স্ট্যাকটিতে একটি নতুন নেভিগেশন পদক্ষেপ যুক্ত করার মানক উপায়:

casper.start('http://google.fr/');

casper.then(function() {
  this.echo('I\'m in your google.');
});

casper.then(function() {
  this.echo('Now, let me write something');
});

casper.then(function() {
  this.echo('Oh well.');
});

casper.run();

আপনি প্রয়োজন হিসাবে অনেক পদক্ষেপ যোগ করতে পারেন। নোট করুন যে বর্তমান Casperউদাহরণটি স্বয়ংক্রিয়ভাবে thisআপনার জন্য পদক্ষেপ ফাংশনের মধ্যে কীওয়ার্ডকে আবদ্ধ করে ।

আপনার নির্ধারিত সমস্ত পদক্ষেপগুলি চালনার জন্য, run()পদ্ধতিটি কল করুন এবং ভয়েলা।

দ্রষ্টব্য: পদ্ধতিটি start()ব্যবহার করার জন্য আপনাকে অবশ্যই ক্যাস্পার দৃষ্টান্তটি আবশ্যক then()

সতর্কতা:then() দুটি পদক্ষেপে যুক্ত পদক্ষেপ ফাংশনগুলি প্রক্রিয়াজাত করা হয়:

  1. যখন আগের পদক্ষেপটি কার্যকর করা হয়েছে,
  2. যখন পূর্বের প্রধান এইচটিটিপি অনুরোধ কার্যকর করা হয়েছে এবং পৃষ্ঠাটি লোড হয়েছে ;

নোট করুন যে পৃষ্ঠাটি লোডের কোনও একক সংজ্ঞা নেই ; এটি কি যখন DOMReady ইভেন্টটি ট্রিগার করা হয়েছিল? এটি কি "সমস্ত অনুরোধগুলি শেষ হচ্ছে"? এটি কি "সমস্ত অ্যাপ্লিকেশন যুক্তি সম্পাদন করা হচ্ছে"? বা "সমস্ত উপাদান রেন্ডার হচ্ছে"? উত্তর সর্বদা প্রসঙ্গে নির্ভর করে। সুতরাং আপনি কী waitFor()আশা করেন তার উপর সুস্পষ্ট নিয়ন্ত্রণ রাখতে সর্বদা পারিবারিক পদ্ধতিগুলি ব্যবহার করতে উত্সাহিত হন কেন ।

একটি সাধারণ কৌশলটি হ'ল waitForSelector():

casper.start('http://my.website.com/');

casper.waitForSelector('#plop', function() {
  this.echo('I\'m sure #plop is available in the DOM');
});

casper.run();

পর্দার আড়ালে, এর উত্স কোডটিCasper.prototype.then নীচে দেখানো হয়েছে:

/**
 * Schedules the next step in the navigation process.
 *
 * @param  function  step  A function to be called as a step
 * @return Casper
 */
Casper.prototype.then = function then(step) {
    "use strict";
    this.checkStarted();
    if (!utils.isFunction(step)) {
        throw new CasperError("You can only define a step as a function");
    }
    // check if casper is running
    if (this.checker === null) {
        // append step to the end of the queue
        step.level = 0;
        this.steps.push(step);
    } else {
        // insert substep a level deeper
        try {
            step.level = this.steps[this.step - 1].level + 1;
        } catch (e) {
            step.level = 0;
        }
        var insertIndex = this.step;
        while (this.steps[insertIndex] && step.level === this.steps[insertIndex].level) {
            insertIndex++;
        }
        this.steps.splice(insertIndex, 0, step);
    }
    this.emit('step.added', step);
    return this;
};

ব্যাখ্যা:

অন্য কথায়, then()নেভিগেশন প্রক্রিয়ার পরবর্তী পদক্ষেপের সময়সূচী।

যখন then()ডাকা হয়, এটি একটি পরামিতি হিসাবে একটি ফাংশন পাস যা একটি পদক্ষেপ হিসাবে ডাকা হয়।

এটি উদাহরণস্বরূপ শুরু হয়েছে কিনা তা পরীক্ষা করে এবং এটি না থাকলে এটি নিম্নলিখিত ত্রুটিটি প্রদর্শন করে:

CasperError: Casper is not started, can't execute `then()`.

এরপরে, এটি পরীক্ষা করে যদি pageবস্তুটি হয় কিনা null

যদি শর্তটি সত্য হয় তবে ক্যাস্পার একটি নতুন pageঅবজেক্ট তৈরি করে ।

এর পরে, প্যারামিটারটি then()যাচাই করে stepএটি পরীক্ষা করে না যে এটি কোনও ফাংশন নয়।

যদি প্যারামিটারটি কোনও ফাংশন না হয় তবে এটি নিম্নলিখিত ত্রুটিটি দেখায়:

CasperError: You can only define a step as a function

তারপরে, ফাংশনটি ক্যাস্পার চলছে কিনা তা পরীক্ষা করে।

যদি ক্যাস্পার চলমান না থাকে তবে then()সারিটির শেষের ধাপটি যুক্ত করে।

অন্যথায়, যদি ক্যাস্পার চলমান থাকে তবে এটি একটি সাবসেটপটি পূর্বের ধাপের চেয়ে গভীরতর স্তর সন্নিবেশ করায়।

অবশেষে, then()একটি step.addedইভেন্ট নির্গত করে ফাংশনটি সমাপ্ত হয় এবং ক্যাস্পার অবজেক্টটি প্রদান করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.