TL;DR
Chrome بلا واجهة مستخدم رسومية يشحن في Chrome 59. وهي طريقة لتشغيل متصفِّح Chrome في بيئة بلا واجهة مستخدم رسومية. في الأساس، الجري Chrome بدون Chrome! فهو يجمع جميع ميزات الأنظمة الأساسية للويب الحديثة بواسطة Chromium ومحرك عرض Blink إلى سطر الأوامر.
لماذا يعتبر ذلك مفيدًا؟
المتصفح بلا واجهة مستخدم رسومية هو أداة رائعة للاختبارات الآلية وبيئات الخادم التي لا تحتاج إلى هيكل واجهة مستخدم مرئي. على سبيل المثال، قد ترغب في إجراء بعض الاختبارات على صفحة ويب حقيقية، أو إنشاء ملف PDF، أو مجرد فحص كيفية عرض المتصفح لعنوان URL.
بداية بلا واجهة مستخدم رسومية (CLI)
أسهل طريقة لبدء استخدام وضع التشغيل بلا واجهة مستخدم رسومية هي فتح برنامج Chrome الثنائي.
من سطر الأوامر. إذا كان لديك الإصدار 59 من Chrome أو الإصدارات الأحدث، يمكنك بدء 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 بلا واجهة مستخدم رسومية. هناك بعض علامات سطر الأوامر المفيدة. لأداء المهام الشائعة.
طباعة نموذج العناصر في المستند (DOM)
يطبع علم --dump-dom
بـ document.body.innerHTML
إلى تنسيق stdout:
chrome --headless --disable-gpu --dump-dom https://www.chromestatus.com/
إنشاء ملف PDF
تنشئ العلامة --print-to-pdf
ملف PDF للصفحة:
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/
سيؤدي تنفيذ العمل باستخدام --screenshot
إلى إنشاء ملف باسم screenshot.png
في
دليل العمل الحالي. للحصول على لقطات شاشة كاملة للصفحة
أكثر مشاركة. هناك مدونة رائعة
مشاركة من ديفيد شنير التي ستساعدك. إتمام الدفع
استخدام Chrome بلا واجهة مستخدم رسومية كأداة مبرمَجة لأخذ لقطات الشاشة .
وضع REPL (تكرار القراءة والتقييم)
تعمل العلامة --repl
بلا واجهة مستخدم رسومية في وضع يمكنك من خلاله تقييم تعبيرات 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
.
في متصفح آخر للتأكد من أن كل شيء يعمل. ستظهر لك قائمة
الصفحات القابلة للفحص التي يمكنك فيها النقر عليها ومعرفة ما تعرضه "بلا واجهة مستخدم رسومية":
من هنا، يمكنك استخدام ميزات "أدوات مطوّري البرامج" المألوفة لفحص المحتوى وتصحيح الأخطاء وضبط إعداداته الصفحة كما تفعل عادةً. إذا كنت تستخدم بلا واجهة مستخدم رسومية آليًا، أداة فعّالة لتصحيح الأخطاء والاستجابة لعرض جميع بروتوكولات أدوات مطوّري البرامج عبر السلك، والتواصل مع المتصفح.
استخدام (عقدة) آليًا
محرك العرائس
Puppeteer هو مكتبة عُقد التي طوّرها فريق 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-عن بُعد بتشغيل 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 ويتم استخراجه الآن للاستخدام المستقل.
وحدة NPM chrome-launcher
سيتم العثور على مكان
تثبيت Chrome وإعداد مثيل تصحيح الأخطاء وبدء تشغيل المتصفّح وإيقافه
عند الانتهاء من البرنامج. أفضل جزء هو أنها تعمل عبر أنظمة أساسية مختلفة بفضل
عقدة!
بشكل تلقائي، سيحاول chrome-launcher
تشغيل Chrome Canary (إذا كان
مثبت)، ولكن يمكنك تغيير ذلك لتحديد Chrome الذي تريد استخدامه يدويًا. إلى
استخدمه، قم بالتثبيت أولاً من npm:
npm i --save chrome-launcher
مثال: استخدام chrome-launcher
لتشغيل النسخة بلا واجهة مستخدم رسومية
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
. تذكر، هناك
لن تكون أي واجهة مستخدم للمتصفح. نحن بلا واجهة مستخدم رسومية.
يجب استخدام بروتوكول "أدوات مطوري البرامج" للتحكّم في المتصفّح.
جارٍ استرداد معلومات حول الصفحة
لنبدأ في تثبيت المكتبة:
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>
للصفحة باستخدام واجهات برمجة تطبيقات DOM.
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
في الوقت الحالي، يفتح سيلينيوم مثيلاً كاملاً من Chrome. بعبارة أخرى، إنها تلقائيًا ولكن ليس بلا واجهة مستخدم رسومية تمامًا. ومع ذلك، يمكن أن يكون السيلينيوم مهيأ لتشغيل Chrome بلا واجهة مستخدم رسومية مع قليل من العمل. أنصح به تشغيل السيلينيوم باستخدام متصفِّح 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();
})();
موارد أخرى
وفي ما يلي بعض الموارد المفيدة لمساعدتك على البدء:
مستندات Google
- عارض بروتوكول أدوات مطوّري البرامج - المستندات المرجعية لواجهة برمجة التطبيقات
الأدوات
- chrome-remote-interface - العقدة التي تتضمّن بروتوكول "أدوات مطوّري البرامج"
- Lighthouse - أداة آلية للاختبار وجودة تطبيق الويب تستخدم البروتوكول بشكل مكثّف
- chrome-launcher - وحدة العقدة الخاصة بتشغيل Chrome، وهو جاهز للتشغيل الآلي
إصدارات تجريبية
- الويب بلا واجهة مستخدم رسومية" - المدونة الرائعة لبول كينلان مشاركة حول استخدام ميزة "بلا واجهة مستخدم رسومية" باستخدام api.ai.
الأسئلة الشائعة
هل أحتاج إلى علامة --disable-gpu
؟
على نظام التشغيل Windows فقط. لم تعُد الأنظمة الأساسية الأخرى تتطلب هذا الإجراء. العلامة --disable-gpu
هي
أو حل مؤقت لبعض الأخطاء. لن تحتاج إلى هذه العلامة في الإصدارات المستقبلية من
Chrome. لمزيد من المعلومات، يمكنك الاطّلاع على crbug.com/737678.
لمزيد من المعلومات.
هل ما زلت بحاجة إلى Xvfb؟
لا، إذ لا يستخدم Chrome بلا واجهة مستخدم رسومية نافذة، ولذلك لا يستخدم خادم عرض مثل Xvfb لم تعد هناك حاجة إليه. يمكنك إجراء اختباراتك المبرمَجة بدونها بنجاح.
ما هو Xvfb؟ Xvfb هو خادم عرض في الذاكرة للأنظمة الشبيهة بـ Unix ويتيح لك لتشغيل تطبيقات رسومية (مثل Chrome) بدون شاشة عرض فعلية. يستخدم العديد من الأشخاص Xvfb لتشغيل إصدارات سابقة من Chrome لتنفيذ "بلا واجهة مستخدم رسومية" اختبار الفرضية.
كيف يمكنني إنشاء حاوية Docker تشغّل Chrome بلا واجهة مستخدم رسومية؟
اطّلع على منارة-ci. تحتوي على
مثال على ملف Dock
التي تستخدم 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.