Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 389f5b7

Browse files
authored
refactor: ActionBar directive and patching of Views in renderer (#979)
refactor(renderer): invoke removeFromQueue for every element refactor(action-bar): insert ActionItems at correct positions ActionBar's insertChild method is now passed a next view argument. When the view to insert is an ActionItem, next is used to find the correct position to insert the new item. refactor(renderer): patch every View with ViewExtensions When a View is passed through the renderer on insert/remove it's patched with ViewExtensions for its class. That is done for parent views and for child views. fixes #689, fixes #978
1 parent a262281 commit 389f5b7

File tree

11 files changed

+419
-80
lines changed

11 files changed

+419
-80
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Component } from "@angular/core";
2+
3+
@Component({
4+
template: `
5+
<ActionBar title="Action Bar Dynamic Items">
6+
<NavigationButton
7+
*ngIf="showNavigationButton"
8+
android.systemIcon="ic_menu_back"
9+
></NavigationButton>
10+
11+
<ActionItem text="one" *ngIf="show1"></ActionItem>
12+
<ActionItem text="two" *ngIf="show2"></ActionItem>
13+
</ActionBar>
14+
15+
<StackLayout>
16+
<Button text="toggle nav" (tap)="showNavigationButton = !showNavigationButton"></Button>
17+
<Button text="toggle 1" (tap)="show1 = !show1"></Button>
18+
<Button text="toggle 2" (tap)="show2 = !show2"></Button>
19+
</StackLayout>
20+
`
21+
})
22+
export class ActionBarDynamicItemsComponent {
23+
public showNavigationButton = true;
24+
public show1 = true;
25+
public show2 = true;
26+
}
27+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Component } from "@angular/core";
2+
3+
@Component({
4+
template: `
5+
<ActionBarExtension>
6+
<ActionItem (tap)="show = !show" text="toggle">
7+
</ActionItem>
8+
9+
<ActionItem *ngIf="show" text="conditional">
10+
</ActionItem>
11+
</ActionBarExtension>
12+
`
13+
})
14+
export class ActionBarExtensionComponent {
15+
public show = true;
16+
}

‎e2e/renderer/app/app-routing.module.ts‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
22
import { NativeScriptRouterModule } from "nativescript-angular/router";
33

