تم شحن واجهة "Chrome بلا واجهة مستخدم رسومية" في Chrome 59. وهي طريقة لتشغيل متصفّح Chrome في بيئة بلا واجهة مستخدم رسومية. بشكل أساسي، يتم تشغيل Chrome بدون chrome! ويوفّر ذلك جميع ميزات منصة الويب الحديثة التي يقدّمها Chromium ومحرّك العرض Blink إلى سطر الأوامر.
المتصفّح بلا واجهة مستخدم رسومية هو أداة رائعة للاختبارات المبرمَجة وبيئات الخادم التي لا تحتاج إلى واجهة مستخدم مرئية. على سبيل المثال، قد تريد إجراء بعض الاختبارات على صفحة ويب حقيقية أو إنشاء ملف PDF لها أو مجرد فحص كيفية عرض المتصفّح لعنوان URL.
بدء استخدام "Chrome بلا واجهة مستخدم رسومية" (واجهة سطر الأوامر)
أسهل طريقة للبدء في استخدام "وضع التشغيل بلا واجهة مستخدم رسومية" هي فتح ملف Chrome الثنائي من سطر الأوامر. إذا كان لديك Chrome 59 أو إصدار أحدث، ابدأ تشغيل Chrome باستخدام العلامة --headless:
chrome \
--headless \ # Runs Chrome in headless mode.
--disable-gpu \ # Temporarily needed if running on Windows.
--remote-debugging-port=9222 \
https://www.chromestatus.com # URL to open. Defaults to about:blank.
يجب أن يشير chrome إلى تثبيت Chrome. وسيختلف الموقع الدقيق من نظام أساسي إلى آخر. بما أنّني أستخدم جهاز Mac، أنشأت أسماء مستعارة مناسبة لكل إصدار من Chrome مثبّت لديّ.
إذا كنت تستخدم القناة الثابتة من Chrome ولا يمكنك الحصول على الإصدار التجريبي، استخدِم chrome-canary:
alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"
alias chrome-canary="/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary"
alias chromium="/Applications/Chromium.app/Contents/MacOS/Chromium"
تنزيل Chrome Canary.
ميزات سطر الأوامر
في بعض الحالات، قد لا تحتاج إلى برمجة "Chrome بلا واجهة مستخدم رسومية". هناك بعض علامات سطر الأوامر المفيدة لتنفيذ المهام الشائعة.
طباعة نموذج العناصر في المستند
تطبع العلامة --dump-dom السمة document.body.innerHTML على الإخراج العادي:
chrome --headless --disable-gpu --dump-dom https://www.chromestatus.com/
### Create a PDF
The `--print-to-pdf` flag creates a PDF of the page:
```shell
chrome --headless --disable-gpu --print-to-pdf https://www.chromestatus.com/
أخذ لقطات شاشة
لالتقاط لقطة شاشة لصفحة، استخدِم العلامة --screenshot:
chrome --headless --disable-gpu --screenshot https://www.chromestatus.com/
# Size of a standard letterhead.
chrome --headless --disable-gpu --screenshot --window-size=1280,1696 https://www.chromestatus.com/
# Nexus 5x
chrome --headless --disable-gpu --screenshot --window-size=412,732 https://www.chromestatus.com/
سيؤدي تشغيل Chrome باستخدام العلامة --screenshot إلى إنشاء ملف باسم screenshot.png في دليل العمل الحالي. إذا كنت تبحث عن لقطات شاشة بملء الصفحة، فإنّ العملية أكثر تعقيدًا بعض الشيء. هناك منشور رائع على المدوّنة من David Schnurr يقدّم لك كل ما تحتاج إليه. يمكنك الاطّلاع على
استخدام "Chrome بلا واجهة مستخدم رسومية" كأداة مبرمَجة لأخذ لقطات الشاشة .
وضع REPL (حلقة القراءة والتقييم والطباعة)
تشغّل العلامة --repl "Chrome بلا واجهة مستخدم رسومية" في وضع يمكنك فيه تقييم تعابير JavaScript في المتصفّح، مباشرةً من سطر الأوامر:
$ chrome --headless --disable-gpu --repl --crash-dumps-dir=./tmp https://www.chromestatus.com/
[0608/112805.245285:INFO:headless_shell.cc(278)] Type a Javascript expression to evaluate or "quit" to exit.
>>> location.href
{"result":{"type":"string","value":"https://www.chromestatus.com/features"}}
>>> quit
$
كيف يمكنني تصحيح أخطاء Chrome بدون واجهة مستخدم متصفّح؟
عند تشغيل Chrome باستخدام --remote-debugging-port=9222، يبدأ تشغيل مثيل
مع تفعيل بروتوكول "أدوات مطوّري البرامج". يُستخدم البروتوكول للتواصل مع Chrome وتشغيل مثيل المتصفّح بلا واجهة مستخدم رسومية. وهو أيضًا ما تستخدمه أدوات مثل Sublime وVS Code وNode لتصحيح أخطاء تطبيق عن بُعد. #synergy
بما أنّه ليس لديك واجهة مستخدم متصفّح للاطّلاع على الصفحة، انتقِل إلى http://localhost:9222 في متصفّح آخر للتأكّد من أنّ كل شيء يعمل بشكلٍ سليم. ستظهر لك قائمة بالصفحات التي يمكن فحصها، ويمكنك النقر عليها والاطّلاع على ما يعرضه "Chrome بلا واجهة مستخدم رسومية":
من هنا، يمكنك استخدام ميزات "أدوات مطوّري البرامج" المألوفة لفحص الصفحة وتصحيح أخطائها وتعديلها كما تفعل عادةً. إذا كنت تستخدم "Chrome بلا واجهة مستخدم رسومية" بطريقة آلية، فإنّ هذه الصفحة هي أيضًا أداة قوية لتصحيح الأخطاء من أجل الاطّلاع على جميع أوامر بروتوكول "أدوات مطوّري البرامج" الأولية التي يتم إرسالها عبر الشبكة للتواصل مع المتصفّح.
الاستخدام بطريقة آلية (Node)
محرك العرائس
Puppeteer هي مكتبة Node طوّرها فريق Chrome. توفّر واجهة برمجة تطبيقات عالية المستوى للتحكّم في Chrome بلا واجهة مستخدم رسومية (أو واجهة كاملة). وهي مشابهة لمكتبات الاختبارات المبرمَجة الأخرى، مثل Phantom وNightmareJS، ولكنّها تعمل فقط مع أحدث إصدارات Chrome.
يمكن استخدام Puppeteer، من بين أمور أخرى، لأخذ لقطات شاشة وإنشاء ملفات PDF والتنقّل بين الصفحات وجلب معلومات عنها بسهولة. أنصحك باستخدام المكتبة إذا كنت تريد برمجة اختبارات المتصفّح بسرعة. فهي تخفي تعقيدات بروتوكول "أدوات مطوّري البرامج" وتتولى المهام المتكرّرة، مثل تشغيل مثيل تصحيح الأخطاء من Chrome.
لتثبيت المكتبة، يُرجى اتّباع الخطوات التالية:
npm i --save puppeteer
مثال : طباعة وكيل المستخدم
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch();
console.log(await browser.version());
await browser.close();
})();
مثال : أخذ لقطة شاشة للصفحة
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.chromestatus.com', {waitUntil: 'networkidle2'});
await page.pdf({path: 'page.pdf', format: 'A4'});
await browser.close();
})();
يمكنك الاطّلاع على مستندات Puppeteer لمعرفة المزيد عن واجهة برمجة التطبيقات الكاملة.
مكتبة CRI
chrome-remote-interface هي مكتبة منخفضة المستوى مقارنةً بواجهة برمجة التطبيقات في Puppeteer. أنصحك باستخدامها إذا كنت تريد استخدام بروتوكول أدوات مطوّري البرامج مباشرةً.
تشغيل Chrome
لا تشغّل chrome-remote-interface متصفّح Chrome، لذا عليك تشغيله بنفسك.
في قسم واجهة سطر الأوامر، بدأنا تشغيل Chrome يدويًا باستخدام
--headless --remote-debugging-port=9222. ومع ذلك، لبرمجة الاختبارات بالكامل، من المحتمل أن تريد إنشاء Chrome من تطبيقك.
إحدى الطرق هي استخدام child_process:
const execFile = require('child_process').execFile;
function launchHeadlessChrome(url, callback) {
// Assuming MacOSx.
const CHROME = '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome';
execFile(CHROME, ['--headless', '--disable-gpu', '--remote-debugging-port=9222', url], callback);
}
launchHeadlessChrome('https://www.chromestatus.com', (err, stdout, stderr) => {
...
});
ولكنّ الأمور تصبح معقّدة إذا كنت تريد حلاً قابلاً للنقل يعمل على أنظمة أساسية متعددة. ما عليك سوى الاطّلاع على المسار الذي تم ترميزه بشكلٍ ثابت إلى Chrome :(
استخدام ChromeLauncher
Lighthouse هي أداة رائعة
لاختبار جودة تطبيقات الويب. تم تطوير وحدة قوية لتشغيل Chrome ضمن Lighthouse، وتم استخراجها الآن لاستخدامها بشكلٍ مستقل.
ستعثر وحدة chrome-launcher NPM
على مكان تثبيت
Chrome، وتُعدّ مثيلاً لتصحيح الأخطاء، وتشغّل المتصفّح، وتوقفه
عند انتهاء برنامجك. وأفضل ما في الأمر أنّه يعمل من عدّة منصات بفضل Node.
بشكلٍ تلقائي، سيحاول chrome-launcher تشغيل Chrome Canary (إذا كان مثبّتًا)، ولكن يمكنك تغيير ذلك لاختيار Chrome الذي تريد استخدامه يدويًا. لاستخدام هذه الوحدة، عليك أولاً تثبيتها من npm:
npm i --save chrome-launcher
مثال : استخدام chrome-launcher لتشغيل "Chrome بلا واجهة مستغل رسومية"
const chromeLauncher = require('chrome-launcher');
// Optional: set logging level of launcher to see its output.
// Install it using: npm i --save lighthouse-logger
// const log = require('lighthouse-logger');
// log.setLevel('info');
/**
* Launches a debugging instance of Chrome.
* @param {boolean=} headless True (default) launches Chrome in headless mode.
* False launches a full version of Chrome.
* @return {Promise<ChromeLauncher>}
*/
function launchChrome(headless=true) {
return chromeLauncher.launch({
// port: 9222, // Uncomment to force a specific port of your choice.
chromeFlags: [
'--window-size=412,732',
'--disable-gpu',
headless ? '--headless' : ''
]
});
}
launchChrome().then(chrome => {
console.log(`Chrome debuggable on port: ${chrome.port}`);
...
// chrome.kill();
});
لا يؤدي تشغيل هذا النص البرمجي إلى تنفيذ الكثير من الإجراءات، ولكن من المفترض أن يظهر لك مثيل من Chrome في "إدارة المهام" تم تحميل about:blank فيه. تذكَّر أنّه لن تكون هناك أي واجهة مستخدم متصفّح. نحن نستخدم "Chrome بلا واجهة مستخدم رسومية".
للتحكّم في المتصفّح، نحتاج إلى بروتوكول "أدوات مطوّري البرامج".
استرداد معلومات عن الصفحة
لتثبيت المكتبة، يُرجى اتّباع الخطوات التالية:
npm i --save chrome-remote-interface
أمثلة
مثال : طباعة وكيل المستخدم
const CDP = require('chrome-remote-interface');
...
launchChrome().then(async chrome => {
const version = await CDP.Version({port: chrome.port});
console.log(version['User-Agent']);
});
يؤدي ذلك إلى ظهور نص مشابه لما يلي: HeadlessChrome/60.0.3082.0
مثال : التحقّق مما إذا كان الموقع الإلكتروني يتضمّن بيان تطبيق ويب
const CDP = require('chrome-remote-interface');
...
(async function() {
const chrome = await launchChrome();
const protocol = await CDP({port: chrome.port});
// Extract the DevTools protocol domains we need and enable them.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const {Page} = protocol;
await Page.enable();
Page.navigate({url: 'https://www.chromestatus.com/'});
// Wait for window.onload before doing stuff.
Page.loadEventFired(async () => {
const manifest = await Page.getAppManifest();
if (manifest.url) {
console.log('Manifest: ' + manifest.url);
console.log(manifest.data);
} else {
console.log('Site has no app manifest');
}
protocol.close();
chrome.kill(); // Kill Chrome.
});
})();
مثال : استخراج <title> للصفحة باستخدام واجهات برمجة تطبيقات نموذج العناصر في المستند
const CDP = require('chrome-remote-interface');
...
(async function() {
const chrome = await launchChrome();
const protocol = await CDP({port: chrome.port});
// Extract the DevTools protocol domains we need and enable them.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const {Page, Runtime} = protocol;
await Promise.all([Page.enable(), Runtime.enable()]);
Page.navigate({url: 'https://www.chromestatus.com/'});
// Wait for window.onload before doing stuff.
Page.loadEventFired(async () => {
const js = "document.querySelector('title').textContent";
// Evaluate the JS expression in the page.
const result = await Runtime.evaluate({expression: js});
console.log('Title of page: ' + result.result.value);
protocol.close();
chrome.kill(); // Kill Chrome.
});
})();
استخدام Selenium وWebDriver وChromeDriver
في الوقت الحالي، يفتح Selenium مثيلاً كاملاً من Chrome. بعبارة أخرى، هو حلّ مبرمَج ولكنّه ليس "بلا واجهة مستخدم رسومية" تمامًا. ومع ذلك، يمكن إعداد Selenium لتشغيل "Chrome بلا واجهة مستخدم رسومية" مع القليل من العمل. أنصحك بالاطّلاع على تشغيل Selenium باستخدام "Chrome بلا واجهة مستخدم رسومية" إذا كنت تريد التعليمات الكاملة حول كيفية إعداد كل شيء بنفسك، ولكنّني أدرجت بعض الأمثلة أدناه لمساعدتك في البدء.
استخدام ChromeDriver
ChromeDriver 2.32 يستخدم متصفّح Chrome 61 ويعمل بشكلٍ جيد مع "Chrome بلا واجهة مستخدم رسومية".
لتثبيت البرنامج، يُرجى اتّباع الخطوات التالية:
npm i --save-dev selenium-webdriver chromedriver
مثال:
const fs = require('fs');
const webdriver = require('selenium-webdriver');
const chromedriver = require('chromedriver');
const chromeCapabilities = webdriver.Capabilities.chrome();
chromeCapabilities.set('chromeOptions', {args: ['--headless']});
const driver = new webdriver.Builder()
.forBrowser('chrome')
.withCapabilities(chromeCapabilities)
.build();
// Navigate to google.com, enter a search.
driver.get('https://www.google.com/');
driver.findElement({name: 'q'}).sendKeys('webdriver');
driver.findElement({name: 'btnG'}).click();
driver.wait(webdriver.until.titleIs('webdriver - Google Search'), 1000);
// Take screenshot of results page. Save to disk.
driver.takeScreenshot().then(base64png => {
fs.writeFileSync('screenshot.png', new Buffer(base64png, 'base64'));
});
driver.quit();
استخدام WebDriverIO
WebDriverIO هي واجهة برمجة تطبيقات أعلى مستوى فوق Selenium WebDriver.
لتثبيت البرنامج، يُرجى اتّباع الخطوات التالية:
npm i --save-dev webdriverio chromedriver
مثال: فلترة ميزات CSS على chromestatus.com
const webdriverio = require('webdriverio');
const chromedriver = require('chromedriver');
const PORT = 9515;
chromedriver.start([
'--url-base=wd/hub',
`--port=${PORT}`,
'--verbose'
]);
(async () => {
const opts = {
port: PORT,
desiredCapabilities: {
browserName: 'chrome',
chromeOptions: {args: ['--headless']}
}
};
const browser = webdriverio.remote(opts).init();
await browser.url('https://www.chromestatus.com/features');
const title = await browser.getTitle();
console.log(`Title: ${title}`);
await browser.waitForText('.num-features', 3000);
let numFeatures = await browser.getText('.num-features');
console.log(`Chrome has ${numFeatures} total features`);
await browser.setValue('input[type="search"]', 'CSS');
console.log('Filtering features...');
await browser.pause(1000);
numFeatures = await browser.getText('.num-features');
console.log(`Chrome has ${numFeatures} CSS features`);
const buffer = await browser.saveScreenshot('screenshot.png');
console.log('Saved screenshot...');
chromedriver.stop();
browser.end();
})();
تنزيل الإصدار القديم من "Chrome بلا واجهة مستخدم رسومية" باسم chrome-headless-shell
بدءًا من الإصدار 112 من Chrome، يتوفّر "وضع التشغيل بلا واجهة مستخدم رسومية" الجديد من Chrome (--headless=new). يتيح هذا الوضع للمطوّرين تشغيل Chrome نفسه بدلاً من ملف ثنائي منفصل في بيئة غير مراقَبة بدون أي واجهة مستخدم مرئية، وهو أمر مفيد لحالات استخدام الاختبارات والتشغيل الآلي.
هناك حالات استخدام مختلفة لواجهة "Chrome بلا واجهة مستخدم رسومية" القديمة و"وضع التشغيل بلا واجهة مستخدم رسومية" الجديد:
- واجهة "Chrome بلا واجهة مستخدم رسومية" القديمة هي برنامج تضمين خفيف الوزن حول وحدة
//contentفي Chromium، وبالتالي فإنّ عدد التبعيات أقل بكثير. على وجه التحديد، لا تتطلّب هذه الواجهة X11/Wayland وD-Bus، وهي في بعض النواحي أكثر فعالية من متصفّح Chrome الكامل. ويجعل ذلك هذه الواجهة مناسبة لحالات استخدام مثل أخذ لقطات الشاشة المبرمَجة أو جمع بيانات الويب. - من ناحية أخرى، فإنّ "وضع التشغيل بلا واجهة مستخدم رسومية" الجديد هو متصفّح Chrome الحقيقي، وبالتالي فهو أكثر موثوقية وأصالة ويقدّم المزيد من الميزات. ويجعله ذلك أكثر ملاءمةً لاختبارات تطبيقات الويب الشاملة أو اختبارات إضافات المتصفّح عالية الدقة.
بعبارة أخرى، هناك مقايضة بين الأداء والأصالة. ما هو "وضع التشغيل بلا واجهة مستخدم رسومية" الأنسب لك؟ يعتمد ذلك على حالة استخدامك.
قد يرغب المطوّرون والمختبِرون الذين لا يحتاجون إلى وظائف Chrome الكاملة لحالات استخدام التشغيل الآلي في استخدام الإصدار القديم من "Chrome بلا واجهة مستخدم رسومية". وفي الحالات الأخرى، من المرجّح أنّ "وضع التشغيل بلا واجهة مستخدم رسومية" الجديد هو الخيار الأفضل.
لضمان استمرار توفّر الخيار بين هذين الوضعَين للمطوّرين والمختبِرين، يسرّنا الإعلان عن أنّ الإصدار القديم من "Chrome بلا واجهة مستخدم رسومية" يتوفّر الآن كملف ثنائي مستقل chrome-headless-shell. يتم إنشاء هذه الملفات الثنائية الجديدة chrome-headless-shell لكل إصدار من Chrome يظهر للمستخدمين، وتتوفّر للتنزيل من خلال البنية الأساسية لـ Chrome for Testing بدءًا من Chrome 120.
كيف يمكنني الحصول على الملفات الثنائية chrome-headless-shell؟
كما هو الحال مع الملفات الثنائية الأخرى في Chrome for Testing، أسهل طريقة لتنزيل chrome-headless-shell لنظامك الأساسي هي باستخدام أداة سطر الأوامر @puppeteer/browsers، التي تتوفّر باستخدام npm. إليك بعض الأمثلة:
# Download the latest available `chrome-headless-shell` binary corresponding to the Stable channel.
npx @puppeteer/browsers install chrome-headless-shell@stable
# Download a specific `chrome-headless-shell` version.
npx @puppeteer/browsers install chrome-headless-shell@120.0.6098.0
إذا كنت تفضّل إنشاء النصوص البرمجية المبرمَجة الخاصة بك لتنزيل الملفات الثنائية chrome-headless-shell، فإنّنا نوفّر لك كل ما تحتاج إليه. يقدّم Chrome for Testing نقاط نهاية JSON API تتضمّن أحدث الإصدارات المتاحة لكل قناة إصدار من Chrome (الإصدارات الثابتة والإصدارات التجريبية وقناة إصدارات المطوّرين و"إصدار Canary"). للحصول على نظرة عامة سريعة على الحالة الأخيرة، يُرجى الاطّلاع على لوحة بيانات إتاحة Chrome for Testing.
الملاحظات
نتطلّع إلى تلقّي ملاحظاتك عن chrome-headless-shell. إذا واجهتك أي مشاكل، يمكنك الإبلاغ عنها.
موارد أخرى
في ما يلي بعض الموارد المفيدة لمساعدتك في البدء:
مستندات Google
- عارض بروتوكول "أدوات مطوّري البرامج": مستندات مرجع واجهة برمجة التطبيقات
الأدوات
- chrome-remote-interface: وحدة Node التي تضمّ بروتوكول "أدوات مطوّري البرامج"
- Lighthouse: أداة مبرمَجة لاختبار جودة تطبيقات الويب، وتستخدم البروتوكول بشكلٍ كبير
- chrome-launcher: وحدة Node لتشغيل Chrome، جاهزة للتشغيل الآلي
العروض التوضيحية
- "الويب بلا واجهة مستخدم رسومية" - منشور رائع على مدوّنة Paul Kinlan حول استخدام "Chrome بلا واجهة مستخدم رسومية" مع api.ai.
الأسئلة الشائعة
هل أحتاج إلى العلامة --disable-gpu؟
فقط على نظام التشغيل Windows. لم تعُد الأنظمة الأساسية الأخرى تتطلّب ذلك. العلامة --disable-gpu هي حلّ مؤقت لبعض الأخطاء. لن تحتاج إلى هذه العلامة في الإصدارات المستقبلية من Chrome. يمكنك الاطّلاع على crbug.com/737678
لمزيد من المعلومات.
هل ما زلت بحاجة إلى Xvfb؟
لا، لا يستخدم "Chrome بلا واجهة مستخدم رسومية" نافذة، لذا لم يعُد هناك حاجة إلى خادم عرض مثل Xvfb. يمكنك تشغيل اختباراتك المبرمَجة بدون ذلك.
ما هو Xvfb؟ Xvfb هو خادم عرض في الذاكرة للأنظمة الشبيهة بنظام Unix، ويتيح لك تشغيل التطبيقات الرسومية (مثل Chrome) بدون شاشة فعلية متصلة. يستخدم العديد من الأشخاص Xvfb لتشغيل الإصدارات السابقة من Chrome لإجراء اختبارات "بلا واجهة مستخدم رسومية".
كيف يمكنني إنشاء حاوية Docker تشغّل "Chrome بلا واجهة مستخدم رسومية"؟
يمكنك الاطّلاع على lighthouse-ci. يتضمّن هذا البرنامج مثالاً على ملف Dockerfile يستخدم node:8-slim كصورة أساسية، ويُثبِّت Lighthouse ويشغّله على App Engine Flex.
هل يمكنني استخدام هذه الميزة مع Selenium أو WebDriver أو ChromeDriver؟
نعم. يمكنك الاطّلاع على استخدام Selenium وWebDriver وChromeDriver.
ما العلاقة بين هذه الميزة وPhantomJS؟
"Chrome بلا واجهة مستخدم رسومية" مشابه لأدوات مثل PhantomJS. يمكن استخدام كلتا الأداتَين للاختبارات المبرمَجة في بيئة بلا واجهة مستخدم رسومية. الفرق الرئيسي بينهما هو أنّ Phantom يستخدم إصدارًا قديمًا من WebKit كمحرّك عرض، بينما يستخدم "Chrome بلا واجهة مستخدم رسومية" أحدث إصدار من Blink.
في الوقت الحالي، يقدّم Phantom أيضًا واجهة برمجة تطبيقات أعلى مستوى من بروتوكول "أدوات مطوّري البرامج".
أين يمكنني الإبلاغ عن الأخطاء؟
للإبلاغ عن الأخطاء في "Chrome بلا واجهة مستخدم رسومية"، يمكنك تسجيلها على crbug.com.
للإبلاغ عن الأخطاء في بروتوكول "أدوات مطوّري البرامج"، يمكنك تسجيلها على github.com/ChromeDevTools/devtools-protocol.