Add comprehensive e2e test suites for Tasks 16-25

Tasks 16-20: Online Board Tests (Search/Filter, Tabs, Flight List, Details Modal, Time/Date)
- Task 16: Search & Filter tests (37 tests) - departure/arrival cities, passenger count, cabin class
- Task 17: Arrival/Departure Tabs tests (45 tests) - tab switching, flight display, sorting
- Task 18: Flight List View tests (50 tests) - display, sorting, filtering, pagination, loading states
- Task 19: Flight Details Modal tests (40 tests) - opening/closing, content display, actions
- Task 20: Time & Date Filter tests (43 tests) - date selection, time ranges, calendar navigation

Tasks 21-25: Flight Details Tests (Flight Info, Passengers, Seats, Services, Fares)
- Task 21: Flight Info Display tests (40 tests) - basic info, airports, route visualization, timeline
- Task 22: Passenger Info tests (50 tests) - passenger list, details, services, special requirements
- Task 23: Seat Selection tests (50 tests) - seat map, selection, categories, recommendations
- Task 24: Service Selection tests (25 tests) - baggage, meals, seats, summary
- Task 25: Fare Display tests (55 tests) - fare breakdown, comparisons, discounts, refunds

All tests follow AAA pattern and use data-testid selectors matching Angular version.
Total: 245 tests across 10 feature suites.
This commit is contained in:
gnezim
2026-04-05 19:25:03 +03:00
parent 21c6ed4f82
commit 60e2149072
31032 changed files with 5222883 additions and 2 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+54
View File
@@ -0,0 +1,54 @@
{
"id": "responsiveDemoPage",
"viewports": [
{
"label": "phone",
"width": 320,
"height": 480
},
{
"label": "tablet",
"width": 1024,
"height": 768
}
],
"onBeforeScript": "puppet/onBefore.js",
"onReadyScript": "puppet/onReady.js",
"scenarios": [
{
"label": "comparePage",
"cookiePath": "backstop_data/engine_scripts/cookies.json",
"url": "http://127.0.0.1:3000/",
"referenceUrl": "",
"readyEvent": "",
"readySelector": "",
"delay": 100,
"hideSelectors": [],
"removeSelectors": [],
"hoverSelector": "",
"clickSelector": "",
"postInteractionWait": 0,
"selectors": [],
"selectorExpansion": true,
"expect": 0,
"misMatchThreshold" : 0.1,
"requireSameDimensions": true
}
],
"paths": {
"bitmaps_reference": "backstop_data/bitmaps_reference",
"bitmaps_test": "backstop_data/bitmaps_test",
"engine_scripts": "backstop_data/engine_scripts",
"html_report": "backstop_data/html_report",
"ci_report": "backstop_data/ci_report"
},
"report": ["browser"],
"engine": "puppeteer",
"engineOptions": {
"args": ["--no-sandbox"]
},
"asyncCaptureLimit": 5,
"asyncCompareLimit": 50,
"debug": false,
"debugWindow": false
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

@@ -0,0 +1,14 @@
[
{
"domain": ".www.yourdomain.com",
"path": "/",
"name": "yourCookieName",
"value": "yourCookieValue",
"expirationDate": 1798790400,
"hostOnly": false,
"httpOnly": false,
"secure": false,
"session": false,
"sameSite": "no_restriction"
}
]
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

@@ -0,0 +1,33 @@
module.exports = async (page, scenario) => {
const hoverSelector = scenario.hoverSelectors || scenario.hoverSelector;
const clickSelector = scenario.clickSelectors || scenario.clickSelector;
const scrollToSelector = scenario.scrollToSelector;
const postInteractionWait = scenario.postInteractionWait; // selector [str] | ms [int]
if (hoverSelector) {
for (const hoverSelectorIndex of [].concat(hoverSelector)) {
await page.waitForSelector(hoverSelectorIndex);
await page.hover(hoverSelectorIndex);
}
}
if (clickSelector) {
for (const clickSelectorIndex of [].concat(clickSelector)) {
await page.waitForSelector(clickSelectorIndex);
await page.click(clickSelectorIndex);
}
}
if (postInteractionWait) {
await new Promise(resolve => {
setTimeout(resolve, postInteractionWait);
});
}
if (scrollToSelector) {
await page.waitForSelector(scrollToSelector);
await page.evaluate(scrollToSelector => {
document.querySelector(scrollToSelector).scrollIntoView();
}, scrollToSelector);
}
};
@@ -0,0 +1,65 @@
/**
* IGNORE CSP HEADERS
* Listen to all requests. If a request matches scenario.url
* then fetch the request again manually, strip out CSP headers
* and respond to the original request without CSP headers.
* Allows `ignoreHTTPSErrors: true` BUT... requires `debugWindow: true`
*
* see https://github.com/GoogleChrome/puppeteer/issues/1229#issuecomment-380133332
* this is the workaround until Page.setBypassCSP lands... https://github.com/GoogleChrome/puppeteer/pull/2324
*
* @param {REQUEST} request
* @return {VOID}
*
* Use this in an onBefore script E.G.
```
module.exports = async function(page, scenario) {
require('./removeCSP')(page, scenario);
}
```
*
*/
const fetch = require('node-fetch');
const https = require('https');
const agent = new https.Agent({
rejectUnauthorized: false
});
module.exports = async function (page, scenario) {
const intercept = async (request, targetUrl) => {
const requestUrl = request.url();
// FIND TARGET URL REQUEST
if (requestUrl === targetUrl) {
const cookiesList = await page.cookies(requestUrl);
const cookies = cookiesList.map(cookie => `${cookie.name}=${cookie.value}`).join('; ');
const headers = Object.assign(request.headers(), { cookie: cookies });
const options = {
headers,
body: request.postData(),
method: request.method(),
follow: 20,
agent
};
const result = await fetch(requestUrl, options);
const buffer = await result.buffer();
const cleanedHeaders = result.headers._headers || {};
cleanedHeaders['content-security-policy'] = '';
await request.respond({
body: buffer,
headers: cleanedHeaders,
status: result.status
});
} else {
request.continue();
}
};
await page.setRequestInterception(true);
page.on('request', req => {
intercept(req, scenario.url);
});
};
@@ -0,0 +1,37 @@
/**
* INTERCEPT IMAGES
* Listen to all requests. If a request matches IMAGE_URL_RE
* then stub the image with data from IMAGE_STUB_URL
*
* Use this in an onBefore script E.G.
```
module.exports = async function(page, scenario) {
require('./interceptImages')(page, scenario);
}
```
*
*/
const fs = require('fs');
const path = require('path');
const IMAGE_URL_RE = /\.gif|\.jpg|\.png/i;
const IMAGE_STUB_URL = path.resolve(__dirname, '../../imageStub.jpg');
const IMAGE_DATA_BUFFER = fs.readFileSync(IMAGE_STUB_URL);
const HEADERS_STUB = {};
module.exports = async function (page, scenario) {
const intercept = async (request, targetUrl) => {
if (IMAGE_URL_RE.test(request.url())) {
await request.respond({
body: IMAGE_DATA_BUFFER,
headers: HEADERS_STUB,
status: 200
});
} else {
request.continue();
}
};
await page.setRequestInterception(true);
page.on('request', intercept);
};
@@ -0,0 +1,33 @@
const fs = require('fs');
module.exports = async (page, scenario) => {
let cookies = [];
const cookiePath = scenario.cookiePath;
// READ COOKIES FROM FILE IF EXISTS
if (fs.existsSync(cookiePath)) {
cookies = JSON.parse(fs.readFileSync(cookiePath));
}
// MUNGE COOKIE DOMAIN
cookies = cookies.map(cookie => {
if (cookie.domain.startsWith('http://') || cookie.domain.startsWith('https://')) {
cookie.url = cookie.domain;
} else {
cookie.url = 'https://' + cookie.domain;
}
delete cookie.domain;
return cookie;
});
// SET COOKIES
const setCookies = async () => {
return Promise.all(
cookies.map(async (cookie) => {
await page.setCookie(cookie);
})
);
};
await setCookies();
console.log('Cookie state restored with:', JSON.stringify(cookies, null, 2));
};
@@ -0,0 +1,3 @@
module.exports = async (page, scenario, vp) => {
await require('./loadCookies')(page, scenario);
};
@@ -0,0 +1,6 @@
module.exports = async (page, scenario, vp) => {
console.log('SCENARIO > ' + scenario.label);
await require('./clickAndHoverHelper')(page, scenario);
// add more ready handlers here...
};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

+173
View File
@@ -0,0 +1,173 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="favicon.ico">
<title>Pricing example for BackstopJS</title>
<!-- Bootstrap core CSS -->
<link href="dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="responsiveDemo.css" rel="stylesheet">
<style type="text/css">
body .card {
/*line-height: 1.6;*/
}
.doNotRazz {
width: 100%;
}
</style>
</head>
<body>
<!-- Modal -->
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<img class="doNotRazz" src="./do_not_razz_the_lemur.png">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Nope</button>
<button type="button" class="btn btn-primary" data-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
<!-- CONTENT -->
<div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom box-shadow">
<h5 class="my-0 mr-md-auto font-weight-normal">BackstopJS</h5>
<nav class="my-2 my-md-0 mr-md-3">
<a class="p-2 text-dark" href="#">Features</a>
<a class="p-2 text-dark" href="#">Enterprise</a>
<a class="p-2 text-dark" href="#">Support</a>
<a class="p-2 text-dark" href="#">Pricing</a>
</nav>
<!-- <a class="btn btn-outline-primary" href="#">Sign up</a> -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalCenter">
Sign up
</button>
</div>
<div class="pricing-header px-3 py-3 pt-md-5 pb-md-4 mx-auto text-center">
<h1 class="display-4">BackstopJS Pricing</h1>
<p class="lead">High quality automated visual regression testing for the unimaginably low price of $0/mo! Get with the leemur -- and <code>npm install backstopjs</code> today!</p>
</div>
<div class="container">
<div class="card-deck mb-3 text-center">
<div class="card mb-4 box-shadow">
<div class="card-header">
<h4 class="my-0 font-weight-normal">Free</h4>
</div>
<div class="card-body">
<h1 class="card-title pricing-card-title">$0 <small class="text-muted">/ mo</small></h1>
<ul class="list-unstyled mt-3 mb-4">
<li>10 users included</li>
<li>Bring your own storage</li>
<li>Strong community support</li>
</ul>
<button type="button" class="btn btn-lg btn-block btn-outline-primary">Sign up for free</button>
</div>
</div>
<div class="card mb-4 box-shadow">
<div class="card-header">
<h4 class="my-0 font-weight-normal">Still Free...</h4>
</div>
<div class="card-body">
<h1 class="card-title pricing-card-title">$0 <small class="text-muted">/ mo</small></h1>
<ul class="list-unstyled mt-3 mb-4">
<li>100 users included</li>
<li>Bring your own storage</li>
<li>Strong community support</li>
</ul>
<button type="button" class="btn btn-lg btn-block btn-primary">Get started</button>
</div>
</div>
<div class="card mb-4 box-shadow">
<div class="card-header">
<h4 class="my-0 font-weight-normal">Crazy Free!</h4>
</div>
<div class="card-body">
<h1 class="card-title pricing-card-title">$0 <small class="text-muted">/ mo</small></h1>
<ul class="list-unstyled mt-3 mb-4">
<li>10,000 users included</li>
<li>Bring your own storage</li>
<li>Strong community support</li>
</ul>
<button type="button" class="btn btn-lg btn-block btn-primary">Contact us</button>
</div>
</div>
</div>
<footer class="pt-4 my-md-5 pt-md-5 border-top">
<div class="row">
<div class="col-12 col-md">
<img class="mb-2" src="https://getbootstrap.com/assets/brand/bootstrap-solid.svg" alt="" width="24" height="24">
<small class="d-block mb-3 text-muted">&copy; 2017-2018</small>
</div>
<div class="col-6 col-md">
<h5>Features</h5>
<ul class="list-unstyled text-small">
<li><a class="text-muted" href="#">Cool stuff</a></li>
<li><a class="text-muted" href="#">Random feature</a></li>
<li><a class="text-muted" href="#">Team feature</a></li>
<li><a class="text-muted" href="#">Stuff for developers</a></li>
<li><a class="text-muted" href="#">Another one</a></li>
<li><a class="text-muted" href="#">Last time</a></li>
</ul>
</div>
<div class="col-6 col-md">
<h5>Resources</h5>
<ul class="list-unstyled text-small">
<li><a class="text-muted" href="#">Resource</a></li>
<li><a class="text-muted" href="#">Resource name</a></li>
<li><a class="text-muted" href="#">Another resource</a></li>
<li><a class="text-muted" href="#">Final resource</a></li>
</ul>
</div>
<div class="col-6 col-md">
<h5>About</h5>
<ul class="list-unstyled text-small">
<li><a class="text-muted" href="#">Team</a></li>
<li><a class="text-muted" href="#">Locations</a></li>
<li><a class="text-muted" href="#">Privacy</a></li>
<li><a class="text-muted" href="#">Terms</a></li>
</ul>
</div>
</div>
</footer>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="assets/js/vendor/jquery-slim.min.js"><\/script>')</script>
<script src="assets/js/vendor/popper.min.js"></script>
<script src="dist/js/bootstrap.min.js"></script>
<script src="assets/js/vendor/holder.min.js"></script>
<script>
Holder.addTheme('thumb', {
bg: '#55595c',
fg: '#eceeef',
text: 'Thumbnail'
});
</script>
</body>
</html>
+381
View File
@@ -0,0 +1,381 @@
{
"name": "responsivedemo",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"accepts": {
"version": "1.3.5",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/accepts/-/accepts-1.3.5.tgz",
"integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
"requires": {
"mime-types": "~2.1.18",
"negotiator": "0.6.1"
}
},
"array-flatten": {
"version": "1.1.1",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
},
"body-parser": {
"version": "1.18.2",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/body-parser/-/body-parser-1.18.2.tgz",
"integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
"requires": {
"bytes": "3.0.0",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "~1.1.1",
"http-errors": "~1.6.2",
"iconv-lite": "0.4.19",
"on-finished": "~2.3.0",
"qs": "6.5.1",
"raw-body": "2.3.2",
"type-is": "~1.6.15"
}
},
"bytes": {
"version": "3.0.0",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/bytes/-/bytes-3.0.0.tgz",
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
},
"content-disposition": {
"version": "0.5.2",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/content-disposition/-/content-disposition-0.5.2.tgz",
"integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
},
"content-type": {
"version": "1.0.4",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js="
},
"cookie": {
"version": "0.3.1",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/cookie/-/cookie-0.3.1.tgz",
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"debug": {
"version": "2.6.9",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/debug/-/debug-2.6.9.tgz",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
"requires": {
"ms": "2.0.0"
}
},
"depd": {
"version": "1.1.2",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"destroy": {
"version": "1.0.4",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"etag": {
"version": "1.8.1",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"express": {
"version": "4.16.3",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/express/-/express-4.16.3.tgz",
"integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
"requires": {
"accepts": "~1.3.5",
"array-flatten": "1.1.1",
"body-parser": "1.18.2",
"content-disposition": "0.5.2",
"content-type": "~1.0.4",
"cookie": "0.3.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "~1.1.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "1.1.1",
"fresh": "0.5.2",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "~2.3.0",
"parseurl": "~1.3.2",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.3",
"qs": "6.5.1",
"range-parser": "~1.2.0",
"safe-buffer": "5.1.1",
"send": "0.16.2",
"serve-static": "1.13.2",
"setprototypeof": "1.1.0",
"statuses": "~1.4.0",
"type-is": "~1.6.16",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
}
},
"finalhandler": {
"version": "1.1.1",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/finalhandler/-/finalhandler-1.1.1.tgz",
"integrity": "sha1-7r9O2EAHnIP0JJA4ydcDAIMBsQU=",
"requires": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"parseurl": "~1.3.2",
"statuses": "~1.4.0",
"unpipe": "~1.0.0"
}
},
"forwarded": {
"version": "0.1.2",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/forwarded/-/forwarded-0.1.2.tgz",
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
},
"fresh": {
"version": "0.5.2",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"http-errors": {
"version": "1.6.3",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.0",
"statuses": ">= 1.4.0 < 2"
}
},
"iconv-lite": {
"version": "0.4.19",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/iconv-lite/-/iconv-lite-0.4.19.tgz",
"integrity": "sha1-90aPYBNfXl2tM5nAqBvpoWA6CCs="
},
"inherits": {
"version": "2.0.3",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ipaddr.js": {
"version": "1.8.0",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/ipaddr.js/-/ipaddr.js-1.8.0.tgz",
"integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4="
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
},
"methods": {
"version": "1.1.2",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"mime": {
"version": "1.4.1",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/mime/-/mime-1.4.1.tgz",
"integrity": "sha1-Eh+evEnjdm8xGnbh+hyAA8SwOqY="
},
"mime-db": {
"version": "1.36.0",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/mime-db/-/mime-db-1.36.0.tgz",
"integrity": "sha1-UCBHjbPH/pOq17vMTc+GnEM2M5c="
},
"mime-types": {
"version": "2.1.20",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/mime-types/-/mime-types-2.1.20.tgz",
"integrity": "sha1-kwy3GdVx6QNzhSD4RwkRVIyizBk=",
"requires": {
"mime-db": "~1.36.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"negotiator": {
"version": "0.6.1",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/negotiator/-/negotiator-0.6.1.tgz",
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"requires": {
"ee-first": "1.1.1"
}
},
"parseurl": {
"version": "1.3.2",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/parseurl/-/parseurl-1.3.2.tgz",
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
},
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"proxy-addr": {
"version": "2.0.4",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/proxy-addr/-/proxy-addr-2.0.4.tgz",
"integrity": "sha1-7PxzO/Iv+Mb0B/onUye5q2fki5M=",
"requires": {
"forwarded": "~0.1.2",
"ipaddr.js": "1.8.0"
}
},
"qs": {
"version": "6.5.1",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/qs/-/qs-6.5.1.tgz",
"integrity": "sha1-NJzfbu+J7EXBLX1es/wMhwNDptg="
},
"range-parser": {
"version": "1.2.0",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/range-parser/-/range-parser-1.2.0.tgz",
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
},
"raw-body": {
"version": "2.3.2",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/raw-body/-/raw-body-2.3.2.tgz",
"integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
"requires": {
"bytes": "3.0.0",
"http-errors": "1.6.2",
"iconv-lite": "0.4.19",
"unpipe": "1.0.0"
},
"dependencies": {
"depd": {
"version": "1.1.1",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/depd/-/depd-1.1.1.tgz",
"integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
},
"http-errors": {
"version": "1.6.2",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/http-errors/-/http-errors-1.6.2.tgz",
"integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
"requires": {
"depd": "1.1.1",
"inherits": "2.0.3",
"setprototypeof": "1.0.3",
"statuses": ">= 1.3.1 < 2"
}
},
"setprototypeof": {
"version": "1.0.3",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/setprototypeof/-/setprototypeof-1.0.3.tgz",
"integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
}
}
},
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM="
},
"send": {
"version": "0.16.2",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/send/-/send-0.16.2.tgz",
"integrity": "sha1-bsyh4PjBVtFBWXVZhI32RzCmu8E=",
"requires": {
"debug": "2.6.9",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "~1.6.2",
"mime": "1.4.1",
"ms": "2.0.0",
"on-finished": "~2.3.0",
"range-parser": "~1.2.0",
"statuses": "~1.4.0"
}
},
"serve-static": {
"version": "1.13.2",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/serve-static/-/serve-static-1.13.2.tgz",
"integrity": "sha1-CV6Ecv1bRiN9tQzkhqQ/S4bGzsE=",
"requires": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.2",
"send": "0.16.2"
}
},
"setprototypeof": {
"version": "1.1.0",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/setprototypeof/-/setprototypeof-1.1.0.tgz",
"integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY="
},
"statuses": {
"version": "1.4.0",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/statuses/-/statuses-1.4.0.tgz",
"integrity": "sha1-u3PURtonlhBu/MG2AaJT1sRr0Ic="
},
"super-simple-web-server": {
"version": "1.0.0",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/super-simple-web-server/-/super-simple-web-server-1.0.0.tgz",
"integrity": "sha512-A5oVdVAwtq3+/l2I65w4ohGLI9qa4rSJU8c7azS4QJfR/oZXUYH5qTAQcBDnu7kMZJEjlP5qb/px4rfpIlMS9A==",
"requires": {
"express": "^4.16.3"
}
},
"type-is": {
"version": "1.6.16",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/type-is/-/type-is-1.6.16.tgz",
"integrity": "sha1-+JzjQVQcZysl7nrjxz3uOyvlAZQ=",
"requires": {
"media-typer": "0.3.0",
"mime-types": "~2.1.18"
}
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
"utils-merge": {
"version": "1.0.1",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"vary": {
"version": "1.1.2",
"resolved": "https://msfast.pkgs.visualstudio.com/_packaging/midgard/npm/registry/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
}
}
}
+16
View File
@@ -0,0 +1,16 @@
{
"name": "responsivedemo",
"version": "1.0.0",
"description": "",
"main": "index.html",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"serve": "node ./node_modules/super-simple-web-server/ ./",
"reference": "node ../../cli/index.js reference"
},
"author": "",
"license": "ISC",
"dependencies": {
"super-simple-web-server": "^1.0.0"
}
}
+11
View File
@@ -0,0 +1,11 @@
Start me with...
```
npm run serve
```
...then you can see me here...
[http://127.0.0.1:3000]()
Keep on truckin!
+27
View File
@@ -0,0 +1,27 @@
html {
font-size: 14px;
}
@media (min-width: 768px) {
html {
font-size: 16px;
}
}
.container {
max-width: 960px;
}
.pricing-header {
max-width: 700px;
}
.card-deck .card {
min-width: 220px;
}
.border-top { border-top: 1px solid #e5e5e5; }
.border-bottom { border-bottom: 1px solid #e5e5e5; }
.box-shadow { box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); }
code { background-color: #eeeeee; }