4+
import { ActionBarDynamicItemsComponent } from "./action-bar/action-bar-dynamic-items.component";
5+
import { ActionBarExtensionComponent } from "./action-bar/action-bar-extension.component";
6+
47
import { ListComponent } from "./list.component";
58
import { NgForComponent } from "./ngfor.component";
69
import { NgForOfComponent } from "./ngforof.component";
@@ -17,6 +20,14 @@ export const routes = [
1720
redirectTo: "/list",
1821
pathMatch: "full"
1922
},
23+
{
24+
path: "action-bar-dynamic",
25+
component: ActionBarDynamicItemsComponent,
26+
},
27+
{
28+
path: "action-bar-extension",
29+
component: ActionBarExtensionComponent,
30+
},
2031
{
2132
path: "list",
2233
component: ListComponent,
@@ -56,6 +67,9 @@ export const routes = [
5667
];
5768

5869
export const navigatableComponents = [
70+
ActionBarDynamicItemsComponent,
71+
ActionBarExtensionComponent,
72+
5973
ListComponent,
6074
NgForComponent,
6175
NgForOfComponent,

‎e2e/renderer/app/content-view.component.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Component } from "@angular/core";
22

33
@Component({
4-
selector: "my-app",
54
template: `
65
<ActionBar title="Content View">
76
<ActionItem (tap)="toggle()">

‎e2e/renderer/app/list.component.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { Component } from "@angular/core";
33
@Component({
44
template: `
55
<FlexboxLayout flexDirection="column">
6+
<Button text="ActionBar dynamic" [nsRouterLink]="['/action-bar-dynamic']"></Button>
7+
<Button text="ActionBarExtension" [nsRouterLink]="['/action-bar-extension']"></Button>
68
<Button text="NgFor" [nsRouterLink]="['/ngfor']"></Button>
79
<Button text="NgForOf" [nsRouterLink]="['/ngforof']"></Button>
810
<Button text="NgIf no layout" [nsRouterLink]="['/ngif-no-layout']"></Button>
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import {
2+
AppiumDriver,
3+
createDriver,
4+
SearchOptions,
5+
elementHelper,
6+
} from "nativescript-dev-appium";
7+
8+
import { isOnTheLeft } from "./helpers/location";
9+
import { DriverWrapper, ExtendedUIElement } from "./helpers/appium-elements";
10+
11+
describe("Action Bar scenario", () => {
12+
let driver: AppiumDriver;
13+
let driverWrapper: DriverWrapper;
14+
15+
describe("dynamically add/remove ActionItems", async () => {
16+
let firstActionItem: ExtendedUIElement;
17+
let secondActionItem: ExtendedUIElement;
18+
let toggleFirstButton: ExtendedUIElement;
19+
let toggleSecondButton: ExtendedUIElement;
20+
21+
before(async () => {
22+
driver = await createDriver();
23+
driverWrapper = new DriverWrapper(driver);
24+
});
25+
26+
after(async () => {
27+
await driver.quit();
28+
console.log("Driver quits!");
29+
});
30+
31+
it("should navigate to page", async () => {
32+
const navigationButton =
33+
await driverWrapper.findElementByText("ActionBar dynamic", SearchOptions.exact);
34+
await navigationButton.click();
35+
36+
const actionBar =
37+
await driverWrapper.findElementByText("Action Bar Dynamic Items", SearchOptions.exact);
38+
});
39+
40+
it("should find elements", async () => {
41+
firstActionItem = await driverWrapper.findElementByText("one");
42+
secondActionItem = await driverWrapper.findElementByText("two");
43+
44+
toggleFirstButton = await driverWrapper.findElementByText("toggle 1");
45+
toggleSecondButton = await driverWrapper.findElementByText("toggle 2");
46+
});
47+
48+
it("should initially render the action items in the correct order", async () => {
49+
await checkOrderIsCorrect();
50+
});
51+
52+
it("should detach first element when its condition is false", done => {
53+
(async () => {
54+
await toggleFirst();
55+
56+
try {
57+
await driverWrapper.findElementByText("one", SearchOptions.exact);
58+
} catch (e) {
59+
done();
60+
}
61+
})();
62+
});
63+
64+
it("should attach first element in the correct position", async () => {
65+
await toggleFirst();
66+
await checkOrderIsCorrect();
67+
});
68+
69+
it("should detach second element when its condition is false", done => {
70+
(async () => {
71+
await toggleSecond();
72+
73+
try {
74+
await driverWrapper.findElementByText("two", SearchOptions.exact);
75+
} catch (e) {
76+
done();
77+
}
78+
})();
79+
});
80+
81+
it("should attach second element in the correct position", async () => {
82+
await toggleSecond();
83+
await checkOrderIsCorrect();
84+
});
85+
86+
it("should detach and then reattach both at correct places", async () => {
87+
await toggleFirst();
88+
await toggleSecond();
89+
90+
await toggleFirst();
91+
await toggleSecond();
92+
93+
await checkOrderIsCorrect();
94+
});
95+
96+
const checkOrderIsCorrect = async () => {
97+
await isOnTheLeft(firstActionItem, secondActionItem);
98+
};
99+
100+
const toggleFirst = async () => {
101+
toggleFirstButton = await toggleFirstButton.refetch();
102+
await toggleFirstButton.click();
103+
};
104+
105+
const toggleSecond = async () => {
106+
toggleSecondButton = await toggleSecondButton.refetch();
107+
await toggleSecondButton.click();
108+
};
109+
110+
});
111+
112+
describe("Action Bar extension with dynamic ActionItem", async () => {
113+
let toggleButton: ExtendedUIElement;
114+
let conditional: ExtendedUIElement;
115+
116+
before(async () => {
117+
driver = await createDriver();
118+
driverWrapper = new DriverWrapper(driver);
119+
});
120+
121+
after(async () => {
122+
await driver.quit();
123+
console.log("Driver quits!");
124+
});
125+
126+
it("should navigate to page", async () => {
127+
const navigationButton =
128+
await driverWrapper.findElementByText("ActionBarExtension", SearchOptions.exact);
129+
await navigationButton.click();
130+
});
131+
132+
it("should find elements", async () => {
133+
toggleButton = await driverWrapper.findElementByText("toggle");
134+
conditional = await driverWrapper.findElementByText("conditional");
135+
});
136+
137+
it("should detach conditional action item when its condition is false", done => {
138+
(async () => {
139+
await toggle();
140+
141+
try {
142+
await driverWrapper.findElementByText("conditional", SearchOptions.exact);
143+
} catch (e) {
144+
done();
145+
}
146+
})();
147+
});
148+
149+
it("should reattach conditional action item at correct place", async () => {
150+
await toggle();
151+
await checkOrderIsCorrect();
152+
});
153+
154+
const checkOrderIsCorrect = async () => {
155+
await isOnTheLeft(toggleButton, conditional);
156+
};
157+
158+
const toggle = async () => {
159+
toggleButton = await toggleButton.refetch();
160+
await toggleButton.click();
161+
};
162+
});
163+
});

‎e2e/renderer/e2e/helpers/appium-elements.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,25 @@ export class DriverWrapper {
3838

3939
return result;
4040
}
41+
42+
@refetchable()
43+
async findElementByXPath(...args: any[]): Promise<ExtendedUIElement> {
44+
const result = await (<any>this.driver).findElementByXPath(...args);
45+
46+
return result;
47+
}
48+
49+
@refetchable()
50+
async findElementsByXPath(...args: any[]): Promise<ExtendedUIElement[]> {
51+
const result = await (<any>this.driver).findElementsByXPath(...args);
52+
53+
return result || [];
54+
}
55+
56+
@refetchable()
57+
async findElementsByClassName(...args: any[]): Promise<ExtendedUIElement[]> {
58+
const result = await (<any>this.driver).findElementsByClassName(...args);
59+
60+
return result || [];
61+
}
4162
}

‎e2e/renderer/e2e/helpers/location.ts‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,14 @@ export const isAbove = async (first: ExtendedUIElement, second: ExtendedUIElemen
1111

1212
assert.isTrue(firstY < secondY);
1313
}
14+
15+
export const isOnTheLeft = async (first: ExtendedUIElement, second: ExtendedUIElement) => {
16+
first = await first.refetch();
17+
second = await second.refetch();
18+
19+
const { x: firstX } = await first.location();
20+
const { x: secondX } = await second.location();
21+
22+
assert.isTrue(firstX < secondX);
23+
}
24+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /