Skip to content

Commit 7d38526

Browse files
authored
Merge branch 'main' into feat/delay-ios-launch
2 parents cab0b20 + 5275b55 commit 7d38526

45 files changed

Lines changed: 1219 additions & 661 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/apps_automated_android.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
node-version: 23.5.0
3232

3333
- name: Derive appropriate SHAs for base and head for `nx affected` commands
34-
uses: nrwl/nx-set-shas@826660b82addbef3abff5fa871492ebad618c9e1 # v4.3.3
34+
uses: nrwl/nx-set-shas@afb73a62d26e41464e9254689e1fd6122ee683c1 # v5.0.1
3535
with:
3636
main-branch-name: 'main'
3737

@@ -65,7 +65,7 @@ jobs:
6565
sudo udevadm trigger --name-match=kvm
6666
6767
- name: Run tests on Android Emulator
68-
uses: reactivecircus/android-emulator-runner@b530d96654c385303d652368551fb075bc2f0b6b # v2.35.0
68+
uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a # v2.37.0
6969
with:
7070
api-level: 35
7171
arch: x86_64

.github/workflows/apps_automated_ios.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
node-version: 23.5.0
3535

3636
- name: Derive appropriate SHAs for base and head for `nx affected` commands
37-
uses: nrwl/nx-set-shas@826660b82addbef3abff5fa871492ebad618c9e1 # v4.3.3
37+
uses: nrwl/nx-set-shas@afb73a62d26e41464e9254689e1fd6122ee683c1 # v5.0.1
3838
with:
3939
main-branch-name: 'main'
4040

@@ -52,10 +52,9 @@ jobs:
5252
run: npx nx run-many --target=test --configuration=ci --projects=core
5353

5454
- name: Start iOS Simulator
55-
uses: futureware-tech/simulator-action@dab10d813144ef59b48d401cd95da151222ef8cd # v4
55+
uses: futureware-tech/simulator-action@e89aa8f93d3aec35083ff49d2854d07f7186f7f5 # v5
5656
with:
5757
model: 'iPhone 16 Pro'
58-
os_version: '18.4'
5958

6059
- name: Run tests on iOS Simulator
6160
run: npx nx test apps-automated -c=ios

.github/workflows/dependency-review.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ jobs:
1919
- name: 'Checkout Repository'
2020
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
2121
- name: 'Dependency Review'
22-
uses: actions/dependency-review-action@05fe4576374b728f0c523d6a13d64c25081e0803 # v4.8.3
22+
uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0

.github/workflows/npm_release_tns_core.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919

2020
steps:
2121
- name: Harden the runner (Audit all outbound calls)
22-
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
22+
uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
2323
with:
2424
egress-policy: audit
2525

.github/workflows/npm_release_types.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919

2020
steps:
2121
- name: Harden the runner (Audit all outbound calls)
22-
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
22+
uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
2323
with:
2424
egress-policy: audit
2525

.github/workflows/npm_release_webpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818

1919
steps:
2020
- name: Harden the runner (Audit all outbound calls)
21-
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
21+
uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
2222
with:
2323
egress-policy: audit
2424

.github/workflows/secure_nx_release.yml

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,11 @@ jobs:
4545
env:
4646
# Optional: provide Nx Cloud token if used in this repo
4747
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
48+
NEXT_PRERELEASE_PROJECT_ALLOWLIST: core,webpack5
4849

4950
steps:
5051
- name: Harden the runner (Audit all outbound calls)
51-
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
52+
uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
5253
with:
5354
egress-policy: audit
5455

@@ -124,8 +125,8 @@ jobs:
124125
fi
125126
fi
126127
127-
# Only consider libs under packages/* and exclude items configured as non-releaseable.
128-
affected_json=$(npx nx show projects --affected --base "$base" --head "$head" --type lib --projects "packages/*" --exclude "ui-mobile-base,types-minimal,winter-tc,types,types-ios,types-android" --json)
128+
# Only consider main-branch prerelease libraries allowed for automatic next publishes.
129+
affected_json=$(npx nx show projects --affected --base "$base" --head "$head" --type lib --projects "$NEXT_PRERELEASE_PROJECT_ALLOWLIST" --json)
129130
affected_list=$(printf '%s' "$affected_json" | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const a=JSON.parse(s||"[]");process.stdout.write(a.join(","));});')
130131
affected_count=$(printf '%s' "$affected_json" | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const a=JSON.parse(s||"[]");process.stdout.write(String(a.length));});')
131132
@@ -337,7 +338,6 @@ jobs:
337338
338339
- name: nx release publish (token, dispatch)
339340
if: ${{ steps.ctx.outputs.mode == 'dispatch' && steps.ctx.outputs.dry_run != 'true' && vars.USE_NPM_TOKEN == 'true' }}
340-
shell: bash
341341
env:
342342
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
343343
NPM_CONFIG_PROVENANCE: true
@@ -353,7 +353,6 @@ jobs:
353353
354354
- name: nx release publish (token, dispatch dry-run)
355355
if: ${{ steps.ctx.outputs.mode == 'dispatch' && inputs.dry-run && vars.USE_NPM_TOKEN == 'true' }}
356-
shell: bash
357356
env:
358357
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
359358
NPM_CONFIG_PROVENANCE: true
@@ -403,9 +402,23 @@ jobs:
403402
- name: Summary
404403
if: always()
405404
run: |
405+
mode="${{ steps.ctx.outputs.mode }}"
406+
406407
echo "Nx Release completed."
407-
echo "- mode: ${{ steps.ctx.outputs.mode }}"
408+
echo "- mode: ${mode}"
408409
echo "- dist-tag: ${{ steps.ctx.outputs.mode == 'tag' && steps.taginfo.outputs.dist_tag || steps.ctx.outputs.dist_tag }}"
409410
echo "- scope: '${{ steps.ctx.outputs.scope }}'"
411+
echo "- next-prerelease-allowlist: ${NEXT_PRERELEASE_PROJECT_ALLOWLIST}"
412+
if [[ "$mode" == "main" ]]; then
413+
echo "- projects: ${{ steps.affected.outputs.projects }}"
414+
elif [[ "$mode" == "dispatch" ]]; then
415+
if [[ -n "${{ steps.ctx.outputs.scope }}" ]]; then
416+
echo "- projects: ${{ steps.ctx.outputs.scope }}"
417+
else
418+
echo "- projects: all configured release projects"
419+
fi
420+
else
421+
echo "- project: ${{ steps.taginfo.outputs.project }}"
422+
fi
410423
echo "- dry-run: ${{ steps.ctx.outputs.dry_run }}"
411424
echo "- use-token: ${{ vars.USE_NPM_TOKEN == 'true' }}"

apps/automated/src/http/http-tests.ts

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ImageSource } from '@nativescript/core';
22
import * as TKUnit from '../tk-unit';
33
import * as http from '@nativescript/core/http';
44
import * as fs from '@nativescript/core/file-system';
5-
import { addHeader } from '@nativescript/core/http/http-request';
5+
import { requestInternal, addHeader, BaseHttpContent } from '@nativescript/core/http/http-request-internal';
66

77
export var test_getString_isDefined = function () {
88
TKUnit.assert(typeof http.getString !== 'undefined', 'Method http.getString() should be defined!');
@@ -329,6 +329,89 @@ export var test_request_requestShouldTimeout = function (done) {
329329
});
330330
};
331331

