chore(): sync with main
8
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/core"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
allow:
|
||||
- dependency-name: "@playwright/test"
|
@ -1,21 +0,0 @@
|
||||
name: 'Test Core E2E'
|
||||
description: 'Test Core E2E'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
- name: Install Dependencies
|
||||
run: npm install
|
||||
working-directory: ./core
|
||||
shell: bash
|
||||
- uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-core
|
||||
path: ./core
|
||||
filename: CoreBuild.zip
|
||||
- name: Test
|
||||
run: npm run test.e2e -- --ci --no-build
|
||||
shell: bash
|
||||
working-directory: ./core
|
@ -29,7 +29,7 @@ runs:
|
||||
working-directory: ./core
|
||||
- name: Test
|
||||
if: inputs.update != 'true'
|
||||
run: npx playwright test --shard=${{ inputs.shard }}/${{ inputs.totalShards }}
|
||||
run: npm run test.e2e -- --shard=${{ inputs.shard }}/${{ inputs.totalShards }}
|
||||
shell: bash
|
||||
working-directory: ./core
|
||||
- name: Test and Update
|
||||
@ -51,7 +51,7 @@ runs:
|
||||
# which is why we not using the upload-archive
|
||||
# composite step here.
|
||||
run: |
|
||||
npx playwright test --shard=${{ inputs.shard }}/${{ inputs.totalShards }} --update-snapshots
|
||||
npm run test.e2e -- --shard=${{ inputs.shard }}/${{ inputs.totalShards }} --update-snapshots
|
||||
git add src/\*.png --force
|
||||
mkdir updated-screenshots
|
||||
cd ../ && rsync -R --progress $(git diff --name-only --cached) core/updated-screenshots
|
||||
|
7
.github/workflows/build.yml
vendored
@ -42,13 +42,6 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-core-spec
|
||||
|
||||
test-core-e2e:
|
||||
needs: [build-core]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/workflows/actions/test-core-e2e
|
||||
|
||||
test-core-screenshot:
|
||||
strategy:
|
||||
# This ensures that all screenshot shard
|
||||
|
26
CHANGELOG.md
@ -3,6 +3,32 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [6.4.0](https://github.com/ionic-team/ionic-framework/compare/v6.3.10...v6.4.0) (2022-12-07)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **modal:** data and role are passed to canDismiss ([#26384](https://github.com/ionic-team/ionic-framework/issues/26384)) ([1b30fc9](https://github.com/ionic-team/ionic-framework/commit/1b30fc97d33e761866b4bcf7518efcdeb753032d)), closes [#26292](https://github.com/ionic-team/ionic-framework/issues/26292)
|
||||
* **toast:** add global config toastDuration ([#26425](https://github.com/ionic-team/ionic-framework/issues/26425)) ([a67a827](https://github.com/ionic-team/ionic-framework/commit/a67a827fedc8adf44a35c786f615871facca60fc))
|
||||
* **toggle:** add toggleOnOffLabels global config option ([#26087](https://github.com/ionic-team/ionic-framework/issues/26087)) ([43e2b39](https://github.com/ionic-team/ionic-framework/commit/43e2b3975d003e29b8060e5f5484bfb3daf457a2))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.3.10](https://github.com/ionic-team/ionic-framework/compare/v6.3.9...v6.3.10) (2022-12-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** add flipRTL to monthAndYear dropdown icon ([#26378](https://github.com/ionic-team/ionic-framework/issues/26378)) ([13fe669](https://github.com/ionic-team/ionic-framework/commit/13fe669dc14eb4c9feda8ee956fec42b994b0f96))
|
||||
* **datetime:** md highlight does not clip at start or end of month ([#26366](https://github.com/ionic-team/ionic-framework/issues/26366)) ([fcfbcdb](https://github.com/ionic-team/ionic-framework/commit/fcfbcdbc200b1354b9128a691fbd9b68d50d8668)), closes [#24891](https://github.com/ionic-team/ionic-framework/issues/24891)
|
||||
* **segment:** scrolling button into view is more consistent ([#26369](https://github.com/ionic-team/ionic-framework/issues/26369)) ([a2d570b](https://github.com/ionic-team/ionic-framework/commit/a2d570b7ad8b799b072ba6eb79d8fe4c6dd77cf0)), closes [#26368](https://github.com/ionic-team/ionic-framework/issues/26368)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.3.9](https://github.com/ionic-team/ionic-framework/compare/v6.3.8...v6.3.9) (2022-11-30)
|
||||
|
||||
|
||||
|
@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [6.4.0](https://github.com/ionic-team/ionic/compare/v6.3.10...v6.4.0) (2022-12-07)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.3.10](https://github.com/ionic-team/ionic/compare/v6.3.9...v6.3.10) (2022-12-07)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.3.9](https://github.com/ionic-team/ionic/compare/v6.3.8...v6.3.9) (2022-11-30)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
18
angular/package-lock.json
generated
@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "6.3.9",
|
||||
"version": "6.4.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/angular",
|
||||
"version": "6.3.9",
|
||||
"version": "6.4.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.3.9",
|
||||
"@ionic/core": "^6.4.0",
|
||||
"ionicons": "^6.0.4",
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"tslib": "^2.0.0"
|
||||
@ -1024,9 +1024,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "6.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.9.tgz",
|
||||
"integrity": "sha512-0JlCGIgLASoxZ6XXEkhCMQzdedvzqI7lsD6zBYPkUyMFOMTff7fZdQg1r9v9IQVHW+UCuyM4xc0MT4YOD4/S3A==",
|
||||
"version": "6.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.4.0.tgz",
|
||||
"integrity": "sha512-rWqXX67bWDD5r5Kleacy4dTBIXcB1gX+2Q5AK7LAtmtHUUuJPqGw/bAWE8hGKlF7ehJTyzb5CYV9XDzb8/00Zw==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.18.0",
|
||||
"ionicons": "^6.0.4",
|
||||
@ -7940,9 +7940,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "6.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.9.tgz",
|
||||
"integrity": "sha512-0JlCGIgLASoxZ6XXEkhCMQzdedvzqI7lsD6zBYPkUyMFOMTff7fZdQg1r9v9IQVHW+UCuyM4xc0MT4YOD4/S3A==",
|
||||
"version": "6.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.4.0.tgz",
|
||||
"integrity": "sha512-rWqXX67bWDD5r5Kleacy4dTBIXcB1gX+2Q5AK7LAtmtHUUuJPqGw/bAWE8hGKlF7ehJTyzb5CYV9XDzb8/00Zw==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.18.0",
|
||||
"ionicons": "^6.0.4",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "6.3.9",
|
||||
"version": "6.4.0",
|
||||
"description": "Angular specific wrappers for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@ -42,7 +42,7 @@
|
||||
"validate": "npm i && npm run lint && npm run test && npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.3.9",
|
||||
"@ionic/core": "^6.4.0",
|
||||
"ionicons": "^6.0.4",
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"tslib": "^2.0.0"
|
||||
|
@ -3,6 +3,42 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [6.4.0](https://github.com/ionic-team/ionic/compare/v6.3.10...v6.4.0) (2022-12-07)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **modal:** data and role are passed to canDismiss ([#26384](https://github.com/ionic-team/ionic/issues/26384)) ([1b30fc9](https://github.com/ionic-team/ionic/commit/1b30fc97d33e761866b4bcf7518efcdeb753032d)), closes [#26292](https://github.com/ionic-team/ionic/issues/26292)
|
||||
* **toast:** add global config toastDuration ([#26425](https://github.com/ionic-team/ionic/issues/26425)) ([a67a827](https://github.com/ionic-team/ionic/commit/a67a827fedc8adf44a35c786f615871facca60fc))
|
||||
* **toggle:** add toggleOnOffLabels global config option ([#26087](https://github.com/ionic-team/ionic/issues/26087)) ([43e2b39](https://github.com/ionic-team/ionic/commit/43e2b3975d003e29b8060e5f5484bfb3daf457a2))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.3.10](https://github.com/ionic-team/ionic/compare/v6.3.9...v6.3.10) (2022-12-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **datetime:** add flipRTL to monthAndYear dropdown icon ([#26378](https://github.com/ionic-team/ionic/issues/26378)) ([13fe669](https://github.com/ionic-team/ionic/commit/13fe669dc14eb4c9feda8ee956fec42b994b0f96))
|
||||
* **datetime:** md highlight does not clip at start or end of month ([#26366](https://github.com/ionic-team/ionic/issues/26366)) ([fcfbcdb](https://github.com/ionic-team/ionic/commit/fcfbcdbc200b1354b9128a691fbd9b68d50d8668)), closes [#24891](https://github.com/ionic-team/ionic/issues/24891)
|
||||
* **segment:** scrolling button into view is more consistent ([#26369](https://github.com/ionic-team/ionic/issues/26369)) ([a2d570b](https://github.com/ionic-team/ionic/commit/a2d570b7ad8b799b072ba6eb79d8fe4c6dd77cf0)), closes [#26368](https://github.com/ionic-team/ionic/issues/26368)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **toast:** add global config toastDuration ([#26401](https://github.com/ionic-team/ionic/issues/26401)) ([e375e9a](https://github.com/ionic-team/ionic/commit/e375e9a1e7d30c481772e84c0ae34f39a019aad3))
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* Revert "feat(toast): add global config toastDuration (#26401)" (#26424) ([b6c0019](https://github.com/ionic-team/ionic/commit/b6c001935b4e51a04aa94b0bd6d849e783c8f607)), closes [#26401](https://github.com/ionic-team/ionic/issues/26401) [#26424](https://github.com/ionic-team/ionic/issues/26424)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.3.9](https://github.com/ionic-team/ionic/compare/v6.3.8...v6.3.9) (2022-11-30)
|
||||
|
||||
|
||||
|
@ -814,7 +814,7 @@ ion-modal,prop,animated,boolean,true,false,false
|
||||
ion-modal,prop,backdropBreakpoint,number,0,false,false
|
||||
ion-modal,prop,backdropDismiss,boolean,true,false,false
|
||||
ion-modal,prop,breakpoints,number[] | undefined,undefined,false,false
|
||||
ion-modal,prop,canDismiss,(() => Promise<boolean>) | boolean,true,false,false
|
||||
ion-modal,prop,canDismiss,((data?: any, role?: string | undefined) => Promise<boolean>) | boolean,true,false,false
|
||||
ion-modal,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
||||
ion-modal,prop,handle,boolean | undefined,undefined,false,false
|
||||
ion-modal,prop,handleBehavior,"cycle" | "none" | undefined,'none',false,false
|
||||
@ -1376,7 +1376,7 @@ ion-toast,prop,animated,boolean,true,false,false
|
||||
ion-toast,prop,buttons,(string | ToastButton)[] | undefined,undefined,false,false
|
||||
ion-toast,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-toast,prop,cssClass,string | string[] | undefined,undefined,false,false
|
||||
ion-toast,prop,duration,number,0,false,false
|
||||
ion-toast,prop,duration,number,config.getNumber('toastDuration', 0),false,false
|
||||
ion-toast,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
||||
ion-toast,prop,header,string | undefined,undefined,false,false
|
||||
ion-toast,prop,htmlAttributes,undefined | { [key: string]: any; },undefined,false,false
|
||||
@ -1386,7 +1386,7 @@ ion-toast,prop,keyboardClose,boolean,false,false,false
|
||||
ion-toast,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
||||
ion-toast,prop,message,IonicSafeString | string | undefined,undefined,false,false
|
||||
ion-toast,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-toast,prop,position,"bottom" | "middle" | "top",'bottom',false,false
|
||||
ion-toast,prop,position,ToastPosition,'bottom',false,false
|
||||
ion-toast,prop,translucent,boolean,false,false,false
|
||||
ion-toast,prop,trigger,string | undefined,undefined,false,false
|
||||
ion-toast,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
|
||||
@ -1428,7 +1428,7 @@ ion-toggle,shadow
|
||||
ion-toggle,prop,checked,boolean,false,false,false
|
||||
ion-toggle,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-toggle,prop,disabled,boolean,false,false,false
|
||||
ion-toggle,prop,enableOnOffLabels,boolean | undefined,undefined,false,false
|
||||
ion-toggle,prop,enableOnOffLabels,boolean | undefined,config.get('toggleOnOffLabels'),false,false
|
||||
ion-toggle,prop,justify,"end" | "space-between" | "start",'space-between',false,false
|
||||
ion-toggle,prop,labelPlacement,"end" | "fixed" | "start",'start',false,false
|
||||
ion-toggle,prop,legacy,boolean | undefined,undefined,false,false
|
||||
|
666
core/package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "6.3.9",
|
||||
"version": "6.4.0",
|
||||
"description": "Base components for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@ -37,7 +37,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@axe-core/playwright": "^4.4.2",
|
||||
"@axe-core/puppeteer": "^4.3.2",
|
||||
"@ionic/eslint-config": "^0.3.0",
|
||||
"@ionic/prettier-config": "^2.0.0",
|
||||
"@jest/core": "^27.5.1",
|
||||
@ -53,7 +52,6 @@
|
||||
"@types/swiper": "5.4.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.17.0",
|
||||
"@typescript-eslint/parser": "^5.17.0",
|
||||
"aws-sdk": "^2.738.0",
|
||||
"clean-css-cli": "^5.6.1",
|
||||
"domino": "^2.1.6",
|
||||
"eslint": "^7.32.0",
|
||||
@ -63,9 +61,7 @@
|
||||
"fs-extra": "^9.0.1",
|
||||
"jest": "^27.5.1",
|
||||
"jest-cli": "^27.5.1",
|
||||
"pixelmatch": "4.0.2",
|
||||
"prettier": "^2.6.1",
|
||||
"puppeteer": "^10.4.0",
|
||||
"rollup": "^2.26.4",
|
||||
"sass": "^1.26.10",
|
||||
"serve": "^14.0.1",
|
||||
@ -94,12 +90,10 @@
|
||||
"prerender.e2e": "node scripts/testing/prerender.js",
|
||||
"prettier": "prettier \"./src/**/*.{html,ts,tsx,js,jsx}\"",
|
||||
"start": "npm run build.css && stencil build --dev --watch --serve",
|
||||
"test": "stencil test --spec --e2e --max-workers=2",
|
||||
"test": "npm run test.spec && npm run test.e2e",
|
||||
"test.spec": "stencil test --spec --max-workers=2",
|
||||
"test.spec.debug": "npx --node-arg=\"--inspect-brk\" stencil test --spec",
|
||||
"test.e2e": "stencil test --e2e --max-workers=2",
|
||||
"test.screenshot": "stencil test --e2e --screenshot --screenshot-connector=scripts/screenshot/dev.js",
|
||||
"test.screenshot.ci": "stencil test --e2e --screenshot --screenshot-connector=scripts/screenshot/ci.js --ci",
|
||||
"test.e2e": "npx playwright test",
|
||||
"test.watch": "jest --watch --no-cache",
|
||||
"test.treeshake": "node scripts/treeshaking.js dist/index.js",
|
||||
"validate": "npm run lint && npm run test && npm run build && npm run test.treeshake"
|
||||
|
3
core/screenshot/.gitignore
vendored
@ -1,3 +0,0 @@
|
||||
images
|
||||
builds
|
||||
compare.html
|
@ -1,218 +0,0 @@
|
||||
const IonicConnector = require('./ionic');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const S3 = require('aws-sdk/clients/s3');
|
||||
const execa = require('execa');
|
||||
const stream = require('stream');
|
||||
|
||||
const BUILD_URL = 'https://github.com/ionic-team/ionic/commit/';
|
||||
const S3_BUCKET = 'screenshot.ionicframework.com';
|
||||
const s3 = new S3({ apiVersion: '2006-03-01' });
|
||||
|
||||
|
||||
class CIScreenshotConnector extends IonicConnector {
|
||||
|
||||
async initBuild(opts) {
|
||||
const { stdout: result } = await execa('git', ['log', '-1', '--format=%H%n%an <%ae>%n%ct%n%s']);
|
||||
const [ sha1, author, timestamp, msg ] = result.split('\n');
|
||||
const sha1short = sha1.slice(0, 7);
|
||||
|
||||
opts.buildId = sha1short;
|
||||
opts.buildMessage = msg;
|
||||
opts.buildAuthor = author;
|
||||
opts.buildUrl = BUILD_URL + sha1short;
|
||||
opts.previewUrl = `https://${S3_BUCKET}/${sha1short}`;
|
||||
opts.buildTimestamp = (timestamp * 1000);
|
||||
|
||||
await super.initBuild(opts);
|
||||
}
|
||||
|
||||
async uploadImage(image) {
|
||||
const file = path.join(this.imagesDir, image);
|
||||
const stream = fs.createReadStream(file);
|
||||
const key = `data/images/${image}`;
|
||||
|
||||
await this.uploadStream(stream, key, { ContentType: 'image/png' });
|
||||
}
|
||||
|
||||
async uploadStream(stream, key, extra = {}) {
|
||||
try {
|
||||
await s3.headObject({ Bucket: S3_BUCKET, Key: key }).promise();
|
||||
} catch (e) {
|
||||
if (e.statusCode !== 404) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
this.logger.debug(`uploading: ${key}`);
|
||||
await s3.upload({ Bucket: S3_BUCKET, Key: key, Body: stream, ...extra }).promise();
|
||||
}
|
||||
}
|
||||
|
||||
async pullMasterBuild() {
|
||||
await super.pullIonicMasterBuild();
|
||||
}
|
||||
|
||||
async publishBuild(results) {
|
||||
const currentBuild = results.currentBuild;
|
||||
|
||||
const timespan = this.logger.createTimeSpan(`publishing build started`);
|
||||
const images = currentBuild.screenshots.map(screenshot => screenshot.image);
|
||||
const imageBatches = [];
|
||||
|
||||
while (images.length > 0) {
|
||||
imageBatches.push(images.splice(0, 10));
|
||||
}
|
||||
|
||||
for (const batch of imageBatches) {
|
||||
await Promise.all(batch.map(async image => this.uploadImage(image)));
|
||||
}
|
||||
|
||||
const buildBuffer = Buffer.from(JSON.stringify(currentBuild, undefined, 2));
|
||||
const buildStream = new stream.PassThrough();
|
||||
buildStream.end(buildBuffer);
|
||||
|
||||
const uploads = [
|
||||
this.uploadStream(buildStream, `data/builds/${currentBuild.id}.json`, { ContentType: 'application/json' }),
|
||||
];
|
||||
|
||||
if (this.updateMaster) {
|
||||
// master build
|
||||
// update the master data with this current build
|
||||
// no need to upload a compare data
|
||||
const buildStream = new stream.PassThrough();
|
||||
buildStream.end(buildBuffer);
|
||||
const key = `data/builds/master.json`;
|
||||
this.logger.debug(`uploading: ${key}`);
|
||||
uploads.push(
|
||||
s3.upload({ Bucket: S3_BUCKET, Key: key, Body: buildStream, ContentType: 'application/json' }).promise()
|
||||
);
|
||||
|
||||
} else {
|
||||
// PR build
|
||||
// not updating master
|
||||
// upload compare data of the PR against the master data
|
||||
const compare = results.compare;
|
||||
compare.url = `https://${S3_BUCKET}/${compare.a.id}/${compare.b.id}`;
|
||||
|
||||
const compareBuffer = Buffer.from(JSON.stringify(compare, undefined, 2));
|
||||
const compareStream = new stream.PassThrough();
|
||||
compareStream.end(compareBuffer);
|
||||
uploads.push(
|
||||
this.uploadStream(compareStream, `data/compares/${compare.id}.json`, { ContentType: 'application/json' })
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.all(uploads);
|
||||
|
||||
timespan.finish(`publishing build finished`);
|
||||
|
||||
await this.uploadTests(results);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
async uploadTests(results) {
|
||||
const timespan = this.logger.createTimeSpan(`uploading tests started`);
|
||||
|
||||
const appRoot = path.join(__dirname, '..', '..');
|
||||
let uploadPaths = [];
|
||||
|
||||
const cssDir = path.join(appRoot, 'css');
|
||||
fs.readdirSync(cssDir).forEach(cssFile => {
|
||||
uploadPaths.push(path.join(cssDir, cssFile));
|
||||
});
|
||||
|
||||
uploadPaths.push(path.join(appRoot, 'scripts', 'testing', 'styles.css'));
|
||||
|
||||
const distDir = path.join(appRoot, 'dist');
|
||||
const distIonicDir = path.join(distDir, 'ionic');
|
||||
fs.readdirSync(distIonicDir).forEach(distIonicFile => {
|
||||
uploadPaths.push(path.join(distIonicDir, distIonicFile));
|
||||
});
|
||||
|
||||
const distIonicSvgDir = path.join(distIonicDir, 'svg');
|
||||
fs.readdirSync(distIonicSvgDir).forEach(distIonicSvgFile => {
|
||||
uploadPaths.push(path.join(distIonicSvgDir, distIonicSvgFile));
|
||||
});
|
||||
|
||||
results.currentBuild.screenshots.forEach(screenshot => {
|
||||
const testDir = path.dirname(screenshot.testPath);
|
||||
const testIndexHtml = path.join(appRoot, testDir, 'index.html');
|
||||
if (!uploadPaths.includes(testIndexHtml)) {
|
||||
uploadPaths.push(testIndexHtml);
|
||||
}
|
||||
});
|
||||
|
||||
uploadPaths = uploadPaths.filter(p => p.endsWith('.js') || p.endsWith('.css') || p.endsWith('.html') || p.endsWith('.svg'));
|
||||
|
||||
const fileCount = uploadPaths.length;
|
||||
|
||||
const uploadBatches = [];
|
||||
while (uploadPaths.length > 0) {
|
||||
uploadBatches.push(uploadPaths.splice(0, 20));
|
||||
}
|
||||
|
||||
for (const batch of uploadBatches) {
|
||||
await Promise.all(batch.map(async uploadPath => {
|
||||
const stream = fs.createReadStream(uploadPath);
|
||||
const relPath = path.relative(appRoot, uploadPath);
|
||||
const key = `data/tests/${results.currentBuild.id}/${relPath}`;
|
||||
|
||||
let contentType = 'text/plain';
|
||||
if (uploadPath.endsWith('.js')) {
|
||||
contentType = 'application/javascript'
|
||||
} else if (uploadPath.endsWith('.css')) {
|
||||
contentType = 'text/css'
|
||||
} else if (uploadPath.endsWith('.html')) {
|
||||
contentType = 'text/html'
|
||||
} else if (uploadPath.endsWith('.svg')) {
|
||||
contentType = 'image/svg+xml'
|
||||
}
|
||||
|
||||
this.logger.debug(`uploading: ${key} ${contentType}`);
|
||||
await s3.upload({ Bucket: S3_BUCKET, Key: key, Body: stream, ContentType: contentType }).promise();
|
||||
}));
|
||||
}
|
||||
|
||||
timespan.finish(`uploading tests finished: ${fileCount} files`);
|
||||
}
|
||||
|
||||
async getScreenshotCache() {
|
||||
const timespan = this.logger.createTimeSpan(`get screenshot cache started`, true);
|
||||
|
||||
try {
|
||||
const ws = fs.createWriteStream(this.screenshotCacheFilePath);
|
||||
const p = `/data/compares/screenshot-cache.json?ts=${Date.now()}`;
|
||||
await this.downloadToStream(ws, p);
|
||||
|
||||
} catch (e) {
|
||||
this.logger.debug(e);
|
||||
}
|
||||
|
||||
timespan.finish(`get screenshot cache finished`);
|
||||
|
||||
return super.getScreenshotCache();
|
||||
}
|
||||
|
||||
async updateScreenshotCache(cache, buildResults) {
|
||||
const timespan = this.logger.createTimeSpan(`update screenshot cache started`, true);
|
||||
|
||||
cache = await super.updateScreenshotCache(cache, buildResults);
|
||||
|
||||
const cacheBuffer = Buffer.from(JSON.stringify(cache, undefined, 2));
|
||||
const cacheStream = new stream.PassThrough();
|
||||
cacheStream.end(cacheBuffer);
|
||||
|
||||
const key = `data/compares/screenshot-cache.json`;
|
||||
this.logger.debug(`uploading: ${key}`);
|
||||
|
||||
await s3.upload({ Bucket: S3_BUCKET, Key: key, Body: cacheStream, ContentType: 'application/json' }).promise();
|
||||
|
||||
timespan.finish(`update screenshot cache finished`);
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = CIScreenshotConnector;
|
@ -1,14 +0,0 @@
|
||||
const IonicConnector = require('./ionic');
|
||||
|
||||
class DevConnector extends IonicConnector {
|
||||
|
||||
async pullMasterBuild() {
|
||||
await super.pullIonicMasterBuild();
|
||||
|
||||
const masterBuild = await super.getMasterBuild();
|
||||
await this.generateJsonpDataUris(masterBuild);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = DevConnector;
|
@ -1,78 +0,0 @@
|
||||
const ScreenshotConnector = require('@stencil/core/screenshot/local-connector');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const https = require('https');
|
||||
|
||||
class IonicConnector extends ScreenshotConnector {
|
||||
|
||||
async pullIonicMasterBuild() {
|
||||
const timespan = this.logger.createTimeSpan(`pull master screenshot images started`);
|
||||
|
||||
const ws = fs.createWriteStream(this.masterBuildFilePath);
|
||||
const p = `/data/builds/master.json?ts=${Date.now()}`;
|
||||
await this.downloadToStream(ws, p);
|
||||
const masterBuild = await this.getMasterBuild();
|
||||
|
||||
const masterImageNames = masterBuild.screenshots.map(s => s.image);
|
||||
const missingImages = masterImageNames.filter(masterImageName => {
|
||||
try {
|
||||
const masterImagePath = path.join(this.imagesDir, masterImageName);
|
||||
fs.accessSync(masterImagePath);
|
||||
return false;
|
||||
} catch (e) {}
|
||||
return true
|
||||
});
|
||||
|
||||
while (missingImages.length > 0) {
|
||||
const images = missingImages.splice(0, 20);
|
||||
|
||||
await Promise.all(images.map(async image => {
|
||||
this.logger.debug(`downloading: ${image}`);
|
||||
|
||||
try {
|
||||
await this.downloadImage(image);
|
||||
} catch (e) {
|
||||
this.logger.error(`Error with ${image}: ${e}`);
|
||||
throw e;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
timespan.finish(`pull master screenshot images finished`);
|
||||
}
|
||||
|
||||
async downloadToStream(stream, p) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = https.request({
|
||||
method: 'GET',
|
||||
hostname: 'screenshot.ionicframework.com',
|
||||
path: p,
|
||||
});
|
||||
|
||||
req.on('response', res => {
|
||||
if (res.statusCode !== 200) {
|
||||
return reject(new Error(`Bad Status Code: ${res.statusCode}`));
|
||||
}
|
||||
|
||||
stream.on('error', reject);
|
||||
stream.on('close', resolve);
|
||||
|
||||
res.on('error', reject);
|
||||
res.pipe(stream);
|
||||
});
|
||||
|
||||
req.on('error', reject);
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
async downloadImage(image) {
|
||||
const stream = fs.createWriteStream(path.join(this.imagesDir, image));
|
||||
const p = `/data/images/${image}`;
|
||||
|
||||
await this.downloadToStream(stream, p);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = IonicConnector;
|
8
core/src/components.d.ts
vendored
@ -1621,7 +1621,7 @@ export namespace Components {
|
||||
/**
|
||||
* Determines whether or not a modal can dismiss when calling the `dismiss` method. If the value is `true` or the value's function returns `true`, the modal will close when trying to dismiss. If the value is `false` or the value's function returns `false`, the modal will not close when trying to dismiss.
|
||||
*/
|
||||
"canDismiss": boolean | (() => Promise<boolean>);
|
||||
"canDismiss": boolean | ((data?: any, role?: string) => Promise<boolean>);
|
||||
/**
|
||||
* The component to display inside of the modal.
|
||||
*/
|
||||
@ -2967,7 +2967,7 @@ export namespace Components {
|
||||
/**
|
||||
* The position of the toast on the screen.
|
||||
*/
|
||||
"position": 'top' | 'bottom' | 'middle';
|
||||
"position": ToastPosition;
|
||||
/**
|
||||
* Present the toast overlay after it has been created.
|
||||
*/
|
||||
@ -5561,7 +5561,7 @@ declare namespace LocalJSX {
|
||||
/**
|
||||
* Determines whether or not a modal can dismiss when calling the `dismiss` method. If the value is `true` or the value's function returns `true`, the modal will close when trying to dismiss. If the value is `false` or the value's function returns `false`, the modal will not close when trying to dismiss.
|
||||
*/
|
||||
"canDismiss"?: boolean | (() => Promise<boolean>);
|
||||
"canDismiss"?: boolean | ((data?: any, role?: string) => Promise<boolean>);
|
||||
/**
|
||||
* The component to display inside of the modal.
|
||||
*/
|
||||
@ -6983,7 +6983,7 @@ declare namespace LocalJSX {
|
||||
/**
|
||||
* The position of the toast on the screen.
|
||||
*/
|
||||
"position"?: 'top' | 'bottom' | 'middle';
|
||||
"position"?: ToastPosition;
|
||||
/**
|
||||
* If `true`, the toast will be translucent. Only applies when the mode is `"ios"` and the device supports [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility).
|
||||
*/
|
||||
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
@ -54,12 +54,7 @@
|
||||
// Calendar / Body
|
||||
// -----------------------------------
|
||||
:host .calendar-body .calendar-month .calendar-month-grid {
|
||||
/**
|
||||
* 3px top padding adds enough spacing at
|
||||
* the top of the container for the selected
|
||||
* day box shadow to display without clipping.
|
||||
*/
|
||||
@include padding(3px, 10px, 0px, 10px);
|
||||
@include padding(4px, 10px);
|
||||
|
||||
/**
|
||||
* Calendar on MD will show an empty row
|
||||
|
@ -317,8 +317,6 @@ ion-picker-column-internal {
|
||||
*/
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -388,3 +388,30 @@ test.describe('datetime: ionChange', () => {
|
||||
await expect(ionChange).not.toHaveReceivedEvent();
|
||||
});
|
||||
});
|
||||
|
||||
test('datetime: md highlight should not clip at start or end of month', async ({ page, skip }, testInfo) => {
|
||||
skip.mode('ios', 'Highlight does not render on iOS');
|
||||
skip.rtl('Highlight does not render differently for RTL.');
|
||||
|
||||
testInfo.annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/ionic-team/ionic-framework/issues/24891',
|
||||
});
|
||||
|
||||
await page.setContent(`
|
||||
<ion-datetime value="2021-01-01"></ion-datetime>
|
||||
`);
|
||||
|
||||
const datetime = page.locator('ion-datetime');
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
expect(await datetime.screenshot()).toMatchSnapshot(
|
||||
`date-highlight-start-of-month-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
|
||||
await datetime.evaluate((el: HTMLIonDatetimeElement) => (el.value = '2021-01-31'));
|
||||
await page.waitForChanges();
|
||||
|
||||
expect(await datetime.screenshot()).toMatchSnapshot(`date-highlight-end-of-month-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
|
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 17 KiB |