332+
export var test_requestInternal_responseStatusCodeShouldBeDefined = function (done) {
333+
requestInternal({ url: 'https://http-echo.nativescript.org/get', method: 'GET' }).then(
334+
function (response) {
335+
//// Argument (response) is HttpResponse!
336+
var statusCode = response.statusCode;
337+
try {
338+
TKUnit.assert(typeof statusCode !== 'undefined', 'response.statusCode should be defined!');
339+
done(null);
340+
} catch (err) {
341+
done(err);
342+
}
343+
},
344+
function (e) {
345+
//// Argument (e) is Error!
346+
done(e);
347+
},
348+
);
349+
};
350+
351+
export var test_requestInternal_responseContentShouldExposeNativeContentFunctions = function (done) {
352+
requestInternal({ url: 'https://http-echo.nativescript.org/get', method: 'GET' }).then(
353+
function (response) {
354+
try {
355+
TKUnit.assert(typeof response.content.toNativeImage === 'function' && typeof response.content.toNativeString === 'function', `response.content should expose native content functions!`);
356+
done(null);
357+
} catch (err) {
358+
done(err);
359+
}
360+
},
361+
function (e) {
362+
//// Argument (e) is Error!
363+
done(e);
364+
},
365+
);
366+
};
367+
368+
export var test_requestInternal_responseContentShouldExposeHandlerFunctions = function (done) {
369+
const responseHandler = {
370+
toDummy1: () => 'dummy1',
371+
toDummy2: () => 'dummy2',
372+
};
373+
374+
requestInternal({ url: 'https://http-echo.nativescript.org/get', method: 'GET' }, responseHandler).then(
375+
function (response) {
376+
try {
377+
TKUnit.assert(typeof response.content.toDummy1 === 'function' && typeof response.content.toDummy2 === 'function', `response.content should expose content handler functions!`);
378+
done(null);
379+
} catch (err) {
380+
done(err);
381+
}
382+
},
383+
function (e) {
384+
//// Argument (e) is Error!
385+
done(e);
386+
},
387+
);
388+
};
389+
390+
export var test_requestInternal_responseHandlerShouldBeAvailable = function (done) {
391+
const suffix = '-nsformatted';
392+
const responseHandler = {
393+
toFormattedString: function (this: BaseHttpContent) {
394+
return this.toNativeString() + suffix;
395+
},
396+
};
397+
398+
requestInternal({ url: 'https://http-echo.nativescript.org/get', method: 'GET' }, responseHandler).then(
399+
function (response) {
400+
const value = response.content.toFormattedString();
401+
try {
402+
TKUnit.assert(typeof value === 'string' && value.endsWith(suffix), `response.content.toFormattedString should return the response string appended with ${suffix} at the end!`);
403+
done(null);
404+
} catch (err) {
405+
done(err);
406+
}
407+
},
408+
function (e) {
409+
//// Argument (e) is Error!
410+
done(e);
411+
},
412+
);
413+
};
414+
332415
export var test_request_responseStatusCodeShouldBeDefined = function (done) {
333416
var result: http.HttpResponse;
334417

apps/automated/src/ui/image/image-tests.ts

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Image } from '@nativescript/core/ui/image';
22
import { StackLayout } from '@nativescript/core/ui/layouts/stack-layout';
33
import { GridLayout } from '@nativescript/core/ui/layouts/grid-layout';
4-
import { PropertyChangeData, Utils } from '@nativescript/core';
4+
import { PropertyChangeData } from '@nativescript/core';
55
import * as utils from '@nativescript/core/utils';
66
import * as TKUnit from '../../tk-unit';
77
import { getColor } from '../../ui-helper';
@@ -27,8 +27,6 @@ if (__ANDROID__) {
2727
appHelpers.initImageCache(Application.android.startActivity, appHelpers.CacheMode.memory); // use memory cache only.
2828
}
2929

30-
const expectLayoutRequest = __APPLE__ && Utils.SDK_VERSION >= 18;
31-
3230
export const test_Image_Members = function () {
3331
const image = new ImageModule.Image();
3432
TKUnit.assert(types.isUndefined(image.src), 'Image.src is defined');
@@ -269,17 +267,17 @@ export const test_SettingImageSourceWhenSizedToParentDoesNotRequestLayout = ios(
269267

270268
let mainPage = helper.getCurrentPage();
271269
mainPage.content = host;
272-
TKUnit.waitUntilReady(() => host.isLoaded);
270+
271+
const nativeHostView = host.nativeViewProtected as UIView;
272+
273+
// Check if native view layer is still marked as dirty before proceeding
274+
TKUnit.waitUntilReady(() => host.isLoaded && nativeHostView?.layer && !nativeHostView.layer.needsLayout());
273275

274276
let called = false;
275277
image.requestLayout = () => (called = true);
276278
image.src = '~/assets/logo.png';
277279

278-
if (expectLayoutRequest) {
279-
TKUnit.assertTrue(called, 'image.requestLayout should be called.');
280-
} else {
281-
TKUnit.assertFalse(called, 'image.requestLayout should not be called.');
282-
}
280+
TKUnit.assertFalse(called, 'image.requestLayout should not be called.');
283281
});
284282

285283
export const test_SettingImageSourceWhenFixedWidthAndHeightDoesNotRequestLayout = ios(() => {
@@ -291,17 +289,17 @@ export const test_SettingImageSourceWhenFixedWidthAndHeightDoesNotRequestLayout
291289

292290
let mainPage = helper.getCurrentPage();
293291
mainPage.content = host;
294-
TKUnit.waitUntilReady(() => host.isLoaded);
292+
293+
const nativeHostView = host.nativeViewProtected as UIView;
294+
295+
// Check if native view layer is still marked as dirty before proceeding
296+
TKUnit.waitUntilReady(() => host.isLoaded && nativeHostView?.layer && !nativeHostView.layer.needsLayout());
295297

296298
let called = false;
297299
image.requestLayout = () => (called = true);
298300
image.src = '~/assets/logo.png';
299301

300-
if (expectLayoutRequest) {
301-
TKUnit.assertTrue(called, 'image.requestLayout should be called.');
302-
} else {
303-
TKUnit.assertFalse(called, 'image.requestLayout should not be called.');
304-
}
302+
TKUnit.assertFalse(called, 'image.requestLayout should not be called.');
305303
});
306304

307305
export const test_SettingImageSourceWhenSizedToContentShouldInvalidate = ios(() => {

apps/automated/src/ui/label/label-tests.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import * as helper from '../../ui-helper';
66

77
const testDir = 'ui/label';
88

9-
const expectLayoutRequest = __APPLE__ && Utils.SDK_VERSION >= 18;
10-
119
export class LabelTest extends testModule.UITest<Label> {
1210
public create(): Label {
1311
const label = new Label();
@@ -603,7 +601,11 @@ export class LabelTest extends testModule.UITest<Label> {
603601

604602
let mainPage = helper.getCurrentPage();
605603
mainPage.content = host;
606-
TKUnit.waitUntilReady(() => host.isLoaded);
604+
605+
const nativeHostView = host.nativeViewProtected as UIView;
606+
607+
// Check if native view layer is still marked as dirty before proceeding
608+
TKUnit.waitUntilReady(() => host.isLoaded && nativeHostView?.layer && !nativeHostView.layer.needsLayout());
607609

608610
let called = false;
609611
label.requestLayout = () => (called = true);
@@ -618,7 +620,7 @@ export class LabelTest extends testModule.UITest<Label> {
618620
}
619621

620622
public test_SettingTextWhenInFixedSizeGridShouldNotRequestLayout() {
621-
this.requestLayoutFixture(expectLayoutRequest, '', (label) => {
623+
this.requestLayoutFixture(false, '', (label) => {
622624
label.textWrap = false;
623625
let host = new GridLayout();
624626
host.width = 100;
@@ -629,7 +631,7 @@ export class LabelTest extends testModule.UITest<Label> {
629631
}
630632

631633
public test_ChangingTextWhenInFixedSizeGridShouldNotRequestLayout() {
632-
this.requestLayoutFixture(expectLayoutRequest, 'Hello World', (label) => {
634+
this.requestLayoutFixture(false, 'Hello World', (label) => {
633635
label.textWrap = false;
634636
let host = new GridLayout();
635637
host.width = 100;
@@ -640,7 +642,7 @@ export class LabelTest extends testModule.UITest<Label> {
640642
}
641643

642644
public test_SettingTextWhenFixedWidthAndHeightDoesNotRequestLayout() {
643-
this.requestLayoutFixture(expectLayoutRequest, '', (label) => {
645+
this.requestLayoutFixture(false, '', (label) => {
644646
label.textWrap = false;
645647
let host = new StackLayout();
646648
label.width = 100;
@@ -651,7 +653,7 @@ export class LabelTest extends testModule.UITest<Label> {
651653
}
652654

653655
public test_ChangingTextWhenFixedWidthAndHeightDoesNotRequestLayout() {
654-
this.requestLayoutFixture(expectLayoutRequest, 'Hello World', (label) => {
656+
this.requestLayoutFixture(false, 'Hello World', (label) => {
655657
label.textWrap = false;
656658
let host = new StackLayout();
657659
label.width = 100;
@@ -692,7 +694,7 @@ export class LabelTest extends testModule.UITest<Label> {
692694
}
693695

694696
public test_ChangingTextOnSingleLineTextWhenWidthIsSizedToParentAndHeightIsSizedToContentShouldNotRequestLayout() {
695-
this.requestLayoutFixture(expectLayoutRequest, 'Hello World', (label) => {
697+
this.requestLayoutFixture(false, 'Hello World', (label) => {
696698
label.textWrap = false;
697699
let host = new StackLayout();
698700
host.width = 100;

0 commit comments

Comments
 (